Checkout Sessions

A Checkout Session is the recommended way to take payments: your server creates a session with your API key, gets back a hosted checkout url, and your front end opens it as an overlay or redirect. Taxes are calculated automatically.

Core concepts

mode — what the session does

modePurposeNotes
paymentOne-time paymentLine items with one-time or ad hoc pricing
subscriptionStart a subscriptionLine items must reference a recurring price (price_id)
setupSave a card only, no chargeUsed to collect a payment method for later use

presentation — iframe vs link

presentationBuyer experienceFront-end code
iframeSDK overlay; the buyer stays on your site (recommended)FastStar.checkout.open({ url })
linkFull-page redirect to the hosted checkoutwindow.location.href = url

line_items

Each line item references your catalog or, in Direct/PSP mode only, an ad hoc amount:

FieldTypeDescription
price_idstring, optionalA price from your catalog (price_...)
product_idstring, optionalA product from your catalog (prod_...); its default price is used
quantityintQuantity
ad_hoc_amountint64, optionalOne-off amount in the smallest currency unit — Direct/PSP mode only
ad_hoc_currencystring, optionalCurrency for ad_hoc_amount
descriptionstring, optionalLine description shown at checkout

MoR rule: for Merchant of Record merchants, every line item must reference a catalog price_id or product_id — the platform needs product information for tax compliance. Ad hoc amounts (ad_hoc_amount / ad_hoc_currency) are only available in Direct/PSP mode. Manage your catalog via /merchant/catalog/products and /merchant/catalog/prices (see the API reference).

How tax is displayed

Sessions return amount_subtotal, amount_tax and amount_total (all in the smallest currency unit):

  • Tax-inclusive regions (e.g. EU VAT): the tax is already inside the price, so amount_total = amount_subtotal and amount_tax shows the portion included.
  • Tax-exclusive regions (e.g. US sales tax): tax is added on top, so amount_total = amount_subtotal + amount_tax.

Pass buyer_country (and a region where relevant) to get accurate tax at session creation time.

Creating a session

curl https://api.faststarpay.com/api/v1/public/checkout/sessions \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "payment",
    "presentation": "iframe",
    "line_items": [
      { "price_id": "price_xxx", "quantity": 1 }
    ],
    "customer_email": "[email protected]",
    "success_url": "https://yoursite.com/success",
    "cancel_url": "https://yoursite.com/cancel",
    "buyer_country": "US",
    "client_reference_id": "order_10042"
  }'

Response (inside the standard { success, message, data } envelope):

{
  "success": true,
  "message": "Checkout session created successfully",
  "data": {
    "session": {
      "id": "cs_xxx",
      "status": "open",
      "amount_subtotal": 999,
      "amount_tax": 80,
      "amount_total": 1079,
      "currency": "USD",
      "session_token": "xxx",
      "expires_at": "2026-06-13T12:00:00Z"
    },
    "url": "https://cashier.faststarpay.com/checkout/cs_xxx?token=xxx",
    "session_token": "xxx"
  }
}

Request fields

FieldTypeDescription
modestringpayment | subscription | setup
presentationstringiframe | link
line_itemsarraySee above
customer_emailstring, optionalPre-fills the buyer's email
success_urlstringWhere the buyer lands after success
cancel_urlstringWhere the buyer lands after cancel
buyer_countrystring, optionalISO country code, used for tax calculation
client_reference_idstring, optionalYour own order/reference id, echoed back for reconciliation

Server-side example (Node)

// Express: create a Checkout Session and return its url to the browser
app.post('/api/checkout', async (req, res) => {
  const r = await fetch('https://api.faststarpay.com/api/v1/public/checkout/sessions', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': process.env.FASTSTAR_API_KEY, // keep the key on the server
    },
    body: JSON.stringify({
      mode: 'payment',
      presentation: 'iframe',
      line_items: [{ price_id: 'price_xxx', quantity: 1 }],
      success_url: 'https://yoursite.com/success',
      cancel_url: 'https://yoursite.com/cancel',
    }),
  });
  const { data } = await r.json();
  res.json({ url: data.url });
});

Front-end example

// Get the session url from your server, then open the overlay
const { url } = await (await fetch('/api/checkout', { method: 'POST' })).json();
FastStar.checkout.open({ url });

FastStar.on('checkout.success', (data) => {
  // UI only — fulfillment is driven by the payment.succeeded webhook
  console.log('paid', data.checkout_session_id);
  window.location.href = '/thanks';
});

Fulfillment: front-end events confirm the buyer experience, but the source of truth for fulfillment is the server-side webhook (payment.succeeded). Use client_reference_id to match the event to your order.