Skip to content

Commit 0877766

Browse files
article: guide to integrate mobile money payment in a web app
1 parent baa1de4 commit 0877766

File tree

1 file changed

+171
-0
lines changed

1 file changed

+171
-0
lines changed
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
---
2+
title: Guide to integrate mobile money payments for a Python web app with Notchpay in Cameroon
3+
date: '2024-09-07'
4+
tags: ['Payment API', 'Mobile Money', 'Python']
5+
draft: false
6+
summary: 3 simple steps to integrate mobile money payment into your Python web application
7+
images: []
8+
layout: PostLayout
9+
canonicalUrl: mobile-money-integration-python-cameroon-2024
10+
authors: ['nab']
11+
---
12+
13+
This is a translation of an article I wrote in January 2024. In that article, i'm explaining [how to integrate Orange Money or MTN Momo in a python web application](https://peef.dev/post/nasser/comment-integrer-les-paiements-orange-money-ou-mtn-momo-au-cameroun-dans-son-application-avec-python-286).
14+
15+
Just for you to know, i wrote that article because i wanted to share with every developer in Cameroon, the steps i did follow to integrate a mobile money payment provider to my [marketplace](https://peef.dev). I found that platform really simple, so, let's get started.
16+
17+
[Notchpay](https://notchpay.co/) offers you a way to integrate payment methods into your application and supports card and mobile money payments.
18+
19+
The integration is simple:
20+
21+
First, create an account on [Notchpay](https://business.notchpay.co/). Your account gives you access to a sandbox that allows you to test the API. In the **settings** (Settings > Developer), you'll find your **API key** (PUBLIC_KEY) that you'll use for authentication in your application.
22+
23+
## Initiating payment
24+
25+
The [documentation](https://developer.notchpay.co/) already describe all the endpoints you can use, particularly in the [API reference](https://developer.notchpay.co/api/tag/payment) section.
26+
27+
In our case, we will use [Flask](https://pypi.org/project/Flask/) to build the controllers and the [Requests](https://pypi.org/project/requests/) library to make requests to Notchpay.
28+
29+
Let's first initialize the payment:
30+
31+
```python
32+
def initialize_payment(
33+
email, currency, amount, phone, reference, description, callback
34+
):
35+
headers = {"Authorization": PUBLIC_KEY, "Accept": "application/json"}
36+
url = "https://api.notchpay.co/payments/initialize"
37+
data = {
38+
"email": email,
39+
"currency": currency,
40+
"amount": amount,
41+
"phone": phone,
42+
"reference": reference,
43+
"description": description,
44+
"callback": callback,
45+
}
46+
47+
response = requests.post(url, headers=headers, data=data)
48+
49+
if response.ok:
50+
json_response = response.json()
51+
return json_response
52+
else:
53+
return {"status_code": response.status_code, "msg": response.text}
54+
```
55+
56+
In that function:
57+
58+
1. We define the necessary data for the payment as arguments, in the **data** variable,
59+
2. Then the **header** through which we execute our request. This header contains the API Key
60+
3. And we return a JSON response.
61+
62+
For more information on this payment initiation endpoint and the JSON response, just go to the documentation of that endpoint [/payments/initialize](https://developer.notchpay.co/api/tag/payment/post/payments)
63+
64+
Additionally, note that the callback will be a controller on your site that will be called after the payment. You can use it to implement payment verification.
65+
66+
- From there, we'll create our controllers: first a simple web page that displays a "Pay Now" link.
67+
- When this link is clicked, the **pay()** controller is called and will initiate the payment then will do a redirection to the Notchpay payment page:
68+
69+
```python
70+
return redirect(init_payment.get("authorization_url"))
71+
```
72+
73+
- At this point, the Notchpay page dedicated for the payment will be displayed
74+
- The user can then make his payment via credit card or mobile money phone number
75+
76+
```python
77+
HTML_PAGE = """
78+
<h1>Process payment</h1>
79+
<a href="/pay">Pay Now</a>
80+
"""
81+
82+
@app.route("/")
83+
def home():
84+
return HTML_PAGE
85+
86+
@app.route("/pay")
87+
def pay():
88+
payment_reference = uuid.uuid1()
89+
init_payment = initialize_payment(
90+
91+
currency="XAF",
92+
amount="1500",
93+
phone=None,
94+
reference=payment_reference,
95+
description=f"Payment description {payment_reference}",
96+
callback=f"http://localhost:5000/verify", # make sure to have the right host
97+
)
98+
return redirect(init_payment.get("authorization_url"))
99+
```
100+
101+
When the payment is made by the user, it must then be verified through the callback that was passed to the **initialize_payment()** function.
102+
103+
## Payment verification
104+
105+
Here is the verification function :
106+
107+
```python
108+
def verify_payment(reference):
109+
url = f"https://api.notchpay.co/payments/{reference}"
110+
headers = {"Authorization": PUBLIC_KEY}
111+
112+
response = requests.get(url, headers=headers)
113+
114+
if response.ok:
115+
json_response = response.json()
116+
logger.debug(json_response)
117+
return json_response
118+
else:
119+
return {"status_code": response.status_code, "msg": response.text}
120+
```
121+
122+
1. This function takes as parameter the payment reference which is passed in the callback via a **GET** method from Notchpay.
123+
2. We then construct the header through the URL [/payments/{reference}](https://developer.notchpay.co/reference/payments#verify-and-fetch-payment) for payment verification
124+
3. and return a JSON response
125+
126+
The callback will be the **verify()** controller which will extract the reference and pass this payment reference to the **verify_payment()** function
127+
128+
```python
129+
@app.route("/verify")
130+
def verify():
131+
reference = request.args.get("reference")
132+
return verify_payment(reference)
133+
```
134+
135+
From there, you can just retrieve the JSON response to continue your process based on the response (payment failure or success)
136+
137+
## Payment verification through a Webhook
138+
139+
If you want to verify payments in the background, you can set up a webhook in your backend like this:
140+
141+
```python
142+
@app.route("/webhook", methods=["POST"])
143+
def webhook():
144+
signature = request.headers.get("x-notch-signature")
145+
hash_value = hashlib.sha256(HASH_KEY).hexdigest()
146+
if hash_value == signature:
147+
try:
148+
json_data = request.get_json()
149+
logger.info("Webhook data:", json_data)
150+
return "", 200 # OK
151+
except Exception as e:
152+
logger.info("Error parsing JSON:", e)
153+
abort(400) # Bad request
154+
else:
155+
logger.info("Webhook request could not be verified.")
156+
abort(403) # Forbidden
157+
```
158+
159+
Notchpay will then send the response of each payment to your webhook and depending on the result, you can continue your process, such as validating an order for example.
160+
161+
If you're on localhost, you'll need to install [Ngrok](https://ngrok.com/) to make your URL public and go to the Notchpay administration interface to define your webhook with a key and your URL.
162+
163+
The key will be the one you will use as **HASH_KEY** to authenticate your server so that Notchpay recognizes your signature.
164+
165+
That's all for now.
166+
167+
You can find the complete code [here on GitHub](https://github.com/abdounasser202/just-for-fun/tree/main/notchpay)
168+
169+
If you have any questions, don't hesitate to ask in the OSS Telegram Channel.
170+
171+
Ciao !

0 commit comments

Comments
 (0)