Mirakl não é um marketplace onde vender. É o software com que um retalhista monta o seu: Leroy Merlin, Carrefour, Kingfisher, Macy's ou Best Buy figuram hoje como clientes no site da Mirakl. Quando um o convida, vende no operador (as suas categorias, a sua comissão, o seu contrato), mas o seu Odoo comunica com a API da Mirakl, a mesma em todos. Um conector Mirakl bem feito não é «o conector da Leroy Merlin»: são N marketplaces com uma só API e credenciais diferentes. E o difícil não é a API: é repartir o stock entre os canais que olham para o mesmo armazém.
Correção ao nosso próprio site: durante meses tratámos a Leroy Merlin e a GACD como integrações separadas. São duas contas do mesmo conector: o mesmo código com um host, uma chave e um catálogo diferentes.
O que partilham todos os operadores Mirakl e o que não partilham
A API de vendedor da Mirakl tem um código de operação para cada coisa, o mesmo qualquer que seja o nome do operador: OR11 lista encomendas, OR23 e OR24 enviam o tracking e marcam a expedição, OR28 reembolsa, OF01 carrega ofertas por ficheiro, IV01 devolve os documentos de liquidação, M11 é a mensagem com o comprador e SH21 lista as transportadoras. Um operador pode ter famílias desativadas (há os que não têm mensagens nem transportadoras, e o conector marca o endpoint como indisponível perante um 404 ou um 410), mas quando a expõe é a mesma chamada.
O que muda é tudo o que não é API: o host (adeo-marketplace.mirakl.net na Leroy Merlin), a chave e a loja, a árvore de categorias e os atributos obrigatórios (4844 categorias e 35 364 atributos na nossa conta da Leroy Merlin), as transportadoras admitidas (165 códigos), os motivos de reembolso, a moeda e, sobretudo, o modo de impostos: uns enviam os preços com IVA incluído (TAX_INCLUDED) e outros sem IVA (TAX_EXCLUDED). Esse ponto custou-nos uma falha real: o conector tomava o preço com IVA como base, o Odoo somava-o outra vez e 48,86 € entravam como 59,12 €. Verificado nas 20 encomendas reais da conta.
Como se modela no Odoo: uma conta por operador
No nosso conector Mirakl cada operador é uma instância: um registo com o seu URL base, o seu URL da API, a sua chave, a sua loja, a sua empresa, o seu armazém e a sua equipa de vendas. Ao testar a ligação, lê /platform/configuration, /account e /channels e regista que plataforma responde, que loja é e que funções expõe. Na captura, a plataforma detetada é «Marketplace Adeo» e o fornecedor detetado, leroy_merlin.

Da instância depende tudo o que é do operador: o dicionário de categorias, atributos e valores (único por instância e código, pelo que dois operadores nunca se sobrepõem), o mapeamento de categorias e transportadoras e as regras de preço e stock. Um produto do Odoo tem um binding por instância: o mesmo produto, uma oferta diferente em cada operador, com o seu SKU, o seu preço e a sua quantidade. Acrescentar um segundo operador (a GACD, cuja API de vendedor responde em tdmp.mirakl.net, ou qualquer outro) é mais uma instância. Os perfis do catálogo só preenchem valores por defeito; o código que comunica com a Mirakl é um só.
O problema real: repartir o stock
Dois operadores Mirakl, a ManoMano, a Amazon, a Temu ou o seu site podem olhar para o mesmo armazém. Só os dois primeiros são Mirakl: os outros têm a sua própria API de vendedor (Amazon, a SP-API) e são conectores à parte. Mas todos vendem contra o mesmo stock e nenhum sabe dos outros: cada um recebe a quantidade que lhe exporta e vende contra ela até à exportação seguinte. Isso não se resolve «em tempo real», porque nem a API nem o operador funcionam assim; resolve-se com regras por canal. Cada instância decide quatro coisas antes de publicar uma quantidade:
- Que quantidade considera: à mão, prevista, livre (descontando o reservado) ou à mão apenas nos armazéns dessa instância.
- Quanto se guarda: uma margem por instância que cobre as vendas dos outros canais entre duas exportações.
- Mínimo para publicar: se, depois da margem, sobram menos de N unidades, publica-se zero: vender a última unidade em três sítios é a clássica venda em excesso.
- Máximo publicado: um limite por instância, para não mostrar a um operador um stock já prometido a outro.
A ordem está no código: quantidade segundo a estratégia, menos a margem, zero se não chegar ao mínimo, corte ao máximo. Com 12 unidades livres, margem 2, mínimo 3 e máximo 5, cada operador vê 5. Se todos recebem a quantidade à mão sem mais, o primeiro que vender a última unidade deixa os outros a vender ar. Margem e cadência tratamo-las em stock em tempo real para marketplaces, e como se governa tudo a partir de um único Odoo, em vender em vários marketplaces e em soluções.
Encomendas e estados: da Mirakl para o Odoo e vice-versa
A Mirakl tem mais estados de encomenda do que o Odoo precisa e reduz-os a seis: WAITING_ACCEPTANCE, WAITING_DEBIT, STAGING e INCIDENT_OPEN são «pendente»; SHIPPING, «em expedição» (o comprador pagou e corre o prazo para expedir); SHIPPED, «enviado»; RECEIVED e CLOSED, «fechado»; CANCELED e REFUSED, «cancelado»; REFUNDED, «reembolsado». A encomenda da captura entrou como SHIPPED, foi mapeada para «Enviado» e ficou ligada à encomenda de venda S00509, com moeda, total e imposto do payload do operador.

O ciclo de volta: a encomenda pendente é aceite com um PUT para /orders/{id}/accept, por lotes com um limite por passagem; ao validar a guia de remessa envia-se o tracking (OR23) e marca-se a expedição (OR24), e a guia fica carimbada com pedido e resposta; a fatura validada é carregada na encomenda (OR74), apagando antes a anterior do mesmo tipo (OR72, OR76). E a janela incremental pede-se por data de atualização, não de criação: uma encomenda que muda de estado semanas depois nunca voltaria a entrar.
Onde se duplica se o conector não for idempotente
Em três sítios. A encomenda: a base de dados rejeita dois registos com o mesmo identificador na mesma instância (unique(instance_id, mirakl_order_id)); a importação atualiza o existente. A expedição: o conector volta a ler antes o estado; se já for SHIPPED não a repete, e se a releitura falhar não assume nada e faz a chamada, porque dar «já enviado» como adquirido perante um timeout deixava encomendas sem tracking. E o reembolso, que é dinheiro: na auditoria da 16.15.1 vimos que o cliente HTTP repetia qualquer pedido perante 5xx ou timeout, também o de OR28. Um timeout não diz que o pedido não chegou: diz que não se sabe. Hoje só se repetem leituras, exceto o 429, que garante que não foi processado; e o botão recusa-se a enviar um segundo reembolso total se a encomenda já constar como reembolsada.
Liquidações: o que devolve a API e porque merece uma reconciliação própria
A Mirakl não lhe paga encomenda a encomenda: transfere periodicamente um valor líquido, e IV01 devolve o documento que o explica, com o montante transferido e quatro grupos: encomendas, comissões, reembolsos e comissões devolvidas. O conector guarda cada documento por instância (período, moeda, estado de pagamento) e calcula um líquido próprio a partir dos grupos. O que falta para chegar ao transferido é «outras taxas», quase sempre a mensalidade do operador: uma liquidação real arrastava 39,00 € de diferença até incorporarmos esse resíduo, e assim fica à vista como mais uma linha em vez de se esconder numa diferença sem nome.
Quando um operador Mirakl não compensa
Que a API seja a mesma não significa que cada convite mereça um sim. O custo de entrar está no catálogo, não na integração: mapear as suas categorias contra uma árvore de milhares de nós e preencher os atributos obrigatórios de cada família é trabalho de pessoas, e repete-se em cada operador. Poucas categorias afins, uma comissão que consome a margem depois da mensalidade ou um prazo de aceitação que o seu armazém não cumpre: nenhum compensa, por mais fácil que seja ligá-lo. O sinal sai da instância antes de publicar o que quer que seja: sincronize o dicionário, mapeie dez famílias e conte quantos atributos obrigatórios lhe faltam. Se forem centenas, custar-lhe-á mais do que lhe vai vender.
O conector com que fizemos o que descrevemos está em produção com encomendas reais e em verde (163 de 163 testes) no Odoo 19, 18 e 17, depois da auditoria da 16.15.1 (121 achados candidatos, 18 confirmados). Se herdar um conector Mirakl de outra pessoa, o que verificar está em auditar um conector Odoo herdado; se a plataforma que deve comunicar com o Odoo é a sua, isso é um conector Odoo para o seu software.
Perguntas frequentes
Então vendo «na Mirakl»?
Não. Vende no operador que o convidou: ele fixa categorias, comissão, prazos e contrato. A Mirakl é o software com que esse operador gere o seu marketplace, e a sua API é a que integra o seu Odoo.
Preciso de um conector por cada operador Mirakl?
Não. Precisa de uma instância por operador dentro do mesmo conector: host, chave, loja, dicionário, transportadoras e regras de stock próprias. O código que comunica com a API é o mesmo.
Porque é que o stock não pode ir «em tempo real»?
Porque cada operador recebe a quantidade que lhe exporta e vende contra ela até à exportação seguinte, sem saber dos outros. O que evita a venda em excesso é a regra por canal: que quantidade se considera, margem, mínimo e máximo, mais uma cadência razoável.
Ligações úteis dentro da FlexigoTech
O que fazemos sobre isto
Foi convidado por um operador Mirakl e vende com Odoo?
Diga-nos que operador é, quantos canais já olham para o seu armazém e em que versão do Odoo está. Dizemos-lhe o que é preciso para o ligar como mais uma instância e que regras de stock teria de fixar antes de publicar. Escreva para comercial@flexigobe.com ou ligue para +34 616 809 504.

