Skip to main content

settlo-pay-python-sdk

Typed Python SDK (sync and async) for the Settlo Pay API: payments (mobile money, bank, QR), refunds, payouts, beneficiaries, balance, hosted checkout, QR codes and webhook verification.

  • Built on httpx; Pydantic v2 response models; py.typed, checked with mypy --strict
  • Inputs are validated before any request is sent
  • Idempotency keys are generated automatically and reused across retries
  • Retries use exponential backoff, only where they cannot duplicate a charge or payout
  • HTTPS only, redirects never followed, the API key is never logged, printed or pickled

📖 Full reference: documentation.md, covering every method in sync and async form.

There is no sandbox. sk_test_ and sk_live_ keys both move real money.

Install

pip install settlo-pay-python-sdk

Python 3.10+. Import name: settlopay.

Quick start

from settlopay import SettloPay

client = SettloPay()  # reads SETTLO_API_KEY from the environment

payment = client.payments.create(
    amount=25_000,  # TZS, major units
    method="mobile_money",
    phone="+255712345678",  # E.164
    merchant_reference="ORD-8451",
    idempotency_key="order-8451-pay-1",  # derive from your own record
)
print(payment.id, payment.state)  # pi_..., PENDING_AUTH

Async:

from settlopay import AsyncSettloPay

async with AsyncSettloPay() as client:
    balance = await client.balance.retrieve()
    async for p in client.payments.list_all():
        ...

Resources

Attribute Methods
client.payments create, list, list_all, retrieve, amend, cancel, inquire
client.refunds create, retrieve
client.payouts create, quote, list, list_all, retrieve, limits
client.beneficiaries create, list, list_all, retrieve, confirm, resend_code, delete
client.balance retrieve
client.checkout_sessions create, retrieve, cancel
client.qr_code retrieve, request

Amounts accept int, Decimal or numeric str (floats are accepted but discouraged). Response amounts are Decimal.

Errors

from settlopay import SettloError, UnprocessableEntityError, RateLimitError

try:
    client.payouts.create(amount=50_000, idempotency_key="withdrawal-397")
except UnprocessableEntityError as e:  # business decline
    if e.code == "insufficient_funds":
        ...
except RateLimitError as e:
    print("retry in", e.retry_after)
except SettloError as e:
    print(e, e.request_id)  # quote request_id to Settlo support

The full hierarchy is documented in settlopay/exceptions.py. ValidationError covers both local input checks and the API's 400 responses.

Idempotency and retries

Every create call sends an Idempotency-Key. If you don't pass one, the SDK generates a random key and reuses it on every retry of that call. For payouts and payments, pass your own key derived from your database record. Then a crash-and-restart re-sends the same key, and Settlo returns the original result instead of paying twice.

Default policy (RetryPolicy(max_retries=2)):

Failure GET / quote / amend / inquire Create (has key) cancel / confirm / resend / delete
Connection refused (never sent) retry retry retry
Timeout, 500, 502, 504 retry retry, same key no
503 retry no (Settlo wants a new key) no
429 retry after Retry-After (≤ 60 s) same same

Webhooks

from settlopay import verify_webhook, WebhookVerificationError


@app.post("/settlo/webhook")
def webhook():
    try:
        event = verify_webhook(
            request.get_data(),  # RAW bytes
            request.headers.get("Settlo-Signature"),
            os.environ["SETTLO_WEBHOOK_SECRET"],  # full whsec_... string
        )
    except WebhookVerificationError:
        return "", 400
    # Deduplicate on request.headers["Settlo-Event-Id"]; events may arrive out of order.
    enqueue(event)  # respond fast, work later
    return "", 200

Logging

The SDK logs to the settlopay logger: method, path, status, request id and retries. It never logs headers or bodies.

Development

python -m venv .venv && . .venv/bin/activate
pip install --upgrade "pip>=25.1"
pip install -e . --group dev
pre-commit install
pytest                  # unit tests (live tests are deselected)
ruff check . && ruff format --check . && mypy

Live smoke test

Read-only by default (balance, lists, limits, a payout quote):

export SETTLO_API_KEY=sk_...           # from your password manager; never commit it
SETTLO_RUN_LIVE=1 pytest -m live tests/live -v

Add SETTLO_LIVE_PHONE=+2557... SETTLO_ALLOW_MONEY_MOVEMENT=1 to also send one collection prompt to your own phone. Money only moves if you approve it.

Releasing

  1. Bump src/settlopay/_version.py, update CHANGELOG.md, merge to main.
  2. Run the Publish workflow manually to upload to TestPyPI, then check the install.
  3. Tag vX.Y.Z and publish a GitHub Release. The workflow publishes to PyPI via Trusted Publishing (OIDC). No token is stored anywhere.

License

MIT

Metadata

Release files for settlo-pay-python-sdk 0.1.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 settlo-pay-python-sdk 0.1.0
File Size Uploaded Provenance
settlo_pay_python_sdk-0.1.0.tar.gz 55.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for settlo-pay-python-sdk 0.1.0
File Interpreter ABI Platform
settlo_pay_python_sdk-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 93.4 kB

Release files / settlo_pay_python_sdk-0.1.0.tar.gz

Download URL settlo_pay_python_sdk-0.1.0.tar.gz
Size 55.3 kB
Tags Source
SHA-256 checksum
How to use checksums
c531edb9a2fc5ae8ed2735306b9b40f573d3292ca91bacf8df61c8cb427f134b
BLAKE2b-256 checksum
How to use checksums
28a9e78045628c95680dd36fa1ee8ac4813c3bf486eb4eb2b7e6cf8285118198
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release files / settlo_pay_python_sdk-0.1.0-py3-none-any.whl

Download URL settlo_pay_python_sdk-0.1.0-py3-none-any.whl
Size 38.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
352a434a38d7f3de4fe5c0bf4ee8e53ff7288a4f0e95a4f33d7f28c76e23138f
BLAKE2b-256 checksum
How to use checksums
f43a58447a74a8ba75242385d35e437a305badf1cb6710e4adf23439fb9f374f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Security for settlo-pay-python-sdk 0.1.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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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