Metadata-Version: 2.5
Name: vonpay-checkout
Version: 1.1.0
Summary: Von Payments Checkout SDK for Python
Project-URL: Homepage, https://github.com/Von-Payments/vonpay
Project-URL: Documentation, https://docs.vonpay.com
License-Expression: MIT
Keywords: checkout,payments,sdk,vonpay
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
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 :: Software Development :: Libraries
Requires-Python: >=3.9
Requires-Dist: httpx>=0.27
Description-Content-Type: text/markdown

# vonpay-checkout

Python SDK for the [Von Payments Checkout API](https://docs.vonpay.com). Create hosted checkout sessions, verify webhook signatures, and validate signed return redirects.

## Install

```bash
pip install vonpay-checkout
```

**Requires:** Python 3.9+, httpx 0.27+

## Quick start

```python
from vonpay.checkout import VonPayCheckout, VonPayError

client = VonPayCheckout("vp_sk_test_...")

session = client.sessions.create(
    amount=1499,
    currency="USD",
    country="US",
    success_url="https://example.com/order/123/confirm",
)

print(session.checkout_url)
# https://checkout.vonpay.com/checkout?session=vp_cs_test_...
```

### Discrete-lifecycle API

The `payment_intents`, `refunds`, `tokens`, and `capabilities` namespaces give server-side control over payment intents, alongside the existing hosted-checkout `sessions` flow.

```python
# Create a payment intent (auth + capture)
intent = client.payment_intents.create(
    amount=1499,
    currency="usd",
    capture_method="automatic",
    metadata={"order_id": "ord_42"},
    idempotency_key="ord_42-charge-1",
)
print(intent.id, intent.status)  # "vpi_live_…", "succeeded"

# Auth-only + later capture (fulfillment-on-ship)
auth = client.payment_intents.create(amount=1499, currency="usd", capture_method="manual")
client.payment_intents.capture(auth.id, amount_to_capture=1499)

# Refund a captured intent (partial or full)
refund = client.refunds.create(payment_intent=intent.id, amount=500)

# Create a reusable token for save-card / MIT flows
token = client.tokens.create(buyer_id="buyer_42", setup_for_future_use="off_session")

# Read the merchant's processor capability matrix before invoking optional ops
caps = client.capabilities.get()
if caps.supported_operations.partial_refund:
    # partial refunds supported — safe to offer partial-refund UI
    ...
```

## Features

- **Typed session / webhook / error objects** — full `CheckoutSession`, `SessionStatus`, `WebhookEvent`, `VonPayError` types.
- **Webhook verification** — `webhooks.construct_event(raw_body, signature_header, signing_secret)` parses the `x-vonpay-signature: t=<unix>,v1=<hex>` header, verifies HMAC-SHA256 over `f"{t}.{raw_body}"` keyed by your per-endpoint signing secret (`whsec_…`), and enforces the freshness window (≤5 min old / ≤30 sec future). Accepts multiple `v1=` entries for zero-downtime secret rotation.
- **Return confirmation** — `client.sessions.confirm_return(params, session_secret)` verifies the signature **and** confirms server-side that the payment succeeded, returning `ReturnOutcome(paid, signature_valid, status, reason)`. **Use this, and branch on `paid`.** ⚠️ `verify_return_signature()` is the low-level primitive: it proves the message is AUTHENTIC, and a **declined payment is signed just as validly**, so a `true` from it is not proof of payment. ⚠️ `reason == "still_pending"` means the charge is in flight (the ordinary 3-D Secure case) — show a neutral "confirming your payment", never a failure. ⚠️ `paid: true` still does not mean safe to fulfil: record which session IDs you have already fulfilled, and prefer fulfilling from the `charge.succeeded` webhook. ⚠️ **Not `session.succeeded`** — that event is emitted internally but is **not subscribable**: it is absent from the merchant subscription catalog, which accepts an unknown event key, stores nothing and returns success. An endpoint subscribed to it receives nothing, forever, with no error raised at any layer. `charge.succeeded` is the fulfilment event.
- **Auto-retry** — exponential backoff on 429 / 5xx with `Retry-After` header support.
- **Request ID tracing** — every response includes `X-Request-Id` for support tickets.

## Documentation

- [Python SDK reference](https://docs.vonpay.com/sdks/python-sdk)
- [API reference](https://docs.vonpay.com/reference/api)
- [Quickstart](https://docs.vonpay.com/quickstart)

## License

MIT
