Skip to content

Refunds ​

Return a captured payment through the Maytes merchant portal or merchant API. Refunds settle asynchronously, so keep your order record in sync with the checkout status.

Partial refunds are coming

Today a refund returns the full captured amount. Support for partial refunds is on its way.

Requirements:

  • Only a captured checkout can be refunded. For an order that's merely authorized, cancel it instead — no money has moved yet.
  • The customer always gets 100% back on the same card they used to pay.
  • Refunds settle asynchronously with the payment provider — the checkout passes through a brief refunding state before landing on refunded.
  • API requests require a unique merchant_refund_ref. Reusing the same value safely returns the existing refund.

Issue a refund ​

In the portal, find the captured checkout and choose Refund.

To refund through the API, call POST /api/merchant/v1/checkouts/{checkout_uuid}/refund with a unique reference:

bash
curl -sX POST https://api.maytes.co/api/merchant/v1/checkouts/$CHECKOUT_UUID/refund \
  -H "authorization: Bearer $ACCESS_TOKEN" \
  -H 'content-type: application/json' \
  -d '{
    "merchant_refund_ref": "refund_order_1001",
    "reason": "Customer requested a refund"
  }'

The endpoint returns 204 when the refund is accepted. Use RefundCheckout in the backend SDK for the same operation. Then read the checkout until it reaches refunded.


What your integration sees ​

After a refund is issued, the checkout moves from captured → refunding → refunded. The GET checkout response includes these refund fields:

json
{
  "data": {
    "checkout_uuid": "019fbb9e-ecd1-7059-99f3-f8bf47b63931",
    "status": "refunded",
    "amount": 4500,
    "currency": "AUD",
    "refunded_amount": 4500,
    "merchant_processor_fee": 0,
    "merchant_service_fee": 0,
    "last_refund_at": "2026-09-14T10:14:33.000Z"
  }
}
FieldWhat it means
statusrefunding while settling, refunded once the payment provider confirms.
refunded_amountThe amount returned to the customer (minor units). 0 while pending; matches the captured amount once settled.
last_refund_atISO timestamp of the confirmed refund. null while pending.
merchant_processor_feeReserved for processor cost billed to you on the refund. Currently always 0 — refund fee billing is not yet applied.
merchant_service_feeReserved for the Maytes service fee billed to you on the refund. Currently always 0.

Customers always get 100% back

If refund fee billing is introduced, merchant_processor_fee and merchant_service_fee will be billed to you. They will never be deducted from the customer's refund.

Keeping your records in sync ​

Treat refunded as terminal: the order is unpaid again and the customer has their money. Keep your records in sync in either of these ways:

  1. When reading a checkout — in support tools and reconciliation jobs, branch on status and handle refunding and refunded with the other lifecycle states.
  2. When issuing the refund — update your order record when the API accepts the request or your team submits it in the portal. If you need confirmation, poll GET /checkouts/{uuid} until status is refunded.

There is no refund webhook event. Because you initiate the refund, use the checkout status to confirm completion.

What's next ​