0% found this document useful (0 votes)
613 views16 pages

How To Integrate Telebirr in Your Web App by Mukerem Ali Medium

Uploaded by

tovetaw413
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
613 views16 pages

How To Integrate Telebirr in Your Web App by Mukerem Ali Medium

Uploaded by

tovetaw413
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 16

How to Integrate Telebirr in Your Web App | by Mukere... https://medium.com/@mukeremali112/how-to-integrate-...

Open in app Sign up Sign in

Search

How to Integrate Telebirr in Your Web App


Mukerem Ali · Follow
3 min read · Jun 6, 2023

Listen Share

Telebirr is a mobile money service developed and launched by Ethio Telecom, the
state-owned telecommunication and Internet service provider in Ethiopia.

To start integrating the Telebirr API into your web application, you must first
contact the Telebirr administrators. This process involves presenting various
documents, such as a valid business license, to authenticate and validate your
request. Upon successful verification, the Telebirr team will provide you with the
necessary credentials for testing and integration.

Step 1: Initializing API Parameters

Begin by defining the necessary 12 parameters for the Telebirr API. These include
`app_id\`, `app_key`, and `short_code`, provided by Telebirr, along with
dynamically generated values like `timestamp`, `nonce`, and `out_trade_no`. For
instance, set `app_id` as `”YOUR_APP_ID_FROM_TELEBIRR_ADMIN”`. This step
ensures that your application has the necessary credentials and unique identifiers
for each transaction.

1 of 16 7/4/24, 14:35
How to Integrate Telebirr in Your Web App | by Mukere... https://medium.com/@mukeremali112/how-to-integrate-...

1 from datetime import datetime


2
3
4 url = "http://196.188.120.3:11443/ammapi/payment/service-openup/toTradeWebPay/"
5 appId = "YOUR_APP_ID_FROM_TELEBIRR_ADMIN"
6 appKey = "YOUR_APP_KEY_FROM_TELEBIRR_ADMIN"
7 receiveName = "Subscription"
8 shortCode = "YOUR_SHORT_CODE_FROM_TELEBIRR_ADMIN"
9 timeoutExpress = "5"
10 timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
11 nonce = "GFGHG521DF5GDFG12DGFGD5FG46DFG5"
12 outTradeNo = "78EYRFDBVJHXDJLCKXJVCXVKCV"
13 totalAmount = 100
14 notifyUrl = "https://example.com/"
15 returnUrl = "https://example.com/"

telebirr_constants.py hosted with ❤ by GitHub view raw

The `timestamp` represents the current time when the request was sent. Both the
`nonce` and `outTradeNo` are uniquely generated numbers.

Step 2: Constructing the Request String (StringA)

Assemble a query string, `stringA`, by concatenating the 12 required values along


with their keys in ascending order. This step is crucial for creating a standardized
request format for the Telebirr API.

stringA = f"appId={appId}&appKey={appKey}&nonce={nonce}&notifyUrl={notifyUrl}&outTradeNo

Step 3: Creating the JSON Payload

Develop a JSON object using the same 12 values. This JSON structure forms the core
of your API request, maintaining the integrity and structure of the data to be sent to
Telebirr. The JSON key must remain unchanged.

2 of 16 7/4/24, 14:35
How to Integrate Telebirr in Your Web App | by Mukere... https://medium.com/@mukeremali112/how-to-integrate-...

1 ussdjson = {
2 "appId":appId,
3 "nonce":nonce,
4 "notifyUrl":notifyUrl,
5 "outTradeNo":outTradeNo,
6 "receiveName":receiveName,
7 "returnUrl":returnUrl,
8 "shortCode":shortCode,
9 "subject":subject,
10 "timeoutExpress":timeoutExpress,
11 "timestamp":timestamp,
12 "totalAmount":totalAmount,
13 }
14
15 ussdjson = json.dumps(ussdjson).encode('utf-8')

telebirr_ussdjson.py hosted with ❤ by GitHub view raw

Step 4: Encryption of Data

Encrypt the JSON object using the public key stored as an environment variable,
provided by the Telebirr admin. Employ the RSA 2048 encryption method. Given
that RSA 2048 only allows a maximum text size of 245, if our text length exceeds this,
we need to divide the data into chunks of up to 245 bytes. Encrypt each chunk
separately, then combine the encrypted data. This step ensures the security of the
data transmitted.

3 of 16 7/4/24, 14:35
How to Integrate Telebirr in Your Web App | by Mukere... https://medium.com/@mukeremali112/how-to-integrate-...

1 from Crypto.Cipher import PKCS1_OAEP, PKCS1_v1_5


2
3
4 publicKey = “YOUR_PUBLIC_KEY_FROM_TELEBIRR_ADMIN”
5 public_key = RSA.import_key(base64.urlsafe_b64decode(publicKey))
6 encryptor = PKCS1_v1_5.new(public_key)
7
8 maxEncryptSize = 245
9 bufferSize = len(ussdjson)
10 buffersCount = int(math.ceil(bufferSize / maxEncryptSize)) # total buffers count for encrypt
11 dividedSize = int(math.ceil(bufferSize / buffersCount)) # each buffer size
12
13 try:
14 result = []
15 for bufNum in range(buffersCount):
16 result.append(encryptor.encrypt(ussdjson[bufNum * dividedSize: (bufNum + 1) * dividedSize
17 encrypted_decode = b"".join(result)
18 encrypted_encode = base64.b64encode(encrypted_decode)
19 encrypted = str(encrypted_encode, "utf-8")
20 except Exception as e:
21 raise NotFound(e)

telebirr_encrypt_ussdjson.py hosted with ❤ by GitHub view raw

The encrypted value looks like

"QHcp4WhzXO7QCSE8pOtEPbvJqxf4ERjd7z6pEDkukQ0/Hgfn1lq1oVLiJ2S5vHKAHurtu/dwmpRitJhJMY5y2zL

Step 5: Generating the Hash (stringB)

Create a hashed version of `stringA` (termed `stringB`) using SHA256. This hash
acts as a security measure to ensure the integrity of the data being sent.

stringB = sha256(stringA.encode()).hexdigest().upper()

4 of 16 7/4/24, 14:35
How to Integrate Telebirr in Your Web App | by Mukere... https://medium.com/@mukeremali112/how-to-integrate-...

Step 6: Sending the API Request

Compile and send the API request, which includes `app_id`, the encrypted data, and
`stringB`. The content type of the request should be set to application/JSON,
aligning with standard API communication protocols. The `appId` is provided by the
telebirr administrator. `encrypted` represents the encrypted data while `stringB`
represents the hashed data.

1 {
2 "appid": "6uytgbhbjvdf4a9bb80ce6b1a94a1ea1",
3 "sign": "FAFAFC87F5C18A2142B8A905A885A244530D587E1243D0F2F05E2649494FC0A6",
4 "ussd": "QHcp4WhzXO7QCSE8pOtEPbvJqxf4ERjd7z6pEDkukQ0/Hgfn1lq1oVLiJ2S5vHKAHurtu/dwmpRitJhJMY5y2z
5 }
6
7 data = {"appid": appId, "sign": stringB, "ussd": encrypted}
8 headers = {
9 "Content-Type": "application/json;charset=utf-8",
10 }
11 timeout = 5
12
13 param = {
14 "subject": subject,
15 "nonce": nonce,
16 "outTradeNo": outTradeNo,
17 "timestamp": timestamp,
18 "amount": totalAmount,
19 "reason": reason
20 }
21
22 response = requests.post(url=url, json=data, headers=headers, timeout=timeout)

gistfile1.txt hosted with ❤ by GitHub view raw

Step 7: Receiving and Processing the Response

Upon a successful request, the Telebirr API responds with a payment URL
(toPayURL). This URL is then presented to the user to complete the payment
process.

5 of 16 7/4/24, 14:35
How to Integrate Telebirr in Your Web App | by Mukere... https://medium.com/@mukeremali112/how-to-integrate-...

This is sample return response

{
"code": 0,
"msg": "success",
"data": {
"toPayUrl": "https://h5pay.trade.pay/payId=RE9879T0972S"
}
}

Step 8: Handling Payment Notifications

After a successful transaction, Telebirr sends a notification to your system. This


notification, an encrypted string, must be decrypted using the same public key
provided by Telebirr.

Telebirr server calls your notify URL API using text media as parser format. So your notify
API must accept Text /plain type request data.

This is sample notify data

b'QXxPG958j8RTifoKcONoelrH8XSP7vZWajUw2tR07b1/sypWU/sXQAPH0fCUI6jL4I/E7apmGy7CC9hQ4UU7Ye

Create text parser for the DRF API

6 of 16 7/4/24, 14:35
How to Integrate Telebirr in Your Web App | by Mukere... https://medium.com/@mukeremali112/how-to-integrate-...

1 from rest_framework.parsers import BaseParser


2
3
4 class PlainTextParser(BaseParser):
5 """
6 Plain text parser.
7 """
8 media_type = 'text/plain'
9
10
11 def parse(self, stream, media_type=None, parser_context=None):
12 """
13 Simply return a string representing the body of the request.
14 """
15 return stream.read()

telebirr_text_parser.py hosted with ❤ by GitHub view raw

Step 9: Decrypting the Notification

Finally, decrypt the notification to access transaction details such as msisdn,


totalAmount, tradeDate, transactionNo, outTradeNo, and tradeNo. This decrypted data
is essential for reconciling the transaction in your system.

7 of 16 7/4/24, 14:35
How to Integrate Telebirr in Your Web App | by Mukere... https://medium.com/@mukeremali112/how-to-integrate-...

1 import base64
2 import json
3 import rsa
4 import six
5 from Crypto.Cipher import PKCS1_v1_5
6 from Crypto.PublicKey import RSA
7
8
9 class DecryptByPublicKey(object):
10 """
11 the modulus factor is generated first
12 the rsa public key is then generated
13 then use the rsa public key to decrypt the incoming encryption str
14 """
15 def __init__(self):
16 public_key = RSA.import_key(base64.urlsafe_b64decode(publicKey))
17 self._modulus = public_key.n # the modulus
18 self._exponent = public_key.e # factor
19 try:
20 rsa_pubkey = rsa.PublicKey(self._modulus, self._exponent)
21 self._pub_rsa_key = rsa_pubkey.save_pkcs1() # using publickey ( modulus, factor ) calc
22 except Exception as e:
23 raise e
24
25
26 def decrypt(self, b64decoded_encrypt_text) ->str:
27 """
28 decrypt msg by public key
29 """
30 public_key = rsa.PublicKey.load_pkcs1(self._pub_rsa_key)
31 encrypted = rsa.transform.bytes2int(b64decoded_encrypt_text)
32 decrypted = rsa.core.decrypt_int(encrypted, public_key.e, public_key.n)
33 decrypted_bytes = rsa.transform.int2bytes(decrypted)
34 if len(decrypted_bytes) > 0 and list(six.iterbytes(decrypted_bytes))[0] == 1:
35 try:
36 raw_info = decrypted_bytes[decrypted_bytes.find(b'\x00')+1:]
37 except Exception as e:
38 raise e
39 else:
40 raw_info = decrypted_bytes
41 return raw_info.decode("utf-8")
42

8 of 16 7/4/24, 14:35
How to Integrate Telebirr in Your Web App | by Mukere... https://medium.com/@mukeremali112/how-to-integrate-...

43
44 def get_decrypt_data(data):
45 try:
46 data = base64.b64decode(data)
47 except Exception as e:
48 raise NotFound(e)
49
50 decryptor = DecryptByPublicKey()
51 maxEncryptSize = 256
52 bufferSize = len(data)
53 buffersCount = int(math.ceil(bufferSize / maxEncryptSize)) # total buffers count for decrypt
54 dividedSize = int(math.ceil(bufferSize / buffersCount)) # each buffer size
55 result = []
56 try:
57 for bufNum in range(buffersCount):
58 encrypted_text = decryptor.decrypt(data[bufNum * dividedSize: (bufNum + 1) *
59 result.append(encrypted_text)
60 message = "".join(result)
61 except Exception as e:
62 raise NotFound(e)
63 response = json.loads(message)
64
65 if response:
66 outTradeNo = response.get('outTradeNo')
67 tradeNo = response.get('tradeNo')
68 return outTradeNo, tradeNo, response
69 else:
70 raise NotFound("Invalid response") # log to admin

telebirr_decrypt_data.py hosted with ❤ by GitHub view raw

outTradeNo is data generated by our system, and tradeNo is a user’s unique Telebirr
account trading number.

sample decrypted data

{
'msisdn': '251900000032',
'totalAmount': '10',
'outTradeNo': 'CEvSC7isJ74rrXqLVUwkraECfHARP6NL',
'tradeDate': 1647421757000,
'tradeNo': '202203161208521504021872763195393',

9 of 16 7/4/24, 14:35
How to Integrate Telebirr in Your Web App | by Mukere... https://medium.com/@mukeremali112/how-to-integrate-...

'tradeStatus': 2,
'transactionNo': '9CG90NCOK5'
}

Each step in this process is integral to securely and effectively integrating Telebirr
into your web app, ensuring a smooth user experience and maintaining transaction
integrity.

Follow

Written by Mukerem Ali


191 Followers

Software Engineer | Competitive Programmer | Mentor

More from Mukerem Ali

10 of 16 7/4/24, 14:35
How to Integrate Telebirr in Your Web App | by Mukere... https://medium.com/@mukeremali112/how-to-integrate-...

Mukerem Ali

Competitive Programming for Beginners


What is Competitive Programming

Nov 23, 2023 63

11 of 16 7/4/24, 14:35
How to Integrate Telebirr in Your Web App | by Mukere... https://medium.com/@mukeremali112/how-to-integrate-...

Mukerem Ali

My Competitive Programming Journey


My journey in competitive programming and technology is a story of passion, dedication, and
continuous learning. I graduated with a dual…

Nov 21, 2023 74 2

See all from Mukerem Ali

Recommended from Medium

Alexander Nguyen in Level Up Coding

The resume that got a software engineer a $300,000 job at Google.


1-page. Well-formatted.

Jun 1 10.8K 134

12 of 16 7/4/24, 14:35
How to Integrate Telebirr in Your Web App | by Mukere... https://medium.com/@mukeremali112/how-to-integrate-...

Afan Khan in JavaScript in Plain English

Microsoft is ditching React


Here’s why Microsoft considers React a mistake for Edge.

Jun 6 2K 46

Lists

Staff Picks
681 stories · 1110 saves

Stories to Help You Level-Up at Work


19 stories · 679 saves

Self-Improvement 101
20 stories · 2237 saves

Productivity 101
20 stories · 1981 saves

13 of 16 7/4/24, 14:35
How to Integrate Telebirr in Your Web App | by Mukere... https://medium.com/@mukeremali112/how-to-integrate-...

Sufyan Maan, M.Eng in ILLUMINATION

What Happens When You Start Reading Every Day


Think before you speak. Read before you think. — Fran Lebowitz

Mar 11 24K 512

14 of 16 7/4/24, 14:35
How to Integrate Telebirr in Your Web App | by Mukere... https://medium.com/@mukeremali112/how-to-integrate-...

Artturi Jalli

I Built an App in 6 Hours that Makes $1,500/Mo


Copy my strategy!

Jan 23 19.5K 203

Liu Zuo Lin

You’re Decent At Python If You Can Answer These 7 Questions Correctly


# No cheating pls!!

Mar 6 5.9K 29

15 of 16 7/4/24, 14:35
How to Integrate Telebirr in Your Web App | by Mukere... https://medium.com/@mukeremali112/how-to-integrate-...

Vishal Rajput in AIGuys

Prompt Engineering Is Dead: DSPy Is New Paradigm For Prompting


DSPy Paradigm: Let’s program — not prompt — LLMs

May 29 3.8K 36

See more recommendations

16 of 16 7/4/24, 14:35

You might also like