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.

RegistroO que comprovaO que não comprova sozinho
Pedido do lojistaCliente, obrigação e regra de fulfilmentQue os fundos chegaram on-chain
Payment invoiceToken, rede, valor e janela esperadosQue o lojista entregou o produto
Blockchain transactionTransferência pública de tokensQual pedido comercial deveria pagar
Evento assinadoAssociação entre invoice, estado e transaçãoQue 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

CampoOnde guardarFinalidade
Local order IDBanco do lojista e payment contextLookup e fulfilment estáveis
Payment invoice IDPedido e provedorConsulta direta e suporte
Expected business amountPedidoObrigação comercial
Payable token amountInvoiceValor exato do checkout
Token e networkInvoice e payment recordSeparar rotas diferentes
Status e historyPayment recordControlar a próxima ação
Transaction hashPayment record finalLocalizar evidência pública
Paid/expiry timestampsPayment recordTratar pagamentos atrasados
Event/delivery keyWebhook inboxEvitar 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

EstadoSignificadoAção automática
activeSolicitação válida sem pagamento aceitoManter o pedido pending
paidInvoice atingiu a confirmação exigidaPermitir fulfilment idempotente
expiredJanela terminou sem match aceitoBloquear entrega normal e revisar late payment
cancelledSolicitação foi encerradaNã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 →