Skip to content

Idempotency ​

Send an Idempotency-Key header on every mutating request (POST, PUT, PATCH, DELETE). It lets you retry safely after a network failure.

If you omit it, SOAMTAR derives a key from your merchant_ref (or, failing that, from the request body), so identical retries are still de-duplicated. An explicit header always wins and gives you precise control over what counts as "the same operation".

Why ​

Without idempotency, a network timeout during POST /payments forces you to choose between:

  • retrying — risk of creating the payment twice (and asking the customer to pay twice);
  • giving up — risk of losing a payment that actually succeeded on the SOAMTAR side.

With idempotency you can retry safely: SOAMTAR recognises the key and replays the same response as the first time, without creating the resource again.

Format ​

Idempotency-Key: <unique string, max 255 characters>

Recommended: a UUID v4 generated on your side. A key is valid for 24 hours after its first use.

Behaviour ​

CaseResponse
Key never seenAction executed, response cached
Key already seen + same bodyCached response replayed + header Idempotent-Replay: true
Key already seen + different body409 idempotency_conflict
Key still being processed (race)409 idempotency_conflict

The fingerprint is a SHA-256 hash of (method, path, body, query). A single different character is a conflict.

What is cached ​

StatusCached?
2xx, 3xxYes — the request succeeded
4xxYes — the error is deterministic (validation); replaying it reproduces it
5xxNo — the incident is transient, so a retry is allowed

In practice: retry with the same key after a 5xx; after a 4xx, fix the request and use a new key.

Example ​

First call:

bash
curl -X POST https://app.so-amtar.com/v1/payments \
  -H "Authorization: Bearer sk_test_xxx" \
  -H "Idempotency-Key: 4f1c2c8a-9d4e-4b8f-9a1c-2c8a9d4e4b8f" \
  -H "Content-Type: application/json" \
  -d '{"merchant_ref":"ORDER-42","amount":"150.00","currency":"SLE","provider":"orange_money_sl","phone":"+23276123456"}'
# => 201 + transaction TXN-A1B2C3D4E5

Retry (after a network timeout) with the same key and the same body:

bash
curl -X POST https://app.so-amtar.com/v1/payments \
  -H "Authorization: Bearer sk_test_xxx" \
  -H "Idempotency-Key: 4f1c2c8a-9d4e-4b8f-9a1c-2c8a9d4e4b8f" \
  ...
# => 201 + the same transaction TXN-A1B2C3D4E5
# => header Idempotent-Replay: true
# => only one payment request is sent to the customer's phone

With a different body:

bash
# Same key, amount changed
curl -X POST .../v1/payments \
  -H "Idempotency-Key: 4f1c2c8a-9d4e-4b8f-9a1c-2c8a9d4e4b8f" \
  -d '{"merchant_ref":"ORDER-42","amount":"175.00",...}'
# => 409 idempotency_conflict

Best practices ​

  • One key per business operation, not per HTTP request. If the customer taps "Pay" twice, generate the key on the first tap and reuse it.
  • Persist the key on your side until the final outcome (success/failed/cancelled), not just for the duration of the request.
  • Refunds: always send an explicit key on POST /v1/refunds (e.g. refund-<order>-<n>). A refund has no merchant_ref, and two legitimate partial refunds of the same amount must get two different keys, while a retry of the same refund must reuse its key.
  • Avoid timestamps as keys: two retries a millisecond apart would generate two different keys.

SOAMTAR Payment API Documentation.