Skip to main content
Clink 的优惠分两层。搞清楚这两层的关系,后面的配置就都好理解了。

两层模型

Coupon 是折扣规则 —— 减多少、适用哪些商品、持续几个账期、总共能兑换多少次。 Promotion Code 是客户输入的那串码 —— 或者由你在后台预先绑定。
建了 Coupon 不等于客户有码可用。必须在这个 Coupon 下至少建一个 Promotion Code,客户才有东西可输入。
所有接入示例里的 promotionCode 传的都是客户可见的代码字符串,比如 WELCOME20,不是 couponId,也不是 promotionCodeId

创建

一次调用可以把 Coupon 和它下面的码一起建出来:
字段规则:
  • discountTypepercentagefixed_amount。百分比要大于 0 且不超过 100
  • 固定金额用 fixedAmounts 按币种配置,金额仍然是主货币单位(19.99 就写 19.99
  • applyTypenoneproductprice。选后两个时必须给对应的 ID
  • durationTypeoncerepeatingforever
  • Promotion Code 只允许 1 到 32 位英文字母或数字。省略 code 时平台可以生成随机码
  • 有效期用 13 位 Unix 毫秒时间戳。促销码的结束时间不会超过所属 Coupon 的结束时间
durationMonths 这个字段名有误导性。 它按计费期算,不是自然月。月付订阅传 3 是三个月,周付订阅传 3 是三周。
单独给已有 Coupon 加码用 POST /promotion-code/{couponId}。完整字段见 创建优惠券

在各种接入方式里怎么用

Elements 的完整前端事件代码在 Elements 嵌入式收银台,这里不重复一份。

校验规则

这几条是接入时最容易踩的: 临时商品只能配不限商品的 Coupon。 priceDataList 建的临时商品没有 productIdpriceId,所以只能用 applyType: none 的 Coupon。限定了商品或价格的 Coupon 会校验失败。 固定金额 Coupon 必须覆盖订单币种。 订单原始币种在 fixedAmounts 里没配金额,这个 Coupon 就不适用。折扣大于订单金额时最多减到 0,不会产生负数应付金额。 百分比折扣按币种最大小数位向下取整。 前端不要自己重算 —— 展示 Session、预览接口或 Elements amount-change 返回的金额就行。 firstOrderOnly 按这个 Customer 有没有成功过 Order 判断。 不是按浏览器、不是按邮箱文本、也不是按你自己页面的访问次数。 minimumSpend 按订单原始金额和原始币种校验。 对应币种没配置就不满足条件。 错误出现的时机不一样。 隐藏优惠码模式在创建 Session 时就失败并返回错误;可见输入模式在客户点应用时才展示错误。 兑换次数不用你自己核销。 系统在订单创建时预占,支付成功后确认,支付失败后撤销。

订阅优惠持续多久

优惠不产生自己的 Webhook

优惠不会产生独立的「付款成功」事件。判断收款仍然看原来那套:
  • 一次性付款看 Order / Session 结果
  • 订阅看 Subscription / Invoice 结果
你可以在本地记录里存 couponIdpromotionCode、原价、折扣金额和实付金额,用于展示和对账。但不要在 Webhook 到达后自己重新算一遍折扣 —— 以 Clink 返回的金额为准。

两处待确认

下面两点在实现和文档之间存在差异,接入时先别依赖:restrictedCustomerIds 不要传空数组。 接口描述说空数组表示不限制,但当前实现对非 null 的空数组会执行包含校验,结果可能是谁都用不了。不限制时直接省略这个字段perCustomerRedemptionLimit 的实际生效情况未确认。 字段能存能返回,但在当前促销码校验链路里没找到按客户统计并拦截的逻辑。要靠它做每人限领时,先自己验证一遍。

接下来

订阅支付

周期价格、订阅状态和续费。

优惠券概念

资源定义和后台管理。