Skip to main content
Quando uma cobrança não é aprovada, a charge chega ao estado failed e o motivo vem resolvido em um único grupo: payment_error. A Chargefy lê todos os sinais do processamento — código bruto da rede, resposta do emissor, validações locais — e publica uma única leitura final, com categoria, código estável, mensagem e orientação. A evidência bruta da rede, quando existe, vem no mesmo grupo com o prefixo network_*. O mesmo shape aparece em payment_intent.last_payment_error com a última tentativa recusada do intent.

O único objeto que você precisa ler

payment_error é null em cobranças aprovadas. Quando preenchido: A divisão é deliberada: os quatro campos resolvidos pela Chargefy são o contrato estável — ramifique sua integração por eles. Os dois network_* são evidência bruta para diagnóstico e suporte: não são universais, variam por bandeira, só fazem sentido analisados junto de payment_method_details.card.brand e podem ser null quando a rede não devolve um sinal confiável.
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 segura” abaixo. Não exiba message nem códigos crus ao comprador.

Recusa definitiva vs resultado não confirmado

Cada charge representa uma tentativa de cobrar; o payment_intent representa o pagamento que você quer concluir e pode receber outra tentativa quando a anterior termina recusada.
Um timeout não prova que a cobrança falhou. Quando receber payment_result_unconfirmed, repetir a criação ou confirmação pode produzir uma segunda cobrança. Consulte o mesmo recurso até obter o desfecho.
Uma charge recusada é terminal, mas o payment_intent não precisa ser. Em requires_payment_method, confirme novamente o mesmo intent com os dados corrigidos, outro cartão ou outro método. Não crie outro intent só porque uma tentativa falhou.

Testar códigos no sandbox

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).

Categorias (category)

category agrupa os motivos em quatro baldes, úteis para decidir o tratamento sem precisar ramificar por cada code:

Códigos Chargefy (code)

Cada motivo de falha vira um payment_error.code estável e granular. Abaixo, os códigos estão agrupados por category. Significado explica o que aconteceu; Mensagem segura é o texto que o checkout hospedado pode exibir ao comprador; Ação recomendada orienta o próximo passo da integração.

issuer_declined — o banco emissor recusou

invalid — dados do cartão incorretos

blocked — restrição ou suspeita de fraude

processing_error — falha técnica ou de conectividade

processing_error não autoriza retry cego. Quando a API responder payment_result_unconfirmed, a tentativa pode existir: consulte o Payment Intent/Checkout Session e aguarde o webhook. Repetir o write pode cobrar duas vezes.
Se um sinal de falha ainda não tiver classificação específica, a Chargefy não o trata como sucesso nem o deixa sem resposta. A integração recebe o fallback processing_error, a ocorrência é registrada para investigação e o estado do recurso deve ser consultado antes de qualquer nova tentativa.

Como decidir a retentativa

payment_error.advice_code descreve a orientação disponível para aquela ocorrência. Ele complementa payment_error.code; não substitui o estado atual do recurso. Uma nova tentativa após correção é diferente de repetir automaticamente a mesma request. Use uma chave de idempotência para retries seguros de transporte e nunca transforme payment_result_unconfirmed em um novo write. Em cobranças recorrentes, do_not_try_again interrompe a repetição automática do mesmo método sem encerrar a cobrança em aberto. O comprador ainda pode atualizar o cartão ou pagar por outro método; essa ação cria uma nova tentativa dentro do mesmo pagamento.

Quando os campos ficam null

Onde o motivo aparece

  • Resposta da APIGET /v1/charges/{id} traz payment_error; GET /v1/payment-intents/{id} traz last_payment_error da última tentativa, no mesmo shape.
  • Webhookscharge.failed carrega payment_error; o payment.intent.updated da recusa carrega last_payment_error no objeto completo em data.object.
  • Checkout hospedado — o comprador vê a mensagem localizada correspondente ao code, sem nenhum código técnico.

Exemplo: charge.failed

O valor 51 em network_decline_code é um sinal bruto: só deve ser analisado junto de payment_method_details.card.brand. O código Chargefy em payment_error.code é o dado estável para a sua integração.

Como tratar a recusa

Ramifique pela payment_error.category para o tratamento geral e pelo payment_error.code quando precisar de uma mensagem específica. Use payment_error.advice_code para decidir a retentativa. Recusas blocked (como restricted_card, lost_card ou stolen_card) exigem que o cliente use outro método ou acione o banco.
  • Reaja ao webhook charge.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.

Próximos passos

Cobranças

O objeto charge e o ciclo de uma tentativa de cobrança.

Payment Intents

O processo que materializa a charge e expõe last_payment_error.

Evento charge.failed

Payload completo do webhook de cobrança recusada.

Objeto charge

Schema público completo, com o objeto payment_error.