Crave supports four fulfillment methods. This guide covers how to set each one on a cart and what data each method requires.
Available methods
| Method | Value | Use case |
|---|
| Takeout / Pickup | takeout | Customer picks up at the counter |
| Delivery | delivery | Order delivered to customer’s address |
| Table-side | table_side | Dine-in, delivered to a table number |
| Room service | room_service | Hotel/hospitality, delivered to a room |
Check which methods are enabled
Each location has a methodsStatus field indicating what’s available.
const merchant = await storefront.merchant.getBySlug('downtown-pizza');
const location = merchant.locations[0];
console.log(location.methodsStatus);
// { pickup: true, table: true, delivery: true, roomService: false }
Only show fulfillment options that are enabled for the location.
Takeout (default)
Takeout is the simplest method — just set the fulfillment method on the cart.
await storefront.cart.update('loc_123', cartId, {
fulfillmentMethod: 'takeout',
});
Delivery
Delivery requires the customer’s address with geographic coordinates for distance calculation and fee computation.
Check delivery distance
Calculate the distance between the customer and the location to validate the delivery zone.
Set delivery address
Save the address to the cart.
Check delivery distance
const distance = await storefront.locations.getDistance('loc_123', {
lat: 37.7749,
lng: -122.4194,
unit: 'miles',
});
console.log(`${distance.distance.miles} miles away`);
Set delivery address
await storefront.cart.setDelivery('loc_123', cartId, {
street: '123 Main Street',
city: 'San Francisco',
state: 'CA',
zipCode: '94105',
country: 'US',
lat: 37.7749,
lng: -122.4194,
});
The Address type requires these fields:
| Field | Type | Required | Description |
|---|
street | string | Yes | Street address |
streetOptional | string | No | Apt/suite/floor |
city | string | Yes | City |
state | string | Yes | State/province code |
zipCode | string | Yes | Postal code |
country | string | Yes | Country code (e.g., US, GB) |
lat | number | Yes | Latitude |
lng | number | Yes | Longitude |
Use a geocoding service (Google Places, Mapbox) to get lat/lng from the customer’s address input.
Table-side
Table-side service sends the order to a specific table number within the restaurant.
await storefront.cart.setTable('loc_123', cartId, 'T-12');
Table numbers are freeform strings — use whatever format the restaurant uses (e.g., "12", "T-12", "Patio 3").
Room service
Room service is designed for hotels and hospitality venues. It requires a room number and the guest’s last name for verification.
await storefront.cart.setRoom('loc_123', cartId, {
roomNumber: '405',
lastName: 'Johnson',
});
Fulfillment fees
Each fulfillment method may have associated fees configured by the restaurant. These are automatically calculated and included in the cart totals:
| Cart field | Description |
|---|
fulfillmentMethodFeeTotal | The fee for the selected fulfillment method |
fulfillmentMethodFeeTotalFormatted | Formatted version (e.g., "$3.99") |
The fee breakdown is also available in cart.fees:
const cart = await storefront.cart.get('loc_123', cartId);
console.log('Delivery fee:', cart.fulfillmentMethodFeeTotalFormatted);
console.log('Fee rate:', cart.fees.fulfillmentMethodFeeRate);
console.log('Fee fixed:', cart.fees.fulfillmentMethodFeeFix);
Next steps