# Cart Operations & Checkout (/developers/cart-and-checkout)



This page covers the transactional side of the booking flow: building a cart, applying discounts, and completing checkout. It also covers gift card purchasing.

All examples assume you have [initialized the API client](/developers/resytech-api) and [selected an activity, date, and time slot](/developers/activities).

Shopping Cart [#shopping-cart]

createOrUpdateCart [#createorupdatecart]

Create a new cart or update an existing one. The server validates availability and returns pricing details.

```javascript
const result = await api.cart.createOrUpdateCart({
  cart: {
    activity: 'activity-uuid',
    duration: 'duration-uuid',
    date: '2025-07-15',
    timeSlotStart: '10:00',
    timeSlotEnd: '11:00',
    equipment: [
      {
        equipmentUuid: 'equipment-uuid',
        quantity: 1,
        seats: 2,
        addons: [
          {
            addonUuid: 'addon-uuid',
            quantity: 1,
            equipmentUuid: 'equipment-uuid'
          }
        ]
      }
    ]
  }
});

if (result.success) {
  console.log('Cart ID:', result.cartId);
  console.log('Total:', result.cart.total);
  console.log('Stripe account:', result.operatorAccountId);
}
```

To update an existing cart, pass the `cartId`:

```javascript
const updated = await api.cart.createOrUpdateCart({
  cartId: 'existing-cart-id',
  cart: {
    activity: 'activity-uuid',
    duration: 'duration-uuid',
    date: '2025-07-15',
    timeSlotStart: '14:00',
    timeSlotEnd: '15:00',
    equipment: [
      { equipmentUuid: 'equipment-uuid', quantity: 1, seats: 4 }
    ]
  }
});
```

CreateOrUpdateCartRequest [#createorupdatecartrequest]

| Field    | Type                 | Required | Description                                    |
| -------- | -------------------- | -------- | ---------------------------------------------- |
| `cart`   | `ClientShoppingCart` | Yes      | Cart contents (see below)                      |
| `cartId` | `string`             | No       | Existing cart ID to update; omit to create new |

CreateOrUpdateShoppingCartResponse [#createorupdateshoppingcartresponse]

| Field               | Type                         | Description                                                     |
| ------------------- | ---------------------------- | --------------------------------------------------------------- |
| `success`           | `boolean`                    | Whether the operation succeeded                                 |
| `cartId`            | `string`                     | Cart identifier for subsequent operations                       |
| `cart`              | `ServerShoppingCartOverview` | Server-calculated pricing and line items                        |
| `errorCode`         | `ShoppingCartErrorCode`      | Numeric error code (if failed)                                  |
| `removals`          | `ShoppingCartRemoval[]`      | Items removed due to validation (e.g., sold out equipment)      |
| `clientSecret`      | `string`                     | Stripe PaymentIntent client secret (for deferred payment setup) |
| `operatorAccountId` | `string`                     | Stripe connected account ID                                     |

***

ClientShoppingCart [#clientshoppingcart]

The core cart object sent to the server. Used by both `createOrUpdateCart` and `checkout`.

| Field                    | Type                            | Required | Description                                  |
| ------------------------ | ------------------------------- | -------- | -------------------------------------------- |
| `activity`               | `string`                        | Yes      | Activity UUID                                |
| `duration`               | `string`                        | Yes      | Duration UUID                                |
| `date`                   | `string`                        | Yes      | Booking date (YYYY-MM-DD)                    |
| `timeSlotStart`          | `string`                        | Yes      | Start time (HH:mm)                           |
| `timeSlotEnd`            | `string`                        | Yes      | End time (HH:mm)                             |
| `equipment`              | `ClientShoppingCartEquipment[]` | No       | Equipment selections                         |
| `customer`               | `ClientShoppingCartCustomer`    | No       | Customer info (required for checkout)        |
| `downPaymentRequested`   | `boolean`                       | No       | Request down payment instead of full payment |
| `isPrivateTour`          | `boolean`                       | No       | Book as a private tour                       |
| `durationMins`           | `number`                        | No       | Dynamic duration in minutes                  |
| `tripProtectionSelected` | `boolean`                       | No       | Opt into trip protection                     |

ClientShoppingCartEquipment [#clientshoppingcartequipment]

| Field           | Type                                 | Required | Description                |
| --------------- | ------------------------------------ | -------- | -------------------------- |
| `equipmentUuid` | `string`                             | Yes      | Equipment UUID             |
| `quantity`      | `number`                             | Yes      | Number of units            |
| `seats`         | `number`                             | Yes      | Number of seats (guests)   |
| `addons`        | `ClientShoppingCartEquipmentAddon[]` | No       | Add-ons for this equipment |

ClientShoppingCartEquipmentAddon [#clientshoppingcartequipmentaddon]

| Field           | Type     | Required | Description                       |
| --------------- | -------- | -------- | --------------------------------- |
| `addonUuid`     | `string` | Yes      | Add-on UUID                       |
| `quantity`      | `number` | Yes      | Quantity                          |
| `equipmentUuid` | `string` | Yes      | Equipment UUID this add-on is for |

ClientShoppingCartCustomer [#clientshoppingcartcustomer]

| Field         | Type     | Required | Description                           |
| ------------- | -------- | -------- | ------------------------------------- |
| `fullName`    | `string` | No       | Customer full name                    |
| `email`       | `string` | No       | Email address (required for checkout) |
| `countryCode` | `string` | No       | Phone country code (e.g., "1" for US) |
| `country`     | `string` | No       | Country name or code                  |
| `phone`       | `string` | No       | Phone number                          |

***

ServerShoppingCartOverview [#servershoppingcartoverview]

The server-side cart returned in responses. Contains calculated pricing, fees, and applied discounts.

| Field                    | Type                            | Description                          |
| ------------------------ | ------------------------------- | ------------------------------------ |
| `lineItems`              | `CartLineItem[]`                | Itemized charges                     |
| `fees`                   | `Fee[]`                         | Taxes and fees                       |
| `subtotal`               | `number`                        | Subtotal before fees and discounts   |
| `total`                  | `number`                        | Total after all calculations         |
| `feesTotal`              | `number`                        | Sum of all fees                      |
| `discountTotal`          | `number`                        | Sum of all discounts                 |
| `paid`                   | `number`                        | Amount already paid                  |
| `balance`                | `number`                        | Remaining balance                    |
| `couponCode`             | `string`                        | Applied coupon code                  |
| `giftCardCode`           | `string`                        | Applied gift card code               |
| `giftCardAmountApplied`  | `number`                        | Gift card amount used                |
| `giftCardBalance`        | `number`                        | Remaining gift card balance          |
| `dueNow`                 | `number`                        | Amount due at checkout               |
| `dueLater`               | `number`                        | Amount due later (for down payments) |
| `tripProtectionSelected` | `boolean`                       | Whether trip protection is selected  |
| `tripProtectionPrice`    | `number`                        | Trip protection price                |
| `equipment`              | `ServerShoppingCartEquipment[]` | Confirmed equipment selections       |

CartLineItem [#cartlineitem]

| Field   | Type     | Description           |
| ------- | -------- | --------------------- |
| `name`  | `string` | Line item description |
| `price` | `number` | Amount                |
| `type`  | `string` | Item type identifier  |

Fee [#fee]

| Field    | Type               | Description          |
| -------- | ------------------ | -------------------- |
| `uuid`   | `string`           | Fee identifier       |
| `name`   | `string`           | Fee display name     |
| `amount` | `number`           | Fee amount           |
| `type`   | `TaxesAndFeesType` | `0` = tax, `1` = fee |

***

updateCustomer [#updatecustomer]

Update customer information on an active cart.

```javascript
const result = await api.cart.updateCustomer({
  customer: {
    fullName: 'Jane Smith',
    email: 'jane@example.com',
    phone: '5551234567',
    countryCode: '1',
    country: 'US'
  },
  cartId: 'cart-id' // optional if using session-based cart
});
```

UpdateShoppingCartCustomerRequest [#updateshoppingcartcustomerrequest]

| Field      | Type                         | Required | Description      |
| ---------- | ---------------------------- | -------- | ---------------- |
| `customer` | `ClientShoppingCartCustomer` | Yes      | Customer details |
| `cartId`   | `string`                     | No       | Cart ID          |

***

Coupons [#coupons]

applyCoupon [#applycoupon]

```javascript
const result = await api.cart.applyCoupon({
  couponCode: 'SUMMER20',
  cartId: 'cart-id'
});
```

removeCoupon [#removecoupon]

```javascript
const result = await api.cart.removeCoupon({
  cartId: 'cart-id'
});
```

ApplyCouponRequest [#applycouponrequest]

| Field        | Type     | Required | Description          |
| ------------ | -------- | -------- | -------------------- |
| `couponCode` | `string` | No       | Coupon code to apply |
| `cartId`     | `string` | No       | Cart ID              |

***

Gift Cards (on Cart) [#gift-cards-on-cart]

applyGiftCard [#applygiftcard]

```javascript
const result = await api.cart.applyGiftCard({
  giftCardCode: 'GC-ABC123',
  cartId: 'cart-id'
});

if (result.success) {
  console.log('Balance available:', result.availableBalance);
}
```

removeGiftCard [#removegiftcard]

```javascript
const result = await api.cart.removeGiftCard({
  cartId: 'cart-id'
});
```

ApplyGiftCardRequest [#applygiftcardrequest]

| Field          | Type     | Required | Description    |
| -------------- | -------- | -------- | -------------- |
| `giftCardCode` | `string` | No       | Gift card code |
| `cartId`       | `string` | No       | Cart ID        |

ApplyGiftCardResponse [#applygiftcardresponse]

| Field              | Type                | Description                     |
| ------------------ | ------------------- | ------------------------------- |
| `success`          | `boolean`           | Whether the operation succeeded |
| `errorCode`        | `GiftCardErrorCode` | Error code (if failed)          |
| `availableBalance` | `number`            | Remaining gift card balance     |

***

Trip Protection [#trip-protection]

getTripProtectionPreview [#gettripprotectionpreview]

Preview trip protection pricing before the customer opts in.

```javascript
const preview = await api.cart.getTripProtectionPreview({
  cartId: 'cart-id'
});

if (preview.success && preview.available) {
  console.log(`${preview.title}: $${preview.price}`);
  console.log(preview.description);
}
```

TripProtectionPreviewRequest [#tripprotectionpreviewrequest]

| Field    | Type     | Required | Description |
| -------- | -------- | -------- | ----------- |
| `cartId` | `string` | No       | Cart ID     |

TripProtectionPreviewResponse [#tripprotectionpreviewresponse]

| Field            | Type      | Description                        |
| ---------------- | --------- | ---------------------------------- |
| `available`      | `boolean` | Whether trip protection is offered |
| `price`          | `number`  | Price for trip protection          |
| `title`          | `string`  | Display title                      |
| `description`    | `string`  | Display description                |
| `coverageType`   | `number`  | Coverage type identifier           |
| `coverageAmount` | `number`  | Coverage amount                    |

***

Checkout [#checkout]

checkout [#checkout-1]

Process the booking. Requires a complete cart with customer email, and typically a Stripe confirmation token for payment.

```javascript
const result = await api.checkout.checkout({
  cart: {
    activity: 'activity-uuid',
    duration: 'duration-uuid',
    date: '2025-07-15',
    timeSlotStart: '10:00',
    timeSlotEnd: '11:00',
    equipment: [
      { equipmentUuid: 'equip-uuid', quantity: 1, seats: 2 }
    ],
    customer: {
      fullName: 'Jane Smith',
      email: 'jane@example.com',
      phone: '5551234567'
    },
    tripProtectionSelected: false
  },
  stripeConfirmationToken: 'tok_xxx', // from Stripe.js
  agreements: ['agreement-uuid-1'],
  customFields: [
    { uuid: 'field-uuid', answer: 'Some answer' }
  ],
  demographics: [
    { demographicUuid: 'demo-uuid', uuid: 'value-uuid', value: 2 }
  ],
  smsOptIn: true
});

if (result.success) {
  console.log('Confirmation:', result.confirmation);
} else if (result.clientSecret) {
  // Stripe requires additional action (3D Secure, etc.)
  // Use Stripe.js to handle the next action, then retry
  console.log('Payment requires additional action');
}
```

CheckoutRequest [#checkoutrequest]

| Field                     | Type                  | Required | Description                                |
| ------------------------- | --------------------- | -------- | ------------------------------------------ |
| `cart`                    | `ClientShoppingCart`  | Yes      | Complete cart with customer info           |
| `stripeConfirmationToken` | `string`              | No       | Stripe confirmation token for payment      |
| `handledNextAction`       | `string`              | No       | Stripe PaymentIntent ID after handling 3DS |
| `customFields`            | `CustomFieldAnswer[]` | No       | Answers to custom fields                   |
| `demographics`            | `DemographicValue[]`  | No       | Guest demographic breakdown                |
| `agreements`              | `string[]`            | No       | UUIDs of accepted agreements               |
| `smsOptIn`                | `boolean`             | No       | Whether customer opts into SMS             |
| `cartId`                  | `string`              | No       | Cart ID                                    |

CustomFieldAnswer [#customfieldanswer]

| Field    | Type     | Description       |
| -------- | -------- | ----------------- |
| `uuid`   | `string` | Custom field UUID |
| `answer` | `string` | Customer's answer |

DemographicValue [#demographicvalue]

| Field             | Type     | Description                     |
| ----------------- | -------- | ------------------------------- |
| `demographicUuid` | `string` | Demographic UUID                |
| `uuid`            | `string` | Value UUID                      |
| `value`           | `number` | Count (e.g., 2 adults, 1 child) |

CheckoutResponse [#checkoutresponse]

| Field             | Type                                 | Description                                             |
| ----------------- | ------------------------------------ | ------------------------------------------------------- |
| `success`         | `boolean`                            | Whether checkout completed                              |
| `confirmation`    | `string`                             | Booking confirmation number                             |
| `cart`            | `ServerShoppingCartOverview`         | Final cart summary                                      |
| `cartAction`      | `CreateOrUpdateShoppingCartResponse` | Cart validation result                                  |
| `clientSecret`    | `string`                             | Stripe client secret (if further payment action needed) |
| `paymentIntentId` | `string`                             | Stripe PaymentIntent ID                                 |

***

Gift Card Purchasing [#gift-card-purchasing]

These endpoints let customers purchase new gift cards (separate from applying a gift card to a cart).

getSettings [#getsettings]

Get the gift card purchase configuration for the location.

```javascript
const settings = await api.giftCardPurchase.getSettings();

if (settings.success && settings.isAvailable) {
  console.log('Flat amounts:', settings.flatAmounts);
  console.log('Variable:', settings.allowVariableAmounts,
    `$${settings.variableMinAmount}-$${settings.variableMaxAmount}`);
}
```

GetGiftCardPurchaseSettingsResponse [#getgiftcardpurchasesettingsresponse]

| Field                   | Type       | Description                                |
| ----------------------- | ---------- | ------------------------------------------ |
| `isAvailable`           | `boolean`  | Whether gift card purchasing is enabled    |
| `allowFlatAmounts`      | `boolean`  | Whether preset amounts are offered         |
| `flatAmounts`           | `number[]` | Preset dollar amounts                      |
| `allowVariableAmounts`  | `boolean`  | Whether custom amounts are allowed         |
| `variableMinAmount`     | `number`   | Minimum custom amount                      |
| `variableMaxAmount`     | `number`   | Maximum custom amount                      |
| `requireRecipientEmail` | `boolean`  | Whether recipient email is required        |
| `allowCustomMessage`    | `boolean`  | Whether a custom message is allowed        |
| `expirationDays`        | `number`   | Number of days until the gift card expires |

purchase [#purchase]

Purchase a gift card with Stripe payment.

```javascript
const result = await api.giftCardPurchase.purchase({
  amount: 50,
  purchaserName: 'John Doe',
  purchaserEmail: 'john@example.com',
  recipientName: 'Jane Smith',
  recipientEmail: 'jane@example.com',
  customMessage: 'Happy birthday!',
  stripeConfirmationToken: 'tok_xxx'
});

if (result.success) {
  console.log('Gift card code:', result.giftCardCode);
  console.log('Amount:', result.giftCardAmount);
  console.log('Expires:', result.expiresAt);
}
```

PurchaseGiftCardRequest [#purchasegiftcardrequest]

| Field                       | Type     | Required | Description                       |
| --------------------------- | -------- | -------- | --------------------------------- |
| `amount`                    | `number` | Yes      | Gift card amount in dollars       |
| `purchaserName`             | `string` | No       | Buyer's name                      |
| `purchaserEmail`            | `string` | No       | Buyer's email                     |
| `purchaserPhone`            | `string` | No       | Buyer's phone                     |
| `purchaserPhoneCountryCode` | `string` | No       | Phone country code                |
| `recipientName`             | `string` | No       | Recipient's name                  |
| `recipientEmail`            | `string` | No       | Recipient's email                 |
| `customMessage`             | `string` | No       | Personal message                  |
| `stripeConfirmationToken`   | `string` | No       | Stripe token for payment          |
| `handledNextAction`         | `string` | No       | Stripe PaymentIntent ID after 3DS |

PurchaseGiftCardResponse [#purchasegiftcardresponse]

| Field             | Type      | Description                            |
| ----------------- | --------- | -------------------------------------- |
| `success`         | `boolean` | Whether the purchase succeeded         |
| `giftCardCode`    | `string`  | The gift card code                     |
| `giftCardAmount`  | `number`  | Amount loaded                          |
| `expiresAt`       | `Date`    | Expiration date                        |
| `recipientEmail`  | `string`  | Where the gift card was sent           |
| `clientSecret`    | `string`  | Stripe client secret (if 3DS required) |
| `paymentIntentId` | `string`  | Stripe PaymentIntent ID                |

***

Full Example: Cart to Checkout [#full-example-cart-to-checkout]

End-to-end flow from creating a cart through successful checkout.

```javascript
const api = new ResytechApi();

// 1. Initialize
const init = await api.initialization.initialize({
  identifier: 'checkout-flow'
});

const activity = init.activities[0];
const equipment = activity.equipment[0];
const duration = activity.durations[0];

// 2. Create cart
const cartResult = await api.cart.createOrUpdateCart({
  cart: {
    activity: activity.uuid,
    duration: duration.uuid,
    date: '2025-07-15',
    timeSlotStart: '10:00',
    timeSlotEnd: '11:00',
    equipment: [
      {
        equipmentUuid: equipment.uuid,
        quantity: 1,
        seats: 2
      }
    ]
  }
});

if (!cartResult.success) {
  console.error('Cart failed:', cartResult.message, 'Code:', cartResult.errorCode);
  return;
}

const cartId = cartResult.cartId;
console.log('Cart created:', cartId);
console.log('Subtotal:', cartResult.cart.subtotal);

// 3. Update customer info
await api.cart.updateCustomer({
  cartId: cartId,
  customer: {
    fullName: 'Jane Smith',
    email: 'jane@example.com',
    phone: '5551234567',
    countryCode: '1'
  }
});

// 4. Apply a coupon
const couponResult = await api.cart.applyCoupon({
  cartId: cartId,
  couponCode: 'SUMMER20'
});

if (couponResult.success) {
  console.log('Coupon applied!');
}

// 5. Check trip protection
const tripPreview = await api.cart.getTripProtectionPreview({
  cartId: cartId
});

// 6. Process checkout
//    In a real app, collect the Stripe token via Stripe.js/Elements
const checkout = await api.checkout.checkout({
  cart: {
    activity: activity.uuid,
    duration: duration.uuid,
    date: '2025-07-15',
    timeSlotStart: '10:00',
    timeSlotEnd: '11:00',
    equipment: [
      { equipmentUuid: equipment.uuid, quantity: 1, seats: 2 }
    ],
    customer: {
      fullName: 'Jane Smith',
      email: 'jane@example.com',
      phone: '5551234567'
    },
    tripProtectionSelected: tripPreview.available
  },
  cartId: cartId,
  stripeConfirmationToken: 'tok_from_stripe_js',
  agreements: ['agreement-uuid-1'],
  smsOptIn: true
});

if (checkout.success) {
  console.log('Booking confirmed!', checkout.confirmation);
  console.log('Total charged:', checkout.cart.total);
} else if (checkout.clientSecret) {
  // Handle Stripe 3D Secure or other next actions
  // After handling, retry with handledNextAction
  console.log('Additional payment verification required');
} else {
  console.error('Checkout failed:', checkout.message);
}
```
