Skip to content

Commit acea103

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

File tree

1 file changed

+169
-0
lines changed

1 file changed

+169
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
---
2+
title: A simple step-by-step guide to integrate mobile money payments for your python web application in Cameroun (2024)
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. 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. I found that platform really simple, so, let's get started.
14+
15+
[Notchpay](https://notchpay.co/) offers you a way to integrate payment methods into your application and supports card and mobile money payments.
16+
17+
The integration is simple:
18+
19+
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.
20+
21+
## Initiating payment
22+
23+
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.
24+
25+
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.
26+
27+
Let's first initialize the payment:
28+
29+
```python
30+
def initialize_payment(
31+
email, currency, amount, phone, reference, description, callback
32+
):
33+
headers = {"Authorization": PUBLIC_KEY, "Accept": "application/json"}
34+
url = "https://api.notchpay.co/payments/initialize"
35+
data = {
36+
"email": email,
37+
"currency": currency,
38+
"amount": amount,
39+
"phone": phone,
40+
"reference": reference,
41+
"description": description,
42+
"callback": callback,
43+
}
44+
45+
response = requests.post(url, headers=headers, data=data)
46+
47+
if response.ok:
48+
json_response = response.json()
49+
return json_response
50+
else:
51+
return {"status_code": response.status_code, "msg": response.text}
52+
```
53+
54+
In that function:
55+
56+
1. We define the necessary data for the payment as arguments, in the **data** variable,
57+
2. Then the **header** through which we execute our request. This header contains the API Key
58+
3. And we return a JSON response.
59+
60+
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)
61+
62+
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.
63+
64+
- From there, we'll create our controllers: first a simple web page that displays a "Pay Now" link.
65+
- 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:
66+
67+
```python
68+
return redirect(init_payment.get("authorization_url"))
69+
```
70+
71+
- At this point, the Notchpay page dedicated for the payment will be displayed
72+
- The user can then make his payment via credit card or mobile money phone number
73+
74+
```python
75+
HTML_PAGE = """
76+
<h1>Process payment</h1>
77+
<a href="/pay">Pay Now</a>
78+
"""
79+
80+
@app.route("/")
81+
def home():
82+
return HTML_PAGE
83+
84+
@app.route("/pay")
85+
def pay():
86+
payment_reference = uuid.uuid1()
87+
init_payment = initialize_payment(
88+
89+
currency="XAF",
90+
amount="1500",
91+
phone=None,
92+
reference=payment_reference,
93+
description=f"Payment description {payment_reference}",
94+
callback=f"http://localhost:5000/verify", # make sure to have the right host
95+
)
96+
return redirect(init_payment.get("authorization_url"))
97+
```
98+
99+
When the payment is made by the user, it must then be verified through the callback that was passed to the **initialize_payment()** function.
100+
101+
## Payment verification
102+
103+
Here is the verification function :
104+
105+
```python
106+
def verify_payment(reference):
107+
url = f"https://api.notchpay.co/payments/{reference}"
108+
headers = {"Authorization": PUBLIC_KEY}
109+
110+
response = requests.get(url, headers=headers)
111+
112+
if response.ok:
113+
json_response = response.json()
114+
logger.debug(json_response)
115+
return json_response
116+
else:
117+
return {"status_code": response.status_code, "msg": response.text}
118+
```
119+
120+
1. This function takes as parameter the payment reference which is passed in the callback via a **GET** method from Notchpay.
121+
2. We then construct the header through the URL [/payments/{reference}](https://developer.notchpay.co/reference/payments#verify-and-fetch-payment) for payment verification
122+
3. and return a JSON response
123+
124+
The callback will be the **verify()** controller which will extract the reference and pass this payment reference to the **verify_payment()** function
125+
126+
```python
127+
@app.route("/verify")
128+
def verify():
129+
reference = request.args.get("reference")
130+
return verify_payment(reference)
131+
```
132+
133+
From there, you can just retrieve the JSON response to continue your process based on the response (payment failure or success)
134+
135+
## Payment verification through a Webhook
136+
137+
If you want to verify payments in the background, you can set up a webhook in your backend like this:
138+
139+
```python
140+
@app.route("/webhook", methods=["POST"])
141+
def webhook():
142+
signature = request.headers.get("x-notch-signature")
143+
hash_value = hashlib.sha256(HASH_KEY).hexdigest()
144+
if hash_value == signature:
145+
try:
146+
json_data = request.get_json()
147+
logger.info("Webhook data:", json_data)
148+
return "", 200 # OK
149+
except Exception as e:
150+
logger.info("Error parsing JSON:", e)
151+
abort(400) # Bad request
152+
else:
153+
logger.info("Webhook request could not be verified.")
154+
abort(403) # Forbidden
155+
```
156+
157+
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.
158+
159+
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.
160+
161+
The key will be the one you will use as **HASH_KEY** to authenticate your server so that Notchpay recognizes your signature.
162+
163+
That's all for now.
164+
165+
You can find the complete code [here on GitHub](https://github.com/abdounasser202/just-for-fun/tree/main/notchpay)
166+
167+
If you have any questions, don't hesitate to ask in the OSS Telegram Channel.
168+
169+
Ciao !

0 commit comments

Comments
 (0)