Braintree:如何在计费周期中途创建订阅并按比例收费?
结论
创建订阅时,可以同时指定固定账单日并启用 startImmediately。订阅会立即生效,Braintree 会按当前日期到下一个账单日之间的时长计算首期费用,之后固定在每月 1 日续费。
主要配置如下:
billingDayOfMonth: 1options.startImmediately: true
如果没有启用 startImmediately,订阅通常要等到下一个账单日才会开始。在等待期间,也无法按预期修改已激活订阅的 add-on。
创建方式
下面以 Braintree Node.js SDK 的请求结构为例:
const result = await gateway.subscription.create({
paymentMethodToken: paymentMethodToken,
planId: "monthly-plan",
billingDayOfMonth: 1,
options: {
startImmediately: true
}
});
if (!result.success) {
throw new Error(result.message);
}
console.log(result.subscription.id);
console.log(result.subscription.status);
假设客户在当月 15 日注册,计费过程如下:
- Braintree 立即创建并启动订阅。
- 首次收费覆盖注册日至下月 1 日前的剩余周期。
- 从下月 1 日起收取完整月费。
- 之后继续在每月 1 日续费。
字段名称可能因 Braintree SDK 的语言和版本而有所不同。例如,某些 SDK 使用 start_immediately。请以当前 SDK 的 Subscription.create 请求类型为准。
按用户数量计费
不必为每个用户单独创建 add-on。更常见的做法是在 plan 中配置一个“每用户”add-on,再用 quantity 记录用户数量。
创建订阅时,可以设置初始数量:
const result = await gateway.subscription.create({
paymentMethodToken: paymentMethodToken,
planId: "monthly-plan",
billingDayOfMonth: 1,
options: {
startImmediately: true
},
addOns: {
update: [
{
existingId: "per-user",
quantity: initialUserCount
}
]
}
});
客户增加用户后,更新该 add-on 的数量,并启用按比例计费:
const result = await gateway.subscription.update(subscriptionId, {
addOns: {
update: [
{
existingId: "per-user",
quantity: newUserCount
}
]
},
options: {
prorateCharges: true
}
});
如果业务规则要求立即结算新增费用,还可以考虑设置:
options: {
prorateCharges: true,
revertSubscriptionOnProrationFailure: true
}
revertSubscriptionOnProrationFailure 可以避免按比例收费失败后,订阅配置仍被更新。是否支持该选项以及具体字段形式,也要以所用 SDK 版本为准。
注意事项
startImmediately 与 prorateCharges 的用途不同
startImmediately:在创建订阅时立即启动,并处理首个不完整的计费周期。prorateCharges:主要用于订阅创建后,由价格、quantity 或 add-on 变动产生的周期中途差额。
创建订阅时设置 prorateCharges,并不等同于立即启动订阅。
账单日可能有限制
Braintree 可能会限制 billingDayOfMonth 可接受的日期范围,月底日期尤其需要留意。每月 1 日没有月份天数不同的问题,但请求仍应交给 SDK 验证。
不要自行确定首期金额
实际 proration 金额由 Braintree 根据账单周期、变更时间、币种精度和商户账户设置计算。下面的简单公式只能用于估算,不能作为最终扣款依据:
monthly_price × remaining_days / total_days
最终金额应以 Braintree 返回的 transaction 或 subscription 数据为准。
在 sandbox 中验证失败路径
至少需要测试以下情况:
- 客户在月中注册,首期按比例收费成功;
- 首期扣款失败后的订阅状态;
- 增加或减少用户数量;
- add-on 按比例收费失败后的回滚行为;
- 在每月 1 日附近创建订阅的边界情况;
- 时区造成的账单日期偏差。
这个场景通常不需要另行创建一次性 transaction。创建订阅时,优先结合固定的 billingDayOfMonth 和 startImmediately;席位数量则通过一个带 quantity 的 per-user add-on 管理。
备注:内容仅供参考。
