Why Idempotency?
Network failures can cause your request to reach the API but prevent you from receiving the response. Without idempotency, retrying the request could create a second, duplicate charge.
RohoPay enforces idempotency on all mutation endpoints (POST /api/v1/collect and POST /api/v1/disburse). You must include a unique Idempotency-Key header on every collection or disbursement request.
How It Works
- You send a request with
Idempotency-Key: <unique-value>
- RohoPay records the key against the transaction
- If you retry with the same key, RohoPay returns the original response — no duplicate charge
- If you send a new key, a new transaction is created
Generating Keys
Use a UUID or another globally unique identifier. The key must be a string and should be unique per business event (e.g., per order).
import { randomUUID } from "crypto";
const idempotencyKey = randomUUID(); // e.g., "a1b2c3d4-..."
Request Example
curl -X POST https://api.rohopay.com/api/v1/collect \
-H "Authorization: Bearer live_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-d '{"phone": "256700123456", "amount": 50000, "currency": "UGX"}'
Idempotency Key Best Practices
| Practice | Recommendation |
|---|
| Scope | One key per business event (order, subscription charge, etc.) |
| Storage | Store the key in your database alongside the order |
| Format | UUID v4 or similar random identifier |
| Retry window | Safe to retry the same key for up to 24 hours |
| New key | Only generate a new key for an intentionally new transaction |
If you receive a 400, 422, or 500 error, the transaction was not created. It is safe to retry with the same idempotency key. If you receive a 200 or 201, the transaction was created — do NOT generate a new key for that event.
Missing Idempotency Key
If you omit Idempotency-Key on a mutation endpoint, you receive:
{
"success": false,
"error": {
"code": "MISSING_IDEMPOTENCY_KEY",
"message": "Idempotency-Key header is required for this endpoint"
}
}