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 amount para 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.

StatusSignificado
pendingReembolso iniciado, ainda não confirmado pelo provedor.
succeededReembolso confirmado pelo provedor.
failedReembolso falhou no provedor; consulte failure_reason.
cancelledReembolso 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 fica refund_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 (veja failure_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 pending e a transação permanece refund_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.

OrgMerchant

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

FieldTypeRequiredDescription
idstringSimID da transação (tx_…) a reembolsar.

Parâmetros de consulta

FieldTypeRequiredDescription
merchant_idstringCondicionalMerchant de destino (mrc_…). Obrigatório ao usar uma chave de Organization; inferido a partir de uma chave de Merchant.

Corpo

FieldTypeRequiredDescription
amountintegerNãoValor a reembolsar em unidades menores. Omita para um reembolso total. Deve ser ≥ 1 e ≤ ao valor capturado remanescente.
reasonenumNãoMotivo 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"
}
FieldTypeDescription
idstringID da transação pai (tx_…).
refund_idstringO registro de reembolso criado por esta solicitação (ref_…).
statusenumStatus da transação após a solicitação — refund_pending.
amount_capturedintegerValor total capturado na transação, inalterado pelo reembolso.
amount_refundedintegerValor reembolsado por esta solicitação.
total_refundedintegerValor acumulado reembolsado em todos os reembolsos da transação.
updated_atstringCarimbo 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.

OrgMerchant

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

FieldTypeRequiredDescription
idstringSimID da transação (tx_…).

Parâmetros de consulta

FieldTypeRequiredDescription
pageintegerNãoNúmero da página (indexado a partir de 1). Padrão 1, mínimo 1.
limitintegerNãoItens por página. Padrão 20, máximo 100.
merchant_idstringCondicionalMerchant 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.

OrgMerchant

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

FieldTypeRequiredDescription
idstringSimID da transação (tx_…).
refundIdstringSimID do reembolso (ref_…).

Parâmetros de consulta

FieldTypeRequiredDescription
merchant_idstringCondicionalMerchant 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

FieldTypeDescription
idstringID do reembolso (ref_…).
payment_transaction_idstringID da transação pai (tx_…).
amountintegerValor do reembolso em unidades menores.
currencystringCódigo de moeda ISO 4217 (ex.: BRL).
statusenumpending, succeeded, failed ou cancelled.
reasonenum | nullduplicate, fraudulent ou requested_by_customer. null se não informado.
provider_refund_idstring | nullIdentificador opaco do reembolso no provedor conectado. Trate como uma string opaca. null até ser atribuído.
failure_reasonstring | nullDetalhe legível da falha quando status é failed; caso contrário, null.
created_atstringCarimbo de data/hora ISO 8601 UTC de criação.
updated_atstringCarimbo de data/hora ISO 8601 UTC da última atualização.

Erros

Os endpoints de reembolso usam o envelope de erro padrão.

HTTPTypeWhen
400validation_erroramount excede o valor capturado remanescente, ou está malformado.
401authentication_errorChave de API ausente ou inválida.
403authorization_errorA chave não possui o escopo obrigatório, ou a transação está fora do escopo da chave.
404not_found_errorTransação ou reembolso não encontrado, ou não pertencente ao merchant.
409conflict_errorUm reembolso conflitante já está em andamento.
422business_rule_errorA transação não está no status authorized ou refund_pending.
429rate_limit_errorLimite 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.refunded e transaction.partially_refunded.
  • Idempotência e limites de taxa — torne as solicitações de reembolso seguras para novas tentativas.
  • Erros — envelope de erro e tipos.

Nesta página