All examples use test mode. Test and live are physically separate database schemas; a
sk_test_ key can never touch live data. See Modes.1. Authenticate
Every merchant request carries a secret API key as a bearer token. The key prefix selects the mode.2. Create a plan
A plan is the thing customers subscribe to: an amount, an interval, and optional recovery knobs (trialDays, maxCycles).
Amounts are in minor units (kobo).
500000 = ₦5,000.00. Intervals: hour, day, week, month, quarter, biannual, year.3. Create a customer
merchantRef is your own ID for this customer — you can later look them up by it (GET /v1/customers/ref/EXT-001) and fetch their transactions without ever storing a Duro ID.
4. Subscribe them
currentPeriodEnd passes, the billing worker picks it up automatically: it generates an invoice, charges the gateway, and either advances the period (success) or hands the failure to the recovery engine.
5. Listen for what happens
You don’t poll. You subscribe to events. Webhook endpoints are configured in the dashboard (Developers → Webhooks) — add your URL, pick the events, and copy the signing secret (shown once). Duro then delivers signed, retried events for the whole lifecycle to your server.Add an endpoint in the dashboard
Developers → Webhooks → Add endpoint. Enter your
https:// URL and choose the events to receive (e.g. subscription_payment_success, subscription_payment_failed, subscription_payment_recovered).Store the signing secret
Shown once on creation. You’ll use it to verify the
Duro-Signature header on every delivery.Verify and handle
Recompute the HMAC and compare in constant time — see Webhook events.
The whole loop, on a timeline
That’s the entire product in one diagram. The rest of these docs explain every arrow.Inline checkout instead
Don’t want to manage subscriptions server-side? Drop in
duro.pay() and let the popup do identity, payment, and tokenisation.Full API reference
Interactive playground for every endpoint, with auth, pagination, idempotency, and the event catalog.