Skip to content

Carts & Checkout

1. Create cart → add items
2. POST /checkout/initiate → tax + shipping rates calculated
3. User selects shipping rate
4. POST /checkout/complete → order created, payment intent returned
5. Client-side payment (Airwallex Drop-in or Stripe Elements)
6. POST /checkout/confirm → order finalized
Terminal window
# Create cart
POST /api/v1/carts
{ "currency": "USD" }
# Add item
POST /api/v1/carts/:cart_id/items
{ "product_id": "uuid", "quantity": 2 }
Terminal window
POST /api/v1/checkout/initiate
{
"cart_id": "uuid",
"shipping_address": {
"first_name": "John",
"last_name": "Doe",
"address1": "123 Main St",
"city": "New York",
"state": "NY",
"country": "US",
"zip": "10001",
"phone": "+12125551234"
},
"currency": "USD"
}

Response includes available_shipping_rates, tax breakdown, and totals.

Terminal window
POST /api/v1/checkout/complete
{
"cart_id": "uuid",
"shipping_address": { ... },
"payment_method": { "type": "stripe_elements" },
"customer_email": "john@example.com",
"selected_shipping_rate": { ... }
}

Response includes client_secret for client-side payment confirmation.

After the client-side payment succeeds:

Terminal window
POST /api/v1/checkout/confirm
{
"order_id": "uuid",
"payment_intent_id": "pi_xxx",
"cart_id": "uuid"
}

The checkout supports multiple payment gateways:

  • Stripe — Stripe Elements (card, Apple Pay, Google Pay)
  • Airwallex — Airwallex Drop-in (card, WeChat Pay, Alipay)
  • Mock — for testing

Configure in [payment] section of config. The gateway is selected based on default_gateway setting.

Shipping rates are calculated based on:

  • Weight-based zones — per-country rates based on total cart weight
  • Flat rate — manual provider with fixed rates

Weight-based zones are the default. Rates are returned in the checkout initiate response.

Phone number is required for shipping — the checkout validates address.phone before initiating.