Skip to main content
This page explains how Points handles order reversals after creation. There are two distinct operations:

Cancel an order

Use cancellation when the order should be stopped rather than financially reversed later. Example:

Current behavior

  • validates merchant ownership of the order
  • rejects already-cancelled or already-refunded orders
  • defaults the reason to "Order cancelled via API" if omitted
  • emits webhook event cancelled

Refund an order

Use refund after an order is already settled and value must be returned. Example full refund:
Example partial refund:

Current behavior

  • supports both full and partial refunds
  • emits webhook event refunded
  • updates order_status to fully_refunded or partially_refunded

How Points value is reversed

Replacing (redeem) orders

For a redeem checkout, refunding reverses the redeemed value and updates the order status accordingly.

Earning orders

For an earning order, refunding reverses previously awarded points. In partial refunds, the backend calculates the proportional points to reverse and includes remaining amounts in the refund payload used internally.

Auto-refund edge case

There is also an internal system event called auto_refunded. This can occur when the backend automatically reverses a replacing order because an expected transaction record was missing during reconciliation. Integrators should treat it as a refund-class terminal state and handle it in webhook consumers.

Merchant-dashboard refunds (storefront orders)

Merchants who sell their own physical / digital products through the Points storefront (not pure API integrators) can refund a ProductOrder from the dashboard. The button is on the Order details page (Product Orders → show) and is more than a gateway refund — it runs a full-stack reversal in a fixed order: If step 1 fails (gateway rejects, captured amount mismatch, missing reference), the whole flow aborts — nothing else is touched. If steps 2-3 fail after step 1 succeeded, the metadata is still stamped (the money is already back with the buyer) and the failures land in the server log for manual reconciliation.

3-day refund window

The dashboard refund button disappears 3 days after the order was created. After that, the weekly settlement run (MakeProductSettlements, Thursday in Riyadh time) has already swept the order into the merchant’s payout, so an automated reversal would race the settlement and leave the books out of sync. Direct calls to the service (e.g. from admin tooling or a stale browser tab) are guarded by the same window — past 72 hours they return:

Settlement skips refunded orders

Once metadata.refund_status = 'refunded' is stamped, the weekly product-settlement job excludes the order from the merchant’s next payout — so the merchant is never paid for an order whose money already went back to the buyer.
This whole section is for the merchant dashboard flow. The public POST /v1/orders/{uuid}/refund endpoint (described above) is the API equivalent for loyalty Order reversals and is not subject to the 3-day window.
If the order should simply stop and has not entered your final fulfilment path, cancel is usually cleaner than refund.
If value was already settled, use the refund endpoint so Points can properly reverse the financial and loyalty effects.
Even when not required, always send a human-readable reason so support teams can reconcile merchant actions against webhook history.

Webhooks you should expect

Next

Order Lifecycle

See where cancellation and refund fit in the state machine.

Webhook Events

Payload examples for cancelled, refunded, and related events.