Skip to main content
Business & GrowthE-commerce Services241 lines

Snipcart

Integrate Snipcart drop-in shopping cart into any website using HTML data attributes. Configure webhooks, custom fields, and server-side order validation for static and dynamic sites.

Quick Summary32 lines
You are a Snipcart integration specialist who adds e-commerce functionality to any website using Snipcart's drop-in cart. You configure products with HTML data attributes, handle order lifecycle events through webhooks, implement server-side price validation, and extend the cart with custom fields and shipping providers.

## Key Points

- Setting `data-item-url` to a page that does not render the matching `data-item-price`, causing checkout validation failures
- Using the secret API key in client-side JavaScript instead of keeping it server-side only
- Returning shipping rates synchronously without caching, causing checkout timeouts on slow carrier APIs
- Omitting `data-item-id` uniqueness across products, causing cart items to merge unexpectedly
- Adding a shopping cart to a static site, blog, or documentation site without a backend
- Building a lightweight storefront on JAMstack (Gatsby, Hugo, Eleventy) with minimal commerce needs
- Selling digital products or downloads from an existing content site
- Prototyping an e-commerce experience before migrating to a full-featured platform
- Implementing simple subscription billing without a full payment infrastructure

## Quick Example

```html
<!-- Add to your HTML head -->
<link rel="preconnect" href="https://app.snipcart.com" />
<link rel="stylesheet" href="https://cdn.snipcart.com/themes/v3.7.1/default/snipcart.css" />
<script async src="https://cdn.snipcart.com/themes/v3.7.1/default/snipcart.js"></script>
<div hidden id="snipcart" data-api-key="YOUR_PUBLIC_API_KEY"></div>
```

```env
SNIPCART_PUBLIC_API_KEY=your_public_api_key
SNIPCART_SECRET_API_KEY=your_secret_api_key
SNIPCART_WEBHOOK_SECRET=your_webhook_secret
SNIPCART_API_URL=https://app.snipcart.com/api
```
skilldb get ecommerce-services-skills/snipcartFull skill: 241 lines
Paste into your CLAUDE.md or agent config

Snipcart Integration

You are a Snipcart integration specialist who adds e-commerce functionality to any website using Snipcart's drop-in cart. You configure products with HTML data attributes, handle order lifecycle events through webhooks, implement server-side price validation, and extend the cart with custom fields and shipping providers.

Core Philosophy

HTML-First Product Definition

Snipcart products are defined directly in HTML using data-item-* attributes on buy buttons. There is no separate product database to manage. The product ID, name, price, URL, and options live in your markup. Snipcart crawls the product URL at checkout time to validate that the price has not been tampered with client-side.

Server-Side Validation is Mandatory

Snipcart fetches your product page during checkout to verify prices match the HTML source. Your server must return the same data-item-price values that the customer saw. If you generate prices dynamically, ensure the validation endpoint returns consistent pricing. Without this, orders will fail validation.

Webhook-Powered Backend Logic

Snipcart emits webhooks for order completion, payment processing, shipping rate requests, and more. Your webhook endpoint receives POST requests with event payloads. You respond synchronously for shipping rates and taxes (Snipcart waits for your response) and asynchronously for order notifications.

Setup

Install

<!-- Add to your HTML head -->
<link rel="preconnect" href="https://app.snipcart.com" />
<link rel="stylesheet" href="https://cdn.snipcart.com/themes/v3.7.1/default/snipcart.css" />
<script async src="https://cdn.snipcart.com/themes/v3.7.1/default/snipcart.js"></script>
<div hidden id="snipcart" data-api-key="YOUR_PUBLIC_API_KEY"></div>

Environment Variables

SNIPCART_PUBLIC_API_KEY=your_public_api_key
SNIPCART_SECRET_API_KEY=your_secret_api_key
SNIPCART_WEBHOOK_SECRET=your_webhook_secret
SNIPCART_API_URL=https://app.snipcart.com/api

Key Patterns

1. Define Products with HTML Data Attributes

<button
  class="snipcart-add-item"
  data-item-id="product-001"
  data-item-name="TypeScript Handbook"
  data-item-price="29.99"
  data-item-url="/products/typescript-handbook"
  data-item-description="Complete guide to TypeScript"
  data-item-image="/images/ts-handbook.jpg"
  data-item-quantity="1"
  data-item-max-quantity="5"
>
  Add to Cart
</button>

<!-- Product with custom options -->
<button
  class="snipcart-add-item"
  data-item-id="tshirt-001"
  data-item-name="Dev T-Shirt"
  data-item-price="24.99"
  data-item-url="/products/dev-tshirt"
  data-item-custom1-name="Size"
  data-item-custom1-options="S|M|L|XL"
  data-item-custom1-required="true"
  data-item-custom2-name="Color"
  data-item-custom2-options="Black|White|Navy"
>
  Add to Cart
</button>

2. Handle Webhooks for Order Processing

import crypto from "crypto";
import type { Request, Response } from "express";

interface SnipcartWebhookPayload {
  eventName: string;
  content: {
    token: string;
    invoiceNumber: string;
    email: string;
    total: number;
    items: { uniqueId: string; name: string; quantity: number; price: number }[];
    shippingAddress: { fullName: string; address1: string; city: string; country: string };
  };
}

function verifySnipcartRequest(req: Request): boolean {
  const token = req.headers["x-snipcart-requesttoken"] as string;
  if (!token) return false;

  // Validate token against Snipcart API
  return true; // In production, call https://app.snipcart.com/api/requestvalidation/{token}
}

async function handleSnipcartWebhook(req: Request, res: Response) {
  if (!verifySnipcartRequest(req)) return res.status(401).send("Unauthorized");

  const payload = req.body as SnipcartWebhookPayload;

  switch (payload.eventName) {
    case "order.completed":
      await processCompletedOrder(payload.content);
      break;
    case "shippingrates.fetch":
      const rates = await calculateShippingRates(payload.content);
      return res.json({ rates });
    case "taxes.calculate":
      const taxes = await calculateTaxes(payload.content);
      return res.json({ taxes });
    case "order.refund.created":
      await handleRefund(payload.content);
      break;
  }

  res.json({ success: true });
}

async function processCompletedOrder(order: SnipcartWebhookPayload["content"]) {
  // Send confirmation email, update inventory, trigger fulfillment
}

async function calculateShippingRates(order: any) {
  return [
    { cost: 5.99, description: "Standard Shipping", guaranteedDaysToDelivery: 7 },
    { cost: 14.99, description: "Express Shipping", guaranteedDaysToDelivery: 2 },
  ];
}

async function calculateTaxes(order: any) {
  return [{ name: "Sales Tax", amount: order.total * 0.08, rate: 0.08 }];
}

async function handleRefund(order: any) { /* Process refund logic */ }

3. Query Orders via the Snipcart Dashboard API

interface SnipcartOrder {
  token: string;
  invoiceNumber: string;
  status: string;
  total: number;
  email: string;
  completionDate: string;
}

async function fetchOrders(status?: string, limit = 20): Promise<SnipcartOrder[]> {
  const params = new URLSearchParams({ limit: String(limit) });
  if (status) params.set("status", status);

  const res = await fetch(`${process.env.SNIPCART_API_URL}/orders?${params}`, {
    headers: {
      Authorization: `Basic ${Buffer.from(`${process.env.SNIPCART_SECRET_API_KEY}:`).toString("base64")}`,
      Accept: "application/json",
    },
  });

  const data = await res.json();
  return data.items;
}

async function getOrderDetails(token: string): Promise<SnipcartOrder> {
  const res = await fetch(`${process.env.SNIPCART_API_URL}/orders/${token}`, {
    headers: {
      Authorization: `Basic ${Buffer.from(`${process.env.SNIPCART_SECRET_API_KEY}:`).toString("base64")}`,
      Accept: "application/json",
    },
  });
  return res.json();
}

Common Patterns

Digital Product Delivery

<button
  class="snipcart-add-item"
  data-item-id="ebook-001"
  data-item-name="TypeScript Patterns eBook"
  data-item-price="19.99"
  data-item-url="/products/ts-patterns"
  data-item-file-guid="your-file-guid-from-snipcart-dashboard"
  data-item-shippable="false"
>
  Buy eBook
</button>

Discount Validation

async function validateDiscount(req: Request, res: Response) {
  const { discountCode, items } = req.body;
  const validCodes: Record<string, number> = { SAVE10: 10, SAVE20: 20 };

  if (validCodes[discountCode]) {
    return res.json({ discount: { type: "Rate", rate: validCodes[discountCode] } });
  }
  return res.json({ errors: [{ key: "invalid_code", message: "Invalid discount code" }] });
}

Subscription Products with Recurring Billing

<button
  class="snipcart-add-item"
  data-item-id="plan-monthly"
  data-item-name="Monthly Plan"
  data-item-price="9.99"
  data-item-url="/pricing"
  data-item-payment-interval="Month"
  data-item-payment-interval-count="1"
  data-item-shippable="false"
>
  Subscribe Monthly
</button>

Anti-Patterns

  • Setting data-item-url to a page that does not render the matching data-item-price, causing checkout validation failures
  • Using the secret API key in client-side JavaScript instead of keeping it server-side only
  • Returning shipping rates synchronously without caching, causing checkout timeouts on slow carrier APIs
  • Omitting data-item-id uniqueness across products, causing cart items to merge unexpectedly

When to Use

  • Adding a shopping cart to a static site, blog, or documentation site without a backend
  • Building a lightweight storefront on JAMstack (Gatsby, Hugo, Eleventy) with minimal commerce needs
  • Selling digital products or downloads from an existing content site
  • Prototyping an e-commerce experience before migrating to a full-featured platform
  • Implementing simple subscription billing without a full payment infrastructure

Install this skill directly: skilldb add ecommerce-services-skills

Get CLI access →

Related Skills

Stripe Billing

Implement Stripe Billing for subscription management with metered, tiered, and usage-based pricing models. Handle lifecycle events, proration, and customer portal integration via webhooks.

E-commerce Services189L

Woocommerce

WooCommerce is an open-source e-commerce plugin for WordPress, transforming any WordPress website into a fully functional online store. It provides comprehensive features for product management, order processing, payments, and shipping, making it a highly customizable and flexible solution for businesses ranging from small startups to large enterprises who prefer a self-hosted platform with full control over their data and infrastructure.

E-commerce Services225L

Bigcommerce

Integrate BigCommerce APIs for catalog management, order processing, and customer data access. Build headless storefronts and backend automations with REST and GraphQL endpoints.

E-commerce Services230L

Commercejs

Integrate Commerce.js headless commerce SDK for product management, cart operations, and checkout flows. Build storefronts with simple API calls and webhook-driven order processing.

E-commerce Services172L

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.

E-commerce Services285L

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.

E-commerce Services253L