Endpoints

POST /payments/{id}/refund

Refund a captured payment in full or in part. Opens an internal claim that releases funds back through the same provider.

POST/api/v1/payments/{id}/refundsecret key

Refund a captured payment. Internally opens a `user_dispute` claim against the source transaction so refunds share the exact same atomic ledger movement (freeze → resolve_approved → release) the chargeback flow uses — keeps the books consistent. The `amount` is in the LOCAL CURRENCY of the original transaction (e.g. MXN for a SPEI charge in Mexico) and uses MAJOR units (e.g. `10` = 10 MXN). Same convention as POST /payments. Omit to refund the full transaction amount.

Body parameters
  • amountnumber
    Local-currency major units. Optional — defaults to the full transaction `amountLocal`. Must be ≤ the captured amount remaining.
  • reasonstring
    Free-form ≤500 chars. Surfaces on the claim record and the dashboard. Common values: `requested_by_customer`, `duplicate`, `fraudulent`, `other`.
Request
curl https://sandbox.key2pays.com/api/v1/payments/TXN-MP331BTF-R308/refund \
  -H "Authorization: Bearer sk_test_51N8mP...exampleK3Y" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 10, "reason": "requested_by_customer" }'
Response
{
  "refundId":      "CLM-MP331G7R-9F49",
  "transactionId": "TXN-MP331BTF-R308",
  "amount":        10,
  "amountUsd":     0.5806,
  "currency":      "MXN",
  "status":        "pending",
  "reason":        "requested_by_customer",
  "createdAt":     "2026-05-12T20:27:53.561Z"
}
Units gotcha: the amount is in local-currency major units (the same field type as the original amountLocal you received on POST /payments), NOT cents. If the original payment was 882.17 MXN and you want to refund 100 MXN, send amount: 100. The response echoes the same units back, plus an amountUsd for cross-currency reporting.
Why "refundId" not "id": a refund is internally a claim (the same model that backs chargebacks) — the prefix CLM- reflects that. The field name refundId on the response is the public identifier you store; use it on GET /api/v1/claims/{id} if you need to fetch its resolution state later.