Skip to content

Refunds

Download .md

Refund a succeeded payment session with POST /gateway/sessions/{id}/refund/. Refunds can be full or partial, and a session can be refunded several times until its whole amount has been returned.

Terminal window
curl https://api.paymee.online/api/v1/gateway/sessions/ps_0b7c3a1e-…/refund/ \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c0e9a-2d4b-4b8e-9a51-0c3f7d2e8b14" \
-d '{
"reason": "Damaged item",
"refund_type": "PARTIAL",
"amount": "3.000"
}'
Field Type Required Notes
reason string (≤ 500) ✅ Why the refund is issued.
refund_type string – FULL (default): the whole amount of the payment. PARTIAL: the amount you give.
amount string for PARTIAL A positive decimal string in TND, e.g. "3.000". Extra decimals are rounded to the millime.
metadata object – Your own key/values, stored with the refund.

A FULL refund always means the full amount of the payment. After a partial refund, return the rest with a PARTIAL refund of the remaining amount.

A refund request that times out may or may not have been processed. To retry without refunding twice, send an Idempotency-Key header: a unique value you generate per refund (a UUID v4 is ideal), up to 255 characters.

  • Repeating a request with the same key and the same body returns the refund that key created — with the Idempotent-Replayed: true header — instead of refunding again.
  • If that refund had been refused (for example insufficient-funds), repeating it with the same key tries again.
  • Using a key that was already used for a different refund request (another body or another session) returns 409 idempotency-key-reuse.

Keys do not expire. Without the header, every request is a new refund: a retried PARTIAL request would refund twice. (Retrying a FULL refund without a key is refused as over-refund, so it is safe either way.)

A refund request answers 200 OK with the refund:

{
"id": "re_4f1d0c2e-9b7a-4c51-8f0e-2a6b1c3d4e5f",
"session_id": "ps_0b7c3a1e-5d2f-4e8a-9c6b-1f2e3d4c5b6a",
"merchant_reference": "order-0001",
"amount": "3.000",
"currency": "TND",
"refund_type": "PARTIAL",
"status": "SUCCEEDED",
"reason": "Damaged item",
"processor_message": null,
"created_at": "2026-11-21T09:12:01.870000Z",
"completed_at": "2026-11-21T09:12:03.095000Z"
}
status Meaning
SUCCEEDED The money is on its way back to the buyer’s card. completed_at is set.
PENDING The refund is accepted but could not be confirmed automatically; it is completed manually and can take a few days. processor_message says why. We contact you if anything is needed on your side.
FAILED The money was not returned. completed_at is set and processor_message says why.

Most card refunds are SUCCEEDED straight away. A PENDING refund ends as SUCCEEDED or FAILED, and you are told by webhook: refund.succeeded or refund.failed (see Webhooks). These events are sent for every refund, including those issued from your dashboard.

Every refund of a session is also listed, oldest first, in the refunds array of GET /gateway/sessions/{id}/ — use it for reconciliation. A refund does not change the session’s own status, which stays SUCCEEDED.

processor_message is informational, for your logs and support; don’t branch on its text.

  • Only a SUCCEEDED session can be refunded. Refunds are always in TND.
  • The total of a session’s refunds can never exceed what was paid. A refund over the remaining amount is refused (over-refund).
  • A partial refund can be refused until the payment has settled, normally the day after the payment (partial-requires-settled). A full refund is accepted right away.
  • A refund can be refused when it can’t be funded from your balance (insufficient-funds).

Errors are problem documents. A refusal changes nothing: you can fix the cause and send the request again.

type suffix HTTP When
bad-request 400 The body isn’t valid JSON, or the Idempotency-Key is empty or over 255 characters.
not-found 404 No such session on this account.
idempotency-key-reuse 409 The Idempotency-Key was already used for a different refund request.
validation-error 422 reason missing, unknown refund_type, or a PARTIAL refund without a positive amount.
invalid-state 422 The session or its payment can’t be refunded (e.g. the session isn’t SUCCEEDED).
no-payment 422 The session has no successful payment.
partial-requires-settled 422 Partial refund before the payment has settled.
over-refund 422 More than the amount left to refund.
insufficient-funds 422 The refund can’t be funded from your balance.
refund-failed 422 The refund could not be recorded; nothing was returned to the buyer.