Reembolsos
Emita reembolsos totais ou parciais sobre transações capturadas, acompanhe o status do ciclo de vida do reembolso e reconcilie os valores reembolsados com a API da Tokeflow.
Um reembolso devolve os fundos de uma transação que já foi capturada. Com a Tokeflow você emite reembolsos por meio de uma única API normalizada — a camada de orquestração repassa a solicitação ao provedor de pagamento conectado, acompanha o resultado e o reflete tanto no registro de reembolso quanto na transação pai.
A Tokeflow padroniza os reembolsos entre provedores: um único formato de solicitação, um único ciclo de vida de status, um único modelo de reconciliação. O provedor de pagamento conectado realiza a movimentação efetiva dos fundos.
A Tokeflow é uma camada de orquestração de pagamentos. Ela registra, roteia e acompanha as solicitações de reembolso e normaliza o resultado; o provedor de pagamento conectado executa o reembolso e liquida os fundos.
Como os reembolsos funcionam
Todo reembolso é filho de uma transação capturada. Você pode reembolsar o valor capturado remanescente por completo, ou emitir vários reembolsos parciais ao longo do tempo até que a transação seja totalmente reembolsada.
- Reembolso total — omita
amountpara reembolsar todo o valor capturado remanescente. - Reembolso parcial — informe
amount(em unidades menores) para reembolsar menos do que o valor capturado remanescente. O saldo restante permanece capturado e pode ser reembolsado posteriormente. - Múltiplos reembolsos parciais — repita os reembolsos parciais até que o valor capturado remanescente chegue a zero. Cada chamada cria um novo registro de reembolso.
Um reembolso só pode ser iniciado quando a transação pai está no status authorized ou refund_pending. Assim que um reembolso é iniciado, a transação passa para refund_pending enquanto o provedor confirma o resultado.
Os resultados de reembolso normalmente são assíncronos. A resposta síncrona confirma que a solicitação foi aceita (refund_pending); assine os webhooks para saber o resultado final em vez de fazer polling.
Ciclo de vida do reembolso
Um registro de reembolso tem o seu próprio status, independente da transação pai.
| Status | Significado |
|---|---|
pending | Reembolso iniciado, ainda não confirmado pelo provedor. |
succeeded | Reembolso confirmado pelo provedor. |
failed | Reembolso falhou no provedor; consulte failure_reason. |
cancelled | Reembolso foi cancelado antes do processamento. |
Como o status do reembolso se reflete na transação
A transação pai reflete o estado agregado dos reembolsos:
- Enquanto qualquer reembolso estiver
pending, a transação ficarefund_pending. - Quando o valor capturado tiver sido totalmente reembolsado, a transação passa a
refunded. - Quando apenas parte do valor capturado tiver sido reembolsada, a transação passa a
partially_refunded.
Reembolsos em dúvida e o saldo reembolsável
Um reembolso reserva o seu valor assim que é iniciado: o saldo reembolsável que a API impõe conta os reembolsos pending além dos succeeded. Enquanto um reembolso anterior ainda está confirmando, um segundo reembolso que levaria o total acima do valor capturado é recusado com 400 (validation_error), de modo que uma requisição repetida ou enviada em duplicidade não move o mesmo dinheiro duas vezes.
Um reembolso só sai de pending quando o provedor dá uma resposta definitiva:
- Se o provedor recusar o reembolso, ele passa para
failed(vejafailure_reason) e o valor reservado é liberado — corrija a requisição e tente novamente. - Se o provedor não retornar nenhum resultado definitivo — um timeout ou um erro do lado do provedor — o reembolso permanece
pendinge a transação permanecerefund_pending. O valor não é liberado, pois os fundos podem já estar em movimento; a resolução não é automática.
Como o resultado pode se resolver de forma assíncrona, assine os webhooks para o resultado final em vez de reenviar o reembolso.
Endpoints
POST/api/v1/transactions/:id/refund
Reembolsa uma transação capturada. Suporta reembolsos totais e múltiplos reembolsos parciais.
Auth: chave de Organization (com merchant_id) ou chave de Merchant. Escopo obrigatório: transactions:write.
Reembolsa uma transação previamente capturada. Omita amount para um reembolso total do valor capturado remanescente, ou informe amount para um reembolso parcial.
A transação deve estar no status authorized ou refund_pending, e o amount do reembolso não pode exceder o valor capturado remanescente. Outros estados retornam 422 business_rule_error; um valor acima do saldo remanescente retorna 400 validation_error.
Parâmetros de caminho
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Sim | ID da transação (tx_…) a reembolsar. |
Parâmetros de consulta
| Field | Type | Required | Description |
|---|---|---|---|
merchant_id | string | Condicional | Merchant de destino (mrc_…). Obrigatório ao usar uma chave de Organization; inferido a partir de uma chave de Merchant. |
Corpo
| Field | Type | Required | Description |
|---|---|---|---|
amount | integer | Não | Valor a reembolsar em unidades menores. Omita para um reembolso total. Deve ser ≥ 1 e ≤ ao valor capturado remanescente. |
reason | enum | Não | Motivo pelo qual o reembolso foi emitido. Um de duplicate, fraudulent, requested_by_customer. |
Envie um cabeçalho Idempotency-Key nas solicitações de reembolso para que uma nova tentativa automática nunca emita um segundo reembolso. Reenviar a mesma chave retorna o resultado original. Consulte Idempotência e limites de taxa.
curl -X POST "https://api.tokeflow.com/api/v1/transactions/tx_777/refund" \
-H "Authorization: Bearer sk_live_mer_…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 3f1c9a7e-2b4d-4e0a-9c6f-7d1e2a3b4c5d" \
-d '{
"amount": 5000,
"reason": "requested_by_customer"
}'Para um reembolso total, omita amount:
curl -X POST "https://api.tokeflow.com/api/v1/transactions/tx_777/refund" \
-H "Authorization: Bearer sk_live_mer_…" \
-H "Content-Type: application/json" \
-d '{ "reason": "duplicate" }'Resposta 200 OK
A resposta confirma que o reembolso foi aceito e ecoa os totais de reconciliação na transação. Os campos monetários estão em unidades menores.
{
"success": true,
"data": {
"id": "tx_777",
"refund_id": "ref_abc123",
"status": "refund_pending",
"amount_captured": 15000,
"amount_refunded": 5000,
"total_refunded": 5000,
"updated_at": "2026-01-15T12:30:00.000Z"
},
"request_id": "req_8f3c2a1b9d4e",
"timestamp": "2026-01-15T12:30:00.000Z"
}| Field | Type | Description |
|---|---|---|
id | string | ID da transação pai (tx_…). |
refund_id | string | O registro de reembolso criado por esta solicitação (ref_…). |
status | enum | Status da transação após a solicitação — refund_pending. |
amount_captured | integer | Valor total capturado na transação, inalterado pelo reembolso. |
amount_refunded | integer | Valor reembolsado por esta solicitação. |
total_refunded | integer | Valor acumulado reembolsado em todos os reembolsos da transação. |
updated_at | string | Carimbo de data/hora ISO 8601 UTC da atualização. |
Em um Idempotency-Key reenviado, este endpoint retorna o resultado original com HTTP 200 em vez de criar um novo reembolso.
GET/api/v1/transactions/:id/refunds
Lista todos os reembolsos de uma transação, do mais recente ao mais antigo.
Auth: chave de Organization (com merchant_id) ou chave de Merchant. Escopo obrigatório: transactions:read.
Use isto para visualizar o histórico de reembolsos, verificar o status de reembolsos parciais ou correlacionar eventos de reembolso com notificações de webhook.
Parâmetros de caminho
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Sim | ID da transação (tx_…). |
Parâmetros de consulta
| Field | Type | Required | Description |
|---|---|---|---|
page | integer | Não | Número da página (indexado a partir de 1). Padrão 1, mínimo 1. |
limit | integer | Não | Itens por página. Padrão 20, máximo 100. |
merchant_id | string | Condicional | Merchant de destino (mrc_…). Obrigatório com uma chave de Organization. |
curl "https://api.tokeflow.com/api/v1/transactions/tx_777/refunds?page=1&limit=20" \
-H "Authorization: Bearer sk_live_mer_…" \
-H "Accept: application/json"Resposta 200 OK
{
"success": true,
"data": [
{
"id": "ref_def456",
"payment_transaction_id": "tx_777",
"amount": 4000,
"currency": "BRL",
"status": "succeeded",
"reason": "requested_by_customer",
"provider_refund_id": "rfnd_7Qx9KpL2",
"failure_reason": null,
"created_at": "2026-01-15T13:10:00.000Z",
"updated_at": "2026-01-15T13:11:42.000Z"
},
{
"id": "ref_abc123",
"payment_transaction_id": "tx_777",
"amount": 5000,
"currency": "BRL",
"status": "succeeded",
"reason": "requested_by_customer",
"provider_refund_id": "rfnd_3Mt0VbN8",
"failure_reason": null,
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:31:05.000Z"
}
],
"meta": {
"pagination": {
"page": 1,
"limit": 20,
"total": 2,
"total_pages": 1,
"has_next": false,
"has_prev": false
}
},
"request_id": "req_5a2f7b1c8e0d",
"timestamp": "2026-01-15T13:12:00.000Z"
}GET/api/v1/transactions/:id/refunds/:refundId
Recupera um único reembolso.
Auth: chave de Organization (com merchant_id) ou chave de Merchant. Escopo obrigatório: transactions:read.
Use isto em fluxos de suporte — por exemplo, para inspecionar um reembolso após uma notificação de webhook, ou quando um reembolso falha ou demora a ser liquidado.
Parâmetros de caminho
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Sim | ID da transação (tx_…). |
refundId | string | Sim | ID do reembolso (ref_…). |
Parâmetros de consulta
| Field | Type | Required | Description |
|---|---|---|---|
merchant_id | string | Condicional | Merchant de destino (mrc_…). Obrigatório com uma chave de Organization. |
curl "https://api.tokeflow.com/api/v1/transactions/tx_777/refunds/ref_abc123" \
-H "Authorization: Bearer sk_live_mer_…" \
-H "Accept: application/json"Resposta 200 OK
{
"success": true,
"data": {
"id": "ref_abc123",
"payment_transaction_id": "tx_777",
"amount": 5000,
"currency": "BRL",
"status": "succeeded",
"reason": "requested_by_customer",
"provider_refund_id": "rfnd_3Mt0VbN8",
"failure_reason": null,
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:31:05.000Z"
},
"request_id": "req_9c4e1d7a2b6f",
"timestamp": "2026-01-15T12:32:00.000Z"
}O objeto de reembolso
| Field | Type | Description |
|---|---|---|
id | string | ID do reembolso (ref_…). |
payment_transaction_id | string | ID da transação pai (tx_…). |
amount | integer | Valor do reembolso em unidades menores. |
currency | string | Código de moeda ISO 4217 (ex.: BRL). |
status | enum | pending, succeeded, failed ou cancelled. |
reason | enum | null | duplicate, fraudulent ou requested_by_customer. null se não informado. |
provider_refund_id | string | null | Identificador opaco do reembolso no provedor conectado. Trate como uma string opaca. null até ser atribuído. |
failure_reason | string | null | Detalhe legível da falha quando status é failed; caso contrário, null. |
created_at | string | Carimbo de data/hora ISO 8601 UTC de criação. |
updated_at | string | Carimbo de data/hora ISO 8601 UTC da última atualização. |
Erros
Os endpoints de reembolso usam o envelope de erro padrão.
| HTTP | Type | When |
|---|---|---|
400 | validation_error | amount excede o valor capturado remanescente, ou está malformado. |
401 | authentication_error | Chave de API ausente ou inválida. |
403 | authorization_error | A chave não possui o escopo obrigatório, ou a transação está fora do escopo da chave. |
404 | not_found_error | Transação ou reembolso não encontrado, ou não pertencente ao merchant. |
409 | conflict_error | Um reembolso conflitante já está em andamento. |
422 | business_rule_error | A transação não está no status authorized ou refund_pending. |
429 | rate_limit_error | Limite de taxa por chave excedido; aguarde e tente novamente. |
{
"error": {
"type": "business_rule_error",
"code": "TRANSACTION_NOT_REFUNDABLE",
"message": "Transaction must be in 'authorized' or 'refund_pending' status to be refunded.",
"details": { "current_status": "failed" },
"request_id": "req_2b8d4f6a1c3e",
"timestamp": "2026-01-15T12:40:00.000Z"
}
}Relacionados
- Transações — crie, capture e inspecione transações.
- Webhooks — receba os eventos
transaction.refundedetransaction.partially_refunded. - Idempotência e limites de taxa — torne as solicitações de reembolso seguras para novas tentativas.
- Erros — envelope de erro e tipos.