mcpField
P
product-bundles-kits

product-bundles-kits

github.com/finsilabs营销与增长6090 次安装6 天前更新
代码仓库

关于 product-bundles-kits

用于规划和实现电商产品组合与套装的技能,涵盖各平台工具、组合定价、组件库存、页面展示及自定义无头架构模型。

主要功能

  1. 01固定与可配置组合
  2. 02组合定价与折扣
  3. 03按组件处理库存
  4. 04产品页组合展示
  5. 05库存可售性校验指南

适用场景

  1. 01提供折扣产品套装
  2. 02创建自由搭配套装
  3. 03添加相关产品推荐
  4. 04构建自定义套装页面

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill product-bundles-kits

安装后在 Claude Code 中输入/product-bundles-kits确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

tile.json
evals/bundle-cart-line-items-and-availability/
criteria.json
task.md
evals/bundle-pdp-display-and-cart-grouping/
criteria.json
task.md
evals/bundle-pricing-calculation/
criteria.json
task.md

详细介绍

产品组合与套装

概述

产品组合让你可以将多个产品作为一个可购买单元一起销售,并可选择提供折扣。这能提高平均订单金额,是电商中最有效的追加销售机制之一。专用的组合应用会处理库存跟踪、定价和展示逻辑,这些功能通常并非平台原生支持。只有当你的套装配置需求(动态组合、实时定价、组件替换)超出应用的功能范围时,才应构建自定义组合系统。

何时使用此技能

  • 实现“经常一起购买”或“完整造型”功能时
  • 销售产品套装时(例如,将相机机身、镜头和包组合销售)
  • 为同时购买一组产品提供折扣时
  • 构建自定义套装配置器,让购物者从选项中自行组合套装时

核心说明

第 1 步:确定平台并选择合适的工具
平台推荐工具原因
ShopifyBundler — Product Bundles 或 Bundle BuilderBundler 最受欢迎;支持固定组合、混搭,以及按组件扣减库存
WooCommerceWooCommerce Product Bundles(WooCommerce 扩展)WooCommerce 官方扩展;支持固定和可配置组合、按组件定价及库存管理
BigCommerceProduct Bundler 应用或原生“经常一起购买”功能BigCommerce App Marketplace 中有多款组合应用;原生“经常一起购买”功能适用于简单的交叉销售
自定义 / 无头架构构建包含组件库存扣减功能的组合数据模型当组合逻辑(实时定价、动态组件替换)超出应用的功能范围时,就需要采用此方案

第 2 步:按平台进行设置

Shopify

选项 A:Bundler — Product Bundles(推荐)

  1. 在 Shopify App Store 中安装 Bundler — Product Bundles
  2. 前往 Bundler → Bundles → Create bundle
  3. 选择组合类型:
    • 固定组合:预先定义的一组产品(例如,“护肤入门套装”)
    • 混搭:购物者从一个系列中选择 X 件商品
    • 自由装箱:购物者可任意组合商品装满一个箱子
  4. 添加组件产品并设置数量
  5. 设置价格:
    • 百分比折扣(例如,组合总价打 85 折)
    • 固定组合价格(例如,无论组件价格如何,均为 $49.99)
    • 各部分价格之和(不打折,仅为方便而组合销售)
  6. Bundler 会处理库存:购买组合后,会自动扣减每个组件的库存

用于“经常一起购买”功能:

  • 在 App Store 中安装 Code Black Belt 的 Frequently Bought Together
  • 该应用会分析你的订单历史,并自动推荐可在 PDP 上组合销售的产品
  • 安装后即可使用,无需手动配置

Shopify Plus 重要说明:

  • 对于必须在购物车中显示为单个商品行的组合(用于忠诚度积分、折扣排除等),可考虑使用 Shopify Bundles(原生功能,可在管理后台的 Products → Bundles 中使用)
  • Shopify 原生的 Bundles 产品类型会创建一个父级 SKU,买家购买该 SKU 后,系统会自动扣减组件库存
WooCommerce

WooCommerce Product Bundles(官方扩展):

  1. 从 WooCommerce.com 安装 WooCommerce Product Bundles
  2. 创建新产品:Products → Add Product → Product type: Bundle
  3. 前往 Bundled Products 选项卡
  4. 添加各个组件:
    • 搜索并选择产品
    • 设置默认数量,以及该组件是否为可选项(适用于可配置套装)
    • 如果组件从不同地点发货,请启用 Ship separately
  5. 在 General 选项卡下设置套装定价:
    • Per-item pricing:套装价格 = 组件价格总和(可选折扣)
    • Static bundle pricing:为套装输入固定价格
  6. 库存:如果要限制可售套装数量(取决于组件库存),请启用 Manage stock?

对于“经常一起购买”:

  • 安装 WooCommerce Frequently Bought Together(提供免费版或付费版)
  • 或使用 YITH WooCommerce Frequently Bought Together

BigCommerce

App Marketplace 中的套装应用:

  1. 在 BigCommerce 管理后台的 Apps 部分搜索 "Bundle"
  2. Bold Bundles 应用广泛使用 — 安装并配置套装产品,将其关联到现有 SKU
  3. 设置折扣规则(折扣百分比、固定价格、买一赠一)
  4. Bold Bundles 会自动处理每个组件的库存扣减

原生交叉销售 / “经常一起购买”:

  1. 前往 Products → [Product] → Related Products tab
  2. 添加相关产品 — 这些产品会作为推荐显示在产品详情页(PDP)上
  3. 不会自动应用折扣,但客户可以单独添加商品

自定义 / 无头架构

对于无头店面,请构建套装模型,将组件作为单独的购物车行项目存储(简化库存、税费和履约处理):

// lib/bundles.ts

interface BundleComponent { variantId: string; quantity: number; unitPrice: number; }
interface BundlePricing { componentSum: number; bundlePrice: number; savings: number; savingsPct: number; }

// Calculate bundle price dynamically from current component prices
export async function calculateBundlePrice(bundle: Bundle, selectedVariants: BundleComponent[]): Promise<BundlePricing> {
  const componentSum = selectedVariants.reduce((total, c) => total + c.unitPrice * c.quantity, 0);

  let bundlePrice: number;
  switch (bundle.pricingType) {
    case 'fixed': bundlePrice = bundle.pricingValue; break;
    case 'discount_pct': bundlePrice = +(componentSum * (1 - bundle.pricingValue / 100)).toFixed(2); break;
    case 'discount_abs': bundlePrice = Math.max(0, +(componentSum - bundle.pricingValue).toFixed(2)); break;
    default: bundlePrice = componentSum;
  }

  const savings = +(componentSum - bundlePrice).toFixed(2);
  return { componentSum, bundlePrice, savings, savingsPct: componentSum > 0 ? Math.round((savings / componentSum) * 100) : 0 };
}

// Check availability for all bundle components atomically
export async function checkBundleAvailability(selectedVariants: BundleComponent[]) {
  const unavailable = [];
  for (const { variantId, quantity } of selectedVariants) {
    const level = await db.inventoryLevels.findFirst({ where: { variantId } });
    const available = (level?.onHand ?? 0) - (level?.reserved ?? 0);
    if (available < quantity) {
      unavailable.push({ variantId, requested: quantity, available: Math.max(0, available) });
    }
  }
  return { available: unavailable.length === 0, unavailable };
}

// Add bundle to cart as separate line items (grouped by bundle ID for UI display)
export async function addBundleToCart(cartId: string, bundleId: string, selectedVariants: BundleComponent[]) {
  const bundle = await db.productBundles.findUnique({ where: { id: bundleId } });
  const pricing = await calculateBundlePrice(bundle, selectedVariants);

  const { available, unavailable } = await checkBundleAvailability(selectedVariants);
  if (!available) throw new Error(`Bundle not available: ${unavailable.map(u => u.variantId).join(', ')}`);

  // Create a bundle group record to keep line items visually associated
  const bundleGroup = await db.cartBundleGroups.create({
    data: { cartId, bundleId, bundlePrice: pricing.bundlePrice, bundleSavings: pricing.savings },
  });

  // Pro-rate the discount across components proportionally to their share of the total
  const lineItems = selectedVariants.map(({ variantId, quantity, unitPrice }) => {
    const itemSubtotal = unitPrice * quantity;
    const discountShare = pricing.savings * (itemSubtotal / pricing.componentSum);
    const discountedUnitPrice = +(unitPrice - discountShare / quantity).toFixed(4);
    return { cartId, variantId, quantity, bundleGroupId: bundleGroup.id, unitPrice: discountedUnitPrice };
  });

  await db.cartItems.createMany({ data: lineItems });
  return bundleGroup;
}

第 3 步:配置产品页面上的套装展示

套装展示检查清单:

  • 显示“价值:$149 | 套装价格:$119 — 立省 $30(优惠 20%)”,让折扣一目了然
  • 显示套装包含的商品及其图片和名称
  • 显示库存情况:如果任何组件缺货,请指出具体商品并推荐替代品
  • 在购物车页面上,将套装行项目归为一组,并在视觉标题中显示套装名称和节省金额徽标

**对于 Shopify/Bundler:**该应用会自动生成套装产品页面 — 在 Bundler → Customize 中自定义模板

**对于 WooCommerce Product Bundles:**该插件会渲染专属的套装产品页面布局;可使用内置 CSS 设置或子主题覆盖样式


第 4 步:验证库存扣减是否正常

设置好套装后,请测试每个组件的库存是否正确扣减:

  1. 为套装下一个测试订单
  2. 检查每个组件产品的库存 — 库存都应按套装组件数量扣减
  3. 测试边界情况:某个组件恰好剩余 1 件时,尝试订购 2 套,第二套应无法下单

最佳实践

  • 使用应用,而不是从头构建 — Shopify 的 Bundler 和 WooCommerce Product Bundles 能处理拆分履约、部分缺货和退款等边界情况,而要正确实现这些功能需要数周时间
  • 始终在服务端验证套装库存 — 添加到购物车前,以原子方式检查所有组件是否有足够库存;只有每个组件都有库存时,套装才可购买
  • 在结账时重新计算套装价格 — 切勿信任客户端提交的套装价格;下单时应根据当前组件价格重新计算
  • 同时显示单品价格和套装价格 — 只有让客户看到相较于单独购买节省了多少,折扣才有意义
  • 套装组件数量控制在 2–5 个 — 组件过多会让购物者困惑,也更难清晰地展示

常见问题

问题解决方案
结账时错误应用了捆绑折扣使用应用内置的折扣逻辑;未经测试,不要在捆绑折扣之上叠加额外的折扣码
商品加入购物车后,某个捆绑组件缺货在结账时重新检查库存;明确显示缺货的具体组件,以便客户进行调整
组件价格变动后,捆绑价格未更新每次刷新购物车和结账时都重新计算捆绑价格,而不只是在添加到购物车时计算
履约系统无法正确处理捆绑商品行项目对于无头构建,确保每个行项目都有标准的 variant_id 和 quantity;bundle_group_id 仅用于界面分组
捆绑中的部分组件未扣减库存设置完成后,务必通过真实订单进行测试,并确认每个组件 SKU 都按正确数量扣减

相关技能

  • @variant-matrix
  • @inventory-tracking
  • @product-content-enrichment

评论

支持 Markdown