游客购卡:不注册也能用,但不能不安全

举报
Rolle 发表于 2026/11/15 18:10:44 2026/11/15
【摘要】 游客购买能显著降低转化门槛,但代价是「订单和用户的绑定」要靠别的方式实现。这里有一条清晰的安全基线。

游客购买能显著降低转化门槛,但代价是「订单和用户的绑定」要靠别的方式实现。这里有一条清晰的安全基线。

能力凭证放在请求头里

订单交付后给用户一个能力凭证,放在 X-Payment-Token 头里,数据库只保存摘要而不是明文。

兑换码是预付凭证,游客卡是订单交付产物,两者的失败模式不一样。

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

恢复链接的凭证不能进查询参数

它应该放在 URL 的 fragment 部分(# 之后)。fragment 不会发给服务器,也就不会进访问日志和 Referer 头。

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

支付前不交付 Key

订单未支付时不能提前把 Key 交出去,否则会出现「没付款但已经有可用 Key」的情况。

到期后续费应该从付款核验成功的时刻重新计时,未激活的 Key 则累加待激活天数。

游客也要能查用量

游客卡同样需要查询入口。查询凭证的机制在这里和普通用户是一样的。

用量统计的时间口径必须写清楚,是 UTC 还是某个业务时区,一周从哪天开始。

一旦这里含糊,用户看到的「今日用量」就会和他自己的记录对不上。

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

游客卡的用量查询路径和普通 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"

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

几个容易踩的坑

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

小结

把配置项和凭据都外置,是成本最低、收益最持久的一个工程习惯。

如果你正在评估方案,可以先注册一个 Key 跑通最小请求,再决定要不要迁移——https://aiminis.info/ 支持按量计费,试用成本很低。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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