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

# Create Checkout Session

> Create a checkout session and get a hosted checkout URL

# Create Checkout Session

Create a checkout session for a customer. Returns a checkout URL where the customer completes payment on Gale's hosted page. Gale handles card collection, eligibility detection, and LMN flow automatically.

<Note>All monetary amounts are integers in cents (e.g., 4995 = \$49.95).</Note>

## Endpoint

```
POST /api/v2/checkout
```

## Authentication

```bash theme={null}
Authorization: Bearer glm_test_YOUR_API_KEY
```

## Request Body

```json theme={null}
{
  "reference_id": "your-order-123",
  "customer": {
    "email": "jane@example.com",
    "first_name": "Jane",
    "last_name": "Doe",
    "phone": "+1-555-123-4567"
  },
  "line_items": [
    {
      "product_id": "BP-MONITOR-001",
      "name": "Digital Blood Pressure Monitor",
      "image_url": "https://yourcdn.com/bp-monitor.jpg",
      "price": 4995,
      "quantity": 1,
      "currency": "USD"
    },
    {
      "product_id": "VITAMINS-030",
      "name": "Daily Multivitamins (30-day)",
      "image_url": "https://yourcdn.com/vitamins.jpg",
      "price": 1999,
      "quantity": 2,
      "currency": "USD"
    }
  ],
  "shipping_info": {
    "address_line_1": "123 Main St",
    "address_line_2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "postal_code": "10001",
    "country": "US"
  },
  "billing_info": {
    "address_line_1": "123 Main St",
    "city": "New York",
    "state": "NY",
    "postal_code": "10001",
    "country": "US"
  },
  "shipping": 500,
  "tax": 410,
  "discount": 0,
  "success_url": "https://yoursite.com/order/success",
  "failure_url": "https://yoursite.com/order/failed",
  "metadata": {
    "platform": "CUSTOM",
    "webhook_url": "https://your-server.com/webhooks/gale"
  }
}
```

## Parameters

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `reference_id` | string | Yes | Your order or cart ID for correlation |
| `customer` | object | Yes | Customer information |
| `customer.email` | string | Yes | Customer email |
| `customer.first_name` | string | Yes | Customer first name |
| `customer.last_name` | string | Yes | Customer last name |
| `customer.phone` | string | No | Customer phone number |
| `line_items` | array | Yes | Products being purchased |
| `line_items[].product_id` | string | Yes | Your product ID (must match synced product) |
| `line_items[].name` | string | Yes | Product name |
| `line_items[].image_url` | string | No | Product image URL |
| `line_items[].price` | integer | Yes | Unit price in cents |
| `line_items[].quantity` | integer | Yes | Quantity |
| `line_items[].currency` | string | Yes | Currency code (e.g., `"USD"`) |
| `shipping_info` | object | Yes | Shipping address |
| `shipping_info.address_line_1` | string | Yes | Address line 1 |
| `shipping_info.address_line_2` | string | No | Address line 2 |
| `shipping_info.city` | string | Yes | City |
| `shipping_info.state` | string | Yes | State |
| `shipping_info.postal_code` | string | Yes | ZIP/Postal code |
| `shipping_info.country` | string | Yes | Country code (e.g., `"US"`) |
| `billing_info` | object | No | Billing address (defaults to shipping if omitted) |
| `billing_info.address_line_1` | string | Yes | Address line 1 |
| `billing_info.address_line_2` | string | No | Address line 2 |
| `billing_info.city` | string | Yes | City |
| `billing_info.state` | string | Yes | State |
| `billing_info.postal_code` | string | Yes | ZIP/Postal code |
| `billing_info.country` | string | Yes | Country code (e.g., `"US"`) |
| `shipping` | integer | No | Shipping amount in cents |
| `tax` | integer | No | Tax amount in cents |
| `discount` | integer | No | Discount amount in cents |
| `success_url` | string | Yes | Redirect URL after successful payment |
| `failure_url` | string | Yes | Redirect URL if payment fails or customer cancels |
| `metadata` | object | No | Custom key-value pairs |
| `metadata.webhook_url` | string | No | URL to receive payment webhooks (recommended) |

<Warning>
  `product_id` is **your** product identifier — the one you supplied when syncing products (`merchant_product_id`), not the numeric id displayed in the dashboard. Line items that don't match a synced product are accepted as **pass-through items and treated as non-HSA/FSA-eligible**, so an unmatched id silently produces a regular (non-eligible) checkout. Your own product ids are identical across test and live, so the same integration carries to go-live unchanged.
</Warning>

## Response

```json theme={null}
{
  "success": true,
  "message": "Checkout created",
  "data": {
    "checkout_id": "cs_a1b2c3...",
    "checkout_url": "https://checkout.withgale.com/checkout/cs_a1b2c3...?token=...",
    "reference_id": "order-789",
    "status": "open",
    "type": "eligible",
    "customer": { "email": "jane@example.com", "first_name": "Jane", "last_name": "Doe" },
    "line_items": [ ... ],
    "amounts": {
      "subtotal": 4995,
      "hsa_amount": 4995,
      "regular_amount": 0,
      "shipping": 995,
      "tax": 410,
      "discount": 0,
      "total": 6400
    },
    "success_url": "https://yourapp.com/checkout/success",
    "failure_url": "https://yourapp.com/checkout/cancel",
    "expires_at": "2026-02-26T14:30:00Z",
    "created_at": "2026-02-26T13:30:00Z"
  },
  "metadata": { "request_id": "..." }
}
```

Fields are returned under `data`.

| Field | Type | Description |
| :- | :- | :- |
| `data.checkout_id` | string | Unique checkout session identifier (`cs_...`) |
| `data.checkout_url` | string | Hosted checkout page URL (includes access token) — redirect customer here |
| `data.status` | string | Session status (`open`) |
| `data.type` | string | Cart type (`eligible`, `split`, `regular`) |
| `data.amounts` | object | All amounts in cents: `subtotal`, `hsa_amount`, `regular_amount`, `shipping`, `tax`, `discount`, `total` |
| `data.expires_at` | timestamp | When session expires |

## Example

```bash theme={null}
curl -X POST https://api.withgale.com/api/v2/checkout \
  -H "Authorization: Bearer glm_test_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "reference_id": "order-789",
    "customer": {
      "email": "jane@example.com",
      "first_name": "Jane",
      "last_name": "Doe"
    },
    "line_items": [
      {
        "product_id": "BP-MONITOR-001",
        "name": "Digital Blood Pressure Monitor",
        "price": 4995,
        "quantity": 1,
        "currency": "USD"
      }
    ],
    "shipping_info": {
      "address_line_1": "123 Main St",
      "city": "New York",
      "state": "NY",
      "postal_code": "10001",
      "country": "US"
    },
    "shipping": 500,
    "tax": 410,
    "success_url": "https://yoursite.com/order/success",
    "failure_url": "https://yoursite.com/order/failed"
  }'
```

### Subscription Checkout <sup>Beta</sup>

```bash theme={null}
curl -X POST https://api.withgale.com/api/v2/checkout \
  -H "Authorization: Bearer glm_test_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "reference_id": "membership-456",
    "customer": {
      "email": "member@example.com",
      "first_name": "Jane",
      "last_name": "Doe"
    },
    "line_items": [
      {
        "product_id": "MEMBERSHIP-PREMIUM",
        "name": "Premium Membership",
        "price": 9900,
        "quantity": 1,
        "currency": "USD"
      }
    ],
    "payment_type": "subscription",
    "subscription": {
      "interval": "monthly",
      "trial_period_days": 14
    },
    "success_url": "https://yoursite.com/welcome",
    "failure_url": "https://yoursite.com/pricing"
  }'
```

## Checkout Types

Gale automatically determines the checkout type based on product eligibility:

| Type | Description |
| :- | :- |
| `eligible` | All items are HSA/FSA eligible |
| `split` | Mix of eligible and non-eligible items |
| `regular` | No items are eligible |

You don't need to specify the type — Gale handles this automatically based on the products in the checkout.

## Checkout Status

| Status | Description |
| :- | :- |
| `open` | Checkout session created, awaiting customer |
| `paid` | Customer completed payment, order created |
| `expired` | Session expired (24 hours) |

## Webhooks

When payment completes, you receive an `order.created` webhook:

```json theme={null}
{
  "type": "order.created",
  "data": {
    "id": "ord_abc123",
    "checkout_id": "01HXYZ...",
    "reference_id": "your-order-123",
    "status": "completed",
    "customer": {
      "email": "jane@example.com"
    }
  }
}
```

See [Webhooks Reference](/developer-manual/webhooks) for setup and all event types.

## Errors

| Status Code | Error Code | Description |
| :- | :- | :- |
| 400 | `bad_request` | Missing or invalid parameters |
| 401 | `unauthorized` | Invalid API key |
| 422 | `validation_error` | Field validation failed |

See [Error Reference](/developer-manual/errors) for details.

## Related

* [Get Checkout Session](/api-reference/endpoint/get-checkout)
* [Checkout Session Object](/api-reference/objects/checkout-session)
* [Checkout Integration Guide](/integration/checkout)
* [Order Object](/api-reference/objects/order)
* [Webhooks](/developer-manual/webhooks)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.