Claude-skill-registry e-commerce
E-commerce platforms, payment processing, and shopping cart patterns
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/e-commerce" ~/.claude/skills/majiayu000-claude-skill-registry-e-commerce && rm -rf "$T"
manifest:
skills/data/e-commerce/SKILL.mdsource content
E-Commerce Development
Overview
Building e-commerce applications with shopping carts, payment processing, inventory management, and order fulfillment.
Shopping Cart
Cart State Management
interface CartItem { productId: string; variantId?: string; quantity: number; price: number; name: string; image: string; } interface Cart { id: string; items: CartItem[]; subtotal: number; tax: number; shipping: number; total: number; discountCode?: string; discountAmount: number; } // Zustand cart store import { create } from 'zustand'; import { persist } from 'zustand/middleware'; interface CartStore { cart: Cart; addItem: (item: Omit<CartItem, 'quantity'>, quantity?: number) => void; updateQuantity: (productId: string, quantity: number) => void; removeItem: (productId: string) => void; clearCart: () => void; applyDiscount: (code: string) => Promise<void>; } const useCartStore = create<CartStore>()( persist( (set, get) => ({ cart: createEmptyCart(), addItem: (item, quantity = 1) => { set((state) => { const existingIndex = state.cart.items.findIndex( (i) => i.productId === item.productId && i.variantId === item.variantId ); const newItems = [...state.cart.items]; if (existingIndex >= 0) { newItems[existingIndex].quantity += quantity; } else { newItems.push({ ...item, quantity }); } return { cart: recalculateCart({ ...state.cart, items: newItems }) }; }); }, updateQuantity: (productId, quantity) => { set((state) => { if (quantity <= 0) { return { cart: recalculateCart({ ...state.cart, items: state.cart.items.filter((i) => i.productId !== productId), }), }; } const newItems = state.cart.items.map((item) => item.productId === productId ? { ...item, quantity } : item ); return { cart: recalculateCart({ ...state.cart, items: newItems }) }; }); }, removeItem: (productId) => { set((state) => ({ cart: recalculateCart({ ...state.cart, items: state.cart.items.filter((i) => i.productId !== productId), }), })); }, clearCart: () => set({ cart: createEmptyCart() }), applyDiscount: async (code) => { const discount = await validateDiscountCode(code); set((state) => ({ cart: recalculateCart({ ...state.cart, discountCode: code, discountAmount: discount.amount, }), })); }, }), { name: 'cart-storage' } ) ); function recalculateCart(cart: Cart): Cart { const subtotal = cart.items.reduce( (sum, item) => sum + item.price * item.quantity, 0 ); const tax = subtotal * 0.1; // 10% tax const shipping = subtotal > 100 ? 0 : 9.99; const total = subtotal + tax + shipping - cart.discountAmount; return { ...cart, subtotal, tax, shipping, total }; }
Payment Processing
Stripe Integration
import Stripe from 'stripe'; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: '2023-10-16', }); // Create checkout session async function createCheckoutSession(cart: Cart, customerId?: string) { const session = await stripe.checkout.sessions.create({ mode: 'payment', customer: customerId, line_items: cart.items.map((item) => ({ price_data: { currency: 'usd', product_data: { name: item.name, images: [item.image], }, unit_amount: Math.round(item.price * 100), }, quantity: item.quantity, })), discounts: cart.discountCode ? [{ coupon: cart.discountCode }] : undefined, shipping_address_collection: { allowed_countries: ['US', 'CA', 'GB'], }, success_url: `${process.env.APP_URL}/checkout/success?session_id={CHECKOUT_SESSION_ID}`, cancel_url: `${process.env.APP_URL}/cart`, metadata: { cartId: cart.id, }, }); return session; } // Create payment intent (for custom checkout) async function createPaymentIntent(amount: number, customerId?: string) { const paymentIntent = await stripe.paymentIntents.create({ amount: Math.round(amount * 100), currency: 'usd', customer: customerId, automatic_payment_methods: { enabled: true }, }); return { clientSecret: paymentIntent.client_secret, paymentIntentId: paymentIntent.id, }; } // Webhook handler async function handleStripeWebhook(body: string, signature: string) { const event = stripe.webhooks.constructEvent( body, signature, process.env.STRIPE_WEBHOOK_SECRET! ); switch (event.type) { case 'checkout.session.completed': { const session = event.data.object as Stripe.Checkout.Session; await fulfillOrder(session); break; } case 'payment_intent.succeeded': { const paymentIntent = event.data.object as Stripe.PaymentIntent; await handlePaymentSuccess(paymentIntent); break; } case 'payment_intent.payment_failed': { const paymentIntent = event.data.object as Stripe.PaymentIntent; await handlePaymentFailure(paymentIntent); break; } } }
React Stripe Elements
import { loadStripe } from '@stripe/stripe-js'; import { Elements, PaymentElement, useStripe, useElements, } from '@stripe/react-stripe-js'; const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_KEY!); function CheckoutForm({ clientSecret }: { clientSecret: string }) { const stripe = useStripe(); const elements = useElements(); const [error, setError] = useState<string | null>(null); const [processing, setProcessing] = useState(false); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!stripe || !elements) return; setProcessing(true); setError(null); const { error: submitError } = await stripe.confirmPayment({ elements, confirmParams: { return_url: `${window.location.origin}/checkout/success`, }, }); if (submitError) { setError(submitError.message || 'Payment failed'); setProcessing(false); } }; return ( <form onSubmit={handleSubmit}> <PaymentElement /> {error && <div className="error">{error}</div>} <button type="submit" disabled={!stripe || processing}> {processing ? 'Processing...' : 'Pay Now'} </button> </form> ); } function CheckoutPage() { const [clientSecret, setClientSecret] = useState(''); useEffect(() => { fetch('/api/create-payment-intent', { method: 'POST', body: JSON.stringify({ amount: cart.total }), }) .then((res) => res.json()) .then((data) => setClientSecret(data.clientSecret)); }, []); if (!clientSecret) return <Loading />; return ( <Elements stripe={stripePromise} options={{ clientSecret, appearance: { theme: 'stripe' } }} > <CheckoutForm clientSecret={clientSecret} /> </Elements> ); }
Inventory Management
interface Product { id: string; name: string; sku: string; price: number; inventory: number; lowStockThreshold: number; variants: ProductVariant[]; } interface ProductVariant { id: string; name: string; sku: string; price: number; inventory: number; attributes: Record<string, string>; } // Inventory operations with optimistic locking async function reserveInventory(items: CartItem[]): Promise<boolean> { return prisma.$transaction(async (tx) => { for (const item of items) { const product = await tx.product.findUnique({ where: { id: item.productId }, select: { inventory: true, version: true }, }); if (!product || product.inventory < item.quantity) { throw new Error(`Insufficient inventory for ${item.name}`); } // Optimistic locking with version check const updated = await tx.product.updateMany({ where: { id: item.productId, version: product.version, inventory: { gte: item.quantity }, }, data: { inventory: { decrement: item.quantity }, version: { increment: 1 }, }, }); if (updated.count === 0) { throw new Error(`Concurrent modification for ${item.name}`); } } return true; }); } // Release inventory (on order cancellation) async function releaseInventory(orderId: string) { const order = await prisma.order.findUnique({ where: { id: orderId }, include: { items: true }, }); await prisma.$transaction( order.items.map((item) => prisma.product.update({ where: { id: item.productId }, data: { inventory: { increment: item.quantity } }, }) ) ); } // Low stock alerts async function checkLowStock() { const lowStockProducts = await prisma.product.findMany({ where: { inventory: { lte: prisma.product.fields.lowStockThreshold }, }, }); for (const product of lowStockProducts) { await sendLowStockAlert(product); } }
Order Management
enum OrderStatus { PENDING = 'pending', PAID = 'paid', PROCESSING = 'processing', SHIPPED = 'shipped', DELIVERED = 'delivered', CANCELLED = 'cancelled', REFUNDED = 'refunded', } interface Order { id: string; userId: string; status: OrderStatus; items: OrderItem[]; subtotal: number; tax: number; shipping: number; total: number; shippingAddress: Address; billingAddress: Address; paymentIntentId: string; trackingNumber?: string; createdAt: Date; updatedAt: Date; } // Create order from checkout session async function fulfillOrder(session: Stripe.Checkout.Session) { const order = await prisma.order.create({ data: { userId: session.client_reference_id!, status: OrderStatus.PAID, paymentIntentId: session.payment_intent as string, subtotal: session.amount_subtotal! / 100, total: session.amount_total! / 100, shippingAddress: JSON.parse(session.metadata!.shippingAddress), items: { create: JSON.parse(session.metadata!.items), }, }, }); // Reserve inventory await reserveInventory(order.items); // Send confirmation email await sendOrderConfirmation(order); // Notify fulfillment system await notifyFulfillment(order); return order; } // Order status updates async function updateOrderStatus(orderId: string, status: OrderStatus) { const order = await prisma.order.update({ where: { id: orderId }, data: { status }, }); // Send notification await sendOrderStatusUpdate(order); return order; }
Product Catalog
// Product search with filters async function searchProducts(params: { query?: string; category?: string; minPrice?: number; maxPrice?: number; sortBy?: 'price' | 'name' | 'createdAt'; sortOrder?: 'asc' | 'desc'; page?: number; limit?: number; }) { const { query, category, minPrice, maxPrice, sortBy = 'createdAt', sortOrder = 'desc', page = 1, limit = 20, } = params; const where: Prisma.ProductWhereInput = { status: 'active', ...(query && { OR: [ { name: { contains: query, mode: 'insensitive' } }, { description: { contains: query, mode: 'insensitive' } }, ], }), ...(category && { categoryId: category }), ...(minPrice && { price: { gte: minPrice } }), ...(maxPrice && { price: { lte: maxPrice } }), }; const [products, total] = await Promise.all([ prisma.product.findMany({ where, orderBy: { [sortBy]: sortOrder }, skip: (page - 1) * limit, take: limit, include: { category: true, images: true, variants: true, }, }), prisma.product.count({ where }), ]); return { products, pagination: { page, limit, total, totalPages: Math.ceil(total / limit), }, }; }
Related Skills
- [[payment-processing]] - Payment systems
- [[backend]] - API development
- [[database]] - Data modeling