一、引子:一个程序员的双十一困境

去年双十一,一个朋友给我发微信:"帮我看看这购物车到底减了多少钱?"

我打开截图:跨店满减300-50、店铺券199-30、品类券满200减20、88VIP折扣、直播间专享红包、前1小时折上折……6重优惠叠加,系统显示"预计节省 ¥287.50"。

朋友问:"那实际付多少?"

我算了5分钟,说:"……大概对。"

注意,我是个做过几套电商系统的程序员。我都只能说出"大概对"。

二、促销复杂度是怎么失控的?

2015年的双十一,规则很简单:全场5折。

去年的双十一,我数了一下某头部平台的优惠类型:满减、店铺券、平台券、品类券、会员券、直播间红包、分期免息、前N件折上折、分享裂变券、以旧换新补贴——10种。

这还不算商家自己后台配置的秒杀、预售、买赠、加价购、第二件半价

为什么会这样?

因为平台要增长,商家要转化,用户要便宜。每一方都在加规则,但没有人做减法

结果是三方都受伤:

  • 消费者:算不明白,觉得被套路,"先涨价后打折"的骂声每年都一样
  • 商家:后台配活动像写代码,一个满减配错门槛,一天亏掉一个月利润
  • 平台:客服40%的咨询是"为什么我的券没用上"

三、促销系统设计的三个核心原则

做了这么多年促销系统,我认为一个健康的促销引擎应该满足三个标准:

1. 规则标准化——不是"能配出来",而是"只能这么配"

很多商家后台的问题是:给你100个字段,你自己组合。看起来灵活,实际上是在让用户"自己发明规则"。

更好的方式是:定义清楚有限的策略类型(满减、满折、特价、秒杀、优惠券……),每个策略有明确的条件、动作、范围,不允许随意组合出"四不像"。

设计启示:系统应该提供15个经过验证的基础策略(满减、满折、阶梯价、秒杀、特价、预售、首单、会员、包邮、买赠、优惠券、积分抵扣、余额抵扣、组合优惠),而不是100个自由字段。

2. 计算白盒化——不是"系统说了算",而是"每一步都能看见"

消费者问客服"为什么我的券没用上",客服只能截图去问技术。技术查日志,日志只写了"条件不满足"。

更好的方式是:每次计算生成一张"计算明细单",列出每一步优惠怎么来的、哪一步条件没过、为什么没过。

这在系统设计上体现为:API 返回的不能只是一个 final_price,而应该包含完整的 applied_rules[]skipped_rules[]diagnosis{} 三层结构。

响应体

{
  "meta": {
    "status": "APPLIED",
    "code": "PROMOTIONS_APPLIED",
    "message": "促销已生效",
    "timestamp": 1779712405924,
    "trace_id": "mptr_20260525_02339f67",
    "has_refund_config": true
  },
  "data": {
    "summary": {
      "original_amount": "288.70",
      "total_discount": "20.00",
      "payable_amount": "268.70",
      "available": true,
      "reward_summary": {
        "gift": 1,
        "points": 1
      }
    },
    "applied_promotions": [
      {
        "promotion_code": "FR_001_2F30D4",
        "strategy_type": "full_reduction",
        "benefit_type": "mixed",
        "discount": "20.00",
        "applied_items": [
          "SKU001",
          "SKU002"
        ],
        "rewards": [
          {
            "type": "gift",
            "sku": "GIFT001",
            "quantity": 1,
            "mode": "manual"
          },
          {
            "type": "points",
            "points": 200
          }
        ],
        "message": "[fixed_amount_reduction] 固定减免: 20.00; [gift_manual] 赠送礼品(手动): GIFT001 x 1; [bonus_points] 赠送积分: 200",
        "tier_details": [],
        "strategy_type_display": "满减"
      }
    ],
    "request": {
      "user_id": 1001,
      "cart_items": [
        {
          "sku": "SKU001",
          "quantity": 2,
          "price": "89.9"
        },
        {
          "sku": "SKU002",
          "quantity": 1,
          "price": "108.90"
        }
      ],
      "promotion_codes": [
        "FR_001_2F30D4"
      ],
      "context": {},
      "preview": false,
      "order_id": "TEST_1779712224773"
    },
    "item_discounts": [
      {
        "sku": "SKU001",
        "quantity": 2,
        "original_price": "179.80",
        "allocated_discount": "12.46",
        "payable": "167.34"
      },
      {
        "sku": "SKU002",
        "quantity": 1,
        "original_price": "108.90",
        "allocated_discount": "7.54",
        "payable": "101.36"
      }
    ]
  },
  "trace": {
    "logs": [
      "诊断信息:规则 FR_001_2F30D4: 规则状态为 paused"
    ]
  }
}

3. 凭证固化——下单时算好的,退款时不许重算

这是血泪教训。很多系统在退款时"重新计算"优惠,导致用户下单时享受的价格,退款时变了。

正确做法:下单时把"每个商品分摊了多少优惠"写成不可篡改的凭证。退款时直接读取,不再重算。

{
    "meta": {
        "status": "APPLIED",
        "code": "TRACE_FOUND"
    },
    "data": {
        "trace_id": "mptr_20260525_9ae7db6f",
        "order_id": "TEST_1779713243262",
        "status": "ACTIVE",
        "storage_location": "redis",
        "created_at": null,
        "expires_at": null,
        "original_request": {
            "user_id": 1001,
            "cart_items": [
                {
                    "sku": "SKU-PAGE-005",
                    "quantity": 3,
                    "price": "24.75"
                },
                {
                    "sku": "SKU-PAGE-006",
                    "quantity": 2,
                    "price": "69.75"
                }
            ],
            "promotion_codes": [
                "FR_001_2F30D4"
            ],
            "context": {},
            "preview": false,
            "order_id": "TEST_1779713243262"
        },
        "promotion_result": {
            "summary": {
                "original_amount": "213.75",
                "total_discount": "20.00",
                "payable_amount": "193.75",
                "available": true,
                "reward_summary": {
                    "gift": 1,
                    "points": 1
                }
            },
            "applied_promotions": [
                {
                    "promotion_code": "FR_001_2F30D4",
                    "strategy_type": "full_reduction",
                    "benefit_type": "mixed",
                    "discount": "20.00",
                    "applied_items": [
                        "SKU-PAGE-005",
                        "SKU-PAGE-006"
                    ],
                    "rewards": [
                        {
                            "type": "gift",
                            "sku": "GIFT001",
                            "quantity": 1,
                            "mode": "manual"
                        },
                        {
                            "type": "points",
                            "points": 200
                        }
                    ],
                    "message": "[fixed_amount_reduction] 固定减免: 20.00; [gift_manual] 赠送礼品(手动): GIFT001 x 1; [bonus_points] 赠送积分: 200",
                    "tier_details": [],
                    "strategy_type_display": "满减",
                    "item_discounts": [
                        {
                            "sku": "SKU-PAGE-005",
                            "quantity": 3,
                            "original_price": "74.25",
                            "allocated_discount": "6.95",
                            "payable": "67.30"
                        },
                        {
                            "sku": "SKU-PAGE-006",
                            "quantity": 2,
                            "original_price": "139.50",
                            "allocated_discount": "13.05",
                            "payable": "126.45"
                        }
                    ],
                    "refund_config": {
                        "auto": {
                            "strategy": "proportional",
                            "coupon_policies": {
                                "tiered": {
                                    "used": {
                                        "action": "return_to_user",
                                        "method": "proportional"
                                    },
                                    "unused": {
                                        "action": "return_to_user",
                                        "method": "full"
                                    },
                                    "expired": {
                                        "action": "forfeit",
                                        "method": "none"
                                    }
                                },
                                "no_threshold": {
                                    "used": {
                                        "action": "return_to_user",
                                        "method": "proportional"
                                    },
                                    "unused": {
                                        "action": "return_to_user",
                                        "method": "full"
                                    },
                                    "expired": {
                                        "action": "forfeit",
                                        "method": "none"
                                    }
                                },
                                "special_price": {
                                    "used": {
                                        "action": "return_to_user",
                                        "method": "proportional"
                                    },
                                    "unused": {
                                        "action": "return_to_user",
                                        "method": "full"
                                    },
                                    "expired": {
                                        "action": "forfeit",
                                        "method": "none"
                                    }
                                },
                                "full_reduction": {
                                    "used": {
                                        "action": "return_to_user",
                                        "method": "proportional"
                                    },
                                    "unused": {
                                        "action": "return_to_user",
                                        "method": "full"
                                    },
                                    "expired": {
                                        "action": "forfeit",
                                        "method": "none"
                                    }
                                },
                                "percentage_discount": {
                                    "used": {
                                        "action": "return_to_user",
                                        "method": "proportional"
                                    },
                                    "unused": {
                                        "action": "return_to_user",
                                        "method": "full"
                                    },
                                    "expired": {
                                        "action": "forfeit",
                                        "method": "none"
                                    }
                                }
                            },
                            "min_refund_ratio": 0,
                            "gift_return_required": true,
                            "use_template_coupon_policy": true,
                            "tiered_degradation_threshold": 0
                        },
                        "fallback": {
                            "enabled": false,
                            "trigger": "amount_exceeds",
                            "threshold": 0,
                            "handler_code": "MANUAL_REVIEW",
                            "handler_note": ""
                        },
                        "coupon_refund_mode": {
                            "tiered": "auto",
                            "no_threshold": "auto",
                            "special_price": "auto",
                            "full_reduction": "auto",
                            "percentage_discount": "auto"
                        }
                    }
                }
            ],
            "item_discounts": [
                {
                    "sku": "SKU-PAGE-005",
                    "quantity": 3,
                    "original_price": "74.25",
                    "allocated_discount": "6.95",
                    "payable": "67.30"
                },
                {
                    "sku": "SKU-PAGE-006",
                    "quantity": 2,
                    "original_price": "139.50",
                    "allocated_discount": "13.05",
                    "payable": "126.45"
                }
            ],
            "used_coupons": [],
            "total_paid": "193.75",
            "currency": "CNY"
        },
        "refund_history": []
    }
}

上述基础策略,来自开源项目 mypromotion-engine-core 的设计。它是一个纯 Python、零框架依赖的促销计算引擎,支持在线体验核心计算逻辑:

最后分享一个工程视角的验证标准:不要只看规则能不能配出来,要看退一单的时候,系统能不能在 100ms 内告诉你"退了多少钱、券回没回"。如果每次退款都要技术人工查日志,说明架构还需要调整。

如果你也在设计促销系统,建议优先做好三件事:规则标准化、计算白盒化、凭证固化。顺序不要反,否则越往后拖,改造成本越高。

下一篇:满300减50,退一件到底该退多少钱?——电商退款计算的三大暗坑

Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐