Table of contents
Zenopay is the payment Service provider in Tanzania that focuses on easy of integration and getting a very minimal collection account ready for use in just few steps. All you have to do just open an account at the platform. With this simplicity, the platform aims to empower developers building local solutions that have to handle payment collection.
The provider currently supports Mobile Payment [of which majority product/solutions in Tanzania base on] with recent realise of Card Payment
I have happened to work on 2-3 projects that had zenopay API integration as the way to collect funds from customers, at first it was fine just dig into their example code then work it on my end. But with 2-3 projects the game started being copy-paste the payment initialiser from project X to project Y.
This lead to the WHY not have a simple package for the community, zenopay
. Lets explore how to use the package to get your solution out to serve your customers.
Getting Started
You will have to open Zenopay
account, from which you will have to request for API credentials. You will be provided with account_id, secret_key and api_key. With creds in hand. lets get into building part of it. It is a straight forward integration.
Installation
Before installation, I assume you already working on the project with virtual environment. If not please read on the how to create virtual environment. Then activate the environment » Install the package.
pip install zenopay #Your system might require the use of pip3, you can adjust that.
Usage
The features currently supported by the official API are mobile, card payment and status check. So lets explore how to use the features.
This assumes that you keep your credentials in a .env file. You can also set the environment variables directly, not good practice though. Lets create an instance of the Zenopay class that will be used to interact with the API [It will be reused in the examples below].
import os
from dotenv import load_dotenv
from zenopay import ZenoPay
load_dotenv()
zenopay_client=ZenoPay(account_id=os.getenv('ZENOPAY_ACCOUNT_ID'))
Payment
With payment, here is how it works just initiate payment request to Zenopay API, then get response according to type of transaction. You can set a url to which the success payment details will be forwarded to, simply put you will receive payment callback. With callback data you can update details on your system to perform some automation.
All payment integrations require you to obtain API Key and Secret Key.
Its recommended to set up a webhook url, so that you can receive updates on successful transaction. Make sure your webhook is live and accepts a POST request, as the request will be relayed only once so in case of missed processing, your customers might have a worst service experience.
You can pass optional metadata, that can be used to verify transaction details on your receiving end, but keeping the details small to reduce the amount of details to be exchanged, just a reasonable amount of data..
Let set keys first before preparing data and initiating the payment request.
zenopay_client.api_key=os.getenv('ZENOPAY_API_KEY')
zenopay_client.secret_key=os.getenv('ZENOPAY_SECRET_KEY')
Mobile Payment [USSD payment]
This is super straight forward you will need few mandatory fields as will be shown in the example below.
# Data to be sent to Zenopay data = { "buyer_name": "jovine me", "buyer_phone": "0718190000", "buyer_email": "jovinerobotics@gmail.com", "amount": 1500, "webhook_url": "https://jovine.me/zenopay/webhook", "metadata": { "products": [1, 3], "customer_id": 1 } } # Initiate a mobile checkout checkout=zenopay_client.mobile_checkout(data) # Print the response print(checkout) # {'status': 'success', 'message': 'Wallet payment successful', 'order_id': '6777ad7e327xxx'} # Keep order_id to keep so that you can verify payment when callback is sent to the webhook...
Almost instantly the phone number will receive a prompt to make payment for the service.
Card payment
With card support, developer are empowered to collect payment via Card as solution grow to online payers.
The payload that you send is almost similar to the USSD with about two optional fields. On triggering card payment, a payment link will be generated to a secure payment site. You will have to render that to the user for payment to go through.
You are presented with options to set pages that will be rendered when payment is SUCCESSFUL or CANCELLED. These two links should be simply pages that will be rendered to the customer.
Setting a not working link, will hurt your customer ending up with disappointed customers.
{ "buyer_name": "jovine me", "buyer_phone": "0718190000", "buyer_email": "jovinerobotics@gmail.com", "amount": 1000, "webhook_url": "https://jovine.me/api/zenopay/webhook", "billling_country": "TZ", "redirect_url": "https://jovine.me/web/zenopay/redirect", "metadata": { "products": [1, 3], "customer_id": 1 } } # Initiate a card checkout checkout=zenopay_client.card_checkout(data) # Print the response print(checkout) #{'status': 'success', 'message': 'Order created successfully', 'order_id': '6777ad7e327xxx', 'payment_link': 'https://secure.payment.tz/link'}
Callback/Webhook
As discussed above, you can set webhook to receive updates when payment is made. This is what bring the power of automation to the projects. You simply need to receive updates, validate them then booomm,
I will illustrate with a simple.
from fastapi import FastAPI, Request from fastapi.responses import JSONResponse app = FastAPI() @app.post("/zenopay/webhook") async def webhook(request: Request): data = await request.json() # Validate the data print(data) # Perform any action here but in case its a long running task, you better perform it as background task. return JSONResponse(content={"status":"success"})
Payment status check
Remember in each trigger of payment request, you are given order_id, now its time to use it to manually check status of payment. You can use the status check API to validate payment in case one provides you with payment order id.
status=zenopay_client.check_order_status(order_id="xxxxx") # Print the response print(status) #{"status": "success","order_id": "6777ad7e327xxx","message": "Order status updated","payment_status": "PENDING"}
Wrap up
I hope this has been a bit of comprehensive guide to get you shipping that project that you have been hesitant because of payment collection issue.
Zenopay community of developers has support of other languages,
Go Lang
Many others at Official Zenopay account.
In case of any issue with the package, please visit the package repo at zenopay. Lets connect Twitter(X)