Home · Developers

Developer platform · §40–43

Build payments for Kenya
with one API.

First sandbox payment should take under ten minutes. Idempotency on every create. Amounts are integer minor units inside Oda. Retail still posts major-unit KES on the frozen checkout contract.

POST http://localhost:4020/v1/payment-intents
Idempotency-Key: order-99181

{
  "amount": 245000,
  "currency": "KES",
  "destination": {
    "type": "oda_handle",
    "value": "javahouse@oda"
  },
  "reference": "ORDER-99181"
}

The resources that matter.

  • /v1/payment-intentsCreate, get, confirm. The verb is not “charge and hope”.
  • /v1/checkout/intentsFrozen Retail path. Confirm writes transactionId like oda_pay_… onto restock.
  • /v1/qr · /v1/aliasesDynamic QR. Handle resolution. No customer secrets in the payload.
  • /v1/webhooks · /v1/reconciliationDeliveries you can replay. Recon you can run. Ledger is not the transactions table.

Rules we will fail a review to keep.

Idempotency-Key

Same key, same intent. Kenya does not get charged twice because a mobile retry fired.

UNKNOWN

Timeout ≠ FAILED. Do not auto-reroute. Do not invent a decline for a pretty dashboard.

Flags, not fiction

Connect, payroll, later products stay flags. Interfaces only. Demo key: oda_sk_demo.

Checkout that Retail already speaks.

GET /health → service oda-pay-checkout. POST/GET /v1/checkout/intents. Confirm. Major-unit KES 320 in becomes 32000 minor units. That contract does not thrash every sprint.

npm install @odapay/sdk-node · base http://localhost:4020/v1

This page is /developers on odapay.odaflow.com. The explorer is :4031 until a developers host points at it.