Quando uma cobrança não é aprovada, a charge chega ao estado failed e carrega o motivo da recusa num único objeto: payment_error. Em vez de devolver o código numérico bruto da rede de pagamentos, normalizamos a resposta — baseada no padrão internacional de mensageria financeira ISO 8583 — em um conjunto estável de códigos em texto. Você integra contra esses códigos, não contra a numeração de uma bandeira ou rede específica.
Você nunca lida com códigos numéricosCódigos como os definidos pela ISO 8583 variam por rede e podem mudar. O contrato público expõe sempre o mesmo payment_error.code legível (insufficient_funds, expired_card, …), independente de qual instituição recusou. Assim sua integração não quebra se a origem do processamento mudar.
A recusa vem sempre agrupada num único objeto, com três campos:
Campo
Tipo
Descrição
payment_error.category
string | null
Categoria coarse da recusa — agrupa os códigos em quatro baldes acionáveis (veja abaixo).
payment_error.code
string | null
Código estável e legível do motivo da recusa (insufficient_funds, expired_card, …).
payment_error.message
string | null
Mensagem em inglês, voltada a logs e desenvolvedores.
O objeto inteiro é null em cobranças aprovadas. Quando preenchido, os três campos vêm juntos.
payment_error.message é texto para dev/log em inglês. A mensagem
amigável que o comprador vê no checkout hospedado é localizada em português e
derivada do mesmo payment_error.code — veja a coluna “Mensagem ao cliente”
abaixo.
Todos os payment_error.code desta página têm um cartão de sandbox correspondente. Use a tabela completa em Sandbox para escolher o cartão e ver o resultado esperado (payment_error.category, payment_error.code e payment_error.message).
Cada motivo de falha vira um payment_error.code estável e granular. Abaixo, os códigos agrupados por category. A coluna Significado explica o que aconteceu na tentativa de cobrança; a Mensagem ao cliente é o texto exibido ao comprador no checkout hospedado.
processing_error — falha técnica ou de conectividade
code
Significado
Mensagem ao cliente
issuer_unavailable
Banco emissor fora do ar ou timeout na comunicação.
”Sistema do banco temporariamente indisponível. Tente novamente em instantes.”
routing_error
Não foi possível rotear a transação ao emissor.
”Não foi possível concluir o pagamento. Tente novamente em instantes.”
duplicate_transaction
Transação duplicada detectada.
”Esta transação parece duplicada. Verifique se o pagamento já foi feito.”
try_again_later
Falha temporária no processamento.
”Não foi possível processar o pagamento. Tente novamente em instantes.”
connection_error
Falha de conexão com o processador.
”Não foi possível conectar ao processador de pagamento. Tente novamente.”
customer_unavailable
Cliente não pôde ser identificado para a cobrança.
”Não foi possível identificar o cliente para esta cobrança.”
processing_error
Falha de comunicação na rede ou erro interno.
”Ocorreu uma falha no processamento. Tente novamente.”
Não mostre o code cru para o comprador — ele é um identificador técnico. Use
a mensagem amigável (a coluna “Mensagem ao cliente”), que o checkout hospedado
já exibe automaticamente.
Ramifique pela payment_error.category para o tratamento geral e pelo
payment_error.code quando precisar de uma mensagem específica. Recusas
processing_error costumam valer uma nova tentativa; já blocked (como
restricted_card, lost_card ou stolen_card) exigem que o cliente acione o
banco.
Reaja ao webhook charge.failed (ou payment.intent.failed) em vez de fazer polling.
Use o metadata da charge/intent para correlacionar a recusa com o pedido no seu sistema.
Para cobranças recorrentes, uma recusa de ciclo move a assinatura para past_due ou unpaid — acompanhe o evento subscription.updated.