Zayono Python SDK
Official Python SDK for the Zayono unified Mobile Money payment gateway for Africa.
- Sync + async out of the box:
ZayonoandAsyncZayono. - Type-safe: ships
py.typed; complete type hints picked up by mypy/pyright/Pylance. - Resilient: automatic retries (429/5xx/connect) with jittered exponential backoff,
honours
Retry-After. - Idempotent by default: every mutating request carries an auto-generated
X-Idempotency-Key(UUIDv4); override withidempotency_key=. - Framework-agnostic: integrates with Django, Flask, FastAPI, Starlette, etc.
Installation
pip install zayono
Requires Python 3.9+.
Quick start (sync)
import os
from zayono import Zayono
client = Zayono(api_key=os.environ["ZAYONO_API_KEY"])
payment = client.payments.create(
amount=5000,
currency="XOF",
description="Premium t-shirt",
customer={
"email": "customer@example.com",
"first_name": "Jean",
"last_name": "Dupont",
},
return_url="https://example.com/success",
metadata={"order_id": "ORD-12345"},
)
print(payment["checkout_url"])
Quick start (async)
import asyncio
from zayono import AsyncZayono
async def main():
async with AsyncZayono(api_key="zyn_test_xxxxx") as client:
payment = await client.payments.create(
amount=5000,
currency="XOF",
description="Premium t-shirt",
return_url="https://example.com/success",
customer={
"email": "c@example.com",
"first_name": "Jean",
"last_name": "Dupont",
},
)
print(payment["checkout_url"])
asyncio.run(main())
Examples
1. Initiate a payment with a specific operator (no hosted page)
from zayono import Zayono
client = Zayono(api_key="zyn_test_xxxxx")
payment = client.payments.create(
amount=15000,
currency="XOF",
operator="mtn_bj",
description="Plan Pro mensuel",
return_url="https://example.com/success",
customer={
"email": "c@example.com",
"first_name": "Jean",
"last_name": "Dupont",
"phone": "+22961000000",
},
)
# Payment is dispatched immediately. Poll its status via retrieve()
2. Initiate a payout (disbursement), async
import asyncio
from zayono import AsyncZayono
async def disburse():
async with AsyncZayono(api_key="zyn_test_xxxxx") as client:
payout = await client.payouts.create(
amount=20000,
currency="XOF",
operator="moov_bj",
recipient={
"phone": "+22961000000",
"first_name": "Kossi",
"last_name": "Mensah",
},
description="Payout for order ORD-12345",
)
print(payout["id"], payout["status"])
asyncio.run(disburse())
3. Stream every successful payment (auto-paginated)
from zayono import Zayono
client = Zayono(api_key="zyn_test_xxxxx")
for payment in client.payments.list(status="success", per_page=100):
print(payment["id"], payment["amount"], payment["currency"])
Async equivalent:
async for payment in async_client.payments.list(status="success"):
print(payment["id"])
4. Verify a webhook signature (FastAPI)
from fastapi import FastAPI, Request, HTTPException
from zayono import Zayono
import os
app = FastAPI()
client = Zayono(api_key=os.environ["ZAYONO_API_KEY"])
@app.post("/webhooks/zayono")
async def webhook(request: Request):
body = await request.body() # raw bytes, required
signature = request.headers.get("x-zayono-signature", "")
secret = os.environ["ZAYONO_WEBHOOK_SECRET"]
if not client.webhooks.verify(body, signature, secret):
raise HTTPException(401, "Invalid signature")
event = await request.json()
# ... handle event["type"], event["data"]
return {"received": True}
Refunds: the public API-key surface does not yet expose
POST /v1/payments/{id}/refunds. For now, trigger refunds from the Zayono merchant dashboard. Arefundsresource will be added to this SDK once the endpoint ships on the v1 surface.
Error handling
from zayono.exceptions import (
ValidationError, AuthenticationError, RateLimitError,
NotFoundError, ServerError, NetworkError,
)
try:
payment = client.payments.create(amount=-1, currency="XOF")
except ValidationError as e:
# 422: e.errors is dict[str, list[str]]
for field, messages in e.errors.items():
print(f"{field}: {', '.join(messages)}")
except AuthenticationError:
# 401 / 403
...
except RateLimitError as e:
# 429: e.retry_after is in seconds, may be None
...
except NotFoundError:
# 404
...
except ServerError:
# 5xx after retries exhausted
...
except NetworkError:
# Transport-level failure (timeout, connect refused, DNS)
...
Configuration
client = Zayono(
api_key="zyn_test_xxxxx",
base_url="https://backend.zayono.com/api/v1", # default
timeout=30.0, # seconds, default 30
max_retries=3, # default 3
application_id=None, # only needed for dashboard endpoints
)
Development
git clone https://github.com/RomualdAKM/sdks-zayono
cd sdks-zayono/zayono-python
pip install -e ".[test]"
pytest # run the test suite
python -m build # produce wheel + sdist into dist/
License
MIT. See LICENSE.
Release files for zayono 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| zayono-1.1.0.tar.gz | 31.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| zayono-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 61.4 kB
Release files / zayono-1.1.0.tar.gz
| Download URL | zayono-1.1.0.tar.gz |
|---|---|
| Size | 31.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3057cb4f8aac0892b5cc9a2f35ca53d4fda4f44c7b1e2d690c592c058a9a2cfa
|
|
BLAKE2b-256 checksum How to use checksums |
2fbd94d49b1fdd3c55dd3fa859d91957b0e4201e36ead8fbf8a8a10e5107d473
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / zayono-1.1.0-py3-none-any.whl
| Download URL | zayono-1.1.0-py3-none-any.whl |
|---|---|
| Size | 30.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
223ee14a13b10eb8b9281b03fdc8646f5d0a86a5f3e9cfb942f104446b27fe2a
|
|
BLAKE2b-256 checksum How to use checksums |
21009486b8b6809e843ff190a911dc7e0f6d3c77fb0a5b56ebc70b866feee2da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|