Billing & Subscriptions
Charge customers on a recurring schedule using mobile money, manage subscription plans, and handle the full lifecycle from trial to cancellation.
Overview
AfriRoute Billing lets you define plans, subscribe customers, and automatically collect recurring payments via mobile money. Failed charges enter a configurable retry (dunning) cycle, and every billing event fires a webhook.
Base URL: https://api.afriroute.ai — Auth: Authorization: Bearer $AFRIROUTE_API_KEY
Endpoints
Create a Plan
POST /v1/billing/plans
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Plan name |
amount | number | Yes | Recurring charge in major units |
currency | string | Yes | ISO 4217 code |
interval | string | Yes | daily, weekly, monthly, yearly |
trial_days | integer | No | Free trial length |
curl -X POST https://api.afriroute.ai/api/v1/billing/plans \
-H "Authorization: Bearer $AFRIROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Pro Monthly",
"amount": 499,
"currency": "ETB",
"interval": "monthly",
"trial_days": 7
}'
{ "plan_id": "plan_pro_monthly", "name": "Pro Monthly", "amount": 499, "interval": "monthly" }
Create a Subscription
POST /v1/billing/subscriptions
const res = await fetch('https://api.afriroute.ai/api/v1/billing/subscriptions', {
method: 'POST',
headers: { 'Authorization': 'Bearer $AFRIROUTE_API_KEY', 'Content-Type': 'application/json' },
body: JSON.stringify({
plan_id: 'plan_pro_monthly',
customer: { phone_number: '+251911234567', email: '[email protected]' },
provider: 'telebirr'
})
});
console.log(await res.json());
import requests
requests.post(
'https://api.afriroute.ai/api/v1/billing/subscriptions',
headers={'Authorization': 'Bearer $AFRIROUTE_API_KEY'},
json={
'plan_id': 'plan_pro_monthly',
'customer': {'phone_number': '+254712345678'},
'provider': 'mpesa'
}
)
{
"subscription_id": "sub_001",
"plan_id": "plan_pro_monthly",
"status": "trialing",
"current_period_end": "2026-06-04T00:00:00Z",
"next_charge_at": "2026-06-04T00:00:00Z"
}
Cancel a Subscription
DELETE /v1/billing/subscriptions/:subscription_id
curl -X DELETE https://api.afriroute.ai/api/v1/billing/subscriptions/sub_001 \
-H "Authorization: Bearer $AFRIROUTE_API_KEY" \
-d '{ "at_period_end": true }'
Subscription Lifecycle
| Status | Meaning |
|---|---|
trialing | In free trial, not yet charged |
active | Charging on schedule |
past_due | A charge failed; dunning in progress |
cancelled | Ended; no further charges |
paused | Temporarily suspended |
Webhook Events
| Event | Description |
|---|---|
subscription.created | New subscription started |
invoice.payment_succeeded | Recurring charge collected |
invoice.payment_failed | Charge failed; retry scheduled |
subscription.cancelled | Subscription ended |
Best Practices
- Use a trial period to validate the customer's mobile money number before the first charge.
- Configure dunning retries to handle temporary wallet-balance failures gracefully.
- Notify customers by SMS before each charge; mobile money users expect a heads-up.
- Cancel
at_period_endso customers keep access through the period they paid for.
Error Handling
| Code | Description | Action |
|---|---|---|
PLAN_NOT_FOUND | Unknown plan_id | Create the plan first |
SUBSCRIPTION_PAST_DUE | Charge failing | Update payment method or retry |
DUPLICATE_SUBSCRIPTION | Customer already on plan | Reuse the existing subscription |
Related Links
Last Updated: May 2026