Docs
Acessar painel

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"
}'
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

  1. Pedido. Você informa o valor (amount_cents) e o motivo (reason, de 3 a 300 caracteres), com Idempotency-Key. Repetir com a mesma chave e o mesmo corpo devolve o mesmo caso; mudar qualquer campo (inclusive o motivo) com a mesma chave responde 409 idempotency_conflict.
  2. Bloqueio. A Koku bloqueia o valor no seu saldo na hora e abre um caso de devolução (case_type: "refund"). Você recebe case.opened.
  3. Processamento. A devolução é enviada ao pagador pela rede de processamento (execution_status passa de queued para submitted e depois completed).
  4. Conclusão. A cobrança vira partially_refunded ou refunded e você recebe charge.refunded e case.resolved.

Regras

  • Só cobrança paid ou partially_refunded pode 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_funds e nada é criado.
  • A tarifa da venda não é devolvida, salvo se o seu contrato disser outra coisa.
  • Se a API responder 409 conflict com details.reason = "manual_refund_required", essa devolução precisa ser feita junto com a Koku: fale com a equipe pelo canal descrito em Suporte, informando o correlation_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 e resolution_note explica 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"
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.