You found the good docs. 👋
If you’ve been staring at the official Telebirr developer portal wondering why a payment integration guide reads like a government procurement document written at 4pm on a Friday — you’re in the right place.
These are the unofficial community docs. Same APIs, same flows, actually explained.
If you’re tired of the official docs: same. The information is technically there, but buried under copy-pasted tables, broken code samples, and zero context about why things work the way they do. This site exists to fix that.
What’s here
This site covers Telebirr payment integration from two angles:
- The raw API — endpoint by endpoint, exactly what Telebirr’s server expects, with working examples in PHP, TypeScript, and Python. Plus all the parts the official docs gloss over (request signing, token expiry, notification verification).
- Community libraries — wrappers that handle the boilerplate for you. Currently:
melaku/telebirrfor PHP and@melakudemeke/telebirr-jsfor JavaScript/TypeScript. A Python library is in the works.
Before you write a single line of code
Getting Telebirr integration approved is a process. Here’s the real sequence — not what the official docs show you.
Create a developer account
Go to developer.ethiotelecom.et/user/home and register. This gives you access to the developer portal where you’ll manage your app credentials once approved.
Submit a proposal in person
This is the step nobody documents. You cannot just sign up online and start calling APIs.
Head to the Telebirr office — find it on Google Maps — and submit your integration proposal. Bring your business details and what you’re building.
After approval, they’ll add you to a WhatsApp or Telegram group where their technical team supports integrations. That group is your main support channel.
Get your public key (this isn’t in the official docs)
Once onboarded, share your merchant short code with the Telebirr team. They’ll send you back a public key.
This public key is not available anywhere in the developer portal documentation. You will not find it by reading the official docs — you have to ask for it directly.
This key is used to verify incoming payment notifications without needing server-to-server communication. You use it on your server to check that callback signatures are genuinely from Telebirr.
Build and test
Use the test environment while building. The portal gives you testbed credentials separate from production. Run through the full flow — token, order creation, checkout, notification handling.
Go live
When you’re ready to go to production, share the following with the Telebirr team:
| What to share | Why |
|---|---|
| Your SSL certificate | Telebirr only sends notifications to HTTPS endpoints |
| Your server IP address | They whitelist it for server-to-server communication |
| Your notify URL | The endpoint they’ll POST signed payment results to |
Once they’ve verified everything on their side, you’re live.
Pick your integration type
The quick version
If you just want to see the full flow, pick your language:
composer require melaku/telebirruse Melaku\Telebirr\Config;
use Melaku\Telebirr\Telebirr;
$config = Config::forProduction([
'fabricAppId' => $_ENV['FABRIC_APP_ID'],
'appSecret' => $_ENV['APP_SECRET'],
'merchantAppId' => $_ENV['MERCHANT_APP_ID'],
'merchantCode' => $_ENV['MERCHANT_CODE'],
'privateKey' => $_ENV['PRIVATE_KEY_PEM'],
'notifyUrl' => 'https://your-site.com/pay/notify',
'redirectUrl' => 'https://your-site.com/pay/return',
]);
$result = (new Telebirr($config))->createCheckoutUrl('Order #1', '250.00');
// Store $result->getMerchOrderId() against your order in your DB
// Telebirr echoes it back in notifications so you can match them
header('Location: ' . $result->getCheckoutUrl());What the official docs don’t tell you
| The pain | What’s actually happening |
|---|---|
"verify sign failed" | Parameters not sorted correctly by ASCII order before signing |
| Token errors after a while | Fabric tokens expire in 60 minutes — the libraries cache until expirationDate automatically (PHP v2.2.0+, JS v3.1.0+) |
| Silent notification failures | Your notifyUrl must be reachable from the internet and whitelisted by Telebirr — the libraries now warn if it points at localhost |
| Wrong env URLs | Test and production have different base URLs — mixing them gives cryptic errors |
"invalid merchant order id" | Order IDs must be alphanumeric only — no underscores, hyphens, or special characters |
| Can’t verify notifications | You need the public key — ask the Telebirr team directly, it’s not in the portal |
ERR_OSSL_UNSUPPORTED / key errors | Ethio Telecom issues keys as bare base64 without PEM armor — the libraries normalize this automatically (PHP v2.2.0+, JS v3.1.0+) |
UNABLE_TO_VERIFY_LEAF_SIGNATURE / cURL error 60 | The test gateway serves an incomplete TLS chain — the libraries bundle the missing CA, so never ship verifySsl: false |
A 4940… error out of nowhere | The sandbox is unstable; 49401024991 is a gateway-side infra error — retry (the libraries offer opt-in retry with backoff), don’t debug your own code |
About this project
- Not affiliated with Ethio Telecom. Community resource maintained by developers who’ve been through the integration.
- PHP library (
melaku/telebirr): github.com/MelakuDemeke/telebirr-php · packagist.org/packages/melaku/telebirr - JavaScript/TypeScript library (
@melakudemeke/telebirr-js): github.com/MelakuDemeke/telebirr-js · npmjs.com/package/@melakudemeke/telebirr-js - Found something wrong? Open an issue on GitHub — the official API occasionally changes without notice.