升了档,钱怎么算才不挨骂:vibe 项目的订阅升降级按比例计费实战
用户中途换档,钱该怎么算?本文讲升级补差价的一条公式、降级三种做法的取舍、年付季付与团队席位的折算、优惠券和税费的算法,以及支付平台里三个容易踩的开关,最后附一份上线前逐项打钩的检查清单。

升了档却被多收了一个月:先讲一个虚构的教训
先讲一个虚构的教学例子。阿远一个人用 AI 搭了个笔记应用“云杉笔记”,分三个档:免费档、30 元一个月的基础档、90 元一个月的专业档。上线第三周,有个用户从基础档升到了专业档,升完当天就写信来问:我这个月明明已经付过 30 元了,为什么升档又收了我整整 90 元?阿远去查账才发现,AI 写的升档代码就是这么干的:用户一点升级,直接按新档全价再收一次,之前那 30 元等于白付了。
阿远赶紧改。改完没过两天,又一个用户从专业档降回基础档,降完就问:我这个月才用了 10 天,剩下的 20 天是不是该退我点钱?阿远一看,降级代码压根没处理退款,用户当月 90 元照收,档位却已经降下去了。用户原话是:钱照收,档位先降,这叫什么道理?
这两件事其实是同一个毛病:订阅换档的时候,钱没按“用了几天、还剩几天”算清楚。用户升档,多付的钱要抵扣;用户降级,没用完的钱要给个说法。不管是多收还是少退,用户第一反应都不是“系统出 bug 了”,而是“这家店在坑我”。一个人这么想,就会去应用商店写差评、去社交平台吐槽,修起来比写代码贵得多。
本文讲的就是这笔账怎么算:升级补多少钱、降级退不退钱、年付和团队席位怎么折算、优惠券和税费怎么不算乱、支付平台里那几个开关到底该怎么拨,最后附一份上线前能逐项打钩的检查清单。本文所有例子里的人名、产品名和数字都是虚构的教学例子,只用来把道理讲清楚;文中的天数、金额和比例都是工程经验建议,不是哪个官方标准,照着用之前先按你自己的定价表验算一遍。

一、先划界:按比例计费只管“中途换档”
动手之前先把范围划清楚,不然很容易把几件不同的事混在一起算。按比例计费只管一件事:用户在一个计费周期没走完的时候换档,这期剩下的钱怎么算。用户中途从 30 元的档升到 90 元的档,补多少;从 90 元的档降到 30 元的档,退不退、退多少,都是这篇要讲的。
有几件看着像、其实不是这篇的事。第一,扣款失败怎么办——卡里没钱、银行拒付、重试几次、什么时候发提醒,那是订阅续费失败挽回的活,另一篇《订阅续费失败挽回》指南已经讲过,这篇不重复。第二,试用到期降级——14 天试用结束自动回到免费档,涉及的是试用到期提醒和降级时机,另一篇《试用到期降级》指南讲过。第三,官方调价——你把专业档从 90 元涨到 110 元,老用户按老价还是新价、有没有过渡期,那是《价格变更与老用户过渡》指南的事。第四,团队加人减人——席位数的计费逻辑在第五节会讲到,但纯粹按人头开票的规则,另一篇《团队席位计费》指南有更细的讲法。第五,积分和余额——用户账户里剩的点数、充值余额怎么抵扣,那是《积分账本》指南的范围。
划界的意义很实际:换档这笔账本身已经够乱了,再把续费失败、试用到期、官方调价都搅进来,代码里一个 if 分支都写不清楚。先把“中途换档”这一个场景算对、算透明,再去管边上的事。
二、按比例计费到底在算什么:就一个公式
按比例计费的道理一句话就能说清:用户这个周期用了几天旧档,就付几天旧档的钱;剩下的几天用新档,就付几天新档的钱。已经付过的钱不是白付的,要从新档的费用里扣掉。公式写出来是这样:补差价 =(新档月价 − 旧档月价)× 剩余天数 ÷ 周期总天数。
拿“云杉笔记”的例子算一遍。基础档 30 元一个月,专业档 90 元一个月,一个周期按 30 天算。用户在第 10 天升级,前面 10 天用的是基础档,后面 20 天用专业档。补差价 =(90 − 30)× 20 ÷ 30 = 40 元。用户这期总共付了 30 + 40 = 70 元,刚好等于 10 天基础档(10 元)加 20 天专业档(60 元)。账面上分毫不差,用户自己拿计算器也能算出来,这就是按比例计费最想达到的效果:不用你解释,用户自己能验算。

算这笔账有三个地方最容易错。第一,天数按“实际周期天数”算,不要按自然月算。2 月只有 28 天,1 月有 31 天,如果代码里写死一个月 30 天,2 月升级的用户就会多付几天钱。正确做法是按这个用户真实的计费周期算:上次扣款日到下次扣款日之间有几天,分母就是几天。第二,“第几天”以用户当地时间为准,不要以服务器时间为准。服务器在 UTC,用户在东八区,差 8 个小时,升级那一刻正好卡在两天交界上,天数就算错一天。第三,金额精确到分,四舍五入只做一次。先算出精确值,最后一步再四舍五入到分;中间每一步都四舍五入,凑出来的账和用户自己算的能差出几分钱,客服解释起来没完没了。
还有一个建议:补差价太小的时候,不如不收。如果用户在周期最后一天升级,补差价只有(90 − 30)× 1 ÷ 30 = 2 元,为 2 元单独开一张发票、单独扣一次款,用户的账单里多一行 2 元的扣款,体验比不收还差。工程经验建议是:补差价低于 5 元时直接免掉,或者记到下个周期一起收,页面上写一句“本次升级免费,下期按新档扣费”。5 元这个数不是标准,只是个经验值,图的是账单干净。
三、升级怎么收:立即补差,还是下期再说
升级有两种收法,各有利弊。第一种是立即补差:用户一点升级,马上按第二节的公式算出补差价扣款,档位立刻生效。用户当下就能用上专业档的功能,你当下就收到钱。第二种是下期生效:用户现在升级,但这个周期还是按旧档走,下个扣款日才按新档扣费、档位才变。账最干净,但用户要等——他可能是因为急着用某个专业功能才点的升级,让他等半个月,黄花菜都凉了。
工程经验建议是:升级默认立即补差、立即生效。这是大多数用户心里的默认预期:我点了升级、付了差价,功能就该现在能用。反过来做——收了钱还让用户等——投诉会比多收钱还多。但有两个例外。第一,用户是在免费档升到付费档,第一次扣款本来就是全价,没有“补差”的概念,直接按新档全价收,别把免费档算进公式里凑数。第二,用户升级的同时还在试用期内,试用还没结束就别急着扣款,先让试用走完,到期再按新档扣,页面上写清楚“试用结束后按专业档 90 元一个月扣费”。
立即补差还有一个细节:扣款失败怎么办。补差价 40 元扣款失败,不能悄悄把用户降回旧档,也不能让用户以为自己已经是专业档了。正确做法是:档位先不升,页面明确告诉用户“升级未完成,补差价 40 元扣款失败,请更换支付方式”,等扣款成功再升档。这个提醒要和续费失败的提醒分开写,别共用同一套文案——用户这时不是“续费失败”,是“升级没成功”,文案写错了用户会以为下个月要被扣两次。
四、降级最容易吵架:退款、余额,还是等到期
降级比升级难,因为降级涉及“把钱还给用户”,而还钱的方式有三种,每种都有人骂。第一种是立即退款:按剩余天数把差价退回原支付方式。用户最满意,但你的现金流最难受,而且退款还要付一遍手续费,退得越多手续费亏得越多。第二种是转余额:差价不退现金,变成账户余额,下次扣费时抵扣。现金流保住了,但用户会觉得“我的钱被锁在你这儿了”。第三种是下期生效:这个周期照旧收旧档的钱、照旧用旧档的功能,下个扣款日才按新档扣费。账最简单,一分钱不用退,但用户会问:我都降级了,为什么这个月还要按 90 元收?
工程经验建议是:降级默认下期生效,不退款、不转余额。这个做法最不容易出错,也最容易在页面上讲清楚:“已申请降级,本周期剩余时间仍可使用专业档,下期起按基础档 30 元一个月扣费。”用户当下没有任何损失——他付过的 90 元对应的专业档功能,这个月照常用到月底——所以接受度其实比想象中高。客服话术也可以写死一句:降级不是“现在就降”,是“下个月开始按低档收费”,高档功能用到这个周期结束。
但降级默认下期生效也有两个例外,该退还得退。第一,用户是年付,一次付了 900 元,用了 100 天就降级,剩下 265 天的差价不是小数目,这时候还坚持“下期生效”,等于让用户等 265 天,太欺负人了。年付降级建议给余额或按比例退款,金额按年付的公式算:差价 × 剩余天数 ÷ 365。第二,用户降级是因为产品出问题——比如专业档的核心功能坏了三天修不好——这时候别跟用户算天数,直接退,退多退少都是态度问题,客服权限里应该有一条“故障降级直接退剩余差价”。
不管选哪种做法,有一件事不能省:降级确认页必须把钱的事写明白。用户点降级之前,页面上就要有一行字说明白三件事:这个周期还收多少钱、下期什么时候开始按新档收、有没有退款、退多少。很多投诉其实不是对“退多少钱”不满,而是对“事先没人告诉我”不满。把这行字写上去,投诉量至少少一半。
五、年付、季付、团队席位:三种变体怎么折算
月付的公式学会了,年付、季付和团队席位都是同一个公式换个分母和单价。先讲年付。云杉笔记的专业档年付 900 元一年,基础档年付 300 元一年。用户在第 100 天从基础档年付升到专业档年付,剩余 265 天,补差价 =(900 − 300)× 265 ÷ 365,约 436 元。注意分母是 365,不是 12 个月;闰年按 366 天算,别写死。还有一个坑:年付用户升级后,下一个扣款日是哪天?建议是周期锚点不变——原来是哪天扣款还是哪天扣款,只补差价,不把周期重置。这样用户每年只需要在同一天记一笔账,客服解释也容易。
季付同理,分母是当季的实际天数。第一季度 90 天、第二季度 91 天,分母跟着真实天数走,不要图省事写死 90 天。季付还有一个常见坑:用户在季末最后两天升级,补差价只有几块钱,按第二节末尾的建议,低于 5 元直接免掉或记到下期,别为几块钱多开一张发票。
团队席位是另一种变体:单价按人算,天数按剩余周期算。云杉笔记的团队档 199 元一个人一个月,一个 5 人团队在第 10 天加到 8 人,多了 3 个人,补差价 = 3 × 199 × 20 ÷ 30,约 398 元。反过来减人,按第四节的建议默认下期生效:这个周期 8 个人照常用,下期按 5 个人扣费。席位增减最容易出的 bug 是“按人头全价收”——加 3 个人就收 3 × 199 = 597 元,不按剩余天数折算,用户一看账单就知道多收了。还有一个细节:加人减人同一天发生多次,只按最后一次净变化算。上午加 2 个人、下午减 2 个人,净变化是 0,账单上就该是 0,别一天出两张账单。
六、优惠券、税费、货币:别让折扣把账算乱
换档的账本来就够乱了,优惠券、税费和多币种再搅进来,算错是常事。先讲优惠券。云杉笔记的专业档 90 元一个月,用户手里有一张 8 折券,基础档 30 元一个月也有 8 折。升级补差价该按原价算还是按折后价算?工程经验建议是:按折后价算差价。折后新档 72 元,折后旧档 24 元,差价 48 元,第 10 天升级补差 = 48 × 20 ÷ 30 = 32 元。按原价算差价再打折,数字上是一样的,但发票上不好写——用户看到“原价差价 60 元打 8 折得 48 元”还能懂,看到“补差 40 元再打 8 折得 32 元”也还行,最怕的是代码里两种算法混着用,有的账单按原价算、有的按折后算,对不上账。
优惠券还有一个坑:券的有效期。用户的 8 折券这个月底到期,他在月底前一天升级,补差价按 8 折算了,下个月扣费时券已经过期,该按原价 90 元扣还是继续 8 折?建议是:券只影响它有效期内的那笔钱,过期之后按原价扣,页面上提前写一句“优惠券有效期至本月底,下期起恢复原价”。别让用户下个月看到账单从 72 元变回 90 元时,觉得是你偷偷涨了价。
税费的原则只有一条:按实收金额计税。补差价 40 元,税就按 40 元算,不要按新档全价 90 元算,也不要按“用户这个周期总共付了 70 元”算。发票上建议把换档的账拆成两行写:一行是“基础档未用部分抵扣 −20 元”,一行是“专业档剩余天数费用 +60 元”,合计 40 元。用户拿着发票一眼就能对上账,财务对账时也好查。多币种同理:用户用美元付的款,补差价也按美元算,别拿人民币的定价表去算美元的账,汇率波动会让同一笔账在不同地方算出不同数字。
七、支付平台里的三个开关:别让默认设置替你做决定
很多 vibe 项目用 Stripe 一类的支付平台收订阅费,换档的逻辑有现成的开关,但 AI 生成的代码常常直接用默认设置,默认设置不一定是你想要的。以 Stripe 为例,改订阅时有个参数叫 proration_behavior,有三个选项。第一个是 create_prorations,也是默认选项:按剩余天数算差价,生成一笔按比例的费用。第二个是 none:不算差价,换档只改档位、不动钱——用户升了档,这个周期一分钱不补,下期才按新档收。第三个是 always_invoice:算出差价后立刻开一张发票、立刻扣款。
这三个选项没有哪个是错的,错的是不知道自己用的是哪个。最常见的事故是:开发者想要“升级立即补差”,代码里却没传这个参数,Stripe 默认用了 create_prorations,差价生成了但没立刻扣款,而是挂在下期账单里一起收——用户这个月没扣钱,下个月账单一看多了一笔 40 元,以为被多收了。反过来,想要“下期生效”的开发者用了默认设置,差价立刻生成,用户当月就被扣了 40 元,又来投诉“不是说好下期才收吗”。所以这一节的建议只有一句话:改订阅的代码里,把 proration_behavior 显式写出来,别留给默认。
还有一个容易忽略的开关是周期锚点 billing_cycle_anchor。升级时锚点有两个选择:保持不变,或者重置为升级当天。保持不变的意思是用户每月的扣款日不变,只补差价;重置的意思是升级当天变成新的扣款日,周期从今天重新开始算。工程经验建议是默认保持不变——用户已经习惯了每月 5 号扣款,你一升级就改成 17 号扣款,他下个月 5 号没扣款会以为订阅掉了,17 号突然扣款又以为被偷扣了。想重置周期的场景只有一个:用户自己要求“就从今天开始算新的一年”,那也得在页面上让他亲手点一下确认,别悄悄改。
最后提醒一句:换档逻辑一定要写测试,别只靠手点。AI 写出来的订阅代码,手点两下看着都对,真到月底对账才发现差了几分钱。测试至少覆盖四种情况:月付周期内升级、月付周期内降级、年付升级、团队加人。每一组都算出手工期望值写进测试里,跑通了再上线。手工期望值就是第二节那个公式,别让测试和代码用同一套公式算——那样错也错得一模一样,测不出问题。
八、上线前必须跑的检查清单
这份清单是给上线前最后一遍检查用的,一共十二项,逐项打钩,缺一项都别急着发版。每一项后面都跟一句“怎么验”,验的方法都写在明处,免得检查流于形式。
- 升级补差价公式验算过:手工算三组数(月初升级、月中升级、月末升级),和页面显示、账单金额、后台记录三处对得上。
- 降级策略写死在代码里:默认下期生效,年付降级给余额或按比例退款,故障降级直接退剩余差价,客服权限里有这条。
- 降级确认页有三行字:这个周期还收多少钱、下期什么时候按新档收、有没有退款、退多少。
- 补差价低于 5 元的处理定好了:免掉或记到下期,页面上有说明,不单独开小额发票。
- 天数按实际周期天数算:分母是用户真实的上次扣款日到下次扣款日之间的天数,不是写死的 30 天。
- “第几天”按用户当地时间算:服务器时区和用户时区对齐过,交界时刻的升级不会算错一天。
- 金额精确到分、四舍五入只做一次:中间不四舍五入,发票两行拆分写得清清楚楚。
- 优惠券按折后价算差价:券过期后恢复原价,页面上提前写明有效期。
- 税费按实收金额计:补差价多少税就按多少算,发票行和账单行对得上。
- 支付平台参数显式写出:proration_behavior 和周期锚点都在代码里写明,不留给默认设置。
- 同一天多次换档只算净变化:上午加人下午减人净变化为 0 时,账单上就是 0,不出多余账单。
- 扣款失败有单独文案:升级补差价扣款失败时档位不升,页面说清楚是“升级未完成”,不和续费失败混用一套文案。
清单跑完,再记五个最常见的坑。第一,升级收了全价没抵扣已付的钱,这是本文开头的事故,AI 生成的订阅代码最爱犯。第二,降级当天就退款,但用户的高档功能用到月底没收回,等于白送半个月。第三,按自然月算天数,2 月的用户多付几天钱。第四,时区没对齐,“第 10 天”算成“第 9 天”或“第 11 天”,差一天就是几块钱的账。第五,发票上只写一行“订阅费 40 元”,用户完全看不出这 40 元是怎么来的,客服只能一句一句解释。这五个坑每一个都对应清单里的一两项,清单逐项打钩,就是为了把它们挡在上线之前。
最后说一句大实话:按比例计费这件事,技术上不难,难的是“让用户自己能算清楚”。公式谁都会写,难的是页面上那一行字、发票上那两行拆分、降级前那个确认页。用户不是会计,他不会去翻你的代码,他只看账单上那几行数字对不对得上自己的直觉。账算得对,还要让人看得懂,这才是这篇指南真正想讲的。把清单跑完,把确认页写好,再上线。
评论 (0)
相关文章

一次扣款失败,系统就把用户当成已经走了——这叫被动流失,常占总流失的两到四成。本文讲怎么搭一条回来的台阶:软拒绝与硬拒绝先分清、重试按第 2、4、8、15 天来、三封提醒邮件怎么写、7 到 14 天宽限期里产品该什么样、更新卡片的入口放哪里、实在挽不回来怎么体面告别。

把商品放进购物车的人不少,最后真付了钱的只有三成。本文讲怎么把这段路修平:购物车里该有什么、库存下单时预留还是付款时扣、结账分几步才不烦、运费和税费什么时候说、支付失败了怎么留住订单、弃购提醒最多发几封、手机上又该怎么做。

留存策略是看不见的工作:不做感觉不到,一旦出问题,修的成本比定规则高十倍。五把尺子定留存期、一张可直接抄的留存清单、热温冷删四站走完、法务保留冻结、备份里的旧数据与删干净的四个标准。