套餐与计费:价格、额度、订单快照三者的关系

举报
Rolle 发表于 2026/11/15 17:35:41 2026/11/15
【摘要】 计费系统里最容易被忽略、后果又最严重的,是「订单快照」。运营调整了套餐,结果已经创建甚至已经支付的订单跟着变了——这时候该以哪一份为准?

计费系统里最容易被忽略、后果又最严重的,是「订单快照」。运营调整了套餐,结果已经创建甚至已经支付的订单跟着变了——这时候该以哪一份为准?

下单那一刻把套餐内容快照进去

价格、每日额度、并发数、有效期,全部在创建订单时快照。之后套餐怎么改,都不影响这张已存在的订单。

正确做法是下单那一刻把套餐内容(价格、每日额度、并发数、有效期)快照进订单。

之后套餐怎么改,都不影响这张已经存在的订单。

金额用整数分,额度用整数

浮点数在累加时会出现精度误差,账目对不上是这类系统最致命的问题。所有的金额和额度计算都要有溢出检查。

价格用整数分存储,额度用整数(并且检查溢出),不能用浮点数。

所有金额和额度的计算都要有溢出检查。

续费要保留的三样东西

原 Key 续费的最大价值是「不用换 Key」。所以今日已用量、已兑换的额外额度、原到期时间的叠加规则都得保留,否则用户会觉得被坑了。

原 Key 续费的最大价值是「不用换 Key」,因为换 Key 意味着所有依赖它的配置都要改。

所以续费时要保留:今日已用量、已兑换的额外额度、以及原到期时间的叠加规则。

支付成功的判定只有一个来源

只有验签通过、且应用、商户、订单、金额、交易状态全部核对无误的支付宝通知或查询结果才能确认付款。浏览器返回地址和前端轮询都不算。

兑换失败通常是「码不存在 / 已使用 / 过期」;游客购卡失败可能是「支付未确认 / 凭证过期 / 目标 Key 已停用」。

这两种失败要给不同的提示,否则用户会反复重试一个根本不会成功的操作。

实操:支付回调的验签与幂等处理骨架。

套餐的实际效果最终体现在「今天还剩多少」上,把它做成用户最常打开的页面。

import hashlib, hmac, json

def verify_notification(raw_body: bytes, headers: dict) -> bool:
    # 1) 验签:用平台公钥对原始报文做 RSA/SM2 验签,
    #    任何字段被改动都会导致验签失败
    # verify_signature(raw_body, headers["signature"], PLATFORM_PUBLIC_KEY)

    # 2) 核对业务字段:应用、商户、订单号、金额、交易状态
    data = json.loads(raw_body)
    if data["app_id"] != APP_ID or data["seller_id"] != SELLER_ID:
        return False
    if data["total_amount"] != str(expected_amount(data["out_trade_no"])):
        return False
    return data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED")

def handle(data):
    # 3) 幂等:同一笔订单重复通知时直接返回成功,
    #    绝不能重复加额度或重复发卡
    order = load_order(data["out_trade_no"])
    if order.paid_at:
        return "SUCCESS"
    with transaction():
        settle_order(order)          # 结算 + 加额度 + 发卡,原子完成
        mark_paid(order, data)
    return "SUCCESS"

# 浏览器返回地址和前端轮询到的状态,都不能作为支付成功的依据。

几个容易踩的坑

  • 价格用浮点数存储,累加后账目对不上。
  • 套餐改了之后已创建的订单也跟着变,用户看到的和付的不一样。
  • 续费时没保留今日已用量,等于凭空多给了一份额度。
  • 奖励金被撤销但已经被抵扣,产生了资损。

小结

技术上的事大多不复杂,难的是把每个异常分支都想清楚。把这份清单存下来,下次排障会快不少。

对具体能力有疑问,可以直接看接入文档 https://aiminis.info/docs/api-integration,里面把 Base URL、鉴权方式和各协议的可选范围都列清楚了。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。