If you are building a web application for the Bangladeshi market, integrating bKash is an absolute necessity. As the largest mobile financial service (MFS) in Bangladesh, bKash is the go-to payment method for millions of users.
However, integrating the bKash API using Python has historically been a headache. Developers often have to write boilerplate code, manually handle token expiration, and deal with raw HTTP requests. Whether you are using Django, Flask, or FastAPI, you just want a clean, Pythonic way to accept payments.
That’s where pybkash comes in. pybkash is a modern, fully-typed Python SDK for the bKash payment gateway that handles all the heavy lifting for you. It covers the entire bKash API surface and uniquely supports both synchronous (Django/Flask) and asynchronous (FastAPI) operations out of the box.
In this tutorial, we will walk through how to easily integrate the bKash payment gateway into your Python application using pybkash.
Prerequisites
Before we start writing code, you will need:
- Python 3.x installed on your system.
-
bKash Sandbox/Merchant Credentials: You need a
username,password,app_key, andapp_secret. You can get these by registering on the bKash Developer Portal.
Step 1: Installation
Installing the package is straightforward. Open your terminal and run:
pip install pybkash
Step 2: Authenticating with the bKash API
To communicate with bKash, you need to generate an authentication token. Traditionally, you would have to request a token and manage its lifecycle. With pybkash, you just pass your credentials into a Token object, and the Client handles the rest automatically.
from pybkash import Client, Token
# 1. Initialize the Token with your bKash credentials
token = Token(
username="your_username",
password="your_password",
app_key="your_app_key",
app_secret="your_app_secret",
sandbox=True # Important: Set to False when moving to production!
)
# 2. Create the bKash Client
client = Client(token)
Note: Always keep your credentials safe using environment variables (e.g., using python-dotenv). Never hardcode them in your production codebase!
Step 3: Creating a Payment (Redirecting the User)
The bKash checkout process follows a redirect-based flow: Create → Execute → Query. First, you create a payment intent on your server. bKash will return a secure URL. You then redirect your customer to this URL to enter their bKash number, OTP, and PIN.
Here is how you create that payment URL:
# 3. Create the payment intent
payment = client.create_payment(
callback_url="https://yoursite.com/api/bkash/callback", # Where bKash sends the user after paying
payer_reference="CUSTOMER_001", # Optional: Pre-populates the bKash number on the checkout page
amount=1000 # The amount to charge in BDT
)
print(f"Payment ID: {payment.payment_id}")
print(f"Redirect User To: {payment.bkash_url}")
What happens here?
-
payment.payment_id: Store this ID in your database. You will need it to verify the payment later. -
payment.bkash_url: Return this URL to your frontend or issue an HTTP redirect so the user can complete the payment.
Step 4: Handling the Callback & Executing the Payment
After the user completes, fails, or cancels the transaction on the bKash page, bKash redirects the user back to the base callback_url you provided in Step 3, appending several query parameters.
For example, a successful redirection looks like this:
https://yoursite.com/api/bkash/callback?paymentID=TR0011...&status=success&signature=...
These query parameters act as a signal indicating that the user has finished interacting with the bKash page.
⚠️ Crucial Security Warning: The callback redirection alone should not be treated as final confirmation of a successful transaction, as malicious users can manipulate URLs. You must execute the payment server-side to actually deduct the funds and securely verify the final state.
When the user hits your callback endpoint, extract the status and paymentID from the URL query parameters, and execute the payment:
# 4. Extract query parameters from your web framework's request object
status_from_url = "success" # Extracted from ?status=success
payment_id_from_url = "payment_id_received_from_query_params"
if status_from_url == "success":
# 5. Execute the payment server-side to finalize the transaction
execution = client.execute_payment(payment_id_from_url)
# 6. Verify if the execution was successful
if execution.is_complete():
print(f"Payment successful! Transaction ID (TrxID): {execution.trx_id}")
# TODO: Update your database, mark the order as paid, and send a receipt!
else:
print(f"Execution failed. Status: {execution.status}")
else:
print(f"User cancelled or failed the payment. Status: {status_from_url}")
And that's it! You've successfully integrated bKash into your Python application.
Bonus: Asynchronous Support for FastAPI Developers
If you are building a high-performance web API using FastAPI or Starlette, blocking synchronous calls can slow down your application. pybkash was built with modern Python in mind and provides first-class async support.
You can simply import the asynchronous client and await your payment methods for non-blocking I/O:
from pybkash import AsyncClient, Token
import asyncio
async def process_bkash_payment():
token = Token(
username="your_username",
password="your_password",
app_key="your_app_key",
app_secret="your_app_secret",
sandbox=True
)
# Initialize the Async client
async_client = AsyncClient(token)
# Create payment asynchronously
payment = await async_client.create_payment(
callback_url="https://yoursite.com/api/bkash/callback",
amount=500
)
print(f"Redirect to: {payment.bkash_url}")
# Run the async function
asyncio.run(process_bkash_payment())
Wrapping Up
Integrating the bKash payment gateway in Python doesn't have to be complicated. By using the pybkash SDK, you can implement secure, production-ready payment flows in just a few lines of code, whether you are using Django, Flask, or FastAPI.
Beyond basic payments, pybkash also supports advanced features like Agreement Creation (Tokenized Checkout), Refunds, and Transaction Searching.
📖 Dive Deeper into the Documentation
This tutorial covered the standard checkout flow, but there is much more! For an in-depth look at all available methods, return types, and operational rules, check out the Detailed Usage Documentation directly in the repository.
🌟 Call to Action
If this guide helped you save time, please consider dropping a star (⭐) on the pybkash GitHub Repository.
If you find any bugs, have feature requests, or want to contribute to making the best bKash Python SDK even better, feel free to open an issue or submit a pull request!
Happy coding! 🚀

Top comments (0)