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_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,
			variant: { size: '10', color: 'Black' },
			metadata: { source: 'homepage-recommendation' },
		},
	],
	settings: {
		options: {
			allowPartialPurchase: true,
		},
		commissionFeePercent: 5,
		commissionFeeFixed: { value: 0.99, currency: 'USD' },
	},
});

const { cartId, checkoutUrl } = cart.data;
console.log('Cart ID:', cartId);
// → "3fa85f64-5717-4562-b3fc-2c963f66afa6"
console.log('Checkout URL:', checkoutUrl);
// → "https://checkout.henrylabs.ai/cart/3fa85f64-..."
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;          // UUID - 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,
	product: {
		link: 'https://www.adidas.com/us/ultraboost-22-shoes/GX5591.html',
		quantity: 1,
		variant: { size: '9.5', color: 'Core Black' },
		shippingOption: { 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,
	product: {
		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 a cart

Retrieve the current state of any cart by cartId. The response includes all items and the checkoutUrl.
const cart = await henry.cart.details({ cartId });

console.log(cart.data.data.items);
console.log(cart.data.checkoutUrl); // still valid - use it any time

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
variantstring | object-String instruction or key/value pairs e.g. { size: "10", color: "Black" }
shippingOption{ id?, value? }-Preferred shipping method
couponsstring[]-Coupon codes to apply at checkout
metadataobject-Arbitrary key/value data passed through to orders

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

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