# Checkout sessions

A checkout session is the simplest way to take a payment in Iceland with Kling. Your server creates it with an amount or products, and the customer pays on a Kling checkout page or in an overlay on your site.

A checkout session is one payment attempt by one customer. Your server creates it with your secret key; Kling returns a `url` for a hosted checkout page and an `id` you can open as an overlay on your own site with the [payment window](https://kling.is/en/docs/embedded-checkout). Card details go straight to Kling's checkout and never touch your server.

## Create a session

`POST /v1/checkout/sessions`. Set the amount in one of three ways (use only one):

| Field | Use it when |
|---|---|
| `amount` | You just need to charge a sum, e.g. `4990` for 4.990 kr. |
| `product_id` | You sell a product set up in Kling. A subscription product starts a subscription. |
| `items` | You want a receipt with lines: each item has a `product_id`, or a `description` and `amount`, plus `quantity` and `tax_rate` (0, 11 or 24, VAT included in the amount) |

```bash
curl -X POST https://api.kling.is/v1/checkout/sessions \
  -H "Authorization: Bearer $KLING_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042" \
  -d '{
    "items": [
      { "description": "T-shirt", "amount": 3990, "quantity": 2, "tax_rate": 24 }
    ],
    "currency": "ISK",
    "customer_email": "anna@example.is",
    "success_url": "https://example.is/thanks",
    "cancel_url": "https://example.is/cart",
    "metadata": { "order_id": "1042" }
  }'
```

Useful optional fields:

- `success_url`, `cancel_url`: where the customer goes afterwards. Kling adds `?session_id=...` to the success URL.
- `locale`: `is` or `en` for the checkout language.
- `customer_id`, or `customer_email`, `customer_name`, `customer_phone` to pre-fill.
- `promotion_code`: apply a discount code.
- `save_payment_method`: keep the card for later charges.
- `capture: false`: authorise now and capture later, see [Payments](https://kling.is/en/docs/payments).
- `payment_method_type`: `card` or `bank_claim` (an [online bank claim](https://kling.is/en/docs/bank-claims)).
- `allow_custom_amount` and `minimum_amount`: let the customer choose the amount.
- `metadata`: your own keys and values, such as an order number.

## What comes back

The response includes `id`, `url`, `status`, `payment_status`, `amount`, `currency`, `expires_at` and the fields you sent. Send the customer to `url`, or open the session in the overlay with its `id`.

- `status`: `open` while waiting, `complete` when finished, `expired` after 24 hours.
- `payment_status`: `paid`, `unpaid`, `awaiting_claim` (a bank claim was issued and the customer pays it in their online bank) or `no_payment_required`.

## Confirm the payment on your server

Don't treat the redirect to `success_url` as proof of payment. Either listen for the `checkout.session.completed` [webhook](https://kling.is/en/docs/webhooks), or fetch the session with `GET /v1/checkout/sessions/{id}` and check `payment_status`. For bank claims, ship when `payment_intent.captured` arrives: that is when the customer has paid.

`GET /v1/checkout/sessions` lists sessions, filtered by `status` and paginated with `limit` and `starting_after`.

## Amounts and currency

Amounts are integers. ISK has no decimals, so `4990` is 4.990 kr. Euros and US dollars can be switched on for your account; ask us at [hallo@kling.is](mailto:hallo@kling.is).
