Para associar um pagamento cripto ao pedido correto, crie primeiro o pedido no sistema do lojista e atribua um ID estável. Envie esse ID como contexto de uma payment invoice separada e salve o invoice ID retornado no pedido. Quando uma consulta autenticada ou webhook assinado informar paid, localize o pedido pela referência, confirme o estado da invoice, registre token, rede, valor e tx hash e execute o fulfilment de forma idempotente. A relação confiável é merchant order ID → payment invoice ID → confirmed blockchain transaction.

Registro O que comprova O que não comprova sozinho
Pedido do lojista Cliente, obrigação e regra de fulfilment Que os fundos chegaram on-chain
Payment invoice Token, rede, valor e janela esperados Que o lojista entregou o produto
Blockchain transaction Transferência pública de tokens Qual pedido comercial deveria pagar
Evento assinado Associação entre invoice, estado e transação Que o efeito downstream aconteceu uma única vez

A blockchain não contém o seu pedido

Uma blockchain registra movimento de ativos. O evento ERC-20 Transfer contém remetente, destinatário e valor; o padrão ERC-20 não contém order number, cliente, SKU ou regra de entrega. Ver 100 USDC na carteira prova uma transferência, mas não diz se ela paga ORDER-4821, uma invoice antiga ou outra obrigação.

Crie a ligação antes de entregar o checkout ao cliente. Tentar inferir depois por endereço, valor ou horário transforma qualquer coincidência em trabalho manual.

Não use address, amount ou screenshot como chave

O receiving address pode ser compartilhado por vários pagamentos. Dois clientes podem enviar o mesmo valor, alguém pode reutilizar instruções antigas e o mesmo formato 0x pode existir em redes EVM diferentes. O valor também não é único: existem preços iguais, underpayment, overpayment e arredondamento. Valores decimais incomuns podem reduzir colisões, mas não substituem foreign keys.

Quando o valor verificado for diferente da fatura, use o fluxo para pagamentos insuficientes e excessivos e mantenha o pedido fora do fulfilment automático normal.

Timestamp e sender address são apenas evidência auxiliar. Exchanges podem atrasar e agrupar saques. Screenshot não é prova e até um tx hash real pode mostrar token, recipient ou rede errada, ou já ter sido usado em outro pedido. Use o guia de verificação manual para validar a transferência.

Ligue três registros com IDs explícitos

Campo Onde guardar Finalidade
Local order ID Banco do lojista e payment context Lookup e fulfilment estáveis
Payment invoice ID Pedido e provedor Consulta direta e suporte
Expected business amount Pedido Obrigação comercial
Payable token amount Invoice Valor exato do checkout
Token e network Invoice e payment record Separar rotas diferentes
Status e history Payment record Controlar a próxima ação
Transaction hash Payment record final Localizar evidência pública
Paid/expiry timestamps Payment record Tratar pagamentos atrasados
Event/delivery key Webhook inbox Evitar efeitos repetidos

Use um database ID imutável ou UUID, não um número de exibição editável. Não coloque secret, private key ou dados pessoais desnecessários em metadata. Assim que criar a invoice, salve o ID do provedor no pedido para permitir navegação nos dois sentidos.

Crie a invoice com idempotência

O site deve validar a compra, criar o local order em payment_pending, gerar um idempotency key para aquele pedido e tentativa, criar a payment invoice com o order ID, salvar invoice ID e checkout URL e só depois redirecionar.

Timeout é ambíguo: a invoice pode ter sido criada mesmo sem a resposta chegar. Repetir com outra chave cria dois checkouts. No GramPayBot, a referência vai em payload; o mesmo Idempotency-Key com os mesmos parâmetros devolve a invoice original, enquanto a reutilização com parâmetros diferentes gera conflict. Consulte API quickstart e API reference.

Um pedido pode ter várias tentativas: order → attempt 1 expired → attempt 2 paid. Não sobrescreva a anterior. Apenas uma tentativa pode fechar o pedido automaticamente; as antigas permanecem para late-payment review.

Deixe a transição final no servidor

Browser return page não é autoridade. Use API autenticada ou webhook server-to-server assinado. Um handler seguro lê o raw body, verifica HMAC em constant time, persiste delivery e body, deduplica por chave estável, responde 2xx rapidamente e processa o pedido em worker assíncrono.

O GramPayBot pode repetir eventos reais até 17 vezes ao longo de aproximadamente quatro dias. Duplicate delivery é um mecanismo normal. As práticas oficiais de webhook da Stripe também recomendam registrar IDs processados.

Deduplicar delivery não basta: webhook e polling podem observar a mesma invoice paga. Proteja o efeito comercial com unique constraint ou conditional transition. O pedido só deve mudar a partir de payment_pending, e deve existir uma única fulfilment job por order ID. A meta é at-least-once delivery com exactly-once business effect.

Mapeie estados a ações permitidas

Estado Significado Ação automática
active Solicitação válida sem pagamento aceito Manter o pedido pending
paid Invoice atingiu a confirmação exigida Permitir fulfilment idempotente
expired Janela terminou sem match aceito Bloquear entrega normal e revisar late payment
cancelled Solicitação foi encerrada Não aceitar como tentativa atual

Payment state e order state podem ser diferentes. Uma invoice paga pode mover o pedido para ready_for_review quando há estoque ou compliance. Uma invoice expirada pode permitir nova tentativa. Preserve status history, motivo e responsável por qualquer override.

Mantenha exceções visíveis

Wrong token contract, wrong network, underpayment, overpayment, late payment, duplicate tx hash e paid invoice sem local order devem entrar em estado de exceção, não no caminho normal. Preserve a transação e deixe uma pessoa autorizada decidir entre aceitar, pedir diferença ou refund. No modelo direct-to-wallet, o lojista assina o refund; o monitor não reverte blockchain.

Operational matching também não substitui contabilidade. Finance pode precisar de fiat value, fee, conversão, documentos e histórico de refund. Faça reconciliação periódica entre paid payment attempts e paid orders, buscando registros órfãos e hashes duplicados. Os tokens EVM aparecem em smart-contract event logs, mas esses logs não conhecem o significado comercial do pedido.

Exemplo com GramPayBot

O SaaS cria ORDER-4821. O backend chama createInvoice com payload: "ORDER-4821" e Idempotency-Key: ORDER-4821:crypto:1, salva public_id e checkout URL. O cliente paga USDC em Base. O GramPayBot confirma a transação e envia invoice_paid assinado com order reference, token, rede e tx hash. O endpoint verifica, persiste e responde 2xx; o worker bloqueia o pedido pending e cria uma única ativação. Retries não ativam o plano novamente.

O guia de verificação automática explica a detecção mais ampla, e o caso de uso para sites mostra a aplicação comercial.

Antes do lançamento, repita invoice creation com a mesma chave, entregue o mesmo webhook duas vezes, deixe uma invoice expirar e teste valor incorreto sem fulfilment. A integração está pronta quando todo pedido pago pode ser seguido até uma invoice e uma transação aceita, e todo retry produz um no-op seguro ou um review item visível.

Próximo passo

Automatize a verificação no seu site

Crie uma invoice por pedido, use hosted checkout e receba um resultado ligado ao pedido.

Ver pagamentos no site →