Skip to main content

Live Example

Overview

The Henry cart is a persistent server-side object that holds items from any merchant in a single checkout experience. Creating a cart immediately returns both a cartId and a checkoutUrl - there’s no separate step to generate a checkout link.

Prerequisites

import HenrySDK from '@henrylabs/sdk';

const henry = new HenrySDK({
	apiKey: process.env.HENRY_SDK_API_KEY!,
});

Create a cart

cart.create is the starting point. Pass an array of items using product link URLs (from search results or any product page), and optionally configure cart settings.
const cart = await henry.cart.create({
	items: [
		{
			link: 'https://www.nike.com/t/air-max-270-shoes/AH8050-002',
			quantity: 1,
			selectedOptions: ['regular', 'black', '10-w'],
			metadata: { source: 'homepage-recommendation' },
		},
	],
	settings: {
		options: {
			allowPartialPurchase: true,
		},
		commissionFeePercent: 5,
		commissionFeeFixed: { value: 0.99, currency: 'USD' },
	},
	tags: { userId: 'user_123', region: 'us-ny' },
});

const { cartId, checkoutUrl } = cart.data;
console.log('Cart ID:', cartId);
// → "crt_sa2aEsCz9PRM"
console.log('Checkout URL:', checkoutUrl);
// → "https://checkout.henrylabs.ai/cart/crt_sa2aEsCz9PRM"
The checkoutUrl is your hosted checkout link - share it with your user directly. See Checkout for how to embed it.

Cart creation response

{
  success: boolean;
  status: string;
  message: string;
  data: {
    cartId: string;          // e.g. "crt_sa2aEsCz9PRM" - store this
    checkoutUrl: string;     // hosted checkout URL - ready to use immediately
    data: {
      items: CartItem[];
      settings?: CartSettings;
    };
    metadata?: Record<string, unknown>;
  };
}

Manage cart items

Add an item

Add a product to an existing cart. Use the product link URL as the identifier.
const updated = await henry.cart.item.add(cartId, {
	item: {
		link: 'https://www.adidas.com/us/ultraboost-22-shoes/GX5591.html',
		quantity: 1,
		selectedOptions: ['regular', 'core-black', '9.5-w'],
		selectedShipping: { value: 'standard' },
		coupons: ['SAVE10'],
		metadata: { giftWrap: true },
	},
});

console.log(updated.data.data.items.length); // cart now has 2 items

Update an item quantity

const updated = await henry.cart.item.update(cartId, {
	item: {
		link: 'https://www.nike.com/t/air-max-270-shoes/AH8050-002',
		quantity: 3, // set new quantity
	},
});
Setting quantity to 0 via cart.item.update also removes the item from the cart.

Remove an item

const updated = await henry.cart.item.remove(cartId, {
	link: 'https://www.nike.com/t/air-max-270-shoes/AH8050-002',
});

console.log(updated.data.data.items.length); // one fewer item

Fetch carts

Henry exposes two retrieval methods with different shapes:
MethodReturnsUse when
cart.list({ cartId?, tags? })Array of cartsLooking up by tags, or paging through many carts
cart.fetch(cartId, { buyer? })A single cartYou know the cartId and optionally want to prefill checkout

List carts

// Fetch a specific cart by ID
const { data: carts } = await henry.cart.list({ cartId });
const cart = carts[0];
console.log(cart.data.items);
console.log(cart.checkoutUrl); // still valid - use it any time

// Filter carts by tags
const { data: userCarts } = await henry.cart.list({
	tags: { userId: 'user_123' },
});

Fetch a single cart (with optional buyer prefill)

cart.fetch returns one cart by id. Pass an optional buyer to prefill the hosted checkout - the returned checkoutUrl will embed the buyer details as query params so fields render pre-filled when the user opens it.
// Plain fetch by id
const { data: cart } = await henry.cart.fetch(cartId);
console.log(cart.data.items, cart.checkoutUrl);

// Fetch + prefill the hosted checkout
const { data: prefilled } = await henry.cart.fetch(cartId, {
	buyer: {
		name: { firstName: 'Jane', lastName: 'Doe' },
		email: 'jane@example.com',
		phone: '+15551234567',
		shippingAddress: {
			name: { firstName: 'Jane', lastName: 'Doe' },
			line1: '350 5th Ave',
			city: 'New York',
			province: 'NY',
			postalCode: '10118',
			countryCode: 'US',
		},
	},
});

// prefilled.checkoutUrl now renders with Jane's details pre-populated
buyer is purely a UX convenience for hosted checkout - it does not persist on the cart. To actually commit buyer info, use Headless Checkout via cart.checkout.purchase.

Delete a cart

Remove a cart entirely when it’s no longer needed (e.g. on session logout).
await henry.cart.delete(cartId);

Cart item fields reference

FieldTypeRequiredDescription
linkstringDirect product URL from any merchant
quantitynumber-Defaults to 1
selectedOptionsstring[]-Ordered array of option values e.g. ['regular', 'black', '10-w']
selectedShipping{ id?, value? }-Preferred shipping method
couponsstring[]-Coupon codes to apply at checkout
metadataobject-Arbitrary key/value data passed through to orders

Cart tags

Attach key-value tags when creating a cart to associate it with your own identifiers (e.g. user IDs, regions, campaigns). You can then filter carts by tags with cart.list.
const cart = await henry.cart.create({
	items: [{ link: '...', quantity: 1 }],
	tags: { userId: 'user_123', campaign: 'summer-sale' },
});

// Later, retrieve all carts for this user
const { data: carts } = await henry.cart.list({
	tags: { userId: 'user_123' },
});

Cart settings reference

FieldTypeDescription
options.allowPartialPurchasebooleanLet buyers remove items during checkout
options.collectBuyerEmail"off" | "required" | "optional"Email collection behavior
options.collectBuyerAddress"off" | "required" | "optional"Address collection behavior
options.collectBuyerPhone"off" | "required" | "optional"Phone collection behavior
commissionFeePercentnumberCommission as a percentage of the order total (0-100)
commissionFeeFixed{ value, currency }Fixed commission amount added to the order
eventsCartEvent[]Triggers to fire when cart events occur

Cart events

settings.events lets you attach triggers to cart lifecycle events. Each entry declares an event type to listen for, an optional conditional, and a list of actions (data) to fire when it occurs.

Supported event types

Order events

Event typeFires when
orderAny order event
order.purchaseAny purchase event (full or partial, any outcome)
order.purchase.pendingPurchase created, awaiting payment confirmation
order.purchase.processingPayment confirmed, placing with merchants
order.purchase.completePurchase completed (full or partial)
order.purchase.cancelledPurchase cancelled (full or partial)
order.purchase.fullA full purchase resolves to any outcome
order.purchase.full.pendingFull purchase pending payment confirmation
order.purchase.full.processingFull purchase confirmed, placing with merchants
order.purchase.full.completeAll items placed successfully
order.purchase.full.cancelledFull purchase cancelled
order.purchase.partialA partial purchase resolves to any outcome
order.purchase.partial.pendingPartial purchase pending
order.purchase.partial.processingPartial purchase processing
order.purchase.partial.completePartial purchase completed
order.purchase.partial.cancelledPartial purchase cancelled
order.itemAny item-level event
order.item.pendingIndividual item pending
order.item.processingIndividual item processing
order.item.completeIndividual item placed successfully
order.item.failedIndividual item failed
order.updateAny order update event
order.update.3ds-required3DS authentication required
order.update.adding-to-cartAdding item to merchant cart
order.update.filling-address-detailsFilling in address details
order.update.filling-card-detailsFilling in card details
order.update.submitting-orderSubmitting the order
order.update.changing-quantityChanging item quantity
order.update.applying-couponApplying a coupon code
order.update.selecting-shippingSelecting shipping option
order.update.selecting-optionsSelecting product options

Points & tier events

Event typeFires when
pointsAny points event
points.givePoints awarded to a buyer
points.removePoints removed from a buyer
tierAny tier event
tier.giveA tier assigned to a buyer
tier.removeA tier removed from a buyer

Supported action types

Action typeDescriptionRequired fields
send_webhookPOST the event payload to a registered webhookwebhookUUID
send_emailSend a notification email-
give_points_fixedAward a fixed number of points to the buyerpoints
give_points_per_spentAward points proportional to the order amountpoints, perAmount
remove_points_fixedDeduct a fixed number of points from the buyerpoints
remove_points_per_spentDeduct points proportional to the order amountpoints, perAmount
give_tierAssign a loyalty tier to the buyertierUUID
remove_tierRemove the buyer’s current tier-

Example - webhook on successful purchase

const cart = await henry.cart.create({
	items: [
		{
			link: 'https://www.nike.com/t/air-max-270-shoes/AH8050-002',
			quantity: 1,
		},
	],
	settings: {
		events: [
			{
				type: 'order.purchase.full.complete',
				data: [
					{
						type: 'send_webhook',
						webhookUUID: 'c5dbd16b-60f1-42c7-8d36-a55c46e7a8c6',
					},
				],
			},
		],
	},
});

Example - award points on purchase

settings: {
  events: [
    {
      type: 'order.purchase.full.complete',
      data: [
        {
          type: 'give_points_per_spent',
          points: 1,
          perAmount: { value: 1, currency: 'USD' }, // 1 point per $1 spent
        },
      ],
    },
  ],
}

Conditionals

Add a conditional to a trigger to gate it on the buyer’s current tier or points balance:
{
  type: 'order.purchase.full.complete',
  conditional: {
    type: 'tier',
    operator: 'equals', // 'equals' | 'not_equals'
    value: 'your-tier-uuid',
  },
  data: [{ type: 'give_points_fixed', points: 500 }],
}
Register and manage webhooks in the Henry Dashboard. The webhookUUID is the identifier assigned when you create a webhook endpoint. See Webhooks for payload shape, verification, and the full event reference.

Error handling

ErrorCause
400 Bad RequestMissing required fields or invalid URL in link
401 UnauthorizedInvalid API key
404 Not FoundcartId does not exist or belongs to a different app

Next steps

Once your cart is ready, proceed to checkout:

Checkout

Embed the hosted checkout or call the headless purchase API

Order Management

Track and list orders after checkout completes