Python SDK
xaalis (in integrations/sdk-python) wraps the API for Python 3.9+ servers. Standard library only — no
requests, no httpx — and fully type-hinted. Not on PyPI yet: pip install ./integrations/sdk-python.
import osfrom xaalis import Xaalis, XaalisAPIError, construct_event, format_xof
xaalis = Xaalis(os.environ["XAALIS_SECRET_KEY"], base_url="http://localhost:4000")
payment = xaalis.payments.create( amount=15000, description="Commande #1042", client_reference="order_1042", success_url="https://shop.example/merci", idempotency_key="payment:order_1042",)print(format_xof(payment["amount"]), payment["checkout_url"])Objects are plain dicts typed as TypedDicts (Payment, Payout, Balance, Account, WebhookDelivery,
WebhookEvent). Every amount is an int in XOF.
| API | Methods |
|---|---|
payments |
create, retrieve, list, list_all (generator over every page) |
payouts |
create, retrieve, list, list_all |
balance |
retrieve |
account |
retrieve, update(webhook_url=...) |
webhook_deliveries |
list(limit=...) |
test_helpers |
simulate_payment(id, "succeeded" | "failed") — test keys only |
construct_event(raw, header, secret) |
verify and parse a webhook |
What it does for you
Section titled “What it does for you”- Idempotency: every
createsends anIdempotency-Key(random unless you passidempotency_key=) and reuses it on each retry. See Idempotency. - Retries: network errors,
429and5xx, with exponential backoff andRetry-After— only when replaying is safe (reads,PATCH, or creates carrying their key). Default 2 retries, 30 s timeout per attempt. Redirects are never followed. - Errors:
XaalisAPIError(status,code,message,details),XaalisConnectionError,XaalisSignatureError— all subclasses ofXaalisError. Codes are listed in Errors. - Safety: refuses a live key over
http://; rejects non-intamounts before sending; never puts the key in an error message orrepr.
try: xaalis.payouts.create(amount=5000, provider="wave", recipient={"phone": "+221770000001"})except XaalisAPIError as err: if err.code == "insufficient_funds": ... # show "balance too low" else: raiseWebhooks
Section titled “Webhooks”Pass the raw request bytes — Flask request.get_data(), Django request.body — never re-serialized JSON:
from xaalis import XaalisSignatureError, construct_event
try: event = construct_event(request.body, request.headers.get("Xaalis-Signature"), os.environ["XAALIS_WEBHOOK_SECRET"])except XaalisSignatureError: return HttpResponse(status=400)# answer 2xx fast, deduplicate on event["id"], check event["livemode"], then fulfilIn test mode, xaalis.test_helpers.simulate_payment(payment["id"], "succeeded") drives the payment
to its final state and fires the same webhook live mode would.
Examples: integrations/sdk-python/examples/ (checkout, webhook server with http.server, payout). Tests:
cd integrations/sdk-python && python3 -m unittest discover -s tests -v. See also the Node SDK.