refund: um objeto financeiro próprio, ligado à cobrança original e com um
status que informa se a devolução ainda está em processamento, foi concluída ou
falhou.
Este guia mostra como decidir entre cancelamento e devolução, criar um refund
total ou parcial, acompanhar o resultado e reconciliar o dinheiro em cartão e
PIX.
A regra principal é simples: se o
payment_intent está succeeded, devolva o
dinheiro com POST /v1/refunds. Se ele ainda não recebeu o dinheiro, cancele
a tentativa com POST /v1/payment-intents/{id}/cancel.Primeiro: cancelar ou devolver?
Olhe ostatus atual do payment_intent antes de escolher a operação.
O que acontece com o dinheiro
A chamada para criar um refund inicia um fluxo financeiro; ela não é apenas uma mudança de status no seu pedido.- A Chargefy valida se a
chargefoi paga, capturada e ainda tem valor disponível para devolução. - O valor solicitado fica logicamente comprometido com aquele refund. Isso impede que dois refunds concorrentes devolvam mais do que foi capturado.
- A devolução é enviada pela mesma transação financeira usada no pagamento.
- O objeto
refundinforma o resultado emstatus. - Somente
status: "succeeded"confirma que a devolução foi processada.
Cartão de crédito
O crédito volta para o mesmo cartão usado na compra. O comprador não informa outro cartão e sua integração não envia dados de destino. Quando o refund chega asucceeded, a devolução foi processada. O tempo para o
crédito aparecer na fatura ou no limite disponível ainda depende do emissor do
cartão e do fechamento da fatura. Por isso, não prometa que o comprador verá o
crédito imediatamente na tela do banco.
PIX
O valor volta pelo fluxo da transação PIX original. Sua integração não envia uma nova chave PIX e não escolhe uma conta de destino. Refunds de PIX costumam concluir rapidamente, mas a regra de integração é a mesma do cartão: espererefund.status: "succeeded" antes de marcar a devolução
como concluída.
Antes de começar
Você precisa de:- uma API key com permissão de escrita;
- o ID do
payment_intent(pi_*) ou dacharge(ch_*); - uma cobrança paga e capturada;
- o valor a devolver, quando a devolução for parcial;
- uma chave de idempotência única para essa operação.
Organization com a organização
conectada dona do pagamento.
Passo a passo
1
Confirme que o pagamento foi concluído
Consulte o Se o retorno estiver em
payment_intent e verifique o status. Um refund só faz sentido
quando existe uma charge paga e capturada.requires_capture, o cartão foi autorizado, mas o
dinheiro ainda não foi capturado. Nesse caso, cancele o Payment Intent em
vez de criar um refund.2
Escolha a referência da devolução
O endpoint aceita exatamente um destes campos:
payment_intent: caminho recomendado quando o seu sistema acompanha a cobrança pelo processo completo. A Chargefy encontra a charge capturada correspondente.charge: use quando você precisa devolver uma tentativa específica, por exemplo, ao reconciliar duas cobranças duplicadas.
3
Escolha entre devolução total e parcial
Para devolver todo o saldo ainda disponível, omita
amount. Para devolver
apenas uma parte, envie amount como inteiro em centavos.Por exemplo, 5000 significa R$ 50,00. Nunca envie 50.00, 50,00 ou uma
string formatada.4
Gere uma chave de idempotência
Use uma chave única por devolução lógica e envie-a somente no header
Idempotency-Key. Se a resposta se perder, repita o mesmo request com a
mesma chave.Não gere uma chave nova só porque ocorreu timeout: isso pode criar uma
segunda devolução.5
Crie o refund
Faça
POST /v1/refunds usando uma das variantes abaixo. A resposta é o objeto
refund completo.6
Decida pelo status do refund
Trate
succeeded como conclusão. Para pending ou requires_action,
mantenha a operação em andamento. Para failed ou canceled, não informe ao
comprador que o dinheiro foi devolvido.7
Acompanhe os webhooks
Persista o
refund.id, processe os eventos de forma idempotente e atualize
o seu pedido usando sempre o estado completo de data.object.Payloads de criação
(a) Devolução total pelo Payment Intent
É o caminho mais simples quando o seu sistema já guarda opi_*. A ausência de
amount significa: devolva todo o valor capturado que ainda está disponível.
(b) Devolução total por uma charge específica
Use esta forma quando houver mais de uma tentativa relacionada ao mesmo pedido e você souber exatamente qualcharge precisa ser devolvida.
(c) Devolução parcial
Envieamount quando somente parte da compra deve voltar ao comprador.
reason é opcional. Use metadata para guardar referências livres do seu
sistema, como o ID do pedido ou do atendimento. Não coloque regra de negócio
essencial apenas em metadata.
Exemplo de resposta
O endpoint retorna200 OK com o objeto refund completo. Neste exemplo, uma
devolução parcial de R$ 50,00 já foi processada:
Como interpretar cada status
Webhooks que sua integração deve tratar
Exemplo resumido de um refund que saiu de
pending para succeeded:
- validar a assinatura do webhook;
- deduplicar pelo
event.id; - localizar a devolução por
data.object.id; - substituir o estado local pelo objeto completo de
data.object; - confirmar a devolução ao comprador somente quando
statusforsucceeded.
Cenários comuns
O comprador desistiu depois de pagar com cartão
O pagamento já estásucceeded. Crie um refund total pelo payment_intent e
use reason: "requested_by_customer". Informe que o crédito pode levar algum
tempo para aparecer na fatura, mesmo depois de o refund ficar succeeded.
Houve duas cobranças para o mesmo pedido
Identifique acharge que deve ser revertida e crie o refund por ela com
reason: "duplicate". Não devolva pelo pedido de forma genérica: duas charges
distintas exigem reconciliação explícita para evitar devolver a cobrança
correta por engano.
Apenas um item do pedido foi devolvido
Some o valor daquele item e envieamount em centavos. O refund será parcial e
o restante da charge continuará pago. Você pode criar outros refunds parciais
depois, até consumir todo o valor capturado disponível.
Um PIX foi pago depois de o pedido ser cancelado
Se a confirmação financeira chegou, existe uma charge paga mesmo que o seu pedido já esteja cancelado. Crie um refund usando essacharge ou o
payment_intent relacionado. Não tente “cancelar o PIX pago”: depois da
liquidação, o caminho correto é a devolução.
A API retornou timeout ou erro 5xx
Não conclua que nada aconteceu. Consulte o refund pelo ID conhecido ou liste os
refunds filtrando por charge ou payment_intent. Depois, repita a chamada com
o mesmo Idempotency-Key e o mesmo corpo.
Uma chave nova representa uma nova operação e pode causar devolução duplicada.
O refund falhou por saldo insuficiente
O objeto pode chegar afailed com failure_reason: "insufficient_funds".
Mantenha a devolução como pendente de resolução no seu backoffice; não informe
ao comprador que o dinheiro voltou. Consulte o refund e acione o suporte se a
causa não puder ser resolvida operacionalmente.
Erros comuns da API
O que não fazer
- Não use o status do seu pedido como prova de que o dinheiro voltou.
- Não trate
refund.createdcomo confirmação financeira. - Não tente cancelar um Payment Intent que já está
succeeded. - Não crie uma nova chave de idempotência para repetir a mesma devolução.
- Não use apenas
charge.statuspara reconciliar; guarde o objetorefunde acompanhe o seustatus. - Não prometa prazo exato de visualização no cartão depois de
succeeded. - Não tente desfazer um refund concluído. Para cobrar novamente, crie uma nova tentativa de pagamento autorizada pelo comprador.
Checklist para produção
- Guardar
payment_intent,chargeerefundno pedido. - Enviar valores monetários como inteiros em centavos.
- Usar
Idempotency-Keyem toda criação de refund. - Processar
refund.created,refund.updatederefund.failed. - Deduplicar webhooks por
event.id. - Tratar somente
refund.status: "succeeded"como conclusão. - Separar “pedido cancelado”, “refund solicitado” e “dinheiro devolvido” no seu modelo de status.
- Testar devolução total, parcial, retry e falha antes de operar em produção.
Próximos passos
Criar um refund
Contrato completo do
POST /v1/refunds, incluindo campos e erros.Objeto refund
Consulte todos os campos, status e motivos de falha.
Idempotência
Saiba como repetir mutações sem executar a mesma operação duas vezes.
Cancelar uma tentativa
Use este fluxo quando o dinheiro ainda não foi capturado.

