mcpField
S
shoplazza-discounts

shoplazza-discounts

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

关于 shoplazza-discounts

shoplazza-discounts 是 shoplazza CLI 的折扣管理技能,涵盖自动折扣、优惠码和优惠券活动。它提供创建、查询、更新、取消及删除等操作指引,并要求缺少必要条件时先询问,避免擅自设定会影响商家收入的折扣。

主要功能

  1. 01创建自动折扣和优惠码
  2. 02管理优惠券活动
  3. 03搜索并查询折扣
  4. 04更新、取消或删除活动
  5. 05根据必填字段提示确认

适用场景

  1. 01设置限时闪购或阶梯满减
  2. 02创建商品或订单优惠码
  3. 03查找并处理已暂停或结束的折扣

安装

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

$npx skills add https://github.com/shoplazza/shoplazza-cli --skill shoplazza-discounts

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

详细介绍

shoplazza CLI — 折扣模块

重要提示——开始前,请先使用 Read 读取 ../shoplazza-common/SKILL.md。 该文件负责所有跨领域机制:三个访问层级、输出封装(.data)、 --dry-run、--jq(包括“不要传入 -r”)、--fields、schema、api rest、身份验证/配置档案, 以及安全协议。本文件仅涵盖折扣领域,不会重复这些内容。

概览

discounts 模块用于管理折扣活动(自动折扣和基于折扣码的折扣)以及优惠券(代金券)活动。三个访问层级均适用(层级选择规则见 shoplazza-common——优先使用 +shortcut)。

没有 +update、+cancel 或 +restart 快捷命令——这些生命周期操作是规范中的叶子节点。

命令一览

意图 → 命令。权威标志/参数请查阅 shoplazza discounts <cmd> --help 和 shoplazza schema discounts.<cmd>,而非本表。

用户意图命令
折扣百分比(使用优惠券码)discounts +percent-code --target order|product --percent <1-99>
固定金额折扣(使用优惠券码)discounts +amount-code --target order|product --off <amt>
免运费优惠券discounts +free-shipping-code
买 X 赠 Y(使用优惠券码)discounts +bxgy-code(购买范围 + 赠送范围)
限时特卖(自动应用,无需折扣码)discounts +flashsale --value ...
买 N 件,第 N 件打折(自动应用,无需折扣码)discounts +mn-discount --tiers "n:%,..."
消费/购买 N 件达到门槛 → 自动折扣discounts +rebate --target order|product --tiers "th:disc,..."
搜索/筛选折扣discounts +search --query ... --progress ongoing
按 ID 获取一项折扣discounts get --params '{"id":"<id>"}'
按折扣码获取一项折扣discounts get-by-code --params '{"discount_code":"<CODE>"}'
取消折扣discounts cancel --data '{"ids":["<id>",...]}'
重启已暂停的折扣discounts restart --data '{"id":"<id>"}'
删除一项已结束的折扣discounts delete --params '{"id":"<id>"}'
删除多项已结束的折扣discounts batch-delete --data '{"ids":[...]}'
更新自动折扣discounts update-automatic --params '{"id":"<id>"}' --data '<body>'
更新非自动折扣(折扣码)discounts update-non-automatic --params '{"id":"<id>"}' --data '<body>'
配置跨类型组合规则discounts combine --data '<rules>'
优惠券活动(代金券)discounts coupons {create,get,update}

执行请求

当用户说“帮我创建一个 X 营销活动”/“create a flash sale”/“建个优惠码”/类似的话时,这属于操作,而不是提问:

  1. 通过下方的触发器表,将意图匹配到快捷方式。
  2. 检查必填字段(每个快捷方式的 no-default 标志)。如果有任何字段缺失或含糊不清 → 使用 AskUserQuestion 提问,绝不捏造。 实际折扣会让商家蒙受损失;“我就默认设成满 100 减 10”是错误做法。
  3. 对于这些必填且无默认值的字段,此技能优先于会话级的“不提澄清问题”偏好。 使用限额不属于此类(见下文)。
  4. 必填项齐全 → 执行(+shortcuts 专为安全执行而设计;仅当用户明确要求时,才先运行 --dry-run)。
  5. 绝不询问具有 CLI 默认值的标志。 这是绝对规则。如果 <shortcut> --help 显示 (default …)/auto-generated if omitted/omit-to-disable,该标志绝不能出现在任何 AskUserQuestion 中。采用默认值;只有用户的措辞明确指定了其他值时才覆盖(例如,“8 折” → --type=amount-percent)。

使用限额为可选项(省略 = 不限)。 --limit-max/--limit-user(以及 flashsale 的 --limit-user-variant/-product/-all)没有需要设置的默认值——省略即可,折扣不设限。不要询问限额,也不要传入 -1(CLI 会拒绝 -1:“must be > 0”)。一个较宽松的例外:对于没有结束日期且不设限的开放式、会产生资金成本的代码/优惠券活动,可以在回复中提及兑换次数不设限——只需提及,不要阻止操作,也不要将其转化为 AskUserQuestion。

绝不询问清单(这些选项均有 CLI 默认值或可通过省略禁用——绝不要提问): --start(默认 now)· --end(默认 -1/永久)· --name(自动生成)· --code(自动生成)· --combines(默认为空 = 不叠加)· --limit-max/ --limit-user(省略 = 不限)· --limit-user-variant/--limit-user-product/ --limit-user-all(flashsale;省略 = 不限)· --limit-order(+bxgy-code,默认 1)· --limit-order-once(+amount-code/+rebate,默认 true)· --type(+rebate 默认 amount-off,+flashsale 默认 percent)· --scope(+mn-discount 默认 highest)· --price-rule(+flashsale 默认 price)· --price-sort(+mn-discount 默认 desc)· --min-amount(默认 0)· --min-quantity(默认 1)· --countries(默认全部)· --stock(省略 = 跟随商品库存)· --exclude(默认关闭)· --customer-segments(省略 = 所有客户均符合条件)。

如有疑问,运行 <shortcut> --help:所在行包含 “(default ...)”、“auto-generated” 或 “omit …” 的任何标志,都采用默认值,不要加入提问清单。

触发语 → 快捷方式
用户说快捷方式如何提取值
满X减Y / 订单满X减Y / 消费X减Y+rebate --target order --type amount-off--tiers "X:Y";多档优惠“满200减20,满500减50” → "200:20,500:50"
商品满X减Y / 商品消费X减Y+rebate --target product --type amount-off需要 --products 或 --collections 或 --variants
满N件减Y元 / 买N件减Y元+rebate --type qty-off--tiers "N:Y"
满X享Y折 / 满X打Y折 / 消费X享Y%折扣+rebate --type amount-percentY 是折扣百分比,例如“8折” → 20(即减价20%)——如有歧义,请确认
满N件享Y折 / 买N件享Y%折扣+rebate --type qty-percent
第N件Y折 / 买N件第N件Y折 / 第N件减价Y%+mn-discount--tiers "N:Y",其中 Y 是减价百分比
闪购 / 限时秒杀 / 限时折扣 / 限时促销+flashsale自动应用,无需代码;--value + --type;通过 --variants/--collections 指定范围(省略 = 所有商品)
优惠码 + X% off / 折扣码立减Y% / X% 折扣优惠券+percent-code--percent 是百分比(1-99)
优惠码立减Y元 / 折扣码减¥Y / 优惠券减$Y+amount-code--off 是金额
包邮码 / 免邮券 / 免运费码+free-shipping-code可选 --off(部分减免),--countries
买X送Y / 买X赠Y / 买X免费得Y+bxgy-code购买范围 + --buy-quantity/--buy-amount;赠送范围 + --get-quantity;--get-free / --get-percent / --get-off

如果有多行匹配,请询问用户选择哪一种。不要猜测。

必填项与询问项对照表

只有没有默认值的标志才需要询问。此处不包括上限——上限默认不限制。

快捷方式用户未指定时必须询问尽可能推断静默使用默认值
+percent-code--percent(百分比)、--target;如果 --target=product,还需询问 --products/--variants/--collections根据“订单/商品”措辞推断 --target--min-amount、--min-quantity、上限、--combines、--code、--name、时间、--customer-segments、--exclude
+amount-code--off(¥)、--target;如果 --target=product,还需询问范围根据措辞推断 --target与 +percent-code 相同,另加 --limit-order-once
+free-shipping-code—(无严格必填项)仅当用户说“运费立减Y元”时推断 --off--off、--min-amount、--min-quantity、--countries、上限、--combines、--code、--name、时间
+bxgy-code购买范围、--buy-quantity 或 --buy-amount、赠送范围、--get-quantity、以及 --get-free/--get-percent/--get-off 之一根据“买N件送M件”推断购买/赠送数量;根据“打折”/“立减”措辞推断 --get-percent/--get-off(两者都没有则使用 --get-free)--limit-order(默认值为 1)、上限、--combines、--code、--name、时间、--exclude
+flashsale仅需询问 --value(绝不询问 --type——其默认值为 percent)根据措辞推断 --type(“X折/X%off”对应 percent,“一口价Y元”对应 fixed-price,“立减Y元”对应 off);根据商品名称推断范围--type(默认值为 percent)、范围(省略 = 所有商品)、--price-rule、--stock、每位用户的上限、--combines、--name、时间
+mn-discount--tiers推断 --scope(“最高档”=highest,“全部档”=all;也可以是 highest-all)--scope、--price-sort、范围标志、上限、--combines、--name、时间、--exclude
+rebate--target、--tiers根据措辞推断 --type——见上方触发语表如果 --target=order,则需询问范围;--limit-order-once、上限、--combines;如果用户未明确指定,则需询问 --type;--name、时间
决策示例
用户说判定
"帮我建个满减活动"ASK — 缺少阶梯和目标范围
"创建一个满减活动,满200减20"ASK — 目标范围不明确(订单还是商品?)
"创建一个满200减20的订单级满减活动,永不过期"CREATE — 所需信息齐全(+rebate --target order --tiers "200:20" --end forever);省略上限 = 不限
"Create a 15% off coupon code"ASK — 目标范围不明确(订单还是商品?)
"Create a 15% off site-wide coupon code, max 100 uses, 1 per customer"CREATE(+percent-code --target order --percent 15 --limit-max 100 --limit-user 1)
"创建闪购活动 50% off"CREATE — --value 50 已足够(+flashsale --value 50);范围可选。可说明除非指定商品,否则适用于全店。
如何提问

使用 AskUserQuestion,提供具体的编号选项。将相关字段合并为一组提问(每次调用 ≤4 个问题)。可提问的问题完整列表如下:

问题类型提问时机示例选项
目标范围(--target)对于 +percent-code/+amount-code/+rebate,用户未说明“订单/商品”时“订单级”、“商品级”
阶梯(--tiers)对于 +rebate/+mn-discount,用户未提供时自由填写:阈值:折扣 对
折扣值(--percent / --off / --value)用户只说明类型(“打个折”)而未给出数值时自由填写数值
商品定位(--products/--collections/--variants)目标范围为商品级,或快捷方式需要指定范围时自由填写 ID 列表
BXGY 买入/赠送商品范围对于 +bxgy-code,未提供范围或触发数量时自由填写 ID 列表 + 数量

仅限这些。不要合并本表以外的任何内容——其他所有标志(包括使用次数上限)都有 CLI 默认值,或可省略以禁用。提问前重新阅读用户消息,并跳过答案已包含在其中的问题。

创建:必填标志

必填 = CLI 缺少该标志(且无默认值)时会拒绝执行命令。使用上限不是必填项——不设上限时省略即可。

快捷方式必填标志
+percent-code--target --percent(当 --target=product 时,还需一个范围标志)
+amount-code--target --off(当 --target=product 时,还需一个范围标志)
+free-shipping-code(无)
+bxgy-code购买范围 ·(--buy-quantity | --buy-amount)· 赠品范围 · --get-quantity ·(--get-free | --get-percent | --get-off)
+flashsale--value
+mn-discount--tiers
+rebate--target --tiers(当 --target=product 时,还需一个范围标志)

“范围标志” = --products / --variants / --collections 中的一个(互斥)。

紧凑的成对/列表语法:

标志格式示例
+rebate --tiersthreshold:discount,..."200:20,500:50"(满 200 减 20,满 500 减 50)
+mn-discount --tiersNth-item:percent,..."3:50,5:70"(买 3 件,第 3 件 5 折;买 5 件,第 5 件 7 折)
+bxgy-code 购买侧--products P1,P2 --buy-quantity 2(或 --buy-amount 100)触发优惠所需的购买侧商品数量/金额
+bxgy-code 赠品侧--get-products P3 --get-quantity 1 --get-free享受折扣的赠品侧商品数量及优惠方式

--start / --end 的时间格式(适用于所有快捷方式):

格式含义
now当前时间
+30d / +2w / +12h相对于当前时间的偏移量
2026-11-01当日 UTC 午夜
2026-11-01T08:00:00指定的 UTC 日期时间
<unix-int>原始 Unix 秒数
forever / -1永不过期(仅适用于 --end)

定位/资格辅助标志(均为可选,适用于大多数快捷方式):

  • --exclude — 将范围 ID 设为屏蔽列表(适用于除所列商品之外的所有商品)。需同时指定范围标志才会生效。
  • --customer-segments <ids> — 将折扣限制为给定细分 ID 中的客户(省略 = 所有客户均符合资格)。

折扣叠加:--combines 用于控制此折扣是否可以与其他折扣叠加。 默认值为空(不叠加)。如需允许叠加:--combines order,product,shipping(可选择其中一部分)。若要设置全局跨类型规则(独立于 --combines),请使用 discounts combine。

查询

优先使用 +search,而不是 list。 两者都会请求 GET /discounts,但 +search 提供命名标志; list 只接受 --params JSON。

discounts +search --progress ongoing --discount-type flashsale --page-limit 250
discounts +search --query "spring" --discount-method discount_code

多值筛选条件(--progress、--discount-type、--discount-method、 --discount-target)接受以逗号分隔的列表。

折扣对象嵌套在 .data.discount.{discount_info,discount_layer,discount_rule,entitled_product,...} 中(通用的“jq 从 .data 开始”规则见 shoplazza-common):

discounts get-by-code --params '{"discount_code":"CODE123"}' \
  --jq '.data.discount.discount_info.id'

discount_type 枚举

这些是 API 的内部名称——用于 --discount-type/--params 中。 它们不是面向用户的标签。

flashsale                m_n_discount
rebate_cta_otr           rebate_ctq_otr           rebate_cta_otp           rebate_ctq_otp
code_percent             code_fix_price_reduction code_bxgy                code_free_shipping

快捷方式对应关系:

快捷方式写入discount_type
+percent-codecode_percent
+amount-codecode_fix_price_reduction
+free-shipping-codecode_free_shipping
+bxgy-codecode_bxgy
+flashsaleflashsale
+mn-discountm_n_discount
+rebate --target=order --type=amount-offrebate_cta_otr
+rebate --target=product --type=qty-offrebate_ctq_otr
+rebate ... --type=amount-percent / qty-percentrebate_cta_otp / rebate_ctq_otp

使用 --discount-type rebate 筛选不会返回任何结果——不存在这个标签;请使用四种 rebate_* 枚举之一。

生命周期 — 请求体结构不对称

注意单数与复数的区别。这是最常见的 spec-leaf 陷阱。

discounts cancel        --data '{"ids":["A","B"]}'   # ARRAY (one or many)
discounts batch-delete  --data '{"ids":["A","B"]}'   # ARRAY (must be finished)
discounts restart       --data '{"id":"A"}'          # SINGULAR — one id only
discounts delete        --params '{"id":"A"}'        # path param, no body, one id

delete 和 batch-delete 只适用于 progress == finished 的折扣。若要删除正在生效的折扣:先执行 cancel,然后再执行 delete。

更新

没有 +update 快捷命令。先用 get 获取内容,再据此构造更新请求的正文:

discounts get --params '{"id":"<id>"}' --jq '.data.discount' > /tmp/d.json
# edit /tmp/d.json …
discounts update-automatic --params '{"id":"<id>"}' --data @/tmp/d.json --dry-run

闪购/返利/满减(无优惠码)使用 update-automatic, 带优惠码的折扣使用 update-non-automatic。正文结构与对应的 create-* 端点相同——运行 schema discounts.update-automatic 查看字段。

适用范围

看起来属于折扣,实际上属于其他模块:

看起来属于折扣实际所属模块命令
礼品卡/储值卡/gift card(可在结账时兑换为商店余额)shoplazza-productsproducts gift-cards
在首页限时促销卡片中展示某项活动shoplazza-themes(创建闪购本身仍在此模块中)themes +edit

Coupon(代金券)与折扣码——两者都属于此模块,请勿混淆:

  • 折扣码(+*-code 快捷命令):顾客在结账时输入的公开代码。
  • Coupons(discounts coupons …):分配给特定顾客、通过营销活动发放的代金券。

默认使用 +*-code 快捷命令。只有用户明确提到“coupon campaign”、“voucher”、“assign to customer”或类似表述时,才使用 coupons。

权限 · 范围

授权按域(即 --domain 的单位)进行,而非按命令进行。授权流程见 shoplazza-common → Authentication。

操作所需权限授权命令
读取(get / get-by-code / list / +search)read_price_rulesauth login --domain discounts
写入(create-* / +* / cancel / restart / delete / batch-delete / update-* / combine / coupons)write_price_rulesauth login --domain discounts

折扣权限范围名为 read_price_rules / write_price_rules——没有名称中包含 “discount”的权限范围。运行 shoplazza auth scopes,检查这两项是否位于 granted_scopes 中;--domain discounts 会展开为这两项。

注意事项

仅列出领域特定的注意事项(通用注意事项——.data 前缀、--jq 不带 -r——见 shoplazza-common)。

症状原因解决方法
每次调用 discounts(包括读取操作)都会出现 403 PermissionDenied,提示“check if a store is a new marketing store”这是店铺端检查,不是权限范围问题:此店铺未启用 discounts API。信封中的通用重新登录 hint 不适用不要重新登录或重试。确认 auth scopes → granted_scopes 中包含 read_price_rules / write_price_rules(即 discounts 权限范围;没有名为“discount”的权限范围);如果已包含,请告知用户此店铺无法通过 CLI 管理 discounts,然后停止操作
get / get-by-code 返回 nulldiscount 对象嵌套在 .data.discount 下从 .data.discount.discount_info.… 开始使用 jq
--discount-type rebate 没有匹配结果“rebate”不是枚举值使用 rebate_cta_otr / rebate_ctq_otr / rebate_cta_otp / rebate_ctq_otp
--limit-max must be > 0 (got -1)上限只能是正数;不接受 -1若要表示“无限制”,请省略上限——不要传入 -1
在 +percent-code 上出现 unknown flag: --offpercent-code 使用 --percent,而非 --off使用 --percent 15(1-99)
在 +flashsale 上出现 unknown flag: --discountflashsale 使用 --value使用 --value 50(以及 --type)
+bxgy-code --buy/--get 被拒绝这些标志不存在购买侧:作用范围标志 + --buy-quantity/--buy-amount;获赠侧:--get-* 作用范围 + --get-quantity + --get-free/--get-percent/--get-off
restart --data '{"ids":["X"]}' 失败restart 请求体为单数形式使用 --data '{"id":"X"}'
delete 返回 4xx 和进度消息discount 尚未处于 finished 状态先执行 cancel,再执行 delete
--target=product 被拒绝,提示“requires one of --products/--collections/--variants”当 target=product 时必须指定产品作用范围传入一个作用范围标志
响应中的 display_name 看起来被截断服务端会自动截断至约 20 个字符如需保留名称,请显式传入 --name
创建了两个具有相同 --code 的 discount每个店铺内的 code 都必须唯一传入明确且唯一的 --code,或省略以自动生成 CLI-XXXXXX
想通过快捷方式更新没有 +update使用 update-automatic / update-non-automatic 并提供完整请求体

示例

# 1. Spend $200 → $20 off, auto-applied, no expiry, unlimited
discounts +rebate --target order --tiers "200:20" --end forever

# 2. 15% off site-wide coupon, max 100 redemptions, 1 per shopper
discounts +percent-code --target order --percent 15 --limit-max 100 --limit-user 1 --code SPRING15

# 3. Buy 2 of P1, get 1 of P2 free, single set per order
discounts +bxgy-code --products P1 --buy-quantity 2 --get-products P2 --get-quantity 1 --get-free

# 4. Find all ongoing flash sales
discounts +search --progress ongoing --discount-type flashsale --page-limit 250 \
  --jq '.data[] | {id: .discount_info.id, name: .discount_info.discount_name}'

# 5. Cancel a code-bearing discount by its code
ID=$(discounts get-by-code --params '{"discount_code":"SPRING15"}' --jq '.data.discount.discount_info.id')
discounts cancel --data "{\"ids\":[\"$ID\"]}" --dry-run     # check first
discounts cancel --data "{\"ids\":[\"$ID\"]}"               # only after the user agrees (next turn)

# 6. Hard-delete the now-finished discount
discounts delete --params "{\"id\":\"$ID\"}"

参考资料

  • 各命令的标志:shoplazza discounts <cmd> --help
  • 规范叶节点的参数 / 请求体 / 响应:shoplazza schema discounts.<cmd>
  • 通用机制(身份验证 / 层级 / 输出信封 / --dry-run / --jq / 安全性):../shoplazza-common/SKILL.md
  • 快捷方式的权威来源:shortcuts/discounts/*.go

评论

支持 Markdown