Integração do Magento 2 com marketplaces: anúncios, pedidos e estoque
Vender o mesmo catálogo na Amazon, no eBay, no Mercado Livre, na Shopee ou em qualquer outro marketplace enquanto o Magento continua como loja principal parece um problema de sincronização. Na prática é quase todo um problema de modelagem de dados. Cada marketplace tem sua própria árvore de categorias, seus próprios atributos obrigatórios por categoria, seu próprio modelo de variações e suas próprias regras para títulos, imagens e preços. Mover os dados é a parte fácil. Mapeá-los para os anúncios serem aceitos e continuarem aceitos é onde o trabalho vai.
Este artigo cobre as escolhas de arquitetura para conectar o Magento 2 a marketplaces, os dados que você precisa modelar, como trazer os pedidos do marketplace de volta ao Magento e as regras de estoque que evitam o overselling.
Três formas de conectar
Extensão conector dentro do Magento
Um módulo instalado no Magento que fala direto com as APIs dos marketplaces. Anúncios, atualizações de estoque e importações de pedidos rodam como jobs de cron ou consumers de queue dentro da loja. É rápido de começar e mantém tudo num admin só. As desvantagens são que mudanças de API dos marketplaces forçam atualizações da extensão no seu ciclo de releases, os jobs pesados de sincronização rodam nos mesmos servidores do storefront e a qualidade dessas extensões varia muito. Revise o código de uma antes de instalar.
Hub ou ERP no meio
Muitos ERPs e ferramentas multicanal já se integram com os principais marketplaces. Nesse arranjo o ERP é o hub: ele publica os anúncios, recebe os pedidos dos marketplaces e envia estoque para todos os canais, incluindo o Magento. O Magento vira um canal entre vários. Costuma ser a opção mais estável quando o ERP já cuida de faturamento e fulfillment, porque os pedidos de marketplace nem precisam entrar no Magento.
Middleware customizado
Um serviço separado que lê o catálogo do Magento, transforma por marketplace, publica os anúncios e empurra os pedidos para onde precisam ir. Dá controle total e mantém a loja limpa, mas você é dono de cada mudança de API em cada marketplace. Faz sentido quando o catálogo tem regras que nenhuma ferramenta pronta resolve, ou quando o volume justifica o investimento.
Os dados que você precisa modelar
Categorias
As categorias dos marketplaces raramente combinam com a árvore da sua loja. Você precisa de um mapeamento de cada categoria do Magento, ou de um atributo de produto, para um ID de categoria do marketplace. O mapeamento deve ficar em dados, não em código, porque os marketplaces mudam suas árvores. Um atributo de produto como marketplace_category_id por canal, ou uma tabela de mapeamento chaveada pela sua própria categoria, ambos funcionam. Um atributo de produto é mais simples quando os produtos estão em várias categorias da loja, porque evita a pergunta de qual categoria vence.
Atributos obrigatórios por categoria
Essa é a parte que causa mais anúncios rejeitados. Uma categoria de marketplace pode exigir marca, modelo, material, voltagem, gênero ou qualquer uma de dezenas de campos, cada um com uma lista fixa de valores aceitos. Os atributos do Magento geralmente são texto livre ou têm opções escritas para o comprador, não para o validador do marketplace.
Duas regras práticas ajudam aqui:
- Puxe da API do marketplace, por categoria, a lista de atributos obrigatórios e valores permitidos, e guarde. Valide os produtos contra ela antes de enviar, para ver os erros no seu sistema em vez de num e-mail de rejeição.
- Mapeie os valores das opções de forma explícita. Uma opção "Stainless steel" do Magento pode ter de virar um ID de valor específico no marketplace. Mantenha esse mapeamento numa tabela que você possa editar sem deploy.
Um bom design de atributos no Magento facilita tudo isso. Veja boas práticas de atributos de produto para saber como configurar atributos select para mapearem de forma limpa.
Variações
Os configurable products do Magento mapeiam para anúncios pai e filho na maioria dos marketplaces, mas os eixos de variação precisam ser os que o marketplace aceita para aquela categoria. Se o seu configurable usa um atributo que o marketplace não reconhece como variação, você ou o mapeia para um aceito ou lista cada filho como um produto próprio. Decida isso por categoria antes de construir a sincronização.
Títulos, descrições e imagens
Marketplaces têm limites de tamanho para títulos, regras contra HTML ou certas palavras nas descrições e regras de imagem sobre fundo e tamanho. Mantenha títulos e descrições específicos de marketplace em atributos separados em vez de transformar o texto da loja na hora. Tire o HTML das descrições antes de enviar, já que muitos marketplaces rejeitam ou sinalizam markup.
Preços
Os preços de marketplace normalmente diferem do preço da loja por causa de comissões e taxas. Guarde-os como atributos separados por canal, ou calcule-os a partir do preço base com uma regra que você consiga explicar. Nunca deixe o conector derivá-los em silêncio de uma fórmula enterrada no código.
Importando pedidos de marketplace para o Magento
Se os pedidos de marketplace precisam estar no Magento, por exemplo porque o Magento dispara a exportação para o ERP e o faturamento, você precisa criar pedidos de forma programática. O marketplace já cobrou o comprador, então o pedido precisa de um método de pagamento que não faz nada na captura e de um método de envio que registra o que o marketplace escolheu. Os dois são módulos customizados pequenos, como mostrado em um método de pagamento customizado.
Um serviço mínimo que monta uma quote e a submete:
<?php
declare(strict_types=1);
namespace Vendor\Marketplace\Model;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\DataObject;
use Magento\Framework\Exception\LocalizedException;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Model\QuoteFactory;
use Magento\Quote\Model\QuoteManagement;
use Magento\Sales\Api\Data\OrderInterface;
use Magento\Store\Model\StoreManagerInterface;
class OrderCreator
{
public function __construct(
private readonly QuoteFactory $quoteFactory,
private readonly CartRepositoryInterface $cartRepository,
private readonly QuoteManagement $quoteManagement,
private readonly ProductRepositoryInterface $productRepository,
private readonly StoreManagerInterface $storeManager
) {
}
public function create(array $data): OrderInterface
{
$store = $this->storeManager->getStore($data['store_code']);
$quote = $this->quoteFactory->create();
$quote->setStore($store);
$quote->setCurrency();
$quote->setCustomerIsGuest(true);
$quote->setCustomerEmail($data['email']);
foreach ($data['items'] as $line) {
$product = $this->productRepository->get($line['sku'], false, (int) $store->getId());
$item = $quote->addProduct($product, new DataObject(['qty' => $line['qty']]));
if (is_string($item)) {
throw new LocalizedException(__($item));
}
$item->setCustomPrice($line['price']);
$item->setOriginalCustomPrice($line['price']);
}
$quote->getBillingAddress()->addData($data['address']);
$quote->getShippingAddress()
->addData($data['address'])
->setCollectShippingRates(true)
->collectShippingRates()
->setShippingMethod($data['shipping_method']);
$quote->getPayment()->importData(['method' => $data['payment_method']]);
$quote->collectTotals();
$this->cartRepository->save($quote);
$order = $this->quoteManagement->submit($quote);
$order->setExtOrderId($data['marketplace_order_id']);
return $order;
}
}
O custom price mantém no pedido o preço do marketplace mesmo que difira do preço do catálogo. Persista o ID do pedido do marketplace (o exemplo define ext_order_id, depois salve o pedido pelo repository) e confira antes de criar qualquer coisa, para uma importação repetida não criar um duplicado. Rode a importação num consumer de queue ou no cron, não numa requisição web, e registre em log toda falha com o ID do pedido do marketplace para alguém poder corrigir e tentar de novo.
Decida também o que fazer quando um SKU não existe mais ou está desativado no Magento. O pedido do marketplace é real e já foi pago, então o importador não deve descartá-lo. Coloque-o num estado de erro com um motivo claro.
Estoque e overselling
Overselling em marketplaces custa mais do que na sua própria loja, porque os marketplaces penalizam cancelamentos com ranking menor ou restrições na conta. Algumas regras reduzem o risco:
- Envie a salable quantity, não a quantidade física. Com MSI, a salable quantity já subtrai as reservas de pedidos ainda não enviados. Os detalhes estão em salable quantity e reservas.
- Mantenha uma folga. Envie a salable quantity menos uma margem de segurança por produto ou categoria, para o tempo entre uma venda num canal e a atualização de estoque nos outros não causar um oversell.
- Empurre as mudanças, não só faça polling. Dispare uma atualização de estoque para um SKU quando a salable quantity dele mudar, e rode uma reconciliação completa agendada para pegar o que escapou.
- Use um stock dedicado se precisar. O MSI permite atribuir sources a stocks por sales channel. Um stock separado para marketplaces dá uma visão diferente da disponibilidade, como explicado em sources e stocks do MSI.
Monitoramento
Uma integração com marketplace precisa de uma tela de erros que alguém que não é desenvolvedor consiga ler. Para cada anúncio, guarde o último status vindo do marketplace e a última mensagem de erro, traduzida para linguagem simples quando possível. A maioria das APIs de marketplace devolve códigos de erro detalhados para anúncios rejeitados. Expô-los num grid do admin economiza horas de tempo de desenvolvedor lendo logs.
FAQ
Os pedidos de marketplace devem ser criados no Magento?
Só se o Magento conduz algo adiante, como a exportação para o ERP ou o faturamento. Se um ERP já recebe os pedidos de marketplace diretamente, adicioná-los ao Magento cria duplicados e trabalho extra.
Por que meus anúncios são rejeitados mesmo com o produto completo no Magento?
Geralmente porque falta um atributo obrigatório específico da categoria ou o valor dele não está na lista aceita pelo marketplace. Valide os produtos contra a lista de atributos do marketplace antes de enviar.
Qual quantidade devo enviar aos marketplaces?
Envie a salable quantity do MSI, menos uma folga de segurança. A quantidade física ignora pedidos feitos mas ainda não enviados, o que leva a overselling.
Como evito que importações de pedidos de marketplace criem duplicados?
Guarde o ID do pedido do marketplace no pedido do Magento e confira antes de criar um novo. Torne a importação idempotente para que novas tentativas sejam seguras.
Atendo como freelancer em Magento e Adobe Commerce, incluindo integrações com marketplaces e ERPs. Se você precisa de ajuda com isso, fale comigo.
Artigos relacionados
Salable quantity errada no Magento 2? Como funcionam as reservations
Por que a salable quantity do Magento 2 difere da quantity, como as inventory reservations funcionam e como achar e corrigir inconsistências com a CLI nativa.
MSI no Magento 2: sources, stocks e sales channels
Como funciona o Multi-Source Inventory do Magento 2: sources, stocks, sales channels, source selection, as tabelas por trás e como atualizar quantidades por código.
Padrões de integração Magento 2 com ERP que se sustentam
Padrões de integração do Magento 2 com ERP: dono dos dados, arquivos em lote, REST e bulk API assíncrona, exportação de pedidos por queue, middleware e as falhas a prever.
Magento 2: tipos de cache, clean, flush e cache type próprio
O que cada cache type do Magento 2 guarda, a diferença real entre cache:clean e cache:flush, caches invalidados e como criar seu próprio cache type.