Refunds
Reverse a payment that has already settled, in full or in part.
A refund only applies to a payment that reached succeeded. A payment that failed needs no refund — the money never left, and any hold on your float was released automatically.
Create a refund
POST /payments/{id}/refunds
Authorization: Bearer $KEY
{
"amount": 500.00,
"reason": "Customer cancelled after posting"
}
| Field | Required | Notes |
|---|---|---|
amount | No | Omit to refund everything still refundable. Must not exceed the remaining refundable amount. |
reason | No | Free text, stored with the refund and shown in the dashboard. |
{
"data": {
"id": "01kxk…",
"payment_id": "01kxjehb1aa3ztdy315q0ffbdh",
"status": "succeeded",
"amount": "500.00",
"currency": "PHP",
"reason": "Customer cancelled after posting",
"created_at": "2026-07-15T09:02:11+00:00"
}
}
Partial refunds
You can refund a payment more than once, up to the customer total. Each call returns its own refund record, and the payment tracks the running total in refunded_amount. Once the whole customer total has been refunded, the payment's status becomes refunded.
Refunds are against the customer total — the bill amount plus the provider convenience fee and Billy's platform fee — so a full refund makes the customer whole on those. On a collect payment the gateway_fee is not refundable: the payment gateway keeps its processing fee, so it can't be clawed back through a refund.
Where the money goes
| Original funding | Where the refund lands |
|---|---|
wallet | Back to your float as a refund credit, spendable immediately. Refunding your customer is then up to you. |
collect | Back to the end-user, on the card or e-wallet they paid with. Their provider decides how quickly it appears. |
Listing refunds
GET /payments/{id}/refunds
Returns every refund against that payment, newest first.
Statuses
| Status | Meaning |
|---|---|
pending | Accepted and being processed. |
succeeded | The money has been returned. |
failed | Could not be completed. Nothing was returned; the payment is unchanged. |
Errors worth handling
| Status | Why |
|---|---|
404 | No such payment on your account. |
422 | The payment hasn't settled, or the amount exceeds what's still refundable. |
A payment.refunded webhook fires on every successful refund, partial or full.