Skip to main content

M-Pesa SDK

CI

mpesa-sdk is a synchronous Python client for Safaricom Daraja REST APIs. The distribution name used by pip is mpesa-sdk; its Python import package is mpesa_sdk.

Install

python -m pip install mpesa-sdk

For local development and tests:

python -m pip install 'mpesa-sdk[test]'

Supported API names

The client uses current Daraja API terminology for M-Pesa Express and Transaction Status:

Daraja capability SDK method
M-Pesa Express (STK Push) Mpesa.mpesa_express_payment(data)
M-Pesa Express query Mpesa.mpesa_express_query(data)
Transaction Status query Mpesa.transaction_status_request(data)
OAuth token oauth_generate_token(...)

Compatibility methods remain available for existing users:

  • lipa_na_mpesa_online_payment aliases mpesa_express_payment.
  • lipa_na_mpesa_online_query aliases mpesa_express_query.
  • The historical typo transation_status_request aliases transaction_status_request.

Successful requests return (response_json, http_status_code). Network failures, non-2xx responses, invalid JSON, and Daraja API rejections raise the documented MpesaError subclasses. Requests use a 10 second timeout by default; a different positive timeout can be supplied to Mpesa or the OAuth helper.

Configure a sandbox client

Keep the consumer key, consumer secret, passkey, and shortcode in a secret manager or environment variables. Do not put real credentials in source code, logs, or a client application.

import os

from mpesa_sdk import Mpesa, oauth_generate_token

token_response, _ = oauth_generate_token(
    os.environ["DARAJA_CONSUMER_KEY"],
    os.environ["DARAJA_CONSUMER_SECRET"],
    env="sandbox",
)
client = Mpesa(token_response["access_token"], env="sandbox")

The environment must be sandbox or production. For compatibility, test is an alias for sandbox, and prod is an alias for production. Unknown values raise MpesaConfigurationError; they never select production by default.

M-Pesa Express (STK Push)

The SDK sends the request; the integrating application creates the request data and handles asynchronous callbacks.

from mpesa_sdk import generate_mpesa_express_password, generate_timestamp

timestamp = generate_timestamp()
payload = {
    "BusinessShortCode": shortcode,
    "Password": generate_mpesa_express_password(shortcode, passkey, timestamp),
    "Timestamp": timestamp,
    "Amount": 10,
    "PartyA": "254700000000",
    "PartyB": shortcode,
    "PhoneNumber": "254700000000",
    "CallBackURL": "https://example.invalid/daraja/stk/callback",
    "AccountReference": "INV-1001",
    "TransactionDesc": "Invoice payment",
}
response, status_code = client.mpesa_express_payment(payload)

generate_timestamp() returns the Daraja timestamp in East Africa Time. generate_mpesa_express_password() Base64-encodes the shortcode, passkey, and timestamp combination used by M-Pesa Express. The former encode_password() name remains available as a compatibility alias.

Transaction Status

Transaction Status is asynchronous. The immediate response acknowledges query submission; the eventual transaction result is delivered separately to the configured ResultURL. Provide exactly one of TransactionID (M-Pesa receipt) or OriginalConversationID.

acknowledgement, status_code = client.transaction_status_request(
    {
        "Initiator": os.environ["DARAJA_INITIATOR"],
        "SecurityCredential": os.environ["DARAJA_SECURITY_CREDENTIAL"],
        "TransactionID": "RECEIPT123",
        "PartyA": shortcode,
        "IdentifierType": "4",
        "ResultURL": "https://example.invalid/daraja/status/result",
        "QueueTimeOutURL": "https://example.invalid/daraja/status/timeout",
        "Remarks": "Reconcile invoice payment",
    }
)

The default IdentifierType is 4, the organization shortcode type used by the Daraja Transaction Status API. Set it explicitly if the transaction requires a different party type.

Errors

  • MpesaConfigurationError: invalid client configuration or missing request values.
  • MpesaTransportError: connection or timeout failure.
  • MpesaRequestError: non-success HTTP response; status_code is available.
  • MpesaAPIError: Daraja returned an API-level rejection; code is available.
  • MpesaResponseError: the response was not a JSON object.

The SDK does not validate callback authenticity, correlate callbacks with business records, or decide whether to create a ledger payment. Applications must validate and deduplicate callbacks, correlate them with the original attempt, and use an authoritative reconciliation result before recording payments. Never treat an accepted request or customer prompt as proof that funds were received.

Development

The test suite mocks HTTP and never contacts Safaricom or requires credentials.

python -m pip install -e '.[test]'
python -m pytest
ruff check .
ruff format --check .

Releases

Merging changes to master runs CI first. If CI passes, Python Semantic Release reads Conventional Commit messages to decide whether to make a release, updates the project version and changelog, creates a GitHub release, and publishes the package to PyPI. Use feat: for new features, fix: for bug fixes, and ! or a BREAKING CHANGE: footer for breaking changes. Prefix non-release changes with types such as docs:, chore:, or test:.

License

MIT

Metadata

Release files for mpesa-sdk 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mpesa-sdk 1.1.0
File Size Uploaded
mpesa_sdk-1.1.0.tar.gz 13.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mpesa-sdk 1.1.0
File Interpreter ABI Platform
mpesa_sdk-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 22.9 kB

Release files / mpesa_sdk-1.1.0.tar.gz

Download URL mpesa_sdk-1.1.0.tar.gz
Size 13.1 kB
Tags Source
SHA-256 checksum
How to use checksums
47fd6e7eb5efdd5b9043d94a05949b5f3c7e07806b2005e552a1e051c6f6a5b4
BLAKE2b-256 checksum
How to use checksums
36b88d7445c0e8f766af2d2e7b73936fd3450558fbb940f6020465eeefd73d05
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / mpesa_sdk-1.1.0-py3-none-any.whl

Download URL mpesa_sdk-1.1.0-py3-none-any.whl
Size 9.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4a13bec7e6c738863a3b5ed046aa82cee41c8dddc90f3d705917af91547f2710
BLAKE2b-256 checksum
How to use checksums
f14ad2a273b95201da04a11e9a3febe00e613ac2f723bc8ab57afc0f83dc7eac
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

2.0.0

2 release files

1.2.0

2 release files

This release

1.1.0 This release

2 release files

1.0.7

2 release files

1.0.6

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page