Pix
Devolução
Como devolver ao pagador todo ou parte do valor de uma cobrança paga.
POST /v1/pix/charges/{id}/refunds devolve ao pagador todo ou parte do valor de uma cobrança paga. Escopo: refunds:write. Referência: Solicitar devolução.
POST/v1/pix/charges/{id}/refunds
curl -X POST 'https://api.kokupay.com/v1/pix/charges/8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47/refunds' \
-H "Authorization: Bearer $KOKU_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: devolucao-pedido-1001-1" \
-d '{
"amount_cents": 5000,
"reason": "Cliente devolveu um item"
}'const response = await fetch('https://api.kokupay.com/v1/pix/charges/8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47/refunds', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KOKU_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'devolucao-pedido-1001-1',
},
body: JSON.stringify({
amount_cents: 5000,
reason: 'Cliente devolveu um item',
}),
});
const data = await response.json();
console.log(response.status, data);import os
import requests
response = requests.request(
"POST",
"https://api.kokupay.com/v1/pix/charges/8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47/refunds",
headers={
"Authorization": f"Bearer {os.environ['KOKU_API_KEY']}",
"Idempotency-Key": "devolucao-pedido-1001-1",
},
json={
"amount_cents": 5000,
"reason": "Cliente devolveu um item",
},
timeout=30,
)
print(response.status_code, response.json())<?php
$ch = curl_init('https://api.kokupay.com/v1/pix/charges/8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47/refunds');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('KOKU_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: devolucao-pedido-1001-1',
],
CURLOPT_POSTFIELDS => json_encode([
'amount_cents' => 5000,
'reason' => 'Cliente devolveu um item',
]),
]);
$data = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo $status, PHP_EOL;
print_r($data);201Resposta
{
"id": "3c7e1b95-6d2a-4f80-9e4b-a1d5c8f20e63",
"gateway_id": "5f0c2a9e-1b7d-4c3e-9a51-2d8e6f4b7c10",
"environment": "production",
"case_type": "refund",
"status": "in_review",
"med_stage": null,
"charge_id": "8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47",
"amount_cents": "5000",
"held_cents": "5000",
"shortfall_cents": "0",
"origin": "gateway",
"reason": "Cliente devolveu um item",
"liability": "gateway",
"execution_status": "queued",
"resolution": null,
"resolution_note": null,
"resolved_amount_cents": null,
"opened_at": "2026-10-08T12:00:00.000Z",
"due_at": null,
"resolved_at": null
}Como funciona
- Pedido. Você informa o valor (
amount_cents) e o motivo (reason, de 3 a 300 caracteres), comIdempotency-Key. Repetir com a mesma chave e o mesmo corpo devolve o mesmo caso; mudar qualquer campo (inclusive o motivo) com a mesma chave responde409 idempotency_conflict. - Bloqueio. A Koku bloqueia o valor no seu saldo na hora e abre um caso de devolução (
case_type: "refund"). Você recebecase.opened. - Processamento. A devolução é enviada ao pagador pela rede de processamento (
execution_statuspassa dequeuedparasubmittede depoiscompleted). - Conclusão. A cobrança vira
partially_refundedourefundede você recebecharge.refundedecase.resolved.
Regras
- Só cobrança
paidoupartially_refundedpode ser devolvida. - Pode ser parcial; a soma das devoluções nunca passa do valor pago. Acima disso:
422. - O valor sai do seu saldo (pendente primeiro, depois disponível). Sem saldo suficiente, a devolução é recusada com
409 insufficient_fundse nada é criado. - A tarifa da venda não é devolvida, salvo se o seu contrato disser outra coisa.
- Se a API responder
409 conflictcomdetails.reason = "manual_refund_required", essa devolução precisa ser feita junto com a Koku: fale com a equipe pelo canal descrito em Suporte, informando ocorrelation_id. - Se a rede de processamento não conseguir executar a devolução, o caso termina
cancelled, nenhum valor é enviado ao pagador, o bloqueio volta ao seu saldo eresolution_noteexplica o ocorrido em texto fixo.
Acompanhando
Consulte os casos da cobrança:
GET/v1/pix/charges/{id}/cases
curl -X GET 'https://api.kokupay.com/v1/pix/charges/8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47/cases' \
-H "Authorization: Bearer $KOKU_API_KEY"const response = await fetch('https://api.kokupay.com/v1/pix/charges/8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47/cases', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.KOKU_API_KEY}`,
},
});
const data = await response.json();
console.log(response.status, data);import os
import requests
response = requests.request(
"GET",
"https://api.kokupay.com/v1/pix/charges/8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47/cases",
headers={
"Authorization": f"Bearer {os.environ['KOKU_API_KEY']}",
},
timeout=30,
)
print(response.status_code, response.json())<?php
$ch = curl_init('https://api.kokupay.com/v1/pix/charges/8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47/cases');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('KOKU_API_KEY'),
],
]);
$data = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo $status, PHP_EOL;
print_r($data);200Resposta
{
"items": [
{
"id": "3c7e1b95-6d2a-4f80-9e4b-a1d5c8f20e63",
"gateway_id": "5f0c2a9e-1b7d-4c3e-9a51-2d8e6f4b7c10",
"environment": "production",
"case_type": "refund",
"status": "resolved",
"med_stage": null,
"charge_id": "8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47",
"amount_cents": "5000",
"held_cents": "0",
"shortfall_cents": "0",
"origin": "gateway",
"reason": "Cliente devolveu um item",
"liability": "gateway",
"execution_status": "completed",
"resolution": "refunded",
"resolution_note": null,
"resolved_amount_cents": "5000",
"opened_at": "2026-10-08T12:00:00.000Z",
"due_at": null,
"resolved_at": "2026-10-08T12:00:04.000Z"
}
]
}E a cobrança, que passa a mostrar refunded_cents:
200Resposta
{
"id": "8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47",
"gateway_id": "5f0c2a9e-1b7d-4c3e-9a51-2d8e6f4b7c10",
"environment": "production",
"order_reference": "PEDIDO-1001",
"amount_cents": "15990",
"currency": "BRL",
"description": "Pedido 1001 - Loja Exemplo",
"status": "partially_refunded",
"fee_percent_bps": 200,
"fee_fixed_cents": "0",
"fee_cents": "320",
"net_cents": "15670",
"reserve_cents": "0",
"refunded_cents": "5000",
"expires_at": "2026-10-07T16:00:00.000Z",
"paid_at": "2026-10-07T15:32:10.000Z",
"late_payment": false,
"is_simulated": false,
"created_at": "2026-10-07T15:30:00.000Z",
"updated_at": "2026-10-08T12:00:04.000Z",
"pix": {
"qr_code_payload": "00020101021226850014br.gov.bcb.pix2563qr.exemplo.com.br/pix/v2/8d3f6a124b9e4c71a2d56e0f1b3c9a475204000053039865406159.905802BR5913LOJA EXEMPLO6009SAO PAULO62070503***6304A1B2",
"txid": "8d3f6a124b9e4c71a2d56e0f1b3c9a47",
"expires_at": "2026-10-07T16:00:00.000Z"
},
"end_to_end_id": "E12345678202610071532a1B2c3D4e5F",
"payments_count": 1,
"failure_message": null
}Os eventos case.opened, charge.refunded e case.resolved estão em Eventos e payloads.
Contestações (MED)
Quando o pagador contesta um Pix pelo Mecanismo Especial de Devolução (MED) do Banco Central, a Koku abre um caso med na cobrança, bloqueia o valor no seu saldo e envia case.opened. O desfecho chega em case.resolved. Acompanhe pelos mesmos endpoints.