telebirr_plus is a simple Node.js backend package and local test website for Telebirr InApp Purchase.
It is designed to work with the Flutter package:
Use this Node package for the backend part. Use the Flutter package for opening the native Telebirr payment SDK.
Using an AI coding assistant to integrate this package into your existing backend? Add or reference skills.md first so the assistant asks for the required Telebirr credentials, private key location, notify URL, existing order model, and checkout route before changing code.
- Customer opens your Flutter app.
- Flutter sends
titleandamountto your backend. - Backend calls Telebirr Apply Fabric Token.
- Backend signs and calls Telebirr Create InApp Order.
- Backend returns
receiveCodeto Flutter. - Flutter calls
Telebirr.pay(...)with thatreceiveCode. - Telebirr app opens and customer pays.
- Flutter receives SDK callback.
- Telebirr calls your backend
notify_url. - Backend can call
queryOrderto confirm the final payment status.
Keep these only on your backend:
- App Secret
- Private key
- Fabric Token logic
- createOrder logic
- queryOrder logic
- notify_url verification
Flutter must only receive receiveCode.
- Create an account at developer.ethiotelecom.et.
- Create or join your organization/team at developer.ethiotelecom.et/user/team.
- Make sure the organization member status is approved.
- Make sure your Telebirr product/contract is approved for InApp payment.
- Get these credentials from the portal:
- Fabric App ID
- Merchant App ID
- Business Short Code
- App Secret
- Private key
If your organization or contract is not approved, Telebirr may return:
60200098: Product is not subscribed or the contract status is not allowed to do this operation.
You can test in two ways:
- Run the included example website first.
- Install
telebirr_plusinside your own Node/Express backend.
Clone this repository:
git clone https://github.com/Dream-Technologies-PLC/telebirr_plus.git
cd telebirr_plus
npm installCreate .env:
cp .env.example .env
mkdir -p keysPut your Telebirr private key here:
keys/private_key.pem
Fill .env:
PORT=3000
TELEBIRR_ENV=test
TELEBIRR_FABRIC_APP_ID=your_fabric_app_id
TELEBIRR_APP_SECRET=your_app_secret
TELEBIRR_MERCHANT_APP_ID=your_merchant_app_id
TELEBIRR_SHORT_CODE=your_business_short_code
TELEBIRR_PRIVATE_KEY_PATH=./keys/private_key.pem
TELEBIRR_NOTIFY_URL=https://yourdomain.com/api/telebirr/notify
TELEBIRR_TIMEOUT=120m
TELEBIRR_PAYEE_TYPE=3000
TELEBIRR_VERIFY_SSL=trueStart the example:
npm startOpen the test website:
http://localhost:3000
Test with cURL:
curl -X POST http://localhost:3000/api/telebirr/create-order \
-H "Content-Type: application/json" \
-d '{
"title": "Local test order",
"amount": "12.00"
}'The response gives you receiveCode. Copy it into the Flutter package example app and press Pay With Telebirr.
Create a Node project:
mkdir telebirr-backend
cd telebirr-backend
npm init -y
npm install telebirr_plus express cors dotenvCreate folders:
mkdir keysPut your private key here:
keys/private_key.pem
Create .env:
PORT=3000
TELEBIRR_ENV=test
TELEBIRR_BASE_URL=
TELEBIRR_FABRIC_APP_ID=your_fabric_app_id
TELEBIRR_APP_SECRET=your_app_secret
TELEBIRR_MERCHANT_APP_ID=your_merchant_app_id
TELEBIRR_SHORT_CODE=your_business_short_code
TELEBIRR_PRIVATE_KEY_PATH=./keys/private_key.pem
TELEBIRR_NOTIFY_URL=https://yourdomain.com/api/telebirr/notify
TELEBIRR_TIMEOUT=120m
TELEBIRR_PAYEE_TYPE=3000
TELEBIRR_VERIFY_SSL=trueFor local Telebirr testbed only, if your machine rejects the Telebirr testbed certificate, use:
TELEBIRR_VERIFY_SSL=falseKeep TELEBIRR_VERIFY_SSL=true in production.
Create server.js:
require('dotenv').config();
const cors = require('cors');
const express = require('express');
const {
TelebirrInAppClient,
createTelebirrRouter,
loadConfigFromEnv,
} = require('telebirr_plus');
const app = express();
const client = new TelebirrInAppClient(loadConfigFromEnv());
app.use(cors());
app.use(express.json());
app.use('/api/telebirr', createTelebirrRouter(client, {
onNotify: async (payload) => {
console.log('Telebirr notify_url payload:', payload);
},
}));
app.listen(3000, () => {
console.log('Telebirr backend running on http://localhost:3000');
});Run:
node server.jsYour backend create-order URL is:
http://localhost:3000/api/telebirr/create-order
Test your own project with cURL:
curl -X POST http://localhost:3000/api/telebirr/create-order \
-H "Content-Type: application/json" \
-d '{
"title": "Example test order",
"amount": "12.00"
}'Successful response:
{
"success": true,
"code": "0",
"message": "Order created.",
"merchantOrderId": "1778088977616",
"receiveCode": "TELEBIRR$BUYGOODS$YOUR_SHORT_CODE$12.00$024demoPrepayId$120m",
"raw": {}
}Copy receiveCode. Flutter uses it to start payment.
Install the Flutter app package:
dependencies:
telebirr_inapp_purchase_plus: ^1.0.3Flutter code:
await Telebirr.initialize(
appId: 'YOUR_MERCHANT_APP_ID',
shortCode: 'YOUR_SHORT_CODE',
returnScheme: 'yourappscheme',
environment: TelebirrEnvironment.test,
);
final result = await Telebirr.pay(receiveCode: receiveCodeFromBackend);
if (result.isSuccess) {
print('Payment successful');
} else {
print('Payment failed: ${result.message}');
}The Flutter app fields should be:
- Backend create-order URL:
http://YOUR_BACKEND_HOST/api/telebirr/create-order - Merchant App ID: your portal Merchant App ID
- Short code: your Business Short Code
- Return app scheme: the scheme configured in your Flutter app
- Amount: order amount
- Title: order title
For a real phone on the same Wi-Fi, do not use localhost in Flutter. Use your computer IP:
http://192.168.x.x:3000/api/telebirr/create-order
This package includes a local HTML test page.
Clone or open this package, then create .env from the example:
cp .env.example .env
mkdir -p keysAdd your private key:
keys/private_key.pem
Run:
npm install
npm startOpen:
http://localhost:3000
The page lets you:
- Create a Telebirr test order
- See the returned
merchantOrderId - Copy the
receiveCode - Copy a Flutter
Telebirr.initializeandTelebirr.paysnippet
There is also a dedicated example env file:
examples/express/.env.example
Testbed:
TELEBIRR_ENV=testProduction:
TELEBIRR_ENV=productionIn Flutter, match the same environment:
environment: TelebirrEnvironment.testor:
environment: TelebirrEnvironment.productionDefault Telebirr gateway URLs:
Testbed: https://developerportal.ethiotelebirr.et:38443/apiaccess/payment/gateway
Production: https://telebirrappcube.ethiomobilemoney.et:38443/apiaccess/payment/gateway
const client = new TelebirrInAppClient(loadConfigFromEnv());Methods:
applyFabricToken()createOrder({ title, amount, merchantOrderId, notifyUrl, redirectUrl, callbackInfo })queryOrder({ merchantOrderId })
Creates these routes:
POST /create-orderPOST /query-orderPOST /notify
curl -X POST http://localhost:3000/api/telebirr/query-order \
-H "Content-Type: application/json" \
-d '{
"merchantOrderId": "1778088977616"
}'Use queryOrder when:
- Flutter callback is delayed
- User closes the app after payment
notify_urlis delayed- You need backend-side final confirmation
Your developer organization, product subscription, or contract is not approved.
Check:
- Developer account status
- Organization member status
- Product subscription
- Contract approval
- Correct Merchant App ID and Short Code
For local testbed, try:
TELEBIRR_VERIFY_SSL=falseThen restart Node.
If testing on a real phone, use your computer LAN IP instead of localhost.
Example:
http://192.168.1.20:3000/api/telebirr/create-order
Use backend notify_url and queryOrder. The Flutter SDK callback is helpful for UI, but final payment confirmation should come from the backend.
Need support with Telebirr integration, websites, mobile apps, or custom software? Contact Dream Technologies PLC: dreamtech.et/contact