关于 coupon-management
面向电商商家的优惠券管理技能,介绍在 Shopify、WooCommerce、BigCommerce 中配置优惠规则,以及自建系统时的实现要点。内容涵盖折扣条件、使用限制、批量码和兑换安全。
主要功能
- 01主流电商平台优惠券配置
- 02折扣类型与适用条件设置
- 03使用次数和有效期限制
- 04批量生成唯一优惠码
- 05自建系统的验证与原子兑换
适用场景
- 01配置首次结账促销码
- 02为邮件营销生成单次使用码
- 03限制优惠券适用商品或客户
- 04设计自建优惠券兑换逻辑
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ finsilabs/ awesome-ecommerce-skills --skill coupon-management安装后在 Claude Code 中输入/coupon-management确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
tile.jsonevals/bulk-code-generation-and-atomic-redempti/criteria.jsontask.mdevals/coupon-database-schema-design/criteria.jsontask.mdevals/coupon-validation-logic-and-error-codes/criteria.jsontask.md详细介绍
优惠券管理
概述
优惠券系统让商家能够创建配置规则的促销代码:百分比或固定金额折扣、最低订单金额要求、每张优惠券或每位客户的使用次数限制,以及有效期。所有主流电商平台都内置了优惠券系统——你几乎从不需要从头构建。本技能将引导你在各个平台上设置优惠券管理,并说明在批量生成唯一代码或跟踪营销活动等高级需求下,何时应使用应用或插件。
何时使用本技能
- 首次为结账流程添加促销代码时
- 从简单的折扣字段迁移到基于规则的优惠券引擎时
- 开展需要为每位接收者生成唯一、仅限使用一次的代码的营销活动时
- 构建用于创建优惠券并监控其表现的管理界面时
- 实施复杂的优惠券规则时,例如排除特定商品或类别,或限制特定客户群使用
核心说明
步骤 1:确定商家的平台和合适的工具
| 平台 | 内置功能 | 何时添加应用/插件 |
|---|---|---|
| Shopify | Shopify 折扣 — 支持百分比、固定金额、免运费、买一送一;支持使用次数限制、有效期、最低消费 | 需要批量生成唯一代码(Shopify 支持导入)、针对特定客户群的优惠券或忠诚度集成(Smile.io、LoyaltyLion)时 |
| WooCommerce | WooCommerce 优惠券 — 内置于核心功能;支持百分比、固定购物车金额、固定商品金额、免运费等类型 | 需要批量生成唯一代码时:使用 WooCommerce Smart Coupons 插件;需要高级规则时:使用 YITH WooCommerce Dynamic Pricing & Discounts |
| BigCommerce | 内置优惠券代码 — 支持百分比、固定金额、免运费、赠送商品等类型 | 需要面向 B2B 的代码或高级限制条件时;BigCommerce 应用市场提供 Coupon Manager Pro 等选项 |
| 自定义 / 无头架构 | 必须自行构建 — 参见下方的自定义部分 | 不适用 — 你正在构建该系统 |
步骤 2:在你的平台上设置标准优惠券
Shopify
- 在 Shopify 管理后台侧边栏中前往 折扣
- 点击 创建折扣 并选择类型:
- 商品折扣金额 — 对特定商品/系列提供百分比或固定金额折扣
- 订单折扣金额 — 对整个购物车提供百分比或固定金额折扣
- 买 X 送 Y — 买一送一及组合优惠
- 免运费 — 使用代码后免除运费
- 配置代码:
- 输入代码(例如
SUMMER20),或点击 生成代码 生成随机代码 - 设置 最低购买要求(最低小计或最低数量)
- 设置 客户资格 — 所有客户、特定客户群或特定客户
- 设置 折扣最大使用次数 — 总使用次数和/或每位客户仅限使用一次
- 设置 生效日期 — 开始日期和可选的结束日期
- 输入代码(例如
- 点击 保存折扣
在 Shopify 上批量生成唯一代码:
- 在同一个“折扣”页面中,选择 生成代码,而不是输入单个代码
- 设置数量(通过界面一次最多生成 100 个;如需更大数量,请使用 Shopify Admin API)
- 所有生成的代码共用相同规则(折扣金额、有效期、使用次数限制)
- 将代码导出为 CSV,以便在电子邮件营销平台中使用
Shopify Plus — 使用 Shopify Scripts 实现高级叠加规则:
- 使用 Shopify Scripts(仅限 Shopify Plus)实现自定义优惠券逻辑:例如,根据客户标签应用不同的折扣百分比,或自动应用优惠券而无需输入代码
- 在 Shopify 管理后台中通过 应用 → Script Editor 访问
WooCommerce
- 前往 WooCommerce → Coupons → Add coupon
- 设置 Coupon code(客户在结账时输入的唯一标识符)
- 在 General 选项卡中:
- Discount type:Percentage discount、Fixed cart discount、Fixed product discount
- Coupon amount:折扣值
- Free shipping:启用后,此代码可提供免运费
- Coupon expiry date:代码失效日期
- 在 Usage restriction 选项卡中:
- Minimum spend:购物车小计必须超过此金额
- Maximum spend:购物车小计不能超过此金额
- Individual use only:不能与其他优惠券同时使用
- Exclude sale items:不适用于已降价商品
- Products 和 Exclude products:限制或排除特定商品
- Product categories 和 Exclude categories:按类别限制或排除
- Email restrictions:仅限指定的客户邮箱使用
- 在 Usage limits 选项卡中:
- Usage limit per coupon:此代码可使用的总次数
- Usage limit per user:单个客户可使用的次数
- 点击 Publish
在 WooCommerce 中批量生成唯一代码:
- 安装 WooCommerce Smart Coupons(高级插件,StoreApps 提供,约 $99/年)
- 前往 WooCommerce → Smart Coupons → Generate Coupons
- 设置数量、折扣金额、到期时间和前缀,即可生成包含唯一代码的 CSV 文件
- 导入到你的邮件平台,或通过邮件平台分发
BigCommerce
- 前往 Marketing → Coupon Codes → Create Coupon Code
- 填写:
- Code:客户输入的代码(或使用自动生成按钮)
- Type:Percentage off order、Dollar amount off order、Percentage off product、Dollar amount off product、Free shipping、Free product
- Discount amount:折扣值
- Applies to:所有商品、特定类别的商品或特定商品
- 在 Restrictions 下设置:
- Minimum order:小计必须超过此金额
- Max uses:允许的总兑换次数
- Max uses per customer:每个账户的使用次数上限
- Expiration date:代码失效日期
- 点击 Save
在 BigCommerce 中批量生成代码:
使用 BigCommerce Promotions API(POST /v2/coupons)以编程方式生成代码,然后导出并分发。
自定义 / Headless
对于 Headless 商店,你需要构建验证和兑换逻辑。关键要求是原子化兑换(防止两位客户同时使用最后一次可兑换次数时发生竞态条件)和幂等的订单处理。
// Coupon validation at checkout
async function validateCoupon(
code: string,
customerId: string,
orderSubtotalCents: number
): Promise<{ valid: boolean; discountCents: number; error?: string }> {
const coupon = await db.coupons.findOne({ code: code.toUpperCase().trim(), is_active: true });
if (!coupon) return { valid: false, discountCents: 0, error: 'Code not found' };
const now = new Date();
if (coupon.expires_at && coupon.expires_at < now) return { valid: false, discountCents: 0, error: 'Code expired' };
if (coupon.usage_limit && coupon.usage_count >= coupon.usage_limit) return { valid: false, discountCents: 0, error: 'Code fully used' };
if (coupon.min_order_cents && orderSubtotalCents < coupon.min_order_cents) return { valid: false, discountCents: 0, error: `Minimum order $${coupon.min_order_cents / 100}` };
// Per-customer limit check
if (coupon.per_customer_limit) {
const uses = await db.couponRedemptions.count({ coupon_id: coupon.id, customer_id: customerId });
if (uses >= coupon.per_customer_limit) return { valid: false, discountCents: 0, error: 'Already used' };
}
const discountCents = coupon.type === 'percentage'
? Math.round(orderSubtotalCents * (coupon.value / 100))
: Math.min(coupon.value_cents, orderSubtotalCents);
return { valid: true, discountCents };
}
// Atomic redemption — use inside the order creation transaction
async function redeemCoupon(tx: Tx, couponId: string, customerId: string, orderId: string, discountCents: number) {
// Atomic increment with guard — prevents over-redemption under concurrency
const result = await tx.raw(
`UPDATE coupons SET usage_count = usage_count + 1
WHERE id = ? AND (usage_limit IS NULL OR usage_count < usage_limit)
RETURNING id`,
[couponId]
);
if (result.rowCount === 0) throw new Error('COUPON_EXHAUSTED');
await tx.couponRedemptions.insert({ coupon_id: couponId, customer_id: customerId, order_id: orderId, discount_cents: discountCents });
}
为邮件营销活动批量生成代码:
import crypto from 'crypto';
function generateCode(prefix = 'PROMO', length = 8): string {
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; // no ambiguous chars
return prefix + '-' + Array.from(crypto.randomBytes(length))
.map(b => chars[b % chars.length]).join('');
}
async function bulkGenerate(template: CouponTemplate, quantity: number): Promise<string[]> {
const codes: string[] = [];
while (codes.length < quantity) {
const batch = Array.from({ length: Math.min(500, quantity - codes.length) }, () => generateCode(template.prefix));
const inserted = await db.coupons.insertMany(
batch.map(code => ({ ...template, code, usage_limit: 1, per_customer_limit: 1 })),
{ onConflict: 'ignore' }
);
codes.push(...inserted.map(r => r.code));
}
return codes;
}
最佳实践
- 将代码统一为大写 — 以大写形式存储和比较代码,并去除空格,以避免因格式细微差异导致“找不到代码”的错误
- 为定向营销活动使用一次性代码 — 通过邮件分发唯一代码时,将每个代码的使用次数上限设为 1,防止代码被分享
- 在创建订单时验证,而不只是在购物车中验证 — 下单时重新检查优惠券是否有效(到期时间、使用次数限制),以应对竞态条件
- 软删除优惠券 — 停用而非删除,以保留兑换历史记录供会计核对
- 跟踪折扣滥用行为 — 如果客户三次或更多次使用折扣代码挽回已放弃的购物车,可考虑将其排除在折扣营销活动之外
- 设置最高折扣金额上限 — 对于百分比优惠券,设置最高折扣金额,避免促销折扣失控(例如,八折优惠,最高减 $50)
常见问题
| 问题 | 解决方案 |
|---|---|
| 两位客户同时兑换最后一次使用机会 | 使用原子 UPDATE ... WHERE usage_count < usage_limit,并验证 rowCount === 1(自定义构建);平台会原生处理 |
| 订单取消后优惠券仍然有效 | 订单取消或退款时减少使用次数;Shopify 会自动处理 |
| 通过多个账户绕过每位客户的使用次数限制 | 在检查客户 ID 的基础上,同时检查电子邮件地址;对于高价值营销活动,要求验证电话号码 |
| 批量生成的代码与现有代码冲突 | 使用 INSERT ... ON CONFLICT DO NOTHING,并重新生成冲突代码,直到达到目标数量 |
| 包邮优惠券意外与百分比折扣叠加 | 明确规定叠加政策;在 Shopify 上,为每项折扣设置“可与以下优惠同时使用”选项 |
相关技能
- @discount-engine
- @price-rules-engine
- @ab-testing-pricing
- @loyalty-points-system
- @checkout-flow-optimization
评论
支持 Markdown