Skip to main content

namibrapay (Python)

Official NamibraPay client for Python. Collections, payouts, verification, invoices and status — with zero dependencies.

  • Standard library only (urllib, hmac, json)
  • Sync client, Python 3.9+
  • PEP 561 typed (py.typed included)
  • Retries that never double-charge

Install

pip install namibrapay

Quick start

import os
from namibrapay import NamibraPay

client = NamibraPay(
    api_key=os.environ["NAMBRAPAY_API_KEY"],
    api_secret=os.environ["NAMBRAPAY_API_SECRET"],
)

tx = client.transactions.collect(
    amount=2500,  # GHS 25.00, in minor units
    channel="mtn_momo",
    payer_identifier="0244000000",
    reference="ORDER-1042",
)

print(tx["reference"], tx["status"])

Omit the credentials to read NAMBRAPAY_API_KEY and NAMBRAPAY_API_SECRET from the environment:

client = NamibraPay()

Python arguments are snake_case; the SDK maps them to the API's camelCase fields for you (payer_identifier → payerIdentifier).

Configuration

Option Default Notes
api_key / api_secret env vars Sent as X-API-Key / X-API-Secret
base_url https://api.namibrapay.com/api/v1 Must include the version segment
timeout 30.0 Per attempt, in seconds
max_retries 2 Applies only to retry-safe calls
headers None Extra headers on every request
transport urllib Advanced/testing hook

Resources

client.transactions.collect(amount=..., channel=..., payer_identifier=..., reference=..., idempotency_key=None)
client.transactions.initialize(amount=..., reference=...)
client.transactions.payout(amount=..., channel=..., recipient_account=..., recipient_bank=..., recipient_name=..., reference=...)
client.transactions.get(reference)
client.transactions.receipt(reference)
client.transactions.reverse(transaction_id, reason=..., amount=None)

client.checkout.retrieve(reference)
client.checkout.pay(reference, channel=..., payer_identifier=...)

client.payment_links.retrieve(slug)
client.payment_links.charge(slug, channel=..., payer_identifier=..., amount=None)

client.invoices.retrieve(code)
client.invoices.pay(code)

client.virtual_accounts.create(customer_name=..., customer_phone=..., ghana_card_number=...)
client.virtual_accounts.list()
client.virtual_accounts.sync_balance(account_id)

client.verification.banks()
client.verification.networks()
client.verification.resolve_account(bank_reference=..., account_number=..., amount=None)
client.verification.resolve_wallet(network=..., wallet_number=...)
client.verification.verify_id(id_type="ghanacard", id_number=...)
client.verification.confirm_payee(payee_type=..., expected_name=..., account_number=..., bank_reference=None, network=None)

client.status.snapshot()
client.status.incidents(page=None, limit=None)   # {"data": [...], "pagination": {...}}
client.status.feed()                             # RSS 2.0 as a string

client.health()

Every method returns the data object from the envelope directly — a dict, not a custom model, so new API fields arrive without an SDK release.

Money amounts

Amounts are integers in minor units (pesewas) and must be whole cedis: GHS 10.00 → 1000. Collections have a minimum of 100, payouts 1000. The SDK raises NamibraPayError before any request is made when the value is invalid.

Errors

from namibrapay import NamibraPayAPIError, NamibraPayConnectionError, NamibraPayError

try:
    client.transactions.payout(...)
except NamibraPayAPIError as error:
    if error.code == "BIZ_009":
        ...  # insufficient balance, etc.
    print(error.status_code, error.errors)
except NamibraPayConnectionError as error:
    print("network failed", error.cause)

NamibraPayAPIError exposes status_code, code, errors, body, retry_after_seconds and is_retryable.

Retries and idempotency

The SDK retries 408, 429, 500, 502, 503 and 504 with backoff and honours Retry-After.

Call Retried? Why
GET (get, receipt, status, …) Yes Reads are safe to repeat
collect, initialize, payout Yes The API deduplicates on reference
Any call with idempotency_key Yes The key makes the retry safe
reverse, checkout.pay, payment_links.charge, invoices.pay, virtual_accounts.create No A retry would create a second money movement

Webhooks

from flask import Flask, request, abort
from namibrapay.webhooks import construct_webhook_event, WebhookSignatureError

app = Flask(__name__)

@app.post("/webhooks/namibrapay")
def receive():
    try:
        event = construct_webhook_event(
            request.get_data(),  # raw bytes, not request.json
            request.headers.get("X-Webhook-Signature", ""),
            app.config["NAMBRAPAY_WEBHOOK_SECRET"],
        )
    except WebhookSignatureError:
        abort(401)

    # Acknowledge fast; do the work out of band.
    return "", 200

verify_webhook_signature and compute_webhook_signature are available if you prefer to handle the details yourself. Comparison is constant-time.

Async

This release is synchronous. Inside async frameworks (FastAPI, Starlette, aiohttp) run calls in a worker thread so the event loop stays free:

from starlette.concurrency import run_in_threadpool

tx = await run_in_threadpool(client.transactions.get, "ORDER-1042")

Versioning

The package follows semver. Additions are minor, breaking changes are major. namibrapay.__version__ matches pyproject.toml.

License

MIT

Metadata

Release files for namibrapay 0.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 namibrapay 0.1.0
File Size Uploaded Provenance Actions
namibrapay-0.1.0.tar.gz 21.6 kB Without provenance Details for namibrapay-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for namibrapay 0.1.0
File Interpreter ABI Platform Actions
namibrapay-0.1.0-py3-none-any.whl Python 3 none any Details for namibrapay-0.1.0-py3-none-any.whl

Total release size: 41.8 kB

Release files / namibrapay-0.1.0.tar.gz

Download URL namibrapay-0.1.0.tar.gz
Size 21.6 kB
Tags Source
SHA-256 checksum
How to use checksums
9e9a5071efa6ebff163ba0f70ae0e357a06d1fc2e2f931747a4787f59628bf02
BLAKE2b-256 checksum
How to use checksums
a3d2260dcefff57eca20b60d02dbe39ae1fc65e6a2b196b31696ca6a28b8b5c1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.5

Release files / namibrapay-0.1.0-py3-none-any.whl

Download URL namibrapay-0.1.0-py3-none-any.whl
Size 20.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
455b6d39131e4f406afc6694db0229093f127d639163af2118b1f603af8f7c74
BLAKE2b-256 checksum
How to use checksums
113178ca2dd1722106f09bb609d8499eb37c623c2f334dde70c9cdc80e8dc516
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.5

Security for namibrapay 0.1.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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