Metadata-Version: 2.4
Name: django-hesabpay
Version: 0.1.4
Summary: Beginner-friendly Django SDK for the HesabPay payment gateway
Author: Cyber0x3a
License-Expression: MIT
Project-URL: Documentation, https://docs.hesab.com/
Project-URL: Homepage, https://pypi.org/project/django-hesabpay/
Keywords: django,hesabpay,payments,afghanistan,afn
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 5.0
Classifier: Framework :: Django :: 5.1
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Django>=4.2
Requires-Dist: httpx>=0.27
Requires-Dist: cryptography>=42
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: pytest-django>=4.8; extra == "dev"
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: twine>=5; extra == "dev"
Dynamic: license-file

﻿# django-hesabpay

Beginner-friendly Django SDK for the [HesabPay Payment Gateway](https://docs.hesab.com/).

Start a hosted checkout with `hesabpay.checkout(...)`, then run your business logic in `@on_payment_success`. Redirects are for UX. Verified webhooks are the source of truth.

## Install

```bash
pip install django-hesabpay
```

Requires Python 3.10+ and Django 4.2+.

## Quickstart

### 1. Settings

```python
# settings.py
INSTALLED_APPS = [
    # ...
    "hesabpay",
]

HESABPAY = {
    "ENVIRONMENT": "sandbox",  # or "production"
    "SANDBOX_API_KEY": "your-sandbox-key",
    # "PRODUCTION_API_KEY": "your-live-key",  # when ENVIRONMENT=production
    # Public HTTPS origin for redirects (tunnel or production domain):
    "PUBLIC_BASE_URL": "https://your-domain.example",
    "SUCCESS_URL": "/success/",
    "FAILURE_URL": "/failure/",
    "HANDLERS": ["shop.payments"],  # modules that register @on_payment_success
}
```

`PUBLIC_BASE_URL` turns relative `SUCCESS_URL` / `FAILURE_URL` paths into absolute HTTPS URLs HesabPay can redirect to. You can also set `SITE_URL` as an alias for `PUBLIC_BASE_URL`.

### 2. Migrate

```bash
python manage.py migrate
```

Webhook and status routes register automatically. The default webhook path is `/hesabpay/webhook/`. Copy that URL into the HesabPay dashboard.

### 3. Start checkout

```python
import hesabpay
from django.shortcuts import redirect

def pay(request, order):
    checkout = hesabpay.checkout(order, user=request.user)
    return redirect(checkout.url)
```

Or from a template:

```django
{% load hesabpay %}
{% hesabpay_checkout_button order user=request.user %}
```

JSON APIs can return `checkout.as_dict()` with `payment_id`, `checkout_url`, `status`, and `items`.

### 4. Fulfill after payment

```python
# shop/payments.py
from hesabpay import on_payment_success

@on_payment_success
def fulfill(context):
    # Your product decides: enroll, unlock, email, ship, etc.
    order = context.instance
    user = context.user
    items = context.items          # local HesabPayPaymentItem rows
    webhook_items = context.webhook_items  # items list from HesabPay webhook
    if not context.is_first_success:
        return
    ...
```

HesabPay webhooks include an `items` array (same shape as create-session). The SDK stores those line items locally and exposes them on the payment context and status endpoint.

Amounts are **AFN**. Currency conversion is out of scope for v1.

## Multi-vendor (advanced)

Easiest path — register a resolver (no dotted settings path needed):

```python
from hesabpay import vendor_resolver, on_payment_success

@vendor_resolver
def vendors_for(context):
    return [
        {"account_number": "700000001", "amount": 50},
        {"account_number": "700000002", "amount": 15},
    ]
```

Then either:

1. Set `AUTO_VENDOR_TRANSFER: True` and `MERCHANT_PIN` in `HESABPAY`, or
2. Call it yourself:

```python
from hesabpay import transfer_to_vendors_from_context

@on_payment_success
def settle(context):
    if context.is_first_success:
        transfer_to_vendors_from_context(context)
```

You can still pass an explicit list to `transfer_to_vendors(...)` when you want full control.
`VENDOR_RESOLVER` settings paths still work as a fallback.

## Commands

```bash
python manage.py hesabpay doctor
python manage.py hesabpay simulate-webhook <payment_reference>
```

Django admin includes payments, webhook events, vendor payouts, and activity logs. Use **Replay fulfillment handlers** on a webhook event if a handler failed after the payment was already acknowledged.

## Official API docs

https://docs.hesab.com/
