You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何防止客户端向PHP服务端提交支付请求前篡改商品价格

防价格篡改解决方案(PHP服务端)

核心原则:绝对不要信任任何前端提交的金额类数据,所有金额计算、校验逻辑必须在服务端完成,具体落地方案如下:

  • 移除前端金额透传逻辑
    不要将总价存放在hidden input中传递,前端结算页仅需要提交商品ID、购买数量、支付渠道标识三个核心参数即可,禁止透传任何价格、总金额类字段。
  • 服务端统一计算应收金额
    收到前端结算请求后,PHP服务端根据商品ID查询数据库中存储的商品官方单价,结合购买数量、运费规则、已领取的优惠抵扣规则,自行计算出真实的应收总金额,该金额为后续传递给移动支付API的唯一有效数值,全程忽略前端传递的任何价格相关参数。
  • 特殊场景下加签名双重校验
    如果你对接的移动支付API流程强制要求前端携带总金额参数提交,可增加签名校验机制做兜底:
    1. 服务端渲染结算页时,先计算出真实应收金额,将商品ID+购买数量+应收金额+服务端私有秘钥拼接后做哈希运算得到签名值,将签名值存入前端隐藏域和订单数据中
    2. 前端提交支付请求时将签名值一同传回服务端,服务端按同样规则重新计算签名,和传回的签名做对比,不一致直接拒绝请求
      对应PHP示例代码:
    // 结算页生成签名逻辑
    $server_secret = '你自行定义的私有秘钥,存在服务端配置文件中,不可泄露';
    $goods_id = 123; // 从数据库读取的商品ID
    $buy_num = 1; // 用户选择的购买数量
    $real_total = 200; // 服务端计算得到的真实应收金额
    $sign = md5($goods_id . $buy_num . $real_total . $server_secret);
    // 将$sign存入前端隐藏域随其他参数一同提交
    
    // 支付请求接收后的校验逻辑
    $recv_goods_id = intval($_POST['goods_id']);
    $recv_buy_num = intval($_POST['buy_num']);
    $recv_total = floatval($_POST['total_amount']);
    $recv_sign = trim($_POST['sign']);
    $server_secret = '你自行定义的私有秘钥';
    $calc_sign = md5($recv_goods_id . $recv_buy_num . $recv_total . $server_secret);
    if($calc_sign !== $recv_sign){
        die("参数非法,请求已拒绝");
    }
    // 签名校验通过后,必须再查数据库重新计算一次金额,和$recv_total做二次对比,避免签名规则被破解
    
  • 支付回调二次校验
    收到支付渠道的支付成功回调通知后,先查询对应订单的应收金额,和回调接口返回的实际支付金额做对比,只有金额完全一致、订单状态为待支付的情况下,才将订单标记为支付成功,避免回调数据被篡改。

内容的提问来源于stack exchange,提问作者Adam K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 02:09:02