为什么明细账单中“应付金额”跟量价计算后的金额不一致?
阿里云会将同一商品的不同资源实例产生的费用,根据计费方式、结算周期等因素,合并到账单流水中的“应付金额”维度进行结算与产生发票,建议用户以账单号为维度进行数据核对。
同时为了方便用户做更细粒度的数据分析,系统把整条账单的金额,拆分到明细账单里每个实例甚至每个计费项上;
拆分时会存在除不尽的情况,这时为了保证明细账单中,行数据“应付金额”2位精度的小数位数,且列数据求和后与整条账单金额一致,需要对行数据先四舍五入,再把零头随机记在一个实例或计费项上,这就导致了明细账单中出现”应付金额“跟原始应付金额不一致的现象。
这个现象是在整条账单结算完成之后,账单向更细粒度数据做拆分时产生,因此并不影响用户的真实费用。
案例1:优惠金额为0
假设用户有1条账单,内含5个相同配置的实例,分别是A、B、C、D、E。它们的“官网价”一致,均为:12.1234元。

目前系统计算“应付金额”时,涉及逻辑包括不限于以下3点:
超过2位精度:原始“应付金额”=“官网价”-“优惠金额”,“官网价”一般为“单价”“用量”“服务时长”“指定系数”间的算术运算。因为云产品“单价”一般设定为多位小数,经过一系列算术运算后得出的“官网价”也一般为多位小数(例如6位);
规整至2位精度:实际“应付金额”是2位小数,银行或账户结算时,金额只能是2位小数,所以优先确保用户账单和发票都为2位小数;
对账单抹零:将同一条账单中A、B、C、D、E原始“应付金额”求和后再进行抹零。
所以,目前系统计算账单“应付金额”时,做法如下:
求和:将A、B、C、D、E的5个原始“应付金额”求和,总计为60.617元;
抹零:将总原始“应付金额”60.617元抹掉2位精度之后的零头,抹零后为60.61元,作为整条账单的“应付金额”,此金额是用户与阿里云进行实际结算的金额;
拆分:将整条账单的“应付金额”60.61元,除以5,分别得到A、B、C、D、E的2位小数“应付金额”,即A:12.12元,B:12.12元,C:12.12元,D:12.12元,E:12.12元;
加零头:由于使用除法,存在0.01元除不尽的情况,为确保明细账单中,A、B、C、D、E求和的总“应付金额”等于整条账单的“应付金额”金额60.61元,则需要把0.01元的零头加到其中一个实例(举例为E)的“应付金额”上,所以E的“应付金额”变成了12.13元(即12.12+0.01)>“官网价”12.1234元。
案例2:优惠金额不为0
假设用户有1条账单,内含5个相同配置的实例,分别是A、B、C、D、E,它们的“官网价”一致,均为:12.321元。

系统计算账单“应付金额”时,做法如下:
1、第一次抹零:A、B、C、D、E“官网价”均为12.321,抹掉2位精度之后的零头,得到临时“官网价”12.32。“官网价”总计从“61.605”变为“61.6”。第一次抹零金额=61.605-61.6=0.005;
2、减优惠:将临时“官网价”费用减去对应优惠金额,12.32-0.1966=12.1234,得到原始“应付金额”;
3、第二次抹零:参照案例1过程,将同一条账单中A、B、C、D、E原始“应付金额”求和后再进行第二次抹零。第二次抹零金额=61.617-60.61=0.007。
4、计算抹零金额:总抹零金额=0.005+0.007=0.012。
总结:
参照案例1,由于零头的原因,就会导致E的“应付金额”12.13元 >原始“应付金额”12.1234元。
但整体来看,A、B、C、D、E的总实际“应付金额”60.61元 < 60.617元,所以并不存在账单产生额外消费金额或金额不一致的问题。
对于案例2,由于要进行两次抹零,会出现个别账单抹零金额偏大,即大于0.01元的情况。