bachs — Python SDK
The official Python SDK for the Bachs payments and billing platform for African internet businesses and the global customers they serve.
Define products, run hosted checkouts, collect payments in customers' local currencies while settling in your own, manage subscriptions and free trials, issue refunds, respond to disputes, convert balances, withdraw (payout) funds, configure webhooks, and run a Connect-style platform with connected accounts, transfers, and split payments.
Installation
pip install bachs-sdk-python
Requires Python 3.8+. Uses httpx for transport and pydantic for typed models.
Quickstart
from bachs import Client
client = Client(api_key="sk_sandbox_...")
The environment is inferred from the API key prefix: sk_sandbox_... talks to
https://sandbox-api.bachs.io, sk_live_... talks to https://api.bachs.io.
You can override with Client(api_key=..., environment="sandbox") or
Client(api_key=..., base_url="https://...").
Create a checkout session
from bachs import Client, CreateCheckoutSessionRequest, NewCustomerRequest
client = Client(api_key="sk_sandbox_...")
session = client.create_checkout_session(
CreateCheckoutSessionRequest(
customer=NewCustomerRequest(email="buyer@example.com", name="Amina"),
product_cart=[{"product_id": "prod_123", "quantity": 2}],
success_url="https://example.com/thanks?from=checkout",
)
)
print(session.checkout_url) # send the customer here
Create a product and a customer
client.create_product({
"name": "Pro plan",
"description": "Monthly membership",
"price": {"currency": "USD", "amount": "29.00"},
"billing_cycle": {"interval": "month", "frequency": 1},
"trial_period": {"interval": "day", "frequency": 14},
})
customer = client.create_customer(
{"email": "buyer@example.com", "name": "Amina", "phone_number": "+2348012345678"}
)
Create a payout destination and withdraw
dest = client.create_payout_destination({
"destination_type": "bank_account",
"currency": "NGN",
"label": "Main NGN account",
"account_number": "0123456789",
"bank_code": "033",
"account_name": "Amina Okafor",
})
withdrawal = client.create_withdrawal({
"from_currency": "USD",
"to_currency": "NGN",
"amount": "100.00",
"payment_method": "BANK_TRANSFER",
"reference": "wd_20240101_1",
"email": "ops@example.com",
"payout_destination_id": dest.id,
})
Idempotency & acting on behalf of a connected account
Mutating requests support the Idempotency-Key header, and some endpoints
support the X-Connected-Account-ID header:
client.create_refund(
{"charge_id": "chk_...", "reference": "ref_001"},
idempotency_key="retry-safe-key-1",
)
client.get_checkout_settings(connected_account_id="org_connected_...")
client.create_transfer(
{"destination": "self", "amount": "50.00", "currency": "USD"},
connected_account_id="org_connected_...",
)
Errors
All non-2xx responses raise BachsError (or a subclass such as
AuthenticationError, PermissionError_, NotFoundError, ConflictError,
RateLimitError, ServerError) carrying status_code, error_code,
detail, doc_url, and errors.
from bachs import BachsError, RateLimitError
try:
client.get_payment("chk_does_not_exist")
except RateLimitError as exc:
print("throttled; retry after", exc.retry_after)
except BachsError as exc:
print(exc.status_code, exc.error_code, exc.detail)
Webhook verification
Webhooks are the source of truth for fulfilment. Verify every delivery with the endpoint's signing secret:
from bachs import verify_signature
verified = verify_signature(
secret="whsec_...",
payload=request_body_bytes,
signature=request.headers.get("X-Bachs-Signature", ""),
timestamp=request.headers.get("X-Bachs-Timestamp", ""),
)
Money and timestamps
- Money is always a decimal string at the currency's precision (e.g.
"29.00") paired with an ISO 4217currency. Never use floats or minor units. - Timestamps are ISO 8601 UTC strings.
- IDs carry resource prefixes (
cust_,prod_,sub_,chk_,inv_,ref_,psn_,org_,evt_) — treat them as opaque.
Supported operations
Payments (methods, rails, currencies, charges), checkout sessions and checkouts, customers and customer portal sessions, products, product groups, media uploads, subscriptions, refunds, disputes, balances, organizations, connected accounts (capabilities, account links, Tasks, banks, mobile money, uploads), transfers, conversions, payouts (destinations, quotes, withdrawals), and webhook endpoints/events.
Development
pip install -e ".[dev]"
pytest
License
MIT
Release files for bachs-sdk-python 0.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| bachs_sdk_python-0.0.2.tar.gz | 30.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bachs_sdk_python-0.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 61.6 kB
Release files / bachs_sdk_python-0.0.2.tar.gz
| Download URL | bachs_sdk_python-0.0.2.tar.gz |
|---|---|
| Size | 30.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
76da2e8866a043c88f773257d588b7cde6eee5401325352640ead9251eb7251e
|
|
BLAKE2b-256 checksum How to use checksums |
f4eaed306aad738df288381070dbdd1824a68649ae1d37714bea77b9aa9d517d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.2
|
Release files / bachs_sdk_python-0.0.2-py3-none-any.whl
| Download URL | bachs_sdk_python-0.0.2-py3-none-any.whl |
|---|---|
| Size | 31.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
937a347305b401123874b67bd239fd6804aa088f7208cc3175828d073d7f7fac
|
|
BLAKE2b-256 checksum How to use checksums |
ce5d50243ca1de3eeaf40f0480b32537fe5207d24c7f1f94d323c0a61f15cfa1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.2
|