Idempotency and retries
Recover from timeouts without creating duplicate payments.
Give each payment one key
Both payment creation endpoints require Idempotency-Key, containing 8–128 bytes. Use an ASCII identifier, such as a UUID, with no leading or trailing whitespace. Generate and persist the key alongside your business payment request before making the first API call.
A key is scoped to the merchant and payment kind, not to the API credential. Rotating an API key within the same merchant does not create a new idempotency namespace. Use a distinct key for every intended payment, and keep it for retries.
Retry the same request
Repeat the same endpoint, idempotency key, and body after a timeout or uncertain network outcome. This returns the existing payment rather than creating another one.
| Result | HTTP status | replayed |
|---|---|---|
| New request accepted | 202 | false |
| Existing request returned | 200 | true |
| Same key with different payment content | 409 | Not returned |
The fingerprint uses normalized payment input. Your integration should still persist and resend the identical body, including optional fields.
An idempotent replay returns the payment's current state, which may have advanced since the initial response. It does not dispatch another payment or reserve funds again. Replays still require valid credentials, the endpoint scope, and available request-rate capacity.
No public expiry window for idempotency keys is promised. Never recycle a key for a different intended payment. Your reference is not unique and cannot be used to retrieve a payment through the public API; persist the returned payment ID.
Handle an uncertain outcome
A timeout means your server did not receive a response. The payment may already exist.
- Retry using the original key and body.
- Save the returned payment ID.
- Poll that ID or wait for a verified webhook.
- Do not issue another payment with a new key while the original outcome is unresolved.
A payment in unknown is not failed. Creating a replacement may pay twice.
Back off on retries
Use bounded exponential backoff with jitter for transport errors and temporary server failures. Respect Retry-After when present. Do not retry validation, permission, or insufficient-funds errors unchanged.
The API currently limits merchant requests to 120 per minute, shared by API keys and portal activity for that merchant. STK admission limits new requests to 3 per minute per normalized phone, shared across merchants. Business and daily limits may independently return 429; waiting alone does not necessarily resolve those limits.