Metadata-Version: 2.4
Name: payexa
Version: 0.4.3
Summary: Production-ready Python SDK for PAYEXA payment request, callback parsing, and verify flow with sync and async clients
Author: PAYEXA Team
Maintainer: PAYEXA Team
License-Expression: MIT
Project-URL: Homepage, https://pypi.org/project/payexa/
Project-URL: TestPyPI, https://test.pypi.org/project/payexa/
Project-URL: Downloads, https://pypi.org/project/payexa/#files
Keywords: payexa,payments,payment-gateway,sdk,python,async
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests<3,>=2.31
Provides-Extra: async
Requires-Dist: httpx<1,>=0.27; extra == "async"
Provides-Extra: dev
Requires-Dist: build<2,>=1.2; extra == "dev"
Requires-Dist: twine<7,>=5; extra == "dev"
Dynamic: license-file

# PAYEXA Python SDK

Official Python SDK for the PAYEXA payment flow, including payment creation, callback parsing, and transaction verification.

The package provides a small, typed interface for integrating PAYEXA into synchronous and asynchronous Python applications.

## Features

- Sync and async clients in a single package
- Input validation before any HTTP request is sent
- Clear separation between validation, transport, and API errors
- Typed result models for payment requests, callbacks, and verification
- Support for custom `requests.Session` and injected async sessions

## Requirements

- Python 3.10 or newer

## Installation

Install the standard client:

```bash
pip install payexa
```

Install with async support:

```bash
pip install "payexa[async]"
```

## Public API

```python
from payexa import AsyncPayexaClient, PayexaClient
```

Use `PayexaClient` for standard synchronous applications and `AsyncPayexaClient` for async frameworks such as FastAPI.

## Quick Start

```python
from payexa import PayexaClient


with PayexaClient(
    base_url="https://pay.pexn.ir",
    api_key="YOUR_API_KEY",
    default_merchant_id=1001,
) as client:
    payment = client.request_payment(
        amount=600000,
        callback_url="https://merchant.example.com/payexa/callback",
        meta={"order_ref": "INV-1001"},
    )

    print(payment.authority)
    print(payment.order_id)
    print(payment.amount_unique_token)
    print(payment.start_pay_url)
```

## Async Example

```python
from payexa import AsyncPayexaClient


async def create_payment() -> None:
    async with AsyncPayexaClient(
        base_url="https://pay.pexn.ir",
        api_key="YOUR_API_KEY",
        default_merchant_id=1001,
    ) as client:
        payment = await client.request_payment(
            amount=600000,
            callback_url="https://merchant.example.com/payexa/callback",
            meta={"order_ref": "INV-1001"},
        )

        print(payment.authority)
        print(payment.amount_unique_token)
```

## Payment Flow

1. Call `request_payment` on your backend.
2. Store `authority`, `order_id`, and `amount_unique` from the response.
3. Redirect the customer to `start_pay_url`.
4. In the callback handler, call `parse_callback` first and then `verify_payment`.

Example callback verification:

```python
from payexa import PayexaAPIError, PayexaClient, PayexaValidationError


client = PayexaClient(
    base_url="https://pay.pexn.ir",
    api_key="YOUR_API_KEY",
)

callback = client.parse_callback(request.args)

if callback.is_ok:
    try:
        verification = client.verify_payment(
            order_id=stored_order_id,
            token=stored_amount_unique_token,
        )
        print(verification.status)
        print(verification.merchant_verified)
    except PayexaAPIError as exc:
        print(exc.status_code, exc.message)
    except PayexaValidationError as exc:
        print(str(exc))
```

## Error Model

- `PayexaValidationError`: invalid client-side input
- `PayexaTransportError`: network, timeout, or transport-level failure
- `PayexaAPIError`: PAYEXA returned an API error response

`PayexaAPIError` exposes these fields:

- `status_code`
- `message`
- `payload`

## Notes

- `amount` must be a positive numeric value
- `callback_url` must be a valid `http` or `https` URL
- `meta` must be a mapping if provided
- `amount_unique` is stored as `Decimal`
- `amount_unique_token` is the recommended value for verification requests

## Release

For maintainers, the release workflow is documented in `RELEASE_CHECKLIST.md` and covers validation, build, TestPyPI upload, and production publishing commands.
