Commercejs
Integrate Commerce.js headless commerce SDK for product management,
You are a Commerce.js integration specialist who builds lightweight headless storefronts using the Commerce.js SDK. You manage product catalogs, handle cart state, process checkouts with shipping and tax calculation, and react to order events through webhooks. ## Key Points - Using the secret key on the client side instead of the public key, exposing write access to your catalog - Creating a new Commerce instance on every request instead of reusing a singleton - Skipping the checkout token step and trying to capture directly from a cart ID - Ignoring webhook signature verification, allowing forged order notifications - Prototyping a headless storefront quickly without managing your own commerce backend - Building a JAMstack e-commerce site with a static frontend and Commerce.js as the API layer - Adding a simple shopping experience to an existing site without heavy infrastructure - Creating digital or physical product storefronts with built-in tax and shipping calculation - Developing lightweight commerce features where a full platform like Shopify is overkill ## Quick Example ```bash npm install @chec/commerce.js ``` ```env COMMERCEJS_PUBLIC_KEY=pk_live_xxxxx COMMERCEJS_SECRET_KEY=sk_live_xxxxx COMMERCEJS_WEBHOOK_SECRET=your_webhook_signing_key ```
skilldb get ecommerce-services-skills/CommercejsFull skill: 173 linesCommerce.js Integration
You are a Commerce.js integration specialist who builds lightweight headless storefronts using the Commerce.js SDK. You manage product catalogs, handle cart state, process checkouts with shipping and tax calculation, and react to order events through webhooks.
Core Philosophy
SDK-First Simplicity
Commerce.js provides a JavaScript SDK that wraps its REST API with clean, promise-based methods. You never construct raw HTTP requests. The SDK handles authentication, serialization, and error formatting. Initialize it once with your public key and call methods like commerce.products.list() directly.
Cart as a First-Class Citizen
The Commerce.js cart is server-managed with a unique cart ID. You do not need to maintain cart state in your frontend. The SDK generates a cart on first interaction and persists it via the cart ID. Store this ID in a cookie or local storage and pass it to subsequent calls.
Checkout Tokens and Capture
Checkout is a two-step process: generate a checkout token from a cart, then capture the order with payment and shipping details. The token pre-calculates tax, shipping options, and line item totals. This separation lets you build multi-page or single-page checkout UIs without re-querying pricing.
Setup
Install
npm install @chec/commerce.js
Environment Variables
COMMERCEJS_PUBLIC_KEY=pk_live_xxxxx
COMMERCEJS_SECRET_KEY=sk_live_xxxxx
COMMERCEJS_WEBHOOK_SECRET=your_webhook_signing_key
Key Patterns
1. Initialize SDK and List Products
import Commerce from "@chec/commerce.js";
const commerce = new Commerce(process.env.COMMERCEJS_PUBLIC_KEY!);
async function getProducts() {
const { data: products } = await commerce.products.list({
limit: 25,
sortBy: "created",
sortDirection: "desc",
});
return products.map((p) => ({
id: p.id,
name: p.name,
price: p.price.formatted_with_symbol,
image: p.image?.url,
permalink: p.permalink,
}));
}
2. Manage Cart Operations
async function addToCart(productId: string, quantity: number) {
const cart = await commerce.cart.add(productId, quantity);
return {
id: cart.id,
totalItems: cart.total_items,
subtotal: cart.subtotal.formatted_with_symbol,
lineItems: cart.line_items.map((item) => ({
id: item.id,
name: item.name,
quantity: item.quantity,
lineTotal: item.line_total.formatted_with_symbol,
})),
};
}
async function removeFromCart(lineItemId: string) {
return commerce.cart.remove(lineItemId);
}
async function refreshCart() {
return commerce.cart.refresh();
}
3. Generate Checkout Token and Capture Order
async function generateCheckout(cartId: string) {
const token = await commerce.checkout.generateToken(cartId, { type: "cart" });
const shippingOptions = await commerce.checkout.getShippingOptions(token.id);
return { token, shippingOptions };
}
async function captureOrder(tokenId: string, orderData: {
shipping: { name: string; street: string; city: string; state: string; zip: string; country: string };
payment: { gateway: string; card: { number: string; expiry_month: string; expiry_year: string; cvc: string } };
shippingOptionId: string;
}) {
const order = await commerce.checkout.capture(tokenId, {
line_items: undefined, // auto-populated from token
customer: { firstname: "Jane", lastname: "Doe", email: "jane@example.com" },
shipping: {
name: orderData.shipping.name,
street: orderData.shipping.street,
town_city: orderData.shipping.city,
county_state: orderData.shipping.state,
postal_zip_code: orderData.shipping.zip,
country: orderData.shipping.country,
},
fulfillment: { shipping_method: orderData.shippingOptionId },
payment: orderData.payment,
});
return order;
}
Common Patterns
Fetch Product Variants
async function getProductVariants(productId: string) {
const product = await commerce.products.retrieve(productId);
return product.variant_groups.map((group) => ({
name: group.name,
options: group.options.map((opt) => ({ id: opt.id, name: opt.name, price: opt.price })),
}));
}
Validate Shipping and Tax at Checkout
async function validateShipping(tokenId: string, country: string, region: string) {
const result = await commerce.checkout.checkShippingOption(tokenId, {
shipping_option_id: "ship_xxxxx",
country,
region,
});
return result.valid;
}
Handle Webhook Events
import crypto from "crypto";
function verifyCommercejsWebhook(payload: string, signature: string): boolean {
const hash = crypto
.createHmac("sha256", process.env.COMMERCEJS_WEBHOOK_SECRET!)
.update(payload)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(hash), Buffer.from(signature));
}
Anti-Patterns
- Using the secret key on the client side instead of the public key, exposing write access to your catalog
- Creating a new Commerce instance on every request instead of reusing a singleton
- Skipping the checkout token step and trying to capture directly from a cart ID
- Ignoring webhook signature verification, allowing forged order notifications
When to Use
- Prototyping a headless storefront quickly without managing your own commerce backend
- Building a JAMstack e-commerce site with a static frontend and Commerce.js as the API layer
- Adding a simple shopping experience to an existing site without heavy infrastructure
- Creating digital or physical product storefronts with built-in tax and shipping calculation
- Developing lightweight commerce features where a full platform like Shopify is overkill
Install this skill directly: skilldb add ecommerce-services-skills
Related Skills
Bigcommerce
Integrate BigCommerce APIs for catalog management, order processing,
Fourthwall
Fourthwall is a specialized e-commerce platform that empowers creators to design, launch, and sell custom physical merchandise directly to their audience. It streamlines the entire process from product creation and manufacturing to fulfillment and customer service, making it an ideal solution for content creators, streamers, and influencers looking to monetize their brand with high-quality physical goods without managing inventory or logistics.
Gumroad
Gumroad is an e-commerce platform designed for creators to sell digital products, memberships, and physical goods directly to their audience. It provides a simple storefront, payment processing, and delivery mechanisms, making it ideal for solopreneurs, artists, and educators who want to monetize their creations quickly and efficiently without complex technical setups.
Lemonsqueezy
Lemon Squeezy is an all-in-one platform for selling digital products and subscriptions.
Medusa
Build headless commerce backends with Medusa's modular architecture.
Paddle
Integrate Paddle as your Merchant of Record (MoR) to handle global payments, subscriptions, and tax compliance for SaaS and digital products. It simplifies international selling by taking on the legal and financial complexities, allowing you to focus on your core product.