Connect payments.
Keep your product in sync.
Give customers a clear way to pay and your product a reliable payment update. Create invoices, share checkout links and read payment results through the API.
const session = await rw.createCheckoutSession(
"inv_10482",
"2026-08-23T18:00:00Z",
"idem_8f2a1c"
);
return session.checkoutUrl;✓ 201 Created · 184 msFrom invoice to payment result in four steps.
- 01Create an invoice
Fix seller, amount, currency and purpose before payment.
- 02Open checkout
Give the customer an opaque, expiring URL.
- 03Start an attempt
The customer chooses and authorises an enabled wallet.
- 04Check the result
Read the attempt status using its checkout token. If the result is unknown, wait for provider evidence before deciding what happens next.
Primitives that map to the real collection lifecycle.
{
"id": "payatt_7J4M2Q",
"invoiceId": "inv_10482",
"status": "unknown",
"nextAction": "wait_for_update",
"failureCode": null
}Ambiguity is data. `unknown` remains distinct from `failed` and `succeeded` until provider evidence resolves the attempt.
Precise events behind every attempt.
Each payment attempt emits the same vocabulary the platform uses to keep payment truth. Events are at-least-once and deduplicated by a stable event id.
Integrations read current attempt states by polling. Merchant webhooks are unavailable on this route.
Contracts that survive retries and tenants.
A retried create returns the original result instead of a second effect. Send the same key, get the same object.
Every request resolves identifiers within one workspace. A customer or invoice from another workspace is simply not found.
KES 890 is 89000 minor units. Money never travels through the API as a float.
created, initiation_queued, customer_action_required, provider_accepted, unknown, failed, cancelled, expired, succeeded, reversed.
Build the billing integration once.
Connect your billing workflow to the payment routes enabled for your business.
Discuss an integration