Payment happens on Gale’s secure hosted page. These endpoints control the checkout lifecycle.

Create Checkout

POST /v1/checkout
Content-Type: application/json
Authorization: Bearer <merchant_api_token>
Idempotency-Key: <uuid-v4>

Body

{
  "customer": {
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "jane@example.com"
  },
  "line_items": [
    {
      "product_id": "prod_abc123",
      "price_cents": 5000,
      "quantity": 1
    }
  ],
  "shipping_amount_cents": 700,
  "tax_amount_cents": 350,
  "discount_amount_cents": 0,
  "total_amount_cents": 1050,
  "currency": "usd",
  "external_cart_id": "cart-789"
}

Success 201

{
  "checkout_id": "chk_123",
  "status": "UNPAID",
  "checkout_url": "https://checkout.withgale.com/chk_123",
  "expires_at": "2025-06-05T12:30:00Z"
}

Redirect your shopper to checkout_url.

Get Checkout Status

GET /v1/checkout/{checkout_id}
Authorization: Bearer <merchant_api_token>

Subscription fields

If the checkout includes one or more subscription plans:

  • purchase_typeone_time | subscription | mixed
  • subscription_items[] — list of objects
    • plan_id — ID returned from Create Plan
    • plan_name — human-readable name
    • intervalmonthly | quarterly | yearly
    • price_cents — price per billing cycle
    • quantity — how many seats / units

If the cart also contains non-subscription products, those appear in one_time_items[].

Response

{
  "checkout_id": "chk_123",
  "status": "PAID",
  "purchase_type": "subscription",
  "subscription_items": [
    {
      "plan_id": "plan_123",
      "plan_name": "Monthly Lens Supply",
      "interval": "monthly",
      "price_cents": 2500,
      "quantity": 1
    }
  ],
  "one_time_items": [],
  "amount_paid_cents": 2500,
  "currency": "usd",
  "paid_at": "2025-06-05T12:04:12Z"
}

Status values: UNPAID, PAID, REFUNDED, CANCELLED, EXPIRED.

Refund Checkout

Partial or full refund. Omit line_items for a full refund.

POST /v1/checkout/{checkout_id}/refund
Content-Type: application/json
Authorization: Bearer <merchant_api_token>
Idempotency-Key: <uuid-v4>

Partial Refund Body

{
  "line_items": [
    { "line_item_id": "li_01", "quantity": 1, "amount_cents": 100 }
  ],
  "reason": "Damaged item"
}

Success 200

{
  "checkout_id": "chk_123",
  "status": "REFUNDED",
  "refunded_amount_cents": 5000,
  "currency": "usd",
  "refunded_at": "2025-06-05T12:10:22Z"
}

Cancel Checkout

Allowed only while status is UNPAID.

POST /v1/checkout/{checkout_id}/cancel
Authorization: Bearer <merchant_api_token>
Idempotency-Key: <uuid-v4>

Success 200

{
  "checkout_id": "chk_123",
  "status": "CANCELLED",
  "cancelled_at": "2025-06-05T12:08:00Z"
}

Cancelling a paid/expired session returns 409 Conflict.

Subscribe to the checkoutStatusChange webhook for live status updates.