Skip to content

Recurring Subscriptions & Smart Dunning

In Africa, credit card penetration is under 5%. Traditional subscriptions relying on silent card autopay tokenization fail because 90%+ of African payments run on mobile money wallets (Telebirr, CBE Birr, Safaricom M-Pesa).

Zirzir provides a purpose-built Smart Dunning & Recurring Billing Engine engineered specifically for mobile money prompt flows.


Dunning Lifecycle Flow

Create recurring plans via CLI, Dashboard, or REST API:

Terminal window
zirzir sub plan create --name "Pro Monthly" --amount 500.0 --currency ETB --interval month
import { Zirzir } from '@zirzir/sdk';
const zirzir = new Zirzir({
baseUrl: 'http://localhost:8080',
apiKey: process.env.ZIRZIR_API_KEY!,
});
// Create recurring plan
const response = await fetch('http://localhost:8080/api/v1/plans', {
method: 'POST',
headers: {
'X-API-Key': process.env.ZIRZIR_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Pro Tier Monthly',
amount: 500.0,
currency: 'ETB',
interval: 'month',
interval_count: 1,
}),
});

When a user signs up on your website:

Terminal window
curl -X POST http://localhost:8080/api/v1/subscriptions \
-H "X-API-Key: zz_test_..." \
-H "Content-Type: application/json" \
-d '{
"plan_id": "plan_9f81a2b",
"provider": "telebirr",
"customer_phone": "0911223344"
}'
  • Immediate Action: Dispatches an initial mobile money STK push prompt to the customer’s phone.
  • Ledger State: Sets current_period_start, computes current_period_end (+30 days), schedules next_billing_at, and records an open invoice for the first charge.

The Zirzir server runs a built-in background dunning cron worker:

  • Automatically detects when next_billing_at <= NOW().
  • Dispatches recurring STK prompts to user wallets.
  • Increments retry_count and reschedules failed charges with intelligent backoff windows.
  • Each charge creates an invoice with status open. The invoice becomes paid when its payment completes (or failed if it fails), and the billing period advances only on successful settlement.
  • Your backend receives the standard payment.completed / payment.failed / payment.cancelled events for these charges (see Webhooks). There are no separate subscription.* events.

Telebirr and CBE Birr payments are not settled automatically (no status API). Subscriptions on those rails stay open until the payment is reconciled in the dashboard.