Metadata-Version: 2.4
Name: visualpay
Version: 1.0.0
Summary: Official VisualPay Merchant API SDK for Python
Author-email: VisualPay <support@visualpay.net>
License: MIT
Project-URL: Homepage, https://github.com/visualpay/visualpay-python
Project-URL: Documentation, https://visualpay.net/api-docs
Project-URL: Issues, https://github.com/visualpay/visualpay-python/issues
Project-URL: Repository, https://github.com/visualpay/visualpay-python
Keywords: visualpay,crypto,payments,usdt,merchant,api
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.27.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: respx>=0.21; extra == "dev"
Dynamic: license-file

# VisualPay Python SDK

Official Python client for the [VisualPay](https://visualpay.net) Merchant API.

Repository: [visualpay-python](https://github.com/visualpay/visualpay-python)

## Requirements

- Python 3.10+

## Install

```bash
pip install visualpay
```

## Security notes

- API base URL is **hardcoded** to `https://visualpay.net` (not configurable) to prevent host spoofing / MITM via custom endpoints.
- `httpx` is configured with `verify=True` and `follow_redirects=False`.
- Webhook tokens are compared with `hmac.compare_digest` (timing-safe).
- Optional `callback_url` values are rejected unless they use `https://`.
- Keep your merchant API key and webhook secret on the **server only**.
- This SDK is for server-side use (no cookies/sessions). Protect your own routes with your framework’s CSRF and auth controls.

## Quick start

```python
import os
from visualpay import Client

with Client(os.environ["VISUALPAY_API_KEY"]) as client:
    currencies = client.list_currencies()

    created = client.create_transaction({
        "currency_symbol": "USDT",
        "network_code": "trc20",
        "amount_usd": 25.5,
        "ttl": 15,
        "order_id": 100001,
        "email": "payer@example.com",
        "comment": "Invoice #1001",
        "callback_url": "https://example.com/order",
    })

    tracking_code = created["data"]["tracking_code"]
    status = client.get_transaction_status(tracking_code)
```

## Webhooks

VisualPay POSTs JSON with header `token: {webhook_api_key}`.

```python
from visualpay import verify_and_parse, ValidationError

try:
    event = verify_and_parse(
        request.headers.get("token"),
        os.environ["VISUALPAY_WEBHOOK_SECRET"],
        request.get_data(as_text=True),
    )
except ValidationError:
    return "", 401
```

Always confirm payment via webhook or `get_transaction_status` before fulfilling orders.

## API surface

| Method | Endpoint |
|--------|----------|
| `list_currencies()` | `GET /api/v1/merchant/currencies/list` |
| `create_transaction()` | `POST /api/v1/merchant/transaction/create` |
| `get_transaction_status()` | `GET /api/v1/merchant/transaction/status` |
| `cancel_transaction()` | `POST /api/v1/merchant/transaction/cancel` |
| `recheck_transaction()` | `GET /api/v1/merchant/transaction/recheck` |
| `list_transactions()` | `GET /api/v1/merchant/transaction/list` |
| `list_withdrawals()` | `GET /api/v1/merchant/withdrawals/list` |

Docs: [https://visualpay.net/api-docs](https://visualpay.net/api-docs)

## Publish checklist (PyPI)

1. Push this repo to GitHub as `visualpay/visualpay-python`.
2. `python -m build`
3. `twine check dist/*`
4. `twine upload dist/*`
5. Tag `v1.0.0` on GitHub.

## Development

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

## License

MIT — see [LICENSE](LICENSE).
