Skip to main content
204 No Content
No request body. No amount. No JSON in the response. The customer’s full original amount is back in their wallet.

The rules

Full amount only

There is no partial refund. If you need to refund part of a sale, reverse the whole charge and take a new one for the correct amount.

Once

A second attempt returns 409. See below — that is not a failure.

30 minutes, same terminal

This route only reverses a charge taken by the calling terminal within the last 30 minutes. Anything older, or taken by another terminal, returns a 403 with a machine code — see below.

Your charges only

Another merchant’s transaction returns 403, indistinguishable from “not a charge”.
It also works while the customer’s wallet is suspended. A benefit being frozen must never trap money that is rightfully theirs.

The 30-minute window

The terminal credential exists to take payments, so this route is scoped to the one refund a till legitimately makes: undoing its own mistake — wrong amount, wrong customer, charged twice — moments after it happened. Everything else is a manager action: a signed-in merchant admin can reverse any charge, from any terminal and any date, in the Vibepay merchant dashboard (Transactions → open the charge → Refund). Outside the window (or from a different terminal) you get a 403 with a JSON body and a stable code, so your POS can tell the cashier what to actually do:
403 — outside the window
403 — another terminal's charge
Show the instruction, not “forbidden”. Map both codes to a message that points the cashier at the merchant dashboard. The refund is not being refused — it is being routed to someone with the authority to make it.
The plain-text 403 (forbidden) is different: it means the transaction belongs to another merchant or is not a charge, and it carries no code on purpose.

Treat 409 as success

409 Conflict
The customer has their money back. Your local record is simply behind.
Converge, do not retry. On a 409, mark the sale refunded in your own system and show the cashier a success message. This is exactly what the official Vibepay POS app does, and it makes a refund button safe to press twice.

You need the transaction id

tx_01k2y7v9j0e8ra7cx3mbq4d5nf — the id from the charge response. There is no way to refund by QR code, by amount, or by time.
Store the id against your own order record at the moment of sale. If you lose it you can still find the transaction in GET /v1/transactions by amount and timestamp, but that is a manual, error-prone reconciliation in front of a waiting customer.
Printing it on the customer receipt is a good habit. It makes a walk-in refund a lookup instead of a search.

What happens behind the scenes

You get your 204 immediately. Three things then happen asynchronously, none of which can delay or block the refund:
1

The wallet is credited

Already done by the time you get the 204 — this part is synchronous.
2

The VAT receipt is cancelled

Vibepay voids the receipt with the tax authority. vatStatus on the transaction moves to voided. You do not need to file anything.
3

Settlement is adjusted

If the original charge had already been paid out to you in an earlier weekly cycle, the amount is netted off your next payout. Nothing is clawed back from your bank account.

Errors

Reversal is naturally idempotent — the worst a repeat can do is return 409 — so it takes no Idempotency-Key and none is needed.

What happens to the tax receipt

How VAT issuance and voiding work, and how to observe them.