Guides
Implement Idempotency
How to safely send mutation requests with Idempotency-Key header to prevent double-charging or duplicate payouts.
Idempotency guarantees that performing an API operation multiple times produces
the same result as performing it once. In OuiPay, every money-moving request
(POST /v1/payments, POST /v1/transfers, POST /v1/exchange) requires an
Idempotency-Key header.
How idempotency works
sequenceDiagram
autonumber
participant App as Merchant Application
participant API as OuiPay API
participant Cache as Idempotency Engine
participant DB as OuiPay Ledger
App->>API: POST /v1/payments (Idempotency-Key: pay_abc123)
API->>Cache: Check key "pay_abc123"
alt Key exists & complete
Cache-->>API: Saved response JSON
API-->>App: 200 OK (cached response)
else Key exists & in-flight
Cache-->>API: Lock active
API-->>App: 409 Conflict (IN_PROGRESS)
else New key
API->>Cache: Acquire lock "pay_abc123"
API->>DB: Process transaction & ledger entry
API->>Cache: Store result payload
API-->>App: 201 Created (new response)
endRecommended key generation strategies
- Entity-scoped UUID: Combine resource type and unique business identifier:
pay_order_948201ortrf_payout_882910 - UUIDv4: Standard random 128-bit UUID for single-shot operations:
9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d
Code implementation examples
curl -X POST https://api.ouipay.com/v1/payments \
-H "Authorization: Bearer sk_live_..." \
-H "Idempotency-Key: pay_order_948201" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "01M2S17...",
"amount_minor": 15000,
"currency": "NGN",
"method": "card"
}'Handling key conflict errors
If you send a request with a key that is currently processing in another thread, OuiPay returns 409 Conflict with error code IN_PROGRESS:
{
"error": {
"code": "IN_PROGRESS",
"message": "A request with key pay_order_948201 is currently processing.",
"request_id": "req_88192a"
}
}When receiving 409 IN_PROGRESS, retry the request with the exact same key after a exponential delay (e.g. 1s, 2s, 4s). Do not change the key!