Skip to main content

HostPay Python SDK

A small, typed client for the HostPay payments API — wallets, deposits, transfers, payouts, escrow, transaction queries, user/wallet lifecycle management, and webhook verification. Ships both a sync (HostPay) and an async (AsyncHostPay) client.

Install

pip install hostpay

Requires Python 3.8+ and httpx.

Quickstart

from hostpay import HostPay

client = HostPay(api_key="ak-...", secret_key="sk-...")
# Test Mode? use your test keys — same code, no real money moves.

# 1. Create a user and their wallet
user = client.users.create(
    app_user_id="user_123",
    name="Alice",
    phone_number="+23279000000",
    email="alice@example.com",
)
wallet = client.wallets.create(user.id)

# 2. Deposit via mobile money
deposit = client.deposits.mobile_money(wallet_id=wallet.id, amount=100)

# 3. Check the balance (attribute or dict access)
bal = client.wallets.balance(wallet.id)
print(bal.balance, bal["currency"])

# 4. Transfer, pay out, escrow
client.transfers.create(sender_wallet_id=wallet.id, recipient_identifier="bob", amount=20)
client.payouts.mobile_money(wallet_id=wallet.id, amount=5, phone_number="+23279000000")
hold = client.escrow.hold(wallet_id=wallet.id, amount=10)
client.escrow.release(hold.id, recipient_wallet_id="...")

Async

AsyncHostPay exposes the exact same surface — every method awaited, built on httpx.AsyncClient. Use it from FastAPI, aiohttp, or any asyncio app:

from hostpay import AsyncHostPay

async with AsyncHostPay(api_key="ak-...", secret_key="sk-...") as client:
    user = await client.users.create(
        app_user_id="user_123", name="Alice", phone_number="+23279000000"
    )
    wallet = await client.wallets.create(user.id)
    await client.deposits.mobile_money(wallet_id=wallet.id, amount=100)

Outside a context manager, call await client.aclose() when done. Webhook verification (client.webhooks.construct_event) is pure crypto with no I/O, so it stays a plain synchronous call on both clients.

Authentication

Pass your api-key and secret-key once at construction; they're sent on every request. base_url defaults to production — point it at your staging host for testing.

Idempotency

Money-moving calls accept idempotency_key — reuse the same key to safely retry without double-charging:

client.payouts.mobile_money(
    wallet_id=w, amount=5, phone_number="+232...", idempotency_key="order-42-payout"
)

Fees, subscriptions, sync & test helpers

  • client.fees — summary(), configuration(), estimate_deposit(), estimate_withdrawal(), estimate_transfer(), estimate_card_metadata()
  • client.webhooks.subscriptions — create(), list(), update(), delete(), rotate_secret(); the create/rotate response includes the signing secret once
  • client.transactions.sync(reference_id) — instant post-payment reconciliation
  • client.testing.simulate_monime_webhook(transaction_id, status=...) — complete or fail a pending Test Mode deposit (test keys only)
  • client.connect — Stripe Connect onboarding for payout accounts: complete_onboarding() (requires the end customer's IP for Stripe TOS acceptance), upload_verification_document() (JPEG/PNG/PDF ≤ 10 MB), status(), delete()
  • client.users.patch(user_id, ...) — partial update; only the fields you pass change
  • HostPay(..., app_info="YourApp/1.0") — identify your platform; appended to the User-Agent

All of these exist on AsyncHostPay too.

Verifying webhooks

Pass the raw request body and headers straight from your web framework:

from hostpay import HostPay, SignatureVerificationError

client = HostPay(api_key="ak-...", secret_key="sk-...")

# e.g. in Flask
@app.post("/webhooks/hostpay")
def hook():
    try:
        event = client.webhooks.construct_event(
            payload=request.get_data(),          # raw bytes, not request.json
            headers=request.headers,
            secret=WEBHOOK_SIGNING_SECRET,
        )
    except SignatureVerificationError:
        return "", 400
    if event.event == "deposit.completed":
        ...
    return "", 200

Signatures are HMAC-SHA256 over "<timestamp>.<body>"; deliveries older than tolerance seconds (default 300) are rejected.

Errors

All errors derive from HostPayError and carry .status_code and .detail: AuthenticationError (401/403), InvalidRequestError (400/404/422), RateLimitError (429), APIError (5xx), APIConnectionError, SignatureVerificationError.

Sandbox testing

In Test Mode, a user's phone number drives deterministic outcomes (see the Testing guide): +23299000001 completes, +23299000002 fails, +23299000009 stays pending. The same fail number works for payout recipients.

Typed responses

Core methods are annotated with TypedDict models (hostpay.models): users.* return UserRead, wallets.create/get return WalletRead, transfers/ payouts return TransactionResponse, and escrow.* returns EscrowResponse. A type checker (mypy/Pyright) will autocomplete and check keyed access — user["id"], wallet["balance"]. Ad-hoc responses (wallet balance, the deposit envelope) stay loosely typed.

At runtime every response is a HostPayObject (a dict), so both resp["field"] and resp.field work regardless of typing. The model fields mirror the committed ../openapi.json, the source of truth for both SDKs — regenerate the spec with python wallet-system/scripts/dump_openapi.py.

Metadata

Release files for hostpay 0.5.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 hostpay 0.5.0
File Size Uploaded Provenance Actions
hostpay-0.5.0.tar.gz 17.7 kB With provenance Details for hostpay-0.5.0.tar.gz

Built distribution (wheel)

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

Total release size: 35.4 kB

Release files / hostpay-0.5.0.tar.gz

Download URL hostpay-0.5.0.tar.gz
Size 17.7 kB
Tags Source
SHA-256 checksum
How to use checksums
8626ad8e08c8278060e488787153afd9c37633f550a230ba0cbd2e3d4afd9e9d
BLAKE2b-256 checksum
How to use checksums
d49c559d96b8d3927e25cb09a05977dda46ca6da842b74b576d99eb32bfab5c7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jul 5, 2026.

Transparency log

Release files / hostpay-0.5.0-py3-none-any.whl

Download URL hostpay-0.5.0-py3-none-any.whl
Size 17.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5a1db7812d12ca86f0d32fcf8fb1c9c8257cc5976765786c207f3ad6aeee90f1
BLAKE2b-256 checksum
How to use checksums
2ea740229f27d53eb7fda647457b6149cb2924f4a41cf793bc0e7fd70d3fe34c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jul 5, 2026.

Transparency log

Security for hostpay 0.5.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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for hostpay-0.5.0.tar.gz

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 Jul 5, 2026.

Transparency log

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.

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