OuiPay
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)
    end
  1. Entity-scoped UUID: Combine resource type and unique business identifier: pay_order_948201 or trf_payout_882910
  2. 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!

On this page