Skip to main content

manza

Python SDK for the Manza API.

Install

pip install manza

Requires Python 3.11+.

Quick start

from manza import Manza

client = Manza(api_key="sk_live_...")

client.entity.get()
client.accounts.list(currency_code="MAD")
client.customers.list(q="Acme")
client.customers.create(
    customer_type="business",
    company_name="Acme Corp",
    email="billing@acme.com",
)

client.invoices.list()
client.payment_links.cancel(payment_link_id)
client.webhook_endpoints.list()

client.checkout_sessions.create(
    account_id=account_id,
    amount="100.00",
    success_url="https://example.com/ok",
    cancel_url="https://example.com/cancel",
)
client.checkout_sessions.get(session_id)

The client picks up MANZA_API_KEY, MANZA_BASE_URL, MANZA_API_VERSION, and MANZA_TIMEOUT from the environment if you don't pass them. The old ZAZU_* names still work for all of 1.x and emit a one-time FutureWarning.

Hosts

The default base URL is https://ma.manza.finance (Morocco). For South Africa:

client = Manza(api_key="sk_live_...", base_url="https://za.manza.finance")

The replay tests run against the staging host https://ma.manza.dev.

Beneficiaries and trusted payees

beneficiary = client.beneficiaries.create(
    beneficiary_type="business",  # "individual" | "business"
    company_name="Acme Corp",
    email="ap@acme.com",
).body

account = client.beneficiaries.create_external_account(
    beneficiary["id"], account_number="..."  # bank_identifier is required in ZA only
).body
client.beneficiaries.list_external_accounts(beneficiary["id"])  # Page
client.beneficiaries.get_external_account(beneficiary["id"], account["id"])

# Ask for the account to be trusted; a member approves it in the app.
request = client.payee_trust_requests.create([account["id"]]).body
client.payee_trust_requests.get(request["id"])

Transfers and machine authorization

draft = client.transfer_drafts.create(
    account_id=account_id,
    beneficiary_id=beneficiary_id,
    amount="150.00",
    client_reference="po_1",  # unique per entity, at most 128 characters
).body

A duplicate client_reference raises ManzaConflictError with payment_id naming the existing draft. A draft inside the entity's machine-authorization envelope is sent to the enrolled authorizer as a payment.authorization_requested webhook. Answer it with a different API key holding transfers:authorize, signing with manza.transfer_authorization:

from manza import transfer_authorization as ta

signature_input = ta.signature_input(
    payment_id=draft["id"],
    nonce=nonce,  # from the webhook
    amount=draft["amount"],  # the API's decimal string, verbatim
    currency_code=draft["currency_code"],
    account_id=draft["account_id"],
    payee=ta.payee_for(external_account_id=draft["external_account_id"]),
    client_reference=draft["client_reference"],
)
signature = ta.sign(signing_secret, signature_input)  # lowercase hex HMAC-SHA256

authorizer.transfer_drafts.authorize(draft["id"], authorization_id, signature)
# or: authorizer.transfer_drafts.decline(draft["id"], authorization_id, "reason")

payee_for takes exactly one of external_account_id / destination_account_id. A blank signature raises ManzaArgumentError before any request is made.

Pagination

List endpoints return a Page. Iterate one page or chase cursors:

page = client.invoices.list(limit=25)
for invoice in page:
    ...

# All items, automatic cursor chasing:
for invoice in client.invoices.list().auto_paging_iter():
    ...

Errors

Ten concrete subclasses; discriminate with isinstance. ManzaValidationError covers 400 and 422, ManzaConflictError covers 409 and exposes payment_id:

from manza import (
    ManzaValidationError,
    ManzaRateLimitError,
    ManzaNotFoundError,
)

try:
    client.invoices.get("nope")
except ManzaNotFoundError as err:
    print(err.status, err.request_id, err.body)
except ManzaRateLimitError as err:
    print("retry after", err.retry_after, "seconds")

Cross-SDK contract

manza is one of several Manza SDKs that all replay cassettes recorded by the canonical manza-ruby SDK against staging (ma.manza.dev). The wire format is snake_case JSON; request and response shapes match across Ruby, TypeScript, Python, Go, and Rust.

License

MIT.

Metadata

Release files for manza 1.0.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 manza 1.0.0
File Size Uploaded
manza-1.0.0.tar.gz 14.4 kB Details

Built distribution (wheel)

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

Total release size: 34.7 kB

Release files / manza-1.0.0.tar.gz

Download URL manza-1.0.0.tar.gz
Size 14.4 kB
Tags Source
SHA-256 checksum
How to use checksums
706f5d79c200baea7c9dcd3bb810ff4754a9aeb21f6683c9e0a8ed4b857bb0b0
BLAKE2b-256 checksum
How to use checksums
3a45a567323efecad3c5ab0682fe32e15fc8553515735abb7c127ad339a39af6
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 3, 2026.

Transparency log

Release files / manza-1.0.0-py3-none-any.whl

Download URL manza-1.0.0-py3-none-any.whl
Size 20.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ee85b95034ba77f7ed25878351054eca5d3662382d13ab7e065e953e6a16e366
BLAKE2b-256 checksum
How to use checksums
2bf43addd126ff5f563d1cb663cf619663aafa9d2c63d60ca05b250a2e5530fa
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 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

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