Building the integration
Redemption at the till
Let a cashier look up what a customer can spend, apply it as a discount, and commit it at payment.
These endpoints are implemented and in review. The request and response shapes are final.
Earn is one-way and needs no changes to your checkout screen. Redemption is interactive, so it does: the cashier looks up the customer, picks a reward, you apply it as a discount line, and you commit on payment.
1. Eligibility — what can this customer redeem?
POST /v1/redemption/eligibility
{
"customer": { "type": "phone", "value": "+9607123456" },
"orderValue": 45.00
}Read-only and safe to call every time the cart changes. redemptionRate is how many points equal one unit of currency, for a “spend points directly” option.
If the customer is not a Perx member, eligibility returns 200 with membershipId: "" and a warning. Check membershipId before rendering a picker — a UI that keys on the status code will show an empty reward list with no explanation.
Always display reason next to ineligible rewards. Cashiers get asked why, and “Minimum spend of MVR 300 not met” answers it without a support call.
2. Redeem — commit at payment
POST /v1/redemption/redeem
{
"customer": { "type": "phone", "value": "+9607123456" },
"externalTransactionId": "INV-2026-0042",
"rewardId": "9c04e2b1-77aa-4c31-8f0d-2b6e91a4d770",
"orderValue": 45.00
}Send exactly one of rewardId or pointsToRedeem. externalTransactionId must be the same value you will later send as transaction.id on the earn webhook — that is what binds the redemption to the sale.
status: "ALREADY_PROCESSED" on a retry of an identical call means the customer was not charged twice. Treat it as success.
There is no reserve/hold in v1. A redemption committed against a sale the customer then abandons has to be reversed with a refund event. Commit as late as you can.
3. Reversing a redemption
Use the refund path — it reverses the earn and the redemption together in one call.
Business errors
| Status | Meaning | Cashier action |
|---|---|---|
400 | Not eligible or insufficient points, with the reason in message. | Show the reason, pick something else |
404 | Customer is not a Perx member (redeem only). | Offer signup |
409 | Already redeemed against this order. | Nothing — it worked |
502 | Perx temporarily unreachable. | Retry once, then complete the sale without loyalty |
Display message verbatim. It is written for the person at the till.
If Perx is down, complete the sale and queue the earn event. The customer gets their points when we come back. A loyalty platform must never be able to stop a merchant taking money.