This guide walks through the checkout process — from collecting customer information to creating a payment intent and completing the order.
Checkout steps
Set fulfillment method
Choose takeout, delivery, table-side, or room service.
Set order time
ASAP or scheduled for a specific date and time.
Collect customer details
Name, email, and optionally phone number.
Set gratuity (optional)
Apply a tip percentage or custom amount.
Create payment intent
Get a Stripe client secret for secure payment collection.
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:
| Field | Description |
|---|
enabled | Whether tipping is turned on for this location |
tipPercentage | Array of suggested percentages (e.g., ["15", "18", "20"]) |
defaultTipPercentage | The pre-selected percentage |
shouldAllowCustomTip | Whether 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