Official Python SDK for the Zayono unified Mobile Money payment gateway.
Project description
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file zayono-1.1.0.tar.gz.
File metadata
- Download URL: zayono-1.1.0.tar.gz
- Upload date:
- Size: 31.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3057cb4f8aac0892b5cc9a2f35ca53d4fda4f44c7b1e2d690c592c058a9a2cfa
|
|
| MD5 |
b5ffaa74e0b5f65b91df8e28f035d5ec
|
|
| BLAKE2b-256 |
2fbd94d49b1fdd3c55dd3fa859d91957b0e4201e36ead8fbf8a8a10e5107d473
|
File details
Details for the file zayono-1.1.0-py3-none-any.whl.
File metadata
- Download URL: zayono-1.1.0-py3-none-any.whl
- Upload date:
- Size: 30.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
223ee14a13b10eb8b9281b03fdc8646f5d0a86a5f3e9cfb942f104446b27fe2a
|
|
| MD5 |
341cc01246fbfea7c25831b367ed1ff1
|
|
| BLAKE2b-256 |
21009486b8b6809e843ff190a911dc7e0f6d3c77fb0a5b56ebc70b866feee2da
|