mcpField
D
discount-engine

discount-engine

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

关于 discount-engine

面向电商商家与开发者,介绍如何为购物车配置折扣规则并选择平台原生功能或扩展工具。涵盖优惠码、满减、买赠、阶梯折扣和叠加限制,也说明定制店铺的服务端计算原则。

主要功能

  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 discount-engine

安装后在 Claude Code 中输入/discount-engine确认已加载。

包含的文件

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

tile.json
evals/coupon-code-api-validation/
criteria.json
task.md
evals/discount-data-model-and-schema/
criteria.json
task.md
evals/discount-evaluation-pipeline/
criteria.json
task.md

详细介绍

折扣引擎

概述

折扣引擎会针对购物车评估促销活动,并按正确的顺序应用合适的折扣。每个主要的电子商务平台都内置了折扣引擎——在考虑自定义代码之前,应先配置平台的原生系统。本技能介绍如何在各个平台上设置复杂的折扣逻辑(百分比折扣、固定金额折扣、买一赠一、阶梯门槛、条件规则),以及何时使用应用或插件来扩展原生功能。

何时使用此技能

  • 为新的电子商务商店构建促销系统时
  • 为现有结账流程添加优惠码支持时
  • 实现阶梯定价时(例如,购买 3 件以上享 10% 折扣,购买 10 件以上享 20% 折扣)
  • 创建基于购物车条件自动应用的折扣时
  • 需要买一赠一、捆绑或买赠促销时

核心说明

第 1 步:确定商家的平台并选择合适的工具
平台内置折扣功能何时添加应用/插件
Shopify自动折扣、基于优惠码的折扣、买一赠一、阶梯式 Buy X Get Y——均位于 Discounts 管理后台使用 Shopify Plus Scripts 实现高级折扣叠加和自定义逻辑;使用 Bold Discounts 以可视化方式构建规则
WooCommerce优惠券(核心功能)可满足基本需求如需买一赠一、阶梯式数量定价或基于规则的自动折扣:使用 YITH WooCommerce Dynamic Pricing & Discounts(约 $70/年)或 WooCommerce 推出的 Dynamic Pricing 扩展(约 $99/年)
BigCommerce促销引擎支持购物车级和商品级折扣、免费商品、买一赠一BigCommerce 内置的 Promotions 功能强大——边缘情况可使用自定义脚本
自定义 / 无头架构必须自行构建——见下文不适用
第 2 步:在平台上设置自动折扣和买一赠一

Shopify

自动折扣(无需代码):

  1. 前往 Discounts → Create discount → Amount off products(或 Amount off order)
  2. 切换 No discount code(设为自动折扣——无需代码即可应用)
  3. 设置折扣值和条件
  4. 在 Minimum purchase requirements 下:设置触发折扣所需的最低数量或小计金额
  5. 设置 Active dates——在此时间段内,自动折扣会应用于所有符合条件的购物车

买一赠一(Buy X Get Y):

  1. 前往 Discounts → Create discount → Buy X get Y
  2. 设置 Customer buys 部分:数量以及符合条件的商品/系列
  3. 设置 Customer gets 部分:免费/折扣商品的数量以及对应商品
  4. 设置折扣百分比(100% = 免费)
  5. 如有需要,设置 Maximum uses 限制

阶梯式数量折扣(Shopify): Shopify 原生不支持阶梯式数量折扣(例如,1–4 件 = 原价,5–9 件 = 10% 折扣,10 件以上 = 20% 折扣),需要借助应用。可选方案:

  • Bold Discounts(应用商店,约 $20/月):通过可视化界面设置阶梯定价规则
  • Wholesale Club(应用商店):为 B2B 添加批发/阶梯定价层
  • Shopify Plus + Shopify Functions:使用 JavaScript 编写 Discount Function,根据购物车行项目数量应用正确的阶梯折扣

折扣叠加规则: 在 Shopify 中,每项折扣都可以配置为与其他折扣组合:

  1. 编辑折扣 → 向下滚动到 Combinations
  2. 切换可与其组合的折扣类型:商品折扣、订单折扣、配送折扣

WooCommerce

WooCommerce 核心优惠券支持单个代码、百分比和固定金额折扣。对于自动折扣、基于规则的折扣和买一赠一折扣,请使用 Dynamic Pricing & Discounts 插件。

安装 Dynamic Pricing:

  1. 购买并安装 YITH WooCommerce Dynamic Pricing & Discounts,或 WooCommerce 官方推出的 Dynamic Pricing 扩展
  2. 前往 WooCommerce → Dynamic Pricing → Add Rule

创建阶梯数量规则:

  1. 将规则类型设为 Product Pricing 或 Category Pricing
  2. 添加价格阶梯:
    • 数量为 1 至 4 件:优惠 0%(原价)
    • 数量为 5 至 9 件:优惠 10%
    • 数量为 10 至 24 件:优惠 20%
    • 数量为 25 件及以上:优惠 30%
  3. 设置适用的产品或类别
  4. 保存并发布

在 WooCommerce 中设置买一赠一:

  1. 在 Dynamic Pricing 中创建一条新的 Cart Pricing 类型规则
  2. 设置条件:“购物车中包含 X 件 [产品]”
  3. 设置操作:“以[常规价格的 0%]添加 Y 件[产品]”
  4. 或使用 WooCommerce Smart Coupons 设置购买赠礼

防止意外叠加: 在 WooCommerce 核心优惠券中,勾选 Individual use only,以禁止优惠券与其他优惠券叠加使用。对于 Dynamic Pricing 中的自动规则,每条规则都有一个“停止后续规则”选项,可阻止优先级较低的规则生效。


BigCommerce

BigCommerce 提供原生的 Promotions 系统,可满足大多数折扣场景。

  1. 前往 Marketing → Promotions → Create promotion
  2. 设置 Promotion type:购物车级折扣、商品级折扣、免运费、赠送商品、买一赠一
  3. 配置 Conditions:
    • 购物车最低小计
    • 指定要包含或排除的产品或类别
    • 客户群组(适用于 B2B 或特定客群的定价)
  4. 设置 Actions:折扣金额及适用商品
  5. 设置 Coupon(可选):关联一个代码以要求手动使用,或留空以自动应用
  6. 设置 Rules 控制叠加:BigCommerce 允许定义促销能否与其他促销叠加

在 BigCommerce 上设置阶梯数量定价: 使用 Price Lists 功能(Plus 套餐及以上):

  1. 前往 Products → Price Lists
  2. 创建价格表,明确设置不同数量门槛对应的单件价格
  3. 将价格表分配给客户群组
  4. 该群组中的客户会自动看到阶梯价格

Custom / Headless

对于自定义店面,折扣引擎会评估适用的折扣,并将其分配给购物车中的商品行。关键原则是:在服务端进行评估、按优先级应用,并执行叠加规则。

interface Discount {
  id: string;
  type: 'percentage' | 'fixed_amount' | 'bogo' | 'free_shipping';
  value: number;        // percentage (0-100) or cents
  target: 'order' | 'line_item' | 'shipping';
  isStackable: boolean;
  minCartCents?: number;
  minQuantity?: number;
  entitledProductIds?: string[];
  excludedProductIds?: string[];
  startsAt: Date;
  endsAt?: Date;
}

interface CartLine {
  id: string;
  productId: string;
  quantity: number;
  unitPriceCents: number;
}

function evaluateDiscounts(
  cart: { lines: CartLine[]; subtotalCents: number },
  discounts: Discount[]
): { discountId: string; amountCents: number; affectedLineIds: string[] }[] {
  const now = new Date();
  const eligible = discounts.filter(d =>
    d.startsAt <= now && (!d.endsAt || d.endsAt > now)
  );

  // Sort: non-stackable first, then higher-value
  const sorted = [...eligible].sort((a, b) => (a.isStackable ? 1 : -1) - (b.isStackable ? 1 : -1));

  const applications: { discountId: string; amountCents: number; affectedLineIds: string[] }[] = [];
  let nonStackableApplied = false;

  for (const discount of sorted) {
    if (!discount.isStackable && nonStackableApplied) continue;

    // Check minimum cart value
    if (discount.minCartCents && cart.subtotalCents < discount.minCartCents) continue;

    const eligibleLines = cart.lines.filter(line =>
      (!discount.entitledProductIds || discount.entitledProductIds.includes(line.productId)) &&
      (!discount.excludedProductIds || !discount.excludedProductIds.includes(line.productId))
    );
    if (eligibleLines.length === 0) continue;

    let amountCents = 0;
    if (discount.type === 'percentage') {
      amountCents = Math.round(
        eligibleLines.reduce((s, l) => s + l.unitPriceCents * l.quantity, 0) * discount.value / 100
      );
    } else if (discount.type === 'fixed_amount') {
      amountCents = Math.min(discount.value, cart.subtotalCents);
    } else if (discount.type === 'bogo') {
      const buyQty = discount.minQuantity ?? 1;
      for (const line of eligibleLines) {
        const freeItems = Math.floor(line.quantity / (buyQty + discount.value)) * discount.value;
        amountCents += freeItems * line.unitPriceCents;
      }
    }

    if (amountCents > 0) {
      applications.push({ discountId: discount.id, amountCents, affectedLineIds: eligibleLines.map(l => l.id) });
      if (!discount.isStackable) nonStackableApplied = true;
    }
  }

  return applications;
}

创建订单时务必重新运行此评估,而不只是在将商品加入购物车时运行,以捕获竞态条件和已过期的折扣。

最佳实践

  • 始终在服务端计算折扣 — 切勿信任客户端提交的折扣金额;应在结账时重新计算
  • 明确规定叠加规则 — 事先决定多个折扣能否叠加,并将政策记录下来,供商品运营团队参考
  • 设置折扣金额上限 — 对于百分比折扣,应设置最高金额上限,以防促销折扣过高
  • 将促销折扣排除在特价商品之外 — 防止折扣叠加侵蚀利润;Shopify 和 WooCommerce 均支持“排除特价商品”规则
  • 启用前先在预发布环境中测试规则 — 对于无需代码、自动应用于所有符合条件客户的折扣,这一点尤为重要
  • 记录每次折扣应用 — 记录折扣 ID、客户、订单和金额,以便审计和分析促销投资回报率
  • 设置明确的结束日期 — 未设置结束日期的自动折扣会无限期生效;务必设置到期日期

常见问题

问题解决方案
下单后才应用折扣(购物车数据过期)创建订单时重新验证所有折扣;付款前移除已过期或无效的折扣
单件商品的购物车触发买一赠一在触发买一赠一之前,确保购物车数量至少等于购买数量
折扣导致订单总额为负数将折扣总额限制为购物车小计;订单总额不得低于零
自动折扣和代码折扣意外叠加在 Shopify 中检查每项折扣的“组合”设置;在 WooCommerce 优惠券中使用“仅限单独使用”
更新数量后,阶梯折扣显示错误的档位每次购物车数量变化时都重新计算适用档位,而不只是结账时计算

相关技能

  • @stripe-integration
  • @checkout-flow-optimization
  • @coupon-management
  • @price-rules-engine
  • @volume-pricing

评论

支持 Markdown