Skip to main content
This guide walks through the checkout process — from collecting customer information to creating a payment intent and completing the order.

Checkout steps

1

Set fulfillment method

Choose takeout, delivery, table-side, or room service.
2

Set order time

ASAP or scheduled for a specific date and time.
3

Collect customer details

Name, email, and optionally phone number.
4

Set gratuity (optional)

Apply a tip percentage or custom amount.
5

Create payment intent

Get a Stripe client secret for secure payment collection.
6

Confirm payment

Use Stripe.js to complete the charge on the client.

1. Set fulfillment method

Update the cart with the customer’s preferred fulfillment method.
await storefront.cart.update('loc_123', cartId, {
  fulfillmentMethod: 'takeout', // 'takeout' | 'delivery' | 'table_side' | 'room_service'
});
For delivery, table-side, or room service, see the Fulfillment Methods guide.

2. Set order time

// ASAP order
await storefront.cart.updateOrderTime('loc_123', cartId, {
  pickupType: 'ASAP',
});

// Scheduled order
await storefront.cart.updateOrderTime('loc_123', cartId, {
  pickupType: 'LATER',
  orderDate: '2025-03-15',
  orderTime: '18:30',
});
Call storefront.locations.getOrderTimes(locationId) to get the available time slots before showing the picker.

3. Collect customer details

Validate and save the customer’s name and contact information.
await storefront.cart.validateAndUpdateCustomer('loc_123', cartId, {
  customerName: 'Alex Johnson',
  emailAddress: 'alex@example.com',
  phoneNumber: '+1234567890',
});

4. Set gratuity (optional)

If the location has tipping enabled, set a tip amount or percentage.
// First, check if tipping is enabled
const tipConfig = await storefront.locations.getGratuity('loc_123');

if (tipConfig.enabled) {
  // Apply a percentage-based tip
  await storefront.cart.updateGratuity('loc_123', cartId, {
    percentage: '18',
  });

  // Or a fixed amount
  await storefront.cart.updateGratuity('loc_123', cartId, {
    amount: '5.00',
  });
}
The WaiterTipConfigResponse tells you:
FieldDescription
enabledWhether tipping is turned on for this location
tipPercentageArray of suggested percentages (e.g., ["15", "18", "20"])
defaultTipPercentageThe pre-selected percentage
shouldAllowCustomTipWhether to show a custom amount input

5. Create a payment intent

Create a Stripe PaymentIntent to securely collect payment on the client.
const payment = await storefront.payments.createIntent('loc_123', cartId);

// payment.clientSecret — pass to Stripe.js
// payment.stripeAccountId — the connected Stripe account

6. Confirm payment with Stripe.js

Use the clientSecret to complete the payment on the frontend.
import { useStripe, useElements, PaymentElement } from '@stripe/react-stripe-js';

function PaymentForm({ clientSecret }: { clientSecret: string }) {
  const stripe = useStripe();
  const elements = useElements();

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!stripe || !elements) return;

    const { error } = await stripe.confirmPayment({
      elements,
      confirmParams: {
        return_url: `${window.location.origin}/order/confirmation`,
      },
    });

    if (error) {
      console.error('Payment failed:', error.message);
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <PaymentElement />
      <button type="submit" className="mt-4 w-full py-3 bg-teal-600 text-white rounded-lg">
        Pay now
      </button>
    </form>
  );
}
Always use Stripe.js or Stripe Elements for payment collection. Never handle raw card numbers in your own code.

Track analytics events

Fire analytics events at key checkout milestones.
// When the user views the checkout page
await storefront.analyticsEvents.track('loc_123', {
  cartId,
  eventType: 'CHECKOUT_VIEW',
});

// After order is placed
await storefront.analyticsEvents.track('loc_123', {
  cartId,
  eventType: 'ORDER_PLACED',
  metadata: { total: cart.orderTotalWithServiceFee },
});

Complete checkout example

import { storefront } from '@/lib/storefront';

export async function checkout(locationId: string, cartId: string, customer: {
  name: string;
  email: string;
  phone?: string;
}) {
  // 1. Set customer details
  await storefront.cart.validateAndUpdateCustomer(locationId, cartId, {
    customerName: customer.name,
    emailAddress: customer.email,
    phoneNumber: customer.phone,
  });

  // 2. Set order time
  await storefront.cart.updateOrderTime(locationId, cartId, {
    pickupType: 'ASAP',
  });

  // 3. Create payment intent
  const { clientSecret, stripeAccountId } = await storefront.payments.createIntent(
    locationId,
    cartId
  );

  return { clientSecret, stripeAccountId };
}

Next steps