Metadata-Version: 2.4
Name: rohopay
Version: 1.1.1
Summary: Official RohoPay Python SDK for mobile-money & card payments.
License: MIT
Keywords: rohopay,payments,mobile-money,mtn,airtel,mpesa,visa,uganda
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.20

# RohoPay Python SDK

Official Python SDK for RohoPay — mobile-money (MTN, Airtel, M-Pesa) and card
(Visa, Mastercard) payments across East Africa.

## Install

```bash
pip install rohopay
```

## Quick start

```python
import os
import uuid
from rohopay import RohoPay

client = RohoPay(api_key=os.environ["ROHOPAY_API_KEY"])

tx = client.collect(
    phone="256700123456",
    amount=50000,
    currency="UGX",
    description="Order #1001",
    callback_url="https://your-app.com/webhooks/rohopay",
    idempotency_key=str(uuid.uuid4()),  # optional; auto-generated if omitted
)
print(tx.internal_reference, tx.status)

card = client.checkout(
    amount=75000,
    customer_name="Jane Mukasa",
    customer_email="jane@example.com",
    return_url="https://your-app.com/checkout/return",
    card_number="4111111111111111",
    card_expiry="10/26",
    card_cvv="123",
)
# redirect the user to card.payment_url  (card is a CheckoutResult)
```

## Methods

| Method | Endpoint |
|--------|----------|
| `collect(...)` | `POST /api/v1/collect` |
| `disburse(...)` *(live mode only)* | `POST /api/v1/disburse` |
| `checkout(...)` | `POST /api/v1/checkout` |
| `get_transaction(reference)` | `GET /api/v1/transactions/:reference` |
| `list_transactions(**params)` | `GET /api/v1/transactions` |
| `iter_transactions(**params)` | generator, auto-paginates `list_transactions` |
| `get_balance()` | `GET /api/v1/wallet/balance` → `Balance` |
| `verify_webhook(body, sig, secret)` | — |
| `construct_event(body, sig, secret, tolerance_seconds=300)` | — |

## Errors

All errors subclass `rohopay.RohoPayError` and carry `status`, `code`, and
`request_id`:

`AuthenticationError` (401), `InvalidRequestError` (400/404/422),
`IdempotencyError` (409), `RateLimitError` (429), `APIError` (>=500),
`APIConnectionError` (network/timeout), `SignatureVerificationError` (webhooks).

```python
from rohopay import RohoPay, APIError

try:
    client.collect(phone="...", amount=1000)
except APIError as e:
    print(e.status, e.code, e.request_id)
```

## Verify webhooks

```python
import os
raw_body = request.get_data(as_text=True)
signature = request.headers.get("X-RohoPay-Signature", "")
if not client.verify_webhook(raw_body, signature, os.environ["ROHOPAY_WEBHOOK_SECRET"]):
    return "invalid signature", 401

# Or parse + verify in one step (raises SignatureVerificationError):
event = client.construct_event(raw_body, signature, os.environ["ROHOPAY_WEBHOOK_SECRET"])
```

> The gateway signs outgoing webhooks automatically with the `X-RohoPay-Signature`
> header (`sha256=<HMAC-SHA256 of raw body>`). Your webhook secret is
> `HMAC(APP_SECRET, "webhook:<userID>")` — fetch it from **Dashboard → Webhooks**
> (the `webhook_secret` field) and pass it as the `secret` argument.

## Constants

`TransactionStatus`, `PaymentMethod`, `TransactionType`, `Environment` enums,
`CURRENCIES`, `LIVE_BASE_URL`, `SANDBOX_BASE_URL`, `WEBHOOK_SIGNATURE_HEADER`,
and `rohopay.__version__` (`1.1.0`).
