Idempotency and retries
Networks fail. A request can time out after UniPay has already recorded the payment, and your side can’t tell. UniPay is built so that retrying is always safe — provided you retry the right way.
The payment reference (rrn)
Section titled “The payment reference (rrn)”Every payment you report carries an rrn (retrieval reference number): your unique reference for that payment, up to 50 characters.
UniPay uses it to recognise a repeat:
| You send | UniPay answers |
|---|---|
An rrn it hasn’t recorded |
Records the payment. "successful": true, "isNewRecord": true |
An rrn it has already recorded, for the same payment |
Records nothing new. "successful": true, "isNewRecord": false |
An rrn it has already recorded, for a different bill, account, amount or currency |
Refuses it: "successful": false, RRN 'X' was already used for a different payment. |
An rrn it refused before (e.g. the date was wrong) |
Processes it afresh — a corrected retry isn’t blocked by the earlier refusal. |
References are per processor: another processor using the same rrn for its own payment doesn’t affect yours.
So:
- Generate the
rrnonce per payment, before the first attempt, and store it with the transaction. - Reuse it on every retry of that payment — after a timeout, a dropped connection, a
429or a5xx. - Treat
isNewRecord: falseas success. It means UniPay already had the payment. - Never reuse an
rrnfor a different payment. UniPay refuses it. Make references unique across your whole organisation — prefixing your own transaction ID works well.
What to retry
Section titled “What to retry”| Outcome | Retry? |
|---|---|
| Timeout, connection reset, no response | Yes, same request, same rrn. You don’t know whether it arrived. |
429 Too Many Requests |
Yes, after a pause. |
500, 502, 503, 504 |
Yes, with backoff. |
401 Unauthorized |
Get a new token, retry once. |
200 with "successful": false |
No. UniPay understood and refused; the same request gets the same answer. Fix the cause. |
400, 403 |
No. Fix the request or your credentials. |
Back off exponentially with some randomness — for example 2 s, 4 s, 8 s, 16 s, 30 s — and stop after about five attempts. If a payment still isn’t confirmed, park it for investigation rather than dropping it: the customer has paid.
Timeouts
Section titled “Timeouts”Use a 10-second connect timeout and a 30-second read timeout. UniPay normally answers in well under a second; anything above five seconds is worth investigating.
Service providers
Section titled “Service providers”Publishing a bill is also safe to repeat: sending a bill UniPay already has, unchanged, returns AlreadyExists and changes nothing.
Reading the payments feed is safe to repeat too, because you choose where to resume — see Collect payments.
UniPay API v1 · build e1eb5c49 · Powered by Axis Solutions