Skip to main content

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
FieldTypeRequiredDescription
namestringYesPlan name
amountnumberYesRecurring charge in major units
currencystringYesISO 4217 code
intervalstringYesdaily, weekly, monthly, yearly
trial_daysintegerNoFree 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​

StatusMeaning
trialingIn free trial, not yet charged
activeCharging on schedule
past_dueA charge failed; dunning in progress
cancelledEnded; no further charges
pausedTemporarily suspended

Webhook Events​

EventDescription
subscription.createdNew subscription started
invoice.payment_succeededRecurring charge collected
invoice.payment_failedCharge failed; retry scheduled
subscription.cancelledSubscription 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_end so customers keep access through the period they paid for.

Error Handling​

CodeDescriptionAction
PLAN_NOT_FOUNDUnknown plan_idCreate the plan first
SUBSCRIPTION_PAST_DUECharge failingUpdate payment method or retry
DUPLICATE_SUBSCRIPTIONCustomer already on planReuse the existing subscription

Last Updated: May 2026