Skip to main content

daraja-mock

A small local test double for the Safaricom M-Pesa Daraja API, built on Flask. It lets you exercise OAuth and STK Push flows (and the request shapes of a few other endpoints) without a Safaricom account, credentials or internet access.

CI Python License

What this is, and is not. A test double, not a simulator of Safaricom's behaviour, and not affiliated with Safaricom. Only the STK Push query result is configurable. B2C, Account Balance and Transaction Status always return an "accepted" response, and no asynchronous result callbacks are sent. See Limits.

Install

pip install daraja-mock    # installs Flask

Quickstart

import requests
from daraja_mock import DarajaMock

mock = DarajaMock()
base_url = mock.run_thread(port=18080)      # non-blocking; returns "http://127.0.0.1:18080"

token = requests.get(f"{base_url}/oauth/v1/generate").json()["access_token"]
headers = {"Authorization": f"Bearer {token}"}

push = requests.post(
    f"{base_url}/mpesa/stkpush/v1/processrequest", headers=headers,
    json={"BusinessShortCode": "174379", "Amount": 100, "PhoneNumber": "254712345678",
          "CallBackURL": "https://example.com/callback", "AccountReference": "Order001", "TransactionDesc": "Payment"},
).json()
assert push["ResponseCode"] == "0"

mock.set_stk_result(1032)                   # STK queries now report "cancelled by user"
status = requests.post(f"{base_url}/mpesa/stkpushquery/v1/query", headers=headers,
                       json={"CheckoutRequestID": push["CheckoutRequestID"]}).json()
assert status["ResultCode"] == "1032"

Configuration

Method Effect
set_stk_result(code) The ResultCode returned by every STK Push query. Described codes: 0 success, 1 insufficient balance, 1001 and 2001 invalid initiator, 1032 cancelled by user, 1037 timeout. Any other code is returned as Error <code>.
reset() Restore defaults and clear the request log.
request_log() List of recorded requests, each a dict with method, path, body and ts.
set_b2c_result(...), set_balance(...) No effect yet (they warn). The B2C and balance endpoints always accept.

The STK query endpoint returns the configured ResultCode for any CheckoutRequestID; it does not look the id up, and it returns a fresh random CheckoutRequestID of its own.

Endpoints

Endpoint Method Behaviour
/oauth/v1/generate GET Returns access_token and expires_in; credentials are not checked.
/mpesa/stkpush/v1/processrequest POST Accepts the request; ResponseCode is "0".
/mpesa/stkpushquery/v1/query POST Returns the configured ResultCode.
/mpesa/b2c/v3/paymentrequest POST Always accepted.
/mpesa/transactionstatus/v1/query POST Always accepted.
/mpesa/accountbalance/v1/query POST Always accepted.
/mock/balance-callback POST Receives a balance result if you use it as your callback URL.
/health GET {"status": "ok", "version": ...}

Standalone server

python -m daraja_mock                 # http://127.0.0.1:8765
python -m daraja_mock --port 9000
daraja-mock --port 9000               # the same, as an installed command

Use with pesa-cli

pesa-cli 1.0.1 and later reads PESA_BASE_URL, so its commands can run against this server:

python -m daraja_mock --port 8765 &
export PESA_BASE_URL=http://127.0.0.1:8765
pesa auth && pesa stk push 0712345678 100

mpesa-python does not currently accept a custom base URL, so it cannot be pointed at this server yet.

Limits

  • Credentials, shortcodes, passkeys and callback URLs are not validated.
  • No asynchronous result or callback delivery: STK, B2C and balance results that real Daraja posts to your URLs are not sent.
  • STK query is stateless (see above). No C2B URL registration endpoint.
  • It runs on Flask's development server, in a daemon thread for run_thread, in one process.

Tests

pip install -e ".[dev]" && python -m pytest

The tests also fail if this README names a class, method or endpoint that does not exist, and they run the Quickstart above.

Part of the nairobi-stack East Africa engineering ecosystem. Maintained by Gabriel Mahia. Kenya × USA.

Metadata

Release files for daraja-mock 1.0.4

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

Source distribution (sdist)

Source distribution for daraja-mock 1.0.4
File Size Uploaded
daraja_mock-1.0.4.tar.gz 9.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for daraja-mock 1.0.4
File Interpreter ABI Platform
daraja_mock-1.0.4-py3-none-any.whl Python 3 none any Details

Total release size: 17.3 kB

Release files / daraja_mock-1.0.4.tar.gz

Download URL daraja_mock-1.0.4.tar.gz
Size 9.5 kB
Tags Source
SHA-256 checksum
How to use checksums
42776866b79a6a428ad4431b374a92b43a5613e8e4e169f30443b2090e7a9024
BLAKE2b-256 checksum
How to use checksums
249c8a0dda0f6a597827c5bd6ea8aaf86a75cff85a039e252ffebf57b682be5e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release files / daraja_mock-1.0.4-py3-none-any.whl

Download URL daraja_mock-1.0.4-py3-none-any.whl
Size 7.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
40820249ec637fca89f5cad3e9d2fe368ad0c1a1b41daa6cb6496a561afd9062
BLAKE2b-256 checksum
How to use checksums
1dcd7bd94bc954f6e123baaa049033526e2eb97d459003171914d6aef3b8816a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.4 This release

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