Now supporting M-Pesa & Telebirr
The African
Payment
Infrastructure.
Zirzir is the payment stack African startups keep rebuilding: one SDK for Telebirr, Chapa, M-Pesa, and more, plus a server with webhooks, retries, and a real-time dashboard so you can ship payments across African gateways in days, not months.
We got tired of re-writing the same Telebirr RSA encryption and webhook code for every new project. So we open-sourced the whole stack under MIT.
import { Zirzir } from '@zirzir/sdk'
const z = new Zirzir({
provider: 'telebirr',
credentials: {
appId: process.env.TELEBIRR_APP_ID,
appKey: process.env.TELEBIRR_APP_KEY,
publicKey: process.env.TELEBIRR_PUB,
}
})
// USSD push to customer's phone. That's it.
const tx = await z.charge({
amount: 150,
currency: 'ETB',
phone: '0911234567',
reference: 'ride-7842',
}) // handles RSA encryption, phone normalization, & USSD retries
Payments in Africa are
fragmented.
The Problem
- ×
Read 4 different PDFs to understand RSA encryption for Telebirr, Chapa, and M-Pesa.
- ×
Implement custom polling and webhook handlers for every single gateway.
- ×
Build your own dashboard, ledger, and retry engine from scratch.
The Zirzir Way
We abstracted all of that into a single SDK and server. One API call. One ledger. One open-source project.
Fast Integration
Go live with 8+ providers in minutes, not weeks.
Secure by Design
Enterprise-grade encryption and signature verification.
Reliable Webhooks
Automatic retries with exponential backoff built-in.
Self-Hostable
Your data, your server. Completely open source.
Eight gateways. One function call.
Every provider has its own auth scheme, payload shape, and callback
format. Zirzir normalizes them into a single charge() call.
What you get
The SDK
TypeScript, Python, Go. One charge() call
for Telebirr USSD, Chapa cards, and M-Pesa STK push. Handles RSA encryption,
phone normalization, and provider quirks so your application code doesn't have to.
The Server
Single Go binary. Transaction ledger, webhook engine with exponential backoff, real-time dashboard, multi-project isolation, RBAC. The operational layer that turns an SDK into production infrastructure.
The Dashboard
See every transaction, drill into webhook delivery logs, replay failed deliveries, switch between test and live environments. The thing your ops team would otherwise ask engineering to build.
The Cloud
Same server, hosted by us. Point your SDK at api.zirzir.dev,
get an API key, and skip the Docker setup. This is how we fund the open source.
Operations, simplified
A real-time dashboard to monitor transactions, manage webhooks, and toggle between environments. The control center for your payment infrastructure.
Developer
zz_live_48f...92a
Total Volume
14,284.50 ETB
Success Rate
99.2%
Pending
12
Recent Transactions
ride-order-7842
Telebirr • 091****4567
+150.00 ETB
Success
premium-sub-901
M-Pesa • 072****1122
+840.00 KES
Success
invoice-3321
Chapa • VISA **** 4492
+4,200.00 ETB
Pending
Webhook Deliveries
charge.succeeded
POST /webhooks/payments
2.4s • 200 OK
Delivered
charge.pending
POST /webhooks/payments
retry 2 of 5
Retrying
charge.failed
POST /webhooks/internal
5 attempts • 500
Dead-lettered
API Keys
Live secret
zz_live_48f************************92a
Live
Test secret
zz_test_73b************************1df
Test
Rotated (inactive)
zz_live_19a************************7bc
Disabled
Projects
Default Project
live + test • 3 providers
Last active 2m ago
Sandbox
test only • 5 providers
Last active 1h ago
Same API, different mode
Standalone calls gateways directly. Server mode routes through your Zirzir server for webhooks, retries, and a transaction ledger.
The switch is a config change, not a rewrite.
import { Zirzir } from '@zirzir/sdk'
// Talk directly to the payment gateway
const zirzir = new Zirzir({
provider: 'chapa',
credentials: { secretKey: process.env.CHAPA_KEY! }
})
const tx = await zirzir.charge({
amount: 500,
currency: 'ETB',
txRef: 'order_123',
email: 'customer@example.com'
})
Providers
Every provider produces the same Transaction object. A Chapa card payment and a Telebirr USSD push are identical to
your code.
Telebirr
USSD push
Chapa
Cards + Mobile
CBEBirr
Mobile Money
Santim Pay
Aggregator
Awash Bank
Bank Transfer
EthSwitch
Interbank
M-Pesa
STK Push
Airtel Money
Mobile Money
Three layers, use what you need
Start with the SDK for direct gateway access. Add the server when you need webhooks and a dashboard. Or let us host it.
One unified interface for every African payment gateway. TypeScript, Python, and Go. Use standalone or connect to a Zirzir server.
- Single charge/verify/refund API
- TypeScript, Python, Go SDKs
- Standalone or Server mode
- Built-in provider adapters
- Webhook signature verification
- Full type safety
import { Zirzir } from '@zirzir/sdk'
const zirzir = new Zirzir({
provider: 'chapa',
credentials: { secretKey: '...' }
})
const tx = await zirzir.charge({
amount: 500,
currency: 'ETB',
txRef: 'order_123',
})Open core, not open bait
The SDK and server are MIT-licensed. You can fork it, self-host it, sell products built on it. No "community edition" crippled to push you into enterprise.
Zirzir Cloud is how we fund development. Same open-source codebase, hosted by us. If a feature is in the open source today, it stays there. We compete on ops convenience, not feature gatekeeping.
Try it
Sandbox works out of the box. No approvals, no sales calls.