> ## Documentation Index
> Fetch the complete documentation index at: https://docs.craveup.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Fulfillment Methods

> Configure delivery, table-side, and room service for your storefront orders.

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.

```ts theme={null}
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.

<CodeGroup>
  ```ts SDK theme={null}
  await storefront.cart.update('loc_123', cartId, {
    fulfillmentMethod: 'takeout',
  });
  ```

  ```bash REST theme={null}
  curl -X PATCH "https://api.craveup.com/api/v1/locations/loc_123/carts/{cartId}" \
    -H "X-API-Key: $CRAVEUP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"fulfillmentMethod": "takeout"}'
  ```
</CodeGroup>

## Delivery

Delivery requires the customer's address with geographic coordinates for distance calculation and fee computation.

<Steps>
  <Step title="Check delivery distance">
    Calculate the distance between the customer and the location to validate the delivery zone.
  </Step>

  <Step title="Set delivery address">
    Save the address to the cart.
  </Step>
</Steps>

### Check delivery distance

<CodeGroup>
  ```ts SDK theme={null}
  const distance = await storefront.locations.getDistance('loc_123', {
    lat: 37.7749,
    lng: -122.4194,
    unit: 'miles',
  });

  console.log(`${distance.distance.miles} miles away`);
  ```

  ```bash REST theme={null}
  curl -X POST "https://api.craveup.com/api/v1/locations/loc_123/distance" \
    -H "X-API-Key: $CRAVEUP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"lat": 37.7749, "lng": -122.4194, "unit": "miles"}'
  ```
</CodeGroup>

### Set delivery address

<CodeGroup>
  ```ts SDK theme={null}
  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,
  });
  ```

  ```bash REST theme={null}
  curl -X PUT "https://api.craveup.com/api/v1/locations/loc_123/carts/{cartId}/set-delivery" \
    -H "X-API-Key: $CRAVEUP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "street": "123 Main Street",
      "city": "San Francisco",
      "state": "CA",
      "zipCode": "94105",
      "country": "US",
      "lat": 37.7749,
      "lng": -122.4194
    }'
  ```
</CodeGroup>

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                       |

<Tip>
  Use a geocoding service (Google Places, Mapbox) to get `lat`/`lng` from the customer's address input.
</Tip>

## Table-side

Table-side service sends the order to a specific table number within the restaurant.

<CodeGroup>
  ```ts SDK theme={null}
  await storefront.cart.setTable('loc_123', cartId, 'T-12');
  ```

  ```bash REST theme={null}
  curl -X PUT "https://api.craveup.com/api/v1/locations/loc_123/carts/{cartId}/set-table" \
    -H "X-API-Key: $CRAVEUP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"fulfilmentMethod": "table_side", "tableNumber": "T-12"}'
  ```
</CodeGroup>

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.

<CodeGroup>
  ```ts SDK theme={null}
  await storefront.cart.setRoom('loc_123', cartId, {
    roomNumber: '405',
    lastName: 'Johnson',
  });
  ```

  ```bash REST theme={null}
  curl -X PUT "https://api.craveup.com/api/v1/locations/loc_123/carts/{cartId}/set-room" \
    -H "X-API-Key: $CRAVEUP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"roomNumber": "405", "lastName": "Johnson"}'
  ```
</CodeGroup>

## 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`:

```ts theme={null}
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

<CardGroup cols={2}>
  <Card title="Checkout Flow" icon="credit-card" href="/guides/checkout-flow">
    Complete the order with customer details and payment.
  </Card>

  <Card title="Accept Payments" icon="money-bill" href="/guides/accept-payments">
    Set up Stripe for secure payment processing.
  </Card>
</CardGroup>
