> ## Documentation Index
> Fetch the complete documentation index at: https://developer.tazapay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How Checkout Works

Add a low-code cross-border payment page to your website, online shop or marketplace. Create a session on your server, redirect your customer to a Tazapay-hosted payment page, and receive the result via webhook. The same API, the same objects, the same lifecycle regardless of whether the customer pays with a card or a QR code.

## The Object Hierarchy

Every payment flow creates three objects in sequence:

| Object              | What it represents                                                | Created by               |
| ------------------- | ----------------------------------------------------------------- | ------------------------ |
| **Checkout**        | The payment session — amount, currency, customer, allowed methods | You (POST /v3/checkout)  |
| **Payin**           | The collection intent — tracks the full payment lifecycle         | Tazapay, automatically   |
| **Payment Attempt** | A single attempt to pay — one per method try                      | Tazapay, on each attempt |

If a card is declined and the customer retries with a different card, a new Payment Attempt is created on the same Payin.

## The Lifecycle

1. Your server calls `POST /v3/checkout` — returns a hosted payment page `url`
2. You redirect the customer to that `url`
3. Customer selects a payment method, completes authentication
4. Tazapay redirects customer back to your `success_url` or `cancel_url`
5. Tazapay sends webhooks — key events:
   * `checkout.paid` — payment\_status changes to paid
   * `payment_attempt.created` — new payment attempt created
   * `payment_attempt.succeeded` — attempt succeeds
   * `payment_attempt.failed` — attempt fails
   * `payment_attempt.processing` — attempt moves to processing
   * `checkout.expired` — session expires before payment
   * `checkout.created` — session created

## Checkout Status Fields

The Checkout object has two independent status fields that update separately:

**`status`** — the session state:

* `active` — session is open and the customer can still pay
* `expired` — session window closed before payment was completed

**`payment_status`** — the payment outcome:

* `unpaid` — no payment received yet
* `processing` — customer completed all actions but Tazapay hasn't confirmed funds yet; common for async methods like local bank transfer or wire transfer where intermediary banks take time to process
* `paid` — payment confirmed

## Creating a Checkout Session

```json theme={null}
POST /v3/checkout
{
  "invoice_currency": "USD",
  "amount": 10000,
  "customer_details": {
    "name": "Andrea Lark",
    "email": "andrea@example.com",
    "country": "VN"
  },
  "transaction_description": "1 x T-shirt",
  "payment_methods": ["bank_push_vnd"],
  "success_url": "https://mystore.com/success",
  "cancel_url": "https://mystore.com/cancel",
  "webhook_url": "https://mystore.com/webhooks/tazapay",
  "reference_id": "mystore_order_00001"
}
```

**Sample response:**

```json theme={null}
{
  "status": "success",
  "data": {
    "id": "chk_cqd3nep5ct0u7aakeco0",
    "object": "checkout",
    "invoice_currency": "USD",
    "amount": 10000,
    "amount_paid": 0,
    "status": "active",
    "payment_status": "unpaid",
    "payment_methods": ["bank_push_vnd"],
    "url": "https://checkout-sandbox.tazapay.com/transaction/tGxhgHg5USrT3Gizxu-aL-GFF5FhyaCT4KHyXQXcxZE="
  }
}
```

Redirect the customer to the `url` in the response.
