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

  1. You send a request with Idempotency-Key: <unique-value>
  2. RohoPay records the key against the transaction
  3. If you retry with the same key, RohoPay returns the original response — no duplicate charge
  4. 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

PracticeRecommendation
ScopeOne key per business event (order, subscription charge, etc.)
StorageStore the key in your database alongside the order
FormatUUID v4 or similar random identifier
Retry windowSafe to retry the same key for up to 24 hours
New keyOnly 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"
  }
}