Uma chamada de impressão cabe num pedido HTTP, o que faz a impressão de encomendas parecer a integração mais simples do roteiro. Continua simples até à noite em que um cliente recebe dois talões por uma encomenda, ou até à noite em que quarenta encomendas nunca chegam à cozinha e ninguém dá por isso antes de fechar.
Resposta curta: três decisões evitam quase todos os incidentes em produção. Responda ao webhook antes de imprimir, dê a cada trabalho uma chave estável para que uma repetição seja detetável, e decida explicitamente o que acontece quando a impressora está offline. Nenhuma é difícil, e as três acrescentam-se mais facilmente agora do que depois do primeiro incidente.
Os três modos de falha
| Sintoma | Causa real | Correção |
|---|---|---|
| O mesmo talão sai duas vezes | A plataforma repetiu um webhook lento, ou um estado foi reaplicado | Uma chave estável por encomenda |
| Encomendas nunca impressas e ninguém soube | A impressora estava offline e a falha foi engolida | Uma política offline explícita mais um alerta |
| O checkout parece lento, ou expira | A chamada de impressão corre dentro do pedido que confirma a encomenda | Responder primeiro, imprimir depois |
Os três estão ligados. Uma chamada de impressão lenta provoca a repetição que provoca o duplicado, por isso corrigir o primeiro elimina a maior parte do segundo.
1. Responder ao webhook antes de imprimir
O Shopify, o WooCommerce, o Stripe e qualquer plataforma séria repetem quando o seu endpoint está lento ou devolve um erro. Se o seu handler imprime de forma síncrona e a API de impressão demora dois segundos, construiu um gerador de repetições.
export default async function handler(req, res) {
const order = req.body;
// Confirmar de imediato: a plataforma deixa de repetir.
res.status(200).end();
// Depois imprimir, fora do pedido que a plataforma esta a aguardar.
await printOrder(order).catch((err) => {
logger.error({ err, orderId: order.id }, 'falha de impressao');
alertOps(order);
});
}
A regra é que o orçamento de timeout da plataforma e a latência da sua impressora nunca devem partilhar um prazo. É a mesma razão pela qual os conectores Shopify e WooCommerce não imprimem dentro da transação do webhook.
2. Dar chave a cada trabalho
A idempotência aqui não é um luxo de sistemas distribuídos. Uma encomenda pode legitimamente despoletar o seu handler mais do que uma vez: um callback de gateway que chega duas vezes, um comerciante que reaplica um estado pago à mão, uma repetição de webhook que correu contra a sua confirmação.
Ponha um valor estável em origin, e guarde uma marca de impresso do seu lado:
async function printOrder(order) {
const key = `encomenda-${order.id}`;
if (await alreadyPrinted(key)) return;
await fetch(`https://www.expedy.fr/api/v2/printers/${PRINTER_UID}/print`, {
method: 'POST',
headers: {
Authorization: `${process.env.API_SID}:${process.env.API_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ printer_msg: buildTicket(order), origin: key }),
});
await markPrinted(key);
}
Duas coisas ganham o seu lugar aqui. A marca local trava o duplicado antes de chegar à rede, e o origin torna visível no histórico de impressão um duplicado que escapou, o que transforma "acho que imprimiu duas vezes" numa pergunta a que consegue responder.
Escreva a marca na mesma transação que o resto do tratamento da encomenda, se puder. Uma marca escrita depois de uma chamada HTTP bem-sucedida deixa uma janela pequena, e é exatamente dessa janela que saem os talões a dobrar.
3. Escolher a política offline de propósito
Pergunte o que deve acontecer quando a impressora fica sem papel, está desligada, ou está atrás de um router que reiniciou. Só há três respostas sensatas, e a errada é não escolher:
- Pôr em fila e entregar mais tarde. Correto para etiquetas de envio e documentos de armazém, onde um talão impresso vinte minutos depois ainda serve.
- Repetir por pouco tempo, depois alertar. Correto para talões de cozinha, onde um talão impresso vinte minutos depois é pior do que inútil porque o serviço já avançou.
- Alertar de imediato. Correto quando uma pessoa pode agir, e a única opção que transforma uma perda silenciosa num problema conhecido.
Escolha o que escolher, implemente o alerta. A diferença entre um incómodo pequeno e uma má noite não é se a impressora falhou, é se alguém soube.
O que não deve construir
As equipas reconstroem por rotina maquinaria que a API já fornece. Antes de escrever uma fila, um agendador e uma escada de repetições, veja que garantias de entrega já tem: uma API push que retém o trabalho e o entrega quando o equipamento se volta a ligar dispensa a maior parte desse código. Construa as partes que codificam as suas regras de negócio, como que impressora recebe que encomenda, e deixe a fiabilidade do transporte ao transporte.
Testar antes de produção
Três testes apanham a maior parte do que chega a produção:
- Repita o mesmo webhook duas vezes. Deve sair exatamente um talão.
- Desligue a impressora e envie uma encomenda. A política escolhida deve acontecer de forma visível, alerta incluído.
- Encomende um produto com um emoji no nome. As impressoras térmicas falam ESC/POS; translitere antes de enviar, ou vai descobri-lo no pior momento. A referência de paginação documenta o que o formato aceita.
Faça os três contra uma impressora real, não contra um mock. As falhas interessantes são físicas.
Crie uma conta gratuita e ligue os três testes ao seu ramo de integração antes de a primeira encomenda de cliente passar por ele.
A ler também: imprimir encomendas Shopify e encomendas WooCommerce mostram onde ficam estes ganchos em cada plataforma.
FAQ
Porque é que a mesma encomenda às vezes imprime duas vezes?
Quase sempre porque a plataforma repetiu um webhook a que o seu endpoint respondeu devagar, ou porque um estado pago foi aplicado mais do que uma vez. Confirme o webhook antes de imprimir e dê a cada trabalho uma chave estável como o id da encomenda.
Devo imprimir dentro do handler do webhook?
Não. Responda 200 de imediato e depois imprima fora desse pedido. Partilhar um prazo entre o timeout da plataforma e a latência da impressora é o que gera as repetições, e as repetições geram os duplicados.
O que deve acontecer quando a impressora está offline?
Escolha uma política de propósito: pôr em fila e entregar mais tarde, repetir por pouco tempo e depois alertar, ou alertar de imediato. A fila serve para etiquetas de envio, o alerta para talões de cozinha. A única resposta errada é deixar por definir.
Preciso de construir a minha própria fila de impressão?
Normalmente não. Uma API push que retém o trabalho e o entrega quando o equipamento se volta a ligar já faz isso. Escreva o código que codifica as suas regras de negócio, como o encaminhamento para a impressora, não uma segunda camada de transporte.
Como testo a fiabilidade da impressão antes de ir para produção?
Repita um webhook duas vezes esperando um único talão, desligue a impressora e confirme que a política offline e o alerta disparam, e encomende um produto com um emoji no nome. Faça os três contra uma impressora real.