Skip to main content

Async client for bKash Tokenized Checkout (grant/refresh, create/execute, status, search, refund) and SNS IPN verification.

Project description

bkash-pgw-tokenized

PyPI version Python versions License

Async Python client for bKash Tokenized Checkout: grant and refresh tokens, create and execute payments, payment status, search transaction, refund, plus helpers for SNS-signed IPN payloads.

  • Install name (pip): bkash-pgw-tokenized
  • Import package: bkash_pgw_tokenized
  • Requires: Python 3.10+
  • bKash Tokenized API: v1.2.0-beta (default base URLs include /v1.2.0-beta; set base_url in config to target another version if needed)

Installation

pip install bkash-pgw-tokenized

Quick start

from bkash_pgw_tokenized import Bkash, MemoryTokenStore, ensure_id_token

config = {
    "app_key": "...",
    "app_secret": "...",
    "username": "...",
    "password": "...",
    "sandbox": True,  # False for live
}

client = Bkash(config)
store = MemoryTokenStore()

id_token = await ensure_id_token(store, client)

create = await client.create_payment(
    id_token,
    mode="0011",
    payer_reference="INV-001",
    callback_url="https://your.site/payments/bkash/callback",
    amount="100.00",
    currency="BDT",
    intent="sale",
    merchant_invoice_number="INV-001",
)
# create["bkashURL"], create["paymentID"], ...

exec_res = await client.execute_payment(id_token, create["paymentID"])
status = await client.payment_status(id_token, create["paymentID"])
found = await client.search_transaction(id_token, trx_id="...")
refund = await client.refund(
    id_token,
    payment_id="...",
    trx_id="...",
    amount="100.00",
    sku="sku-1",
    reason="Customer request",
)

Optional config keys: "sandbox" (defaults to True), "base_url" (overrides the default host for that mode).

On HTTP error responses, the client raises BkashHttpError with status_code and response_body.

Default API roots are BKASH_TOKENIZED_SANDBOX_BASE_URL and BKASH_TOKENIZED_LIVE_BASE_URL (exported from bkash_pgw_tokenized). For static typing of config, use BkashConfig (or BkashConfigRequired for only the four secret fields).

Authorization header: the raw id_token is sent as Authorization (no Bearer prefix), matching bKash’s tokenized API.

AsyncBkashClient is an alias for Bkash (backward-compatible name).

Status codes and outcomes (success, failure, cancel)

bKash surfaces outcomes in three places: the browser callback to your callbackURL, JSON from Execute / Payment status APIs, and IPN (SNS) payloads. They are not the same thing:

  • statusCode / 0000 on Create only means “create payment session succeeded” and you received bkashURL / paymentID. It does not mean the customer paid.
  • Whether the user finished, failed, or cancelled in the bKash UI is communicated on the callback via the status query parameter (and you need paymentID from that same redirect to call Execute).

1. Merchant callback URL (browser redirect)

After the customer acts in the bKash flow, bKash redirects their browser to the callbackURL you sent in Create payment. That request is a normal HTTP GET with query-string parameters appended (names are commonly camelCase such as paymentID; treat lookups case-insensitively if your framework allows duplicate casing).

Parameters you should handle (tokenized checkout):

Query parameter Typical presence Meaning
paymentID Expected The bKash payment id (same as in the Create response). Required to call execute_payment / payment_status.
status Expected This is where success vs failure vs cancel is indicated for the redirect. String value from bKash (see classification table below).
signature May be present Reserved for callback integrity verification against bKash’s rules. Your app should accept the parameter and verify it when your integration guide requires it.

bKash may add other query keys over time. During integration, log the full query string (or request.GET / request.query_params) in sandbox so you do not miss extra fields your account or API version sends.

How to decide failed vs cancelled vs successful (using only the callback):

Normalize: s = status.strip().lower() (after ensuring status is a non-empty string).

If s is in… Treat as Then
failure, fail, failed Failed Do not call Execute. Mark order unpaid / show error.
cancel, cancelled, canceled Cancelled Do not call Execute. Mark as user-cancelled (distinct from a hard failure if you want different UX).
exactly success (after normalize) Callback success Still not “paid” yet. Call await client.execute_payment(id_token, paymentID) and apply the JSON rules in section 2 (or payment_status if Execute is unclear).
anything else Unknown / unsafe Do not assume success. Treat like failure until you confirm with bKash docs or support for your environment.

If paymentID or status is missing, you cannot complete the flow safely; reject the request and do not Execute.

2. Execute and Payment status API JSON

After the callback indicates status=success, the source of truth for money movement is the Execute response (and optionally Payment status if Execute times out or returns an unusable body).

For Execute and Payment status, treat payment as completed only when all of the following hold (same rules many merchants use in production):

Field Success value
statusCode "0000"
statusMessage "Successful"
transactionStatus "Completed"

If statusCode is present and not "0000", or transactionStatus is present and not "Completed", treat as failure. Use errorCode / statusCode with describe_code from bkash_pgw_tokenized for human-readable messages:

from bkash_pgw_tokenized import describe_code, is_success_status_code

if is_success_status_code(response.get("statusCode")):
    ...
else:
    reason = describe_code(response.get("statusCode") or response.get("errorCode"))

Non-success responses often include statusMessage, errorMessage, or message; fall back to those for display.

3. Create payment response

Create is successful at the API level when statusCode == "0000". You still need bkashURL and paymentID in the payload to send the user to bKash. Any other statusCode means create failed; use describe_code and the message fields above.

4. IPN (SNS inner Message JSON)

For server-side notifications, use ipn_inner_is_success(inner) (see IPN (SNS)). In short:

  • If errorCode / error_code is set and non-empty → not success.
  • If statusCode / status_code is present → it must be "0000"; if transactionStatus / transaction_status is also present, it must be "Completed".
  • If statusCode is absent (some samples) → transactionStatus must be "Completed".

Reference

IPN (SNS)

Payload parsing and validation (imported from bkash_pgw_tokenized):

from bkash_pgw_tokenized import (
    amounts_match,
    extract_inner_from_sns_envelope,
    ipn_inner_is_success,
    verify_topic_arn,
)

if not verify_topic_arn(envelope, expected_topic_arn):
    ...
inner = extract_inner_from_sns_envelope(envelope)
ok, reason = ipn_inner_is_success(inner)

SNS signature verification (depends on cryptography, installed by default):

from bkash_pgw_tokenized.sns_verify import SnsVerificationError, verify_sns_signature

try:
    verify_sns_signature(envelope)
except SnsVerificationError:
    ...

Documentation

Official bKash developer documentation: developer.bka.sh (see also project URLs on PyPI).

Development

From a local clone of the source tree (repository root, where pyproject.toml lives):

pip install -e ".[dev]"
pytest

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bkash_pgw_tokenized-1.0.0.tar.gz (14.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bkash_pgw_tokenized-1.0.0-py3-none-any.whl (14.5 kB view details)

Uploaded Python 3

File details

Details for the file bkash_pgw_tokenized-1.0.0.tar.gz.

File metadata

  • Download URL: bkash_pgw_tokenized-1.0.0.tar.gz
  • Upload date:
  • Size: 14.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.16.5 cpython/3.12.13 HTTPX/0.28.1

File hashes

Hashes for bkash_pgw_tokenized-1.0.0.tar.gz
Algorithm Hash digest
SHA256 8f5cf2d5023689bf8aad7564cfc2172b875f4b5da09d17b8a4c862e6c119bc51
MD5 f2c07bb9ce952fe61d36d04cd8d1dac2
BLAKE2b-256 b95b5af207553e57e3130379a289babdfedb7262f1db5bf719809ccb6de80d52

See more details on using hashes here.

File details

Details for the file bkash_pgw_tokenized-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for bkash_pgw_tokenized-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c4c69fcd957685c18b5ddf64078cbfd3a0f608b07315235c2107182b4b54d08b
MD5 639391d52598181628028d4e3264743f
BLAKE2b-256 86c7b5c8ebe91c3988a22722945b853b7b1b98db605c0b070ec402d40a90d961

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page