# Checkouts

A checkout is a cart that becomes a charge once the shopper authorizes it. Create it with an API key; the shopper authorizes it in the Fluense app.

## Create

```bash
curl -s https://api.fluense.social/checkouts \
  -H "x-api-key: $KEY" \
  -H 'content-type: application/json' \
  -d '{
    "terminal_id": "019a…",
    "currency": "USD",
    "items": [
      { "product_id": "sku-1", "display_name": "Desk lamp", "unit_price": 8900, "qty": 1, "cashback_rate": 500 }
    ],
    "shipping_amount": 0,
    "tax_amount": 800,
    "total": 9700,
    "order_id": "order-1001",
    "expires_in_secs": 3600
  }'
```

```json
{ "id": "019a…", "terminal_id": "019a…" }
```

### Body

| Field | Type | Notes |
| --- | --- | --- |
| `items` | array | Required, non-empty. Each line: `product_id`, `display_name`, `unit_price` (minor units), `qty` > 0, `cashback_rate` (bps, 0–10000), optional `item_image_url`, `item_url` |
| `total` | integer | Required. Must equal `sum(unit_price x qty) + shipping_amount + tax_amount` |
| `currency` | string | ISO-4217, default `USD`. Must match the shopper's account currency |
| `shipping_amount` | integer | Minor units, default 0 |
| `tax_amount` | integer | Minor units, default 0 |
| `terminal_id` | uuid | Optional. Omit to auto-create a `USE_ONCE` terminal |
| `order_id` | string | Your reference; echoed in sale responses. Not used for idempotency |
| `store` / `shipping` | object | Optional JSON blobs returned with the sale |
| `user_confirmation_url` / `user_cancel_url` | string | Optional redirects for hosted flows |
| `expires_in_secs` | integer | 60 s – 7 days; default 24 h |

## Statuses

`PENDING` → `AUTHORIZED` → `CAPTURED`

- `VOIDED` — the authorization was cancelled.
- `EXPIRED` — the checkout expired before payment.
- `SUPERSEDED` — a newer checkout replaced it on the same reusable terminal.

## Authorize (shopper side)

The Fluense app calls this with the shopper's session — it is not a merchant call, but it gates the flow:

```
POST /checkouts/{id}/authorize      # consumer session
```

```json
{ "auth_id": "019a…" }
```

Gates: KYC approved, transaction monitoring, wallet balance >= total. The authorization holds funds for **7 days**; capture inside that window.

## Errors

- `400 empty items` / `bad line` / `bad cashback_rate` — invalid cart.
- `400 total mismatch: server-computed N` — recompute `total`.
- `400 terminal belongs to another merchant` / `only REUSABLE terminals can be reused` / `terminal inactive`.
