Skip to main content
REST APICart + checkout
REST API

Cart + checkout

Build buyer flows that add items, apply discounts, set shipping, and hand off to checkout.

Buyer-side state — create cart, add items, apply coupons, set address, initiate Stripe checkout.

Carts are the buyer's in-progress checkout state. The REST cart API mirrors what the hosted storefront does — create a cart, add items, apply a coupon, set the shipping address, initiate Stripe checkout. No auth required.

Endpoints

Method + pathPurpose
POST /api/storefront/v1/cartsCreate a cart. Returns a token.
GET /api/storefront/v1/carts/{token}Fetch the current cart.
PUT /api/storefront/v1/carts/{token}Update shipping address, selected option, buyer.
DELETE /api/storefront/v1/carts/{token}Cancel the cart.
POST /api/storefront/v1/carts/{token}/itemsAdd a line item.
POST /api/storefront/v1/carts/{token}/couponApply a coupon code.
POST /api/storefront/v1/carts/{token}/checkoutInitiate Stripe checkout. Returns a redirect URL.

Create

bash
curl -X POST https://aly.store/api/storefront/v1/carts \  -H "Content-Type: application/json" \  -d '{    "site_slug": "acme",    "buyer": { "email": "buyer@example.com" }  }'
json
{  "token": "cart_8f3a...",  "status": "active",  "site_slug": "acme",  "items": [],  "totals": { "subtotal": 0, "shipping": 0, "tax": 0, "discount": 0, "total": 0 },  "buyer": { "email": "buyer@example.com" },  "expires_at": "..."}

Add a line item

bash
curl -X POST https://aly.store/api/storefront/v1/carts/cart_8f3a.../items \  -H "Idempotency-Key: $(uuidgen)" \  -H "Content-Type: application/json" \  -d '{    "product_id": "prod_abc",    "variant_options": { "color": "natural" },    "quantity": 2  }'

Apply a coupon

bash
curl -X POST https://aly.store/api/storefront/v1/carts/cart_8f3a.../coupon \  -H "Content-Type: application/json" \  -d '{ "code": "WELCOME10" }'

Set the shipping address

bash
curl -X PUT https://aly.store/api/storefront/v1/carts/cart_8f3a... \  -H "Content-Type: application/json" \  -d '{    "shipping_address": { "country": "US", "state": "CA", "postcode": "94110" },    "selected_shipping_option_id": "ship_std"  }'

Initiate checkout

bash
curl -X POST https://aly.store/api/storefront/v1/carts/cart_8f3a.../checkout \  -H "Content-Type: application/json" \  -d '{ "return_url": "https://my-app.example/thanks" }'
json
{  "redirect_url": "https://checkout.stripe.com/c/pay/cs_test_...",  "session_id": "cs_stripe_...",  "expires_at": "..."}

Redirect the buyer there. On success they return to your return_url; the cart status moves to completed when the Stripe webhook confirms.

REST cart vs UCP checkout
The REST cart drives Stripe-hosted checkout — best for buyer-facing UIs. UCP's checkout sessions are the agent-shaped equivalent — better when an agent needs the server-authoritative price breakdown without redirecting to a hosted page. Both write the same underlying cart rows in Convex.

Cart shape

json
{  "token": "cart_8f3a...",  "status": "active" | "abandoned" | "completed",  "site_slug": "acme",  "items": [    {      "id": "li_1",      "product_id": "prod_abc",      "variant_id": "var_1",      "name": "Linen Tote — natural",      "quantity": 2,      "unit_price": 4200,      "subtotal": 8400,      "image_url": "..."    }  ],  "shipping_address": { "country": "US", "state": "CA", "postcode": "94110" },  "shipping_options": [    { "id": "ship_std", "label": "Standard", "amount": 500 }  ],  "selected_shipping_option_id": "ship_std",  "coupon": { "code": "WELCOME10", "amount_off": 840 },  "totals": { "subtotal": 8400, "shipping": 500, "tax": 720, "discount": 840, "total": 8780 },  "buyer": { "email": "buyer@example.com" },  "expires_at": "..."}
Updated

Was this page helpful?