Chapa
Chapa is Ethiopia’s most developer-friendly payment gateway. It aggregates multiple Ethiopian payment methods (Telebirr, CBEBirr, bank transfers, cards) behind a single checkout page — making it the easiest single integration for broad payment coverage.
Overview
Section titled “Overview”| Property | Value |
|---|---|
| Operator | Chapa Financial Technologies |
| Type | Payment Gateway (multi-method) |
| Country | Ethiopia |
| Currency | ETB, USD (limited) |
| Flow | Hosted Checkout |
| Programmatic Refunds | Yes |
| Sandbox Available | Yes (excellent) |
| Settlement | T+2 business days |
Supported Payment Methods (via Chapa Checkout)
Section titled “Supported Payment Methods (via Chapa Checkout)”When a customer lands on the Chapa checkout page, they can pay via:
- Telebirr
- CBEBirr
- Commercial Bank of Ethiopia (bank transfer)
- Awash Bank
- Cooperative Bank
- Amhara Bank
- Visa / Mastercard (limited availability)
This makes Chapa a compelling “one integration, many methods” option for Ethiopian merchants.
Credentials
Section titled “Credentials”| Credential | Description |
|---|---|
secretKey | Your Chapa secret key (CHASECK_TEST-... for test, CHASECK-... for live) |
Get your keys from dashboard.chapa.co.
Configuration
Section titled “Configuration”const zirzir = new Zirzir({ provider: 'chapa', credentials: { secretKey: process.env.CHAPA_SECRET_KEY! }})client = zirzir.Zirzir( provider="chapa", credentials={"secret_key": os.environ["CHAPA_SECRET_KEY"]})client := zirzir.New(zirzir.Config{ Provider: "chapa", Credentials: map[string]string{ "secret_key": os.Getenv("CHAPA_SECRET_KEY"), },})Charging a Customer
Section titled “Charging a Customer”const tx = await zirzir.charge({ amount: 1500, currency: 'ETB', email: 'customer@example.com', firstName: 'Dawit', lastName: 'Bekele', txRef: `order_${Date.now()}`, returnUrl: 'https://yourapp.com/payment/success', callbackUrl: 'https://yourapp.com/webhooks/zirzir',})
// Redirect to Chapa's hosted checkoutres.redirect(tx.checkoutUrl)Unlike USSD-based providers, Chapa returns a proper checkoutUrl — redirect the customer there.
Sandbox Testing
Section titled “Sandbox Testing”Chapa has the best sandbox of any Ethiopian gateway. Test cards and credentials:
Test Card
Section titled “Test Card”| Field | Value |
|---|---|
| Card Number | 4200000000000000 |
| Expiry | Any future date |
| CVV | Any 3 digits |
Test Mobile Money
Section titled “Test Mobile Money”Use any valid-format phone number in sandbox. The USSD prompt is simulated automatically — no real phone required.
Secret Key Format
Section titled “Secret Key Format”Test keys start with CHASECK_TEST-. Make sure you’re using the test key in development.
Verifying a Transaction
Section titled “Verifying a Transaction”After the customer completes payment and returns to your returnUrl, Chapa appends ?trx_ref=... to the URL. Verify server-side:
app.get('/payment/success', async (req, res) => { const txRef = req.query.trx_ref as string
const tx = await zirzir.verify(txRef)
if (tx.status === 'success') { await fulfillOrder(txRef) return res.render('success') }
res.render('error', { message: 'Payment was not completed' })})Customizing the Checkout Page
Section titled “Customizing the Checkout Page”Chapa’s checkout page supports limited customization via metadata:
const tx = await zirzir.charge({ amount: 500, currency: 'ETB', email: 'customer@example.com', txRef: 'order_001', metadata: { hide_receipt: false, // Show/hide receipt page customization: { title: 'Your Store Name', description: 'Paying for Order #001', logo: 'https://yourstore.com/logo.png' } }})Known Issues & Quirks
Section titled “Known Issues & Quirks”trx_ref vs tx_ref
Section titled “trx_ref vs tx_ref”Chapa’s API uses tx_ref in request bodies but returns trx_ref in query params on the return URL. Zirzir normalizes this — always use txRef in Zirzir calls.
Webhook Verification
Section titled “Webhook Verification”Chapa’s webhook verification uses a hash of the transaction data, not an HMAC of the body. Zirzir handles this internally — use zirzir.webhooks.verify() as normal.
Settlement Delays
Section titled “Settlement Delays”Chapa advertises T+1 settlement but T+2 is more common in practice. Weekends and holidays extend this further.
Currency Limitations
Section titled “Currency Limitations”USD payments through Chapa require additional merchant approval and are not available on new accounts by default.
Fee Structure
Section titled “Fee Structure”Verify current rates with Chapa. Fees change and may vary by merchant tier.
| Volume | Fee |
|---|---|
| Standard | 1.5% per transaction |
| Negotiated (high volume) | 0.8% - 1.2% |
| Minimum fee | 5 ETB |
Chapa fees are inclusive — no additional setup or monthly fees for the basic tier.
Refunds
Section titled “Refunds”Chapa supports full and partial programmatic refunds:
// Full refundconst refund = await zirzir.refund('order_001')
// Partial refundconst refund = await zirzir.refund('order_001', { amount: 250 })Refunds typically process within 3-5 business days.
Settlement
Section titled “Settlement”- Cycle: T+2 business days (in practice)
- Minimum threshold: 500 ETB
- Method: Bank transfer to your registered bank account
- Reports: Available in Chapa dashboard and Zirzir Dashboard (server mode)