欢迎光临
我们一直在努力

智慧充电系统|峰谷电费、服务费、优惠计算逻辑

目录

1、核心概念

2、两种计费模式(生产环境都存在)

模式 A:实时分片计费(线上真实充电桩主流)

模式 B:后处理全量切片(老设备 / 上报粒度粗)

3、各个金额的计算时机【重点】

4、完整业务时序(从启充到出账单)

5、常见坑点(线上生产问题)

6、简单伪代码示意

7、补充:什么场景优惠会实时预览?


业务背景:充电桩设备上报充电度数,计价服务做计费;电费分峰 / 平 / 谷电价(来自电网),服务费是运营商收益,优惠是营销抵扣,要区分:什么时候取电价、什么时候算服务费、什么时候扣优惠、什么时候生成账单。

1、核心概念

  • 峰谷电价(电网侧) 电网给充电站的电价是分时电价,不同时间段,电单价不一样:峰、平、谷。
  • 注意:电价不是固定写死代码,是配置在计价系统,支持后台修改,同步生效;部分场站还有 “尖峰” 档位。

    • 峰时段:电价最高
    • 平时段:中间
    • 谷时段:电价最低(夜间)

    关键点:充电可能跨时段!比如 22:40 开始充电,00:30 结束,横跨平段→谷段。不能简单拿充电开始时间直接套一个电价,要按时间切片分段算电量。

  • 服务费 充电桩运营商收取,一般按 元 / 度,也可以按小时;服务费可以不分峰谷,也可以配置峰谷不同服务费。 总单价 = 分时电费单价 + 分时服务费单价。

  • 优惠 优惠券、折扣、立减、会员折扣、活动补贴;分为:按度优惠、按总金额优惠、固定立减、折扣比例。 优惠是最后抵扣,不是先扣优惠再算电费。

  • 2、两种计费模式(生产环境都存在)

    模式 A:实时分片计费(线上真实充电桩主流)

    充电过程中,设备每隔 30s~5min 上报充电增量度数,计价服务按当前所在的时段实时分片计算。

    适合:直流快充,充电时间短,但可能跨峰谷。

    流程:

  • 用户启动充电,创建充电订单,状态充电中。
  • 充电桩定时上报:累计充电度数、充电时长。计价服务算出本次上报间隔内新增用电量 Δkwh。
  • 取这一段上报时间窗口落在哪个峰谷时段,拿到该时段:电费单价、服务费单价。
  • 分片金额 = Δkwh ×(电费单价 + 服务费单价),累加到订单临时金额。
  • 优惠此时不扣,优惠不实时生效,实时只算原始应付。
  • 用户停止充电,充电桩推送结束报文,上报最终总度数。
  • 充电结束那一刻,统一计算优惠抵扣,算出实付金额,生成账单。
  • 为什么优惠不实时扣:优惠券过期、券被收回、活动下线、多券叠加规则复杂,实时扣会出现回滚、金额错乱,业务上统一在充电结束做优惠计算。

    模式 B:后处理全量切片(老设备 / 上报粒度粗)

    设备只上报开始时间、结束时间、总充电度数,没有中间增量。 计价服务拿到:startTime、endTime、totalKwh。 系统把【开始~结束】整个时间区间,切割成若干峰 / 平 / 谷时间片,按时间占比分摊总电量到各个时段,分别计算每一片电费 + 服务费,求和得到原始总金额,结束后再应用优惠。

    举例子: 充电 22:30 ~ 00:30,总充 20 度

    • 22:30‑23:00:平段,30 分钟
    • 23:00‑00:30:谷段,90 分钟 总时长 120 分钟 平段分摊电量 = 20 × (30/120) =5 度 谷段分摊电量 =20 × (90/120)=15 度 分别用平电价、谷电价算电费,叠加服务费。

    这个是时间占比分摊,前提是假设充电功率稳定;现实快充功率会变化,所以高精度场景优先用设备上报的增量电量分片。

    3、各个金额的计算时机【重点】

    项目计算时机说明
    峰谷电费 充电过程分片计算(实时) / 充电结束后切片分摊 按每一段充电所处的时间,不是开始时间
    服务费 和电费同步分片计算 服务费也可以配置分时,峰期服务费更高
    原始总金额(电费 + 服务费) 充电结束前就累计完成,订单充电中就有预估金额 用户 APP 看到 “预估费用” 就是这个值
    优惠抵扣(券、立减、折扣、会员) 充电停止,拿到最终充电数据之后才计算 充电过程中不扣优惠;避免中途券失效带来金额回滚
    实付金额 优惠计算完成后得出 实付 = 原始总金额‑优惠总额,最低不能小于 0

    边界:优惠大于原始总金额,实付 = 0,不出现负数。

    4、完整业务时序(从启充到出账单)

  • 用户扫码启充,订单创建,状态【充电中】。
  • 充电桩定时上报充电数据:累计度数、功率。计价服务计算间隔增量电量,按当前时间的峰谷配置,累加电费 + 服务费,更新订单预估金额。APP 展示预估费用。
  • 用户手动停止 / 充满自动停止,充电桩上报结束报文:结束时间、最终总度数。
  • 计价服务校验:校验设备上报总度数,补偿分片累计误差(设备上报和服务分片累计会有微小度数差,以设备硬件度数为准)。
  • 重新完整做一次全时段切片重算(生产必做!防止中间上报丢包导致分片金额不准),得到准确原始总费用(电费 + 服务费)。
  • 执行优惠引擎:
    • 查询用户可用优惠券、会员权益、活动规则;
    • 校验券有效期、场站限制、车型限制;
    • 按优先级叠加 / 互斥规则计算优惠总抵扣;
  • 计算实付金额:实付 = max (原始总金额‑优惠金额,0)
  • 生成正式账单,推送给支付模块,发起扣费;订单状态变为待支付 / 已完成。
  • 5、常见坑点(线上生产问题)

  • ❌错误:只拿充电开始时间选峰谷电价,充电跨时段但全程用一个电价。 ✅正确:按时间切片,分段算。

  • ❌错误:充电中途就扣优惠券,充电过程中券过期,金额异常。 ✅正确:优惠统一放在充电结束后计算。

  • ❌错误:服务端分片累加度数和设备硬件总度数不一致,出现金额偏差。 ✅正确:充电结束,以设备上报总度数为准,全量重算,修正累计误差。

  • ❌错误:服务费跟随优惠一起抵扣,混淆电网电费和运营商服务费。

  • 电费是交给电网,服务费是运营商收入;优惠可以抵扣全部,也可以配置只抵扣服务费,不能抵扣电费,看业务规则。

  • 跨零点、跨节假日:峰谷配置区分工作日 / 周末,计价服务要识别充电片段对应的日期类型。
  • 6、简单伪代码示意

    java

    // 1.充电结束,拿到设备真实数据
    LocalDateTime startTime = chargeOrder.getStartTime();
    LocalDateTime endTime = chargeOrder.getEndTime();
    BigDecimal totalKwh = deviceReport.getTotalKwh(); //设备上报最终度数

    //2.时间切片:把[startTime,endTime]切分成多个时段片,每个片段包含:开始、结束、电价、服务费
    List<TimeSlice> slices = peakValleyService.splitTimeSlice(startTime, endTime);

    //3.按时间占比分摊总电量到各个时间片(如果没有中间增量上报)
    BigDecimal originTotal = BigDecimal.ZERO;
    for(TimeSlice slice : slices){
    //分摊该片段电量
    BigDecimal sliceKwh = calcShareKwh(slice, startTime, endTime, totalKwh);
    //片段金额 = 电量*(分时电费+分时服务费)
    BigDecimal sliceAmount = sliceKwh.multiply(slice.electricPrice.add(slice.serviceFee));
    originTotal = originTotal.add(sliceAmount);
    }

    //4.充电结束后,执行优惠引擎
    BigDecimal discount = discountEngine.calcDiscount(userId, orderId, originTotal);
    BigDecimal realPay = originTotal.subtract(discount);
    if(realPay.compareTo(BigDecimal.ZERO) <0){
    realPay = BigDecimal.ZERO;
    }
    //写入订单、账单
    chargeOrder.setOriginAmount(originTotal);
    chargeOrder.setDiscountAmount(discount);
    chargeOrder.setRealPayAmount(realPay);

    7、补充:什么场景优惠会实时预览?

    APP 上充电中展示 “预计优惠后 xx 元”,这只是前端预估算,给用户看的参考值,不是真实扣减。后端真实抵扣一定等充电结束。

    赞(0)
    未经允许不得转载:171主机测评 » 智慧充电系统|峰谷电费、服务费、优惠计算逻辑
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址