Skip to content

Telebirr

Telebirr is Ethiopia’s dominant mobile money platform, operated by Ethio Telecom. With over 40 million registered users, it’s the most widely used payment method in Ethiopia by volume.


PropertyValue
OperatorEthio Telecom
TypeMobile Money
CountryEthiopia
CurrencyETB
FlowUSSD Push
Programmatic RefundsNo
Sandbox AvailableYes (limited)
SettlementT+1 business days

Telebirr does not use a web checkout page. Instead, it initiates a USSD push to the customer’s phone. The flow is:

  1. Your app calls zirzir.charge() with the customer’s phone number
  2. Telebirr sends a USSD prompt to the customer’s phone
  3. Customer approves by entering their Telebirr PIN
  4. Telebirr sends a webhook to your callbackUrl
  5. You verify and fulfill the order

This means checkoutUrl will always be null for Telebirr transactions.


You’ll need the following from Ethio Telecom’s merchant portal:

CredentialDescription
appIdYour merchant App ID
appKeyYour App Key (keep secret)
shortCodeYour merchant short code (e.g., 950702)
publicKeyTelebirr’s RSA public key (for encrypting auth payload)

Getting credentials: Contact Ethio Telecom’s merchant services at their business centers. As of 2024, the process takes 2-4 weeks and requires a business license.


const zirzir = new Zirzir({
provider: 'telebirr',
credentials: {
appId: process.env.TELEBIRR_APP_ID!,
appKey: process.env.TELEBIRR_APP_KEY!,
shortCode: process.env.TELEBIRR_SHORT_CODE!,
publicKey: process.env.TELEBIRR_PUBLIC_KEY!, // RSA public key PEM
}
})
client = zirzir.Zirzir(
provider="telebirr",
credentials={
"app_id": os.environ["TELEBIRR_APP_ID"],
"app_key": os.environ["TELEBIRR_APP_KEY"],
"short_code": os.environ["TELEBIRR_SHORT_CODE"],
"public_key": os.environ["TELEBIRR_PUBLIC_KEY"],
}
)

phone is required for Telebirr. It must be an Ethio Telecom number.

const tx = await zirzir.charge({
amount: 500,
currency: 'ETB',
email: '[email protected]', // For your records; not shown to customer
phone: '0911234567', // Ethio Telecom number
txRef: 'order_001',
callbackUrl: 'https://yourapp.com/webhooks/zirzir',
})
// tx.checkoutUrl is null — customer is prompted via USSD
console.log(tx.status) // 'pending'

Zirzir normalizes phone numbers automatically, but we recommend passing them in 09XXXXXXXX or 2519XXXXXXXX format.

FormatAccepted
0911234567Yes
+251911234567Yes
251911234567Yes
911234567Yes (normalized internally)

Since there’s no checkout page, you need to wait for the customer to approve. Two approaches:

app.post('/webhooks/zirzir', express.raw({ type: 'application/json' }), (req, res) => {
const valid = zirzir.webhooks.verify(req.body, req.headers['x-zirzir-signature'])
if (!valid) return res.sendStatus(401)
const event = JSON.parse(req.body.toString())
if (event.type === 'transaction.success') {
fulfillOrder(event.data.txRef)
}
res.sendStatus(200)
})
// After charge(), show "Check your phone" UI and poll every 5s
const tx = await pollUntilComplete('order_001', { maxAttempts: 24, interval: 5000 })

The Telebirr sandbox environment does not actually send a USSD message to the phone. To test, you must call verify() manually after a short delay — sandbox transactions auto-succeed after ~30 seconds.

// In test mode, manually verify after a delay
if (process.env.NODE_ENV !== 'production') {
await sleep(30000)
const tx = await zirzir.verify('order_001')
console.log(tx.status) // 'success' in sandbox
}

Telebirr’s API does not always reject duplicate txRef values in sandbox. In production it does. Always use unique references.

Telebirr access tokens expire every 30 minutes. The Zirzir SDK handles token refresh automatically — you don’t need to manage this.

Telebirr requires certain request parameters to be RSA-encrypted using their public key. The Zirzir SDK handles this internally, but you must provide the correct publicKey credential. If you get auth errors, double-check the PEM format of your key.

If the customer doesn’t respond to the USSD prompt within 5 minutes, Telebirr marks the transaction as expired. Your webhook will receive a transaction.failed event with reason: 'timeout'.


Telebirr does not support programmatic refunds. You must process refunds manually through the Ethio Telecom merchant portal or by contacting your Telebirr account manager.

Keep your transaction externalId values — you’ll need them for manual refund requests.


Fee structures change. Verify current rates with your Ethio Telecom merchant agreement.

Transaction TypeFee
Merchant-initiated (standard)0.8% of transaction amount
Minimum fee1 ETB
Maximum fee100 ETB

Settlement is net of fees — you receive the transaction amount minus the Telebirr fee.


  • Settlement cycle: T+1 business days (next business day)
  • Minimum settlement amount: 100 ETB
  • Settlement method: Transfer to linked bank account
  • Settlement reports: Available in the Ethio Telecom merchant portal and in the Zirzir Dashboard (server mode)

  • Merchant support: Contact your Ethio Telecom account manager
  • Sandbox access: Request via the Ethio Telecom developer portal
  • Common issue: Transactions stuck in pending — check your callbackUrl is publicly accessible and verify manually