Metadata-Version: 2.4
Name: pycentry
Version: 0.1.1
Summary: Official Python SDK for the Centry payment API
Project-URL: Homepage, https://getcentry.io
Project-URL: Documentation, https://merchant.getcentry.io/docs/payments
Project-URL: Repository, https://github.com/centry/centry-python
Project-URL: Issues, https://github.com/centry/centry-python/issues
Author-email: Centry <hello@getcentry.io>
License: MIT
License-File: LICENSE
Keywords: africa,centry,checkout,fintech,payments,payouts
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.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Requires-Dist: requests>=2.28
Provides-Extra: dev
Requires-Dist: pytest-mock>=3.10; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Description-Content-Type: text/markdown

# Centry Python SDK

Official Python SDK for the [Centry](https://getcentry.io) payment API.

```bash
pip install pycentry
```

> The package is published as `pycentry` on PyPI but imports as `centry`:
> ```python
> from centry import Client
> ```

## Quick start

### Public checkout (customer-facing)

```python
from centry import Client

client = Client(api_key="cen_your_api_key")

session = client.checkout.create(
    amount="5000.00",
    currency="NGN",
    reference="ORDER-12345",
    success_url="https://yoursite.com/success",
    cancel_url="https://yoursite.com/cancel",
    webhook_url="https://yoursite.com/webhooks/centry",
    customer={"email": "customer@example.com"},
)

print(session.checkout_url)  # Redirect customer here
```

### Merchant API (server-to-server)

```python
from centry import Client

merchant = Client(merchant_key="mk_test_...")

# Create a payin (collection)
payin = merchant.payins.create(
    country_code="UG",
    amount=50000,
    payment_method="mobile_money",
    gateway="mtn_momo",
    customer_name="Jane Doe",
    customer_phone="+256700000000",
    reference="ORDER-1234",
    create_invoice=True,   # auto-create invoice in your ERP on completion
)

print(payin.id, payin.status, payin.net_amount)

# Send a payout (disbursement)
payout = merchant.payouts.create(
    country_code="ZA",
    amount=250000,
    payment_method="bank_transfer",
    gateway="netcash",
    recipient_name="Acme Suppliers",
    recipient_account_number="1234567890",
    recipient_bank_name="Standard Bank",
    create_bill=True,       # auto-create bill in your ERP on completion
)

# Check balance
for balance in merchant.balance.list():
    print(f"{balance.currency_code}: {balance.available}")
```

### Both keys in one client

```python
client = Client(
    api_key="cen_...",
    merchant_key="mk_live_...",
)
client.checkout.create(...)
client.payins.create(...)
client.balance.list()
```

### Custom base URL (local development)

```python
client = Client(
    merchant_key="mk_test_...",
    base_url="http://localhost:8000",
)
```

## Auth: two kinds of keys

| Key | Prefix | Used for | Where to find |
|---|---|---|---|
| **API Key** | `cen_...` | Customer-facing checkout | Org admin → Integrations |
| **Merchant Key** | `mk_test_...` / `mk_live_...` | Server-to-server payins, payouts, balance | Merchant admin → API Keys |

The same client can hold both — the SDK picks the right one per endpoint.

## Error handling

All errors inherit from `CentryError`. The SDK maps HTTP status to specific exceptions:

```python
from centry import Client, ValidationError, AuthenticationError, CentryError

try:
    payin = client.payins.create(
        country_code="UG",
        amount=-100,  # invalid
        payment_method="mobile_money",
    )
except ValidationError as e:
    print("Bad input:", e.message)
except AuthenticationError:
    print("Key is invalid or expired")
except CentryError as e:
    print(f"HTTP {e.status_code}: {e.message}")
```

Exceptions:
- `ValidationError` (400) — invalid parameters or insufficient balance
- `AuthenticationError` (401) — invalid or expired key
- `PermissionError` (403) — missing permission / IP not whitelisted / country mismatch
- `NotFoundError` (404) — resource does not exist
- `RateLimitError` (429) — slow down
- `ServerError` (5xx) — unexpected server failure
- `NetworkError` — transport-level failure (DNS, timeout, etc.)

## Response types

All responses are dataclasses with typed fields:

```python
from centry import Balance, Payin, Payout, CheckoutSession

session: CheckoutSession = client.checkout.create(...)
session.checkout_url
session.session_token

payin: Payin = merchant.payins.create(...)
payin.id
payin.net_amount  # str — parse to Decimal if you need arithmetic
payin.centry_fee
payin.gateway_fee
payin.invoice_number  # populated after completion if create_invoice=True
```

## Development

```bash
git clone https://github.com/centry/centry-python
cd centry-python
pip install -e ".[dev]"
pytest
```

## Links

- [API reference](https://merchant.getcentry.io/docs/payments)
- [Example app (Next.js)](https://github.com/centry/centry-demo)
- [Issues](https://github.com/centry/centry-python/issues)
