Connect payments. Keep your product in sync.
Give customers a clear way to pay and your product a reliable payment update. Create invoices, create payment links, read payment results and receive events through the API.

curl https://api.roamerwave.com/v1/invoices/inv_…/\
checkout-sessions \
-H "Authorization: Bearer rw_test_…" \
-H "Idempotency-Key: order-1042-checkout" \
-H "Content-Type: application/json" \
-d '{ "expiresAt": "2026-10-31T20:59:59Z" }'
{
"id": "chk_…",
"checkoutUrl": "https://pay.roamerwave.com/pay/…",
"expiresAt": "2026-10-31T20:59:59Z"
}From invoice to payment result in four steps.

- 01
Create an invoice
Fix seller, amount, currency and purpose before payment.
- 02
Open checkout
Give the customer an opaque, expiring URL.
- 03
The customer pays
On the hosted page the customer chooses an enabled wallet and approves the payment on their phone. Each try is one payment attempt.
- 04
Check the result
Read the attempt with your API key. If the result is unknown, wait for the provider's confirmation before deciding what happens next.
Primitives that map to the real collection lifecycle.
Six objects, in the order a payment moves through them. Each has a stable identifier you can store.
- 01Customer
- 02Product
- 03Subscription
- 04Invoice
- 05Checkout session
- 06Payment attempt
{
"id": "payatt_…",
"invoiceId": "inv_…",
"status": "unknown",
"amount": { "minor": "135000", "currency": "KES" },
"wallet": "mpesa",
"nextAction": "wait_for_update",
"failureCode": null,
"destinationMasked": null,
"statusOccurredAt": null
}Ambiguity is data. unknown remains distinct from failed and succeeded until iPay confirms the result.
Precise events behind every attempt.
Events are signed, delivered at least once and deduplicated by a stable event id. Payment success, reconciliation and settlement are never merged into one event.
- invoice.created
- payment.succeeded
- webhook.test
Read the current state of any attempt on request, or receive these events at your own endpoint as they happen.
The rest of the lifecycle, through the same API.
Events to your system
Subscribe an endpoint to the events you need, so your product updates a membership, plan or account when a payment changes state.
Subscriptions
Subscribe a customer to a price on a monthly or weekly schedule. Pause, resume or cancel it, and follow each billing cycle.
Sign-up links
Create a hosted link customers use to subscribe themselves, and revoke it at any time.
Products and prices
Keep your catalogue in Roamerwave: create products, add prices and list them.
Contracts that survive retries and tenants.
Idempotency-Key on every write
A retried create returns the original result instead of a second effect. Send the same key, get the same object.
Tenant-scoped bearer authentication
Every request resolves identifiers within one workspace. A customer or invoice from another workspace is simply not found.
Integer minor-unit amounts
KES 890 is 89000 minor units, sent as the string "89000". Money never travels through the API as a float.
Normalized payment states
created, initiation_queued, initiation_rejected, customer_action_required, provider_accepted, unknown, failed, cancelled, expired, succeeded, reversed.
Build the billing integration once.
Connect your billing workflow to the payment methods enabled for your business.