用途
该技能追踪店铺在一段时间内通过折扣让出的金额,按周、月或季度分桶,并按折扣代码和折扣类型(百分比 / 固定金额 / 免运费 / 自动折扣)细分。它回答的问题是:“我们的折扣支出是上升还是下降,哪些活动在推动它?”该技能为只读,不执行任何变更。它与 discount-roi-calculator(按单个折扣计算回报)互补,提供总成本的纵向视图。
前置条件
已认证的 Shopify CLI 会话:shopify store auth --store <domain> --scopes read_orders
API 权限范围:read_orders
参数
store(字符串,必填,无默认值):店铺域名(例如 mystore.myshopify.com)
period(字符串,可选,默认 month):分桶大小,可选 week、month 或 quarter
periods_back(整数,可选,默认 12):要报告的桶数量
top_codes(整数,可选,默认 10):单独列出的顶级折扣代码数量,其余归为 other
include_shipping_discounts(布尔,可选,默认 true):是否在总计中计入运费折扣
format(字符串,可选,默认 human):输出格式,human 或 json
安全性
只读技能——不执行任何变更,可随时安全运行。
工作流程
-
根据 period × periods_back 计算时间窗口(例如 month × 12 → 从 11 个月前的桶首日开始,覆盖最近 12 个自然月)。
-
执行 orders 查询:查询条件为 created_at:>='<window_start>' financial_status:paid,first: 250,选取 createdAt、discountCodes、currentTotalDiscountsSet、totalDiscountsSet、cartDiscountAmountSet、discountApplications(含 allocationMethod、targetType、value,以及 DiscountCodeApplication 的 code、AutomaticDiscountApplication 的 title、ManualDiscountApplication 的 title)、shippingLines 的 discountAllocations,并使用分页游标。预期输出为窗口内所有已付款订单及其折扣数据,持续分页直到 hasNextPage: false。
-
对每个订单归因折扣成本:
cart_discount = currentTotalDiscountsSet.shopMoney.amount
shipping_discount = shippingLines.discountAllocations.allocatedAmountSet 之和(仅当 include_shipping_discounts: true 时)
total_discount = cart_discount + shipping_discount
按代码归因:代码折扣优先取第一个 discountApplications.code,自动 / 手动折扣取 title。
-
将每个订单归入其所属周期(周、年-月或年-季度)并聚合:每个桶的总折扣成本、每个折扣代码在每个桶的成本、每种折扣类型在每个桶的成本(percentage、fixed_amount、shipping、automatic)。
-
找出窗口内总成本最高的折扣代码,其余聚合为 other。
GraphQL 操作
orders:query(已针对 api_version 2025-01 验证):
query DiscountCostTrend($query: String!, $after: String) { orders(first: 250, after: $after, query: $query) { edges { node { id name createdAt discountCodes currentTotalDiscountsSet { shopMoney { amount currencyCode } } totalDiscountsSet { shopMoney { amount currencyCode } } cartDiscountAmountSet { shopMoney { amount currencyCode } } discountApplications(first: 10) { edges { node { allocationMethod targetType targetSelection value { ... on PricingPercentageValue { percentage } ... on MoneyV2 { amount currencyCode } } ... on DiscountCodeApplication { code } ... on AutomaticDiscountApplication { title } ... on ManualDiscountApplication { title description } } } } shippingLines(first: 5) { edges { node { title discountAllocations { allocatedAmountSet { shopMoney { amount currencyCode } } } } } } } } pageInfo { hasNextPage endCursor } } }
会话跟踪
Claude 必须在每个阶段输出以下内容,这是强制要求。
开始时输出:
╔══════════════════════════════════════════════╗ ║ SKILL: Discount Cost Trend ║ ║ Store: <store domain> ║ ║ Period: <period> × <periods_back> ║ ║ Started: <YYYY-MM-DD HH:MM UTC> ║ ╚══════════════════════════════════════════════╝
每个步骤后输出:
[N/TOTAL] <QUERY|MUTATION> <OperationName> → Params: <brief summary of key inputs> → Result: <count or outcome>
完成时输出。format 为 human(默认)时:
══════════════════════════════════════════════ DISCOUNT COST TREND (last <periods_back> <period>s) Total discount cost: $<amount> Avg per <period>: $<amount> Latest <period>: $<amount> (<delta_vs_prev_pct>% vs prior)
By bucket: 2025-Q1 $<n> (cart $<n> / shipping $<n>) 2025-Q2 $<n> (cart $<n> / shipping $<n>)
By discount type: code $<n> (<pct>%) automatic $<n> (<pct>%) manual $<n> (<pct>%) shipping $<n> (<pct>%)
Top codes (by total cost): "<code>" $<n> (<pct>%) "<code>" $<n> (<pct>%) other $<n> (<pct>%)
Output: discount_cost_trend_<date>.csv ══════════════════════════════════════════════
format 为 json 时输出:
{ "skill": "discount-cost-trend", "store": "<domain>", "period": "month", "periods_back": 12, "total_discount_cost": 0, "by_bucket": [], "by_type": { "code": 0, "automatic": 0, "manual": 0, "shipping": 0 }, "top_codes": [], "currency": "USD", "output_file": "discount_cost_trend_<date>.csv" }
输出格式
CSV 文件 discount_cost_trend_<YYYY-MM-DD>.csv,列包括:bucket、discount_code_or_title、discount_type、orders_count、cart_discount、shipping_discount、total_discount、currency。
错误处理
THROTTLED:API 速率限制超出,等待 2 秒,最多重试 3 次。
叠加折扣代码:一个订单上有多个代码,按各代码价值占比比例归因,或若相等则标记为 multi-code。
无标题的手动折扣:收银员录入且标题为空,归为 manual:untitled。
多币种订单:展示币种与店铺币种不同,为保持一致,按 shopMoney.amount(店铺币种)求和。
最佳实践
促销频繁的企业用 period: week;有稳定长期优惠的店铺用 period: month;董事会报告用 period: quarter。
在没有活动的情况下趋势持平或上升,通常指向自动折扣蔓延——检查没有结束日期的自动折扣。
将最新桶与 discount-roi-calculator 交叉比对,验证成本增加是否带来匹配的增量收入。
如果会计将运费补贴与产品折扣分开记账,设置 include_shipping_discounts: false。
设置每月自动化:折扣支出超出预算时,应在出现在利润报告之前触发财务审查。