微信支付宝支付回调需要和注意的问题

最近在处理微信支付回调的时候遇到一个奇怪的问题 线下测试都是正常 但是线上会出现回调订单金额不一致的情况

问题所在

  • 项目中存在支付回调的金额效验代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public boolean notify(String outTradeNo, String orderNo, String account, String amount, String tradeStatus, TradeChannel channel) {
    .....略
    Assert.isForbidden(order.getAmount().compareTo(amt) != 0,
    "异常回调结果!",
    () -> {
    log.warn("订单号 {} 回调金额 {} 和实际金额 {} 不一致 丢弃当前通知信息!", orderNo, amount, order.getAmount().doubleValue());
    cache.remove(outTradeNo);
    });
    .....略
    }
  • 微信回调的数据(敏感数据已屏蔽)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <xml>
    <appid><![CDATA[XXXXXXXXXX]]></appid>
    <bank_type><![CDATA[CFT]]></bank_type>
    <cash_fee><![CDATA[29945]]></cash_fee>
    <coupon_count><![CDATA[1]]></coupon_count>
    <coupon_fee>55</coupon_fee>
    <coupon_fee_0><![CDATA[55]]></coupon_fee_0>
    <coupon_id_0><![CDATA[XXXXXXXXXX]]></coupon_id_0>
    <device_info><![CDATA[XXX]]></device_info>
    <fee_type><![CDATA[CNY]]></fee_type>
    <is_subscribe><![CDATA[Y]]></is_subscribe>
    <mch_id><![CDATA[148854xxxx]]></mch_id>
    <nonce_str><![CDATA[8e1c2282b24044bbb232910c97306fde]]></nonce_str>
    <openid><![CDATA[XXXXXXXXXX]]></openid>
    <out_trade_no><![CDATA[XXXXXXXXXX]]></out_trade_no>
    <result_code><![CDATA[SUCCESS]]></result_code>
    <return_code><![CDATA[SUCCESS]]></return_code>
    <sign><![CDATA[A2FFB2D662D25D02637A48B60D472645]]></sign>
    <time_end><![CDATA[20180223143853]]></time_end>
    <total_fee>30000</total_fee>
    <trade_type><![CDATA[NATIVE]]></trade_type>
    <transaction_id><![CDATA[XXXXXXXXXX]]></transaction_id>
    </xml>
  • 微信回调处理的逻辑

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // 异步处理订单
    orderKit.notify(
    // 本商城订单号
    notifyMap.get("out_trade_no"),
    //支付宝订单号
    notifyMap.get("out_trade_no"),
    //购买者账号
    notifyMap.get("openid"),
    //支付的金额
    new BigDecimal(notifyMap.get("cash_fee"))
    .divide(devideNumber, 2, RoundingMode.HALF_UP)
    .toPlainString(),
    //订单的状态
    tradeStatus,
    //支付的方式
    TradeChannel.WEIXIN);
  • 后台日志打印的错误

    1
    INFO  c.s.k.k.OrderKit - 订单号 20180223143832xxxxxxxxxxxx 回调金额 299.45 和实际金额 300.0 不一致 丢弃当前通知信息!

解决方案

  • 细心的小伙伴可能已经发现了 处理逻辑中 代码获取的是 cash_fee 而不是 total_fee
  • 我查阅了一下文档
    • 微信 单位: 分
      • total_fee 订单金额
      • settlement_total_fee 应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额
      • cash_fee 现金支付金额
      • coupon_fee 总代金券金额
    • 支付宝及时到账老接口 单位: 元
      • total_fee 订单金额
    • 支付宝新接口(应用) 单位: 元
      • total_amount 订单金额
      • receipt_amount 商家在交易中实际收到的金额
      • buyer_pay_amount 用户在交易中实际支付的金额
      • point_amount 使用集分宝支付的金额
  • 如果需要对比订单金额 需要使用上述标记了订单金额的字段 而不是别的字段