Uma loja em que o catálogo é lido em tempo real, não copiado uma vez e esquecido.
Construímos lojas e, por cima delas, a camada que normalmente falta: o agente que responde ao cliente lê o preço e o stock diretamente da loja, no momento da pergunta, e recusa inventar um preço não publicado.
Já construídoSe poate verifica din exterior chiar acum, fără să ne întrebi pe noi. Punctul nostru de catalog livrat unui distribuitor răspunde 200 și spune „154 rezultate”; interfața publică a magazinului lui, interogată direct, întoarce antetul `x-wp-total: 154`. Aceeași cifră, două surse independente, verificat pe 06.09.2026. A doua implementare e integrată în platforma de asistenți: serviciul `storeCatalog.service.js` plus trei unelte pe care agentul le poate chema. Rezerva care trebuie spusă: acest al doilea traseu stă pe o ramură de dezvoltare (`feat/store-catalog-global`, `481cfa0`) și nu e încă unificat în trunchi — deci e livrat pentru clienții pe care i-am conectat, nu pornit implicit pentru toți.
A maioria das «integrações de catálogo» é, na verdade, uma exportação. Alguém descarrega os produtos uma vez, cola-os num ficheiro e, daí em diante, o agente que fala com o cliente lê uma fotografia antiga da loja. Funciona impecavelmente até à primeira alteração de preço ou ao primeiro produto esgotado — e então erra com convicção, o que é pior do que ficar calado.
Nós lemos a loja no momento da pergunta. Para lojas em WooCommerce existe uma interface pública — Store API — que devolve produtos, preços e disponibilidade sem chaves, sem conta, sem plugin instalado. O endereço é `/wp-json/wc/store/v1/products`, pedimos 100 produtos por página, com tempo máximo de espera de 20 segundos, e ficamos a saber pelo cabeçalho da resposta quantas páginas existem, em vez de adivinhar. A primeira página é obtida sozinha, o resto em paralelo.
A parte que separa uma integração correta de uma que parece correta é a tradução do preço. A Store API não devolve «129,90»; devolve uma cadeia de dígitos em unidades menores e, separadamente, quantas casas decimais tem a moeda. Quem divide por 100 por hábito erra em silêncio em qualquer moeda que não tenha duas casas decimais. E mais importante: um preço zero não quer dizer grátis, quer dizer não publicado. Para nós, zero torna-se «preço sob consulta — a confirmar com os colegas», e o agente recebe a instrução explícita para não inventar. Vê-se na resposta pública do ponto de catálogo, agora mesmo.
Além do catálogo vêm as outras peças, cada uma com o seu estado real: carrinho e envio de encomenda para o sistema de gestão do restaurante ou da loja, pagamento através da interface MAIB para comerciantes ou através do Stripe, recuperação dos carrinhos abandonados, acompanhamento do estado da encomenda com sincronização a cada 15 minutos. Onde não temos uma integração funcional — e há casos assim — está escrito abaixo exatamente quais são.
Qué incluye
El trabajo, por componentes
Catálogo lido em tempo real, sem chaves e sem plugin
Para WooCommerce usamos o Store API, a interface pública da loja: `/wp-json/wc/store/v1/products`, 100 produtos por página, tempo máximo de espera de 20 segundos, um identificador de cliente próprio no cabeçalho e aceitação exclusiva do código 200. O número de páginas é lido do cabeçalho `x-wp-totalpages`, e o total de produtos de `x-wp-total` — não paginamos até nos denunciarmos. A primeira página é obtida sozinha, o resto em paralelo, com um limite de 30 páginas. Não se instala nada na loja e não nos são dadas chaves de comerciante.
O preço traduzido corretamente, e zero tratado como não publicado
A Store API devolve o preço como string em unidades menores, mais o número de casas decimais da moeda. Dividimos por dez elevado a esse número, não por 100 fixo — caso contrário, qualquer moeda com outro número de casas decimais fica errada e ninguém repara. Zero torna-se `null`, e na resposta aparece „preço sob consulta — a confirmar com colegas”, juntamente com a instrução explícita dada ao agente para não inventar e pedir a confirmação de um colega. O preço sai em duas formas ao mesmo tempo: texto pronto a mostrar na interface e número para a lógica do backend.
Três ferramentas que o agente pode chamar
Na plataforma de assistentes, o catálogo é exposto como três ferramentas incorporadas — pesquisa por palavras, correspondência por um aparelho ou caso de uso, e obtenção de um produto por identificador. O agente vê-as sob os nomes `catalog_cauta`, `catalog_potrivire` e `catalog_produs`, cada uma com os seus parâmetros declarados. Quando a plataforma da loja não é a esperada ou falta o endereço, a ferramenta recusa explicitamente em vez de devolver uma lista vazia que seria interpretada como „não temos o produto”.
As palavras de ligação não estragam o resultado
“Filtro de água” pesquisado literalmente corresponde a tudo o que contém “de”. No ponto de catálogo entregue e na pesquisa do widget vocal cortamos a lista de palavras vazias — `e`, `ou`, `de`, `desde`, `a`, `com`, `em`, `sobre`, `para` — e, se depois do corte não restar nada útil, voltamos às palavras com mais de duas letras. A correspondência parcial tem um limiar: um produto entra nos resultados apenas se atingir pelo menos metade das palavras restantes.
Quando a loja não tem interface, lemos a página
Nem toda a loja tem Store API. Para as restantes, temos um extrator que abre as páginas de listagem e lê os seus cartões de produto, com orçamento escrito no código: no máximo 20 páginas de listagem, 200 produtos, 24 páginas de detalhe, 50.000 caracteres de HTML por página, 5 segundos por pedido e um prazo limite de 45 segundos para toda a operação. Lê primeiro os dados estruturados do tipo produto na página, depois os cartões, depois os metadados de partilha — por esta ordem, porque a primeira fonte é aquela que a loja escreveu de propósito.
Atualidade com limites escritos, não com esperança
O catálogo é mantido em memória durante 10 minutos por loja, e os pedidos simultâneos para a mesma loja são fundidos num só, para que dez clientes que perguntem ao mesmo tempo não produzam dez descargas. No ponto público do catálogo, a resposta leva também instrução de cache para a rede de distribuição: 5 minutos fresco, mais 10 minutos servido em cache enquanto é atualizado em segundo plano. O número de resultados devolvidos é limitado a 20, com valor predefinido 6.
Encomenda, carrinho e ligação ao sistema de gestão
O carrinho, o envio da encomenda e a sua passagem para o sistema de gestão do cliente são funções separadas, não um formulário. Existe também a recuperação de carrinhos abandonados, a encomenda por conversa e o acompanhamento do estado da encomenda, com duas tarefas agendadas que correm a cada 15 minutos — uma sincroniza o resultado das encomendas, a outra completa os estados do sistema de gestão numa janela de dois dias atrás e um dia à frente.
Pagamentos: o que funciona e o que não funciona
Funcional e no código: a interface MAIB para comerciantes — token, depois pedido de pagamento, com as credenciais de cada loja lidas da base de dados e a função ativada explicitamente — e Stripe, com o montante convertido em unidades menores e a cobrança guardada no registo. O que NÃO funciona, para não haver surpresas: Paynet, Netopia e mobilPay não têm implementação, e o código recusa explicitamente quando são pedidos. O percurso do Moldindconbank é um esqueleto que devolve erro sem credenciais. Incluímo-los no projeto como trabalho, não como integração existente.
O agente não inventa quando a rede falha
Se a consulta da loja falhar, a ferramenta não devolve uma lista vazia — devolve uma mensagem que diz ao agente para não formular uma resposta sobre o catálogo. A diferença é importante: uma lista vazia traduz-se em „não temos”, e um „não temos” dito erradamente perde uma encomenda tão seguramente como um preço errado.
Qué aspecto tiene
El recorrido, paso a paso.
01
Verificação da loja, antes de qualquer promessa
Consultamos a interface pública com um único pedido, com tempo máximo de espera de 15 segundos, e lemos quantos produtos tem no cabeçalho. A partir dessa resposta sabemos se o percurso vivo é possível, quantos produtos existem e quão completa é a informação de preço. Se a loja não responder, dizemo-lo antes da oferta, não durante a implementação.
02
Ligação do catálogo e a primeira passagem pelos preços
Entregamos a ligação, mais um passo pelos produtos com preço zero ou em falta — são quase sempre produtos reais, não erros, e a forma como o agente os trata é uma decisão da loja, não nossa. Entregamos também o texto exato com que o agente recusa dar um preço não publicado.
03
As ferramentas do agente e os seus limites
Montamos a pesquisa, o matching e a disponibilização de um produto, cada um com o número máximo de resultados definido em conjunto. Aqui também se escrevem os sinónimos próprios da loja — como o cliente chama um produto face a como o catálogo o nomeia. Sem esta etapa, a pesquisa é tecnicamente correta e inútil na prática.
04
A encomenda, o pagamento e a ligação com a gestão
São construídos nesta ordem, e cada peça só entra depois de verificado o acesso real ao sistema do outro lado. Para pagamentos, parte-se apenas de um fornecedor para o qual temos implementação funcional; o resto trata-se como trabalho novo, com o risco já dito, e não como uma opção assinalada na proposta.
05
A entrega, com a lista de faltas
Entregamos os endereços, as configurações, os limites escritos em código e a lista do que não está coberto. Por exemplo: o ponto público de catálogo entregue não tem tempo máximo de espera no pedido à loja — se a loja responder muito lentamente, o pedido prolonga-se. É uma falta real, colocamo-la na lista de entrega e no plano de reparações, não numa nota interna.
Magazinul, agentul care răspunde, sistemul de gestiune și furnizorul de plată — patru sisteme separate, cu o singură sursă de adevăr pentru preț: magazinul, citit în momentul întrebării.
Os dados
Qué tocamos, dónde están y cuánto se quedan
Las preguntas que hace cualquiera que tenga un delegado de protección de datos — hechas aquí antes de que las haga él.
Dados do catálogo
Nome, descrição curta, preço atual e preço de lista, disponibilidade, imagem, categoria e endereço do produto — tudo lido da interface pública da loja, que os publica de qualquer forma para qualquer visitante. Não copiamos a base de dados da loja e não pedimos chaves de comerciante. Ficam com o cliente; nós lemo-los a pedido.
Onde se guarda e por quanto tempo
O catálogo é mantido na memória do processo por 10 minutos por loja e desaparece ao reiniciar — não existe connosco uma cópia persistente dele. No ponto público de catálogo, a rede de distribuição ainda o mantém fresco durante 5 minutos e como versão antiga durante 10 minutos enquanto é atualizado. Uma exportação congelada, quando é a única opção técnica, é marcada explicitamente como instantâneo com data, e não como fonte viva.
Dados da conversa e da encomenda
O que o cliente pergunta e o que encomenda passam pela plataforma de conversa e, quando aplicável, para o sistema de gestão da loja. Quem tem acesso, por quanto tempo se guarda e o que se apaga são definidos no projeto, com o registo de operações escrito antes do arranque, e não depois do primeiro incidente.
As credenciais de pagamento
As credenciais de comerciante ficam na base de dados da plataforma, por loja, e só são lidas quando a função de pagamento é explicitamente ativada para essa loja. Não chegam à página pública e não passam pela conversa. A configuração da conta de comerciante é feita pelo titular da conta, não por nós.
O que não tocamos
Não recolhemos dados de cartão. Não pedimos acesso de administrador à loja para ler o catálogo — a interface usada é pública. Quando um projeto realmente exige acesso privilegiado, pede-se em separado, com finalidade escrita, e não se mantém "para qualquer eventualidade".
Un caso
Um catálogo de 154 produtos, lido no momento da pergunta
A situação
Um distribuidor de café e água em Chișinău, com loja em WooCommerce e agentes que respondem aos clientes em texto e por telefone. O catálogo muda com frequência; uma lista copiada uma vez fica errada em poucos dias, e um preço errado dito ao telefone não se retira.
Qué construimos
Montámos um ponto de catálogo separado, que interroga a interface pública da loja: 100 produtos por página, o número de páginas lido do cabeçalho, a primeira página obtida isoladamente e o resto em paralelo, limite de 30 páginas. O preço é traduzido de unidades menores de acordo com o número de casas decimais declarado pela loja; zero torna-se «preço sob consulta — confirmado pelos colegas», com instrução escrita para o agente não inventar. A pesquisa corta as palavras de ligação e exige que um produto atinja pelo menos metade das palavras restantes antes de aparecer nos resultados. A resposta é mantida 10 minutos na memória e 5 minutos na rede de distribuição, com mais 10 minutos servidos em versão antiga enquanto é atualizada. Os agentes de voz chamam-no como um simples ponto web, não como uma integração especial.
Qué salió
Verificado em 06.09.2026, em dois pedidos independentes: o ponto de catálogo responde «154 resultados» e lista o primeiro produto com preço e disponibilidade, e o segundo com «preço sob consulta — confirmado pelos colegas»; interrogada diretamente, a interface da loja devolve `x-wp-total: 154`. A mesma cifra de duas fontes que não se conhecem entre si — isso é a verificação, não a nossa declaração.
Qué no dice el caso
O ponto de catálogo entregue não tem tempo máximo de espera no pedido à loja: se a loja responder muito devagar, o pedido prolonga-se em vez de falhar de forma limpa. É uma falha real, encontrada ao reler o código, e está na lista de correções — não na lista de funções. Em separado: o filtro de palavras vazias descrito acima está ativo no ponto entregue e na pesquisa do widget de voz; na versão incorporada na plataforma ainda não foi portado, por isso aí uma pesquisa com muitas palavras de ligação devolve resultados mais amplos.
Perguntas
Lo que nos pregunta la gente antes de llamar
O que significa «catálogo vivo» e como verifico que não é apenas conversa?
Significa que o agente lê a loja no momento da pergunta. Verifica-se em dois pedidos, sem nós: o nosso ponto de catálogo para um distribuidor responde «154 resultados», e a interface pública da loja dele, interrogada diretamente, devolve no cabeçalho `x-wp-total: 154`. A mesma cifra, duas fontes independentes, na mesma data. Um catálogo copiado uma vez não consegue fazer isso — fica dessincronizado à primeira alteração.
Tenho de vos dar chaves ou acesso à loja?
Para a leitura do catálogo em WooCommerce, não. O Store API é a interface pública da loja: os mesmos dados que qualquer visitante vê, servidos num formato legível por programa, sem chave de comerciante e sem plugin instalado. O comentário está escrito mesmo no nosso código, para não se perder. Só pedimos acesso privilegiado onde a função realmente o exige — por exemplo, ao enviar encomendas para o sistema de gestão — e aí com finalidade escrita.
O que acontece com os produtos sem preço?
São tratados como não publicados, não como gratuitos. Na interface da loja um preço ausente vem como zero, e uma integração ingénua mostra-o como «0 MDL». No nosso caso, zero torna-se «preço sob consulta — confirmado pelos colegas», e o agente recebe a instrução explícita para não inventar um valor e pedir confirmação de uma pessoa. Vê-se na resposta pública: o segundo produto da lista aparece exatamente assim.
Quão recente é o preço, concretamente?
No máximo 10 minutos de antiguidade ao nível da plataforma, por loja, e os pedidos simultâneos para a mesma loja fundem-se numa única descarga. No ponto público de catálogo, a rede de distribuição serve durante 5 minutos a versão recente e durante mais 10 minutos a versão antiga, enquanto a atualiza em segundo plano. Os valores são configuráveis por projeto; estão escritos como variáveis, não escondidos.
A minha loja não está em WooCommerce. O que fazem?
Depende do que expõe. Se tiver uma interface própria, lemo-la como qualquer outra. Se não tiver nada, temos um extrator que abre as páginas de listagem e lê os cartões de produto, com orçamento escrito no código: 20 páginas, 200 produtos, 5 segundos por pedido, prazo-limite de 45 segundos. Lê primeiro os dados estruturados da página, depois os cartões, depois os metadados de partilha. É uma solução de recurso honesta, não equivalente: uma loja que mude o tema pode quebrar o extrator, uma interface não.
Que pagamentos podem integrar já agora?
Funcional e no código: a interface MAIB para comerciantes — obtenção de token, depois pedido de pagamento, com as credenciais de cada loja lidas da base de dados e a função ativada explicitamente — e Stripe, com o montante convertido em unidades menores e a cobrança guardada no registo. O que não é funcional, dito antes do contrato: Paynet, Netopia e mobilPay não têm implementação, e o código recusa explicitamente quando são pedidos; o percurso do Moldindconbank é um esqueleto que devolve erro sem credenciais. Qualquer um deles pode ser construído, mas entra como trabalho novo, com o respetivo risco.
O agente pode inventar um produto que vocês não têm?
Talvez, se você não o impedir — e é disso que nós cuidamos. Três barreiras: o preço não publicado vem com instrução escrita para não inventar; a plataforma inadequada ou a morada em falta fazem a ferramenta recusar explicitamente, e não devolver uma lista vazia; e a falha de rede devolve uma mensagem que diz ao agente para não formular uma resposta sobre o catálogo. A diferença entre «lista vazia» e «não foi possível ler» é a diferença entre uma encomenda perdida e uma adiada com uma frase.
Porque é que importa quem divide por 100?
Porque a interface não envia „129,90”. Envia uma cadeia de dígitos em unidades menores e, em separado, quantas casas decimais tem a moeda. Dividir por 100 é correto para as moedas com duas casas decimais e silenciosamente errado para as outras — ninguém recebe erro, apenas números maus. Nós dividimos por dez elevado ao número declarado pela loja. É uma linha de código, e é exatamente o tipo de linha em que se vê se alguém leu a documentação ou adivinhou.
O que é que vocês não assumem?
Não tratamos de dados de cartão nem configuramos a conta de comerciante no lugar do titular. Não garantimos que um extrator de páginas resista a uma mudança de tema da loja — é por isso que preferimos a interface quando ela existe. Não prometemos aumentos de vendas; o que podemos mostrar é que o número dito pelo agente coincide com o número da loja, na mesma data. E não apresentamos como integração algo que no código é um esqueleto: a lista acima diz quais são.
16 delas são código e ficheiros dos nossos repositórios. Não publicamos o nome nem a linha: juntos, numa única página, descreveriam com demasiada precisão como estão construídos sistemas que não são só nossos. Percorremo-los consigo, no repositório, a pedido — a verificação continua possível, só que se faz numa conversa.