Metadata-Version: 2.4
Name: bachs-sdk-python
Version: 0.0.2
Summary: Official Python SDK for the Bachs payments and billing platform for African internet businesses.
Author-email: Bachs <support@bachs.io>
License: MIT
Project-URL: Homepage, https://docs.bachs.io
Project-URL: Documentation, https://docs.bachs.io
Project-URL: Source, https://github.com/Daviduche03/weldrr-template-python
Keywords: bachs,payments,billing,subscriptions,checkout,africa,sdk
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.24
Requires-Dist: pydantic>=2.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: build>=0.10; extra == "dev"
Requires-Dist: twine>=4.0; extra == "dev"

# bachs — Python SDK

The official Python SDK for the [Bachs](https://docs.bachs.io) 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

```bash
pip install bachs-sdk-python
```

Requires Python 3.8+. Uses `httpx` for transport and `pydantic` for typed models.

## Quickstart

```python
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

```python
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

```python
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

```python
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:

```python
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`.

```python
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:

```python
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 4217 `currency`. 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

```bash
pip install -e ".[dev]"
pytest
```

## License

MIT
