wechatpay-apiv3/wechatpay-apache-httpclient

0.4.7 回调验签失败

gebizhuxiaowang opened this issue · 4 comments

回调验签报错, 想先确认下通过这种方式获取的body 和验签参数是否有问题?

public ResponseModel weChatCallBack(@RequestBody final JSONObject body, final HttpServletRequest request) {
        // 从请求头中获取验签相关参数
        //微信支付的平台证书序列号
        final String wechatPaySerial = request.getHeader("Wechatpay-Serial");
        final String nonce = request.getHeader("Wechatpay-Nonce");
        final String timestamp = request.getHeader("Wechatpay-Timestamp");
        final String signatureBase64 = request.getHeader("Wechatpay-Signature");
        if (StringUtil.isEmpty(wechatPaySerial) || StringUtil.isEmpty(nonce)
                || StringUtil.isEmpty(timestamp) || StringUtil.isEmpty(signatureBase64)) {
            throw new GeneralException(ResponseCode.ParameterError);
        }
        log.error("signatureBase64 :{}", signatureBase64);
        this.mepetOrderService.payNotification(wechatPaySerial, nonce, timestamp, signatureBase64, body.toString());
        return ResponseUtil.success();
    }

这是调试时获取到的内容:
com.wechat.pay.contrib.apache.httpclient.exception.ValidationException: 验签失败:serial=[3C2CFC143FD20F786EA6B921CD9BA11099D9EA21] message=[1657515952 3LKhe6BZwUlvY9cJ71rsXAcDi5FUnK7A {"summary":"支付成功","event_type":"TRANSACTION.SUCCESS","create_time":"2022-07-11T11:31:43+08:00","resource":{"associated_data":"transaction","ciphertext":"lmlx35+mpSb7Q/RmzyOuBV0H+ZYDdDEhQCD4p3X8D9bU+I8FCc/9CgQ3FNs6KN3UdmZS93+4OJkGqEW+oyS3tafNtw6hHu+YEQBvoN2I4yosjfqYbQ/qF+7GRUPEAP6RoJtLdPjYA9RUo8UjuQxx0pavLKv6kKsMc9ElRVGuHiTcGlveHsmeLMAISSnmhkEBjxyLjf1FwaeqyzrQWEYFdHzoK2FCYh3GQ1VMzU/VskLgJH8PdRfTuz0eSuEU9KlNTuTqwcif4jT+enTXmnL+kC2sSWTg7MkrOA4vN0h/YEU2dOzmQMNVOsQrKiKNZY4X9MWWCX9Xa8kq6Rp9iCOBGKJcxYRveKfgeAPxuwKgSJl/+5FJxBCFBfKJnyk5lDLCBlhTc5V5Bmzd59xalzCMZ2Pyh/84ETBPZl8hO6hMAywtFltSbujf1mQUt25LKxtpbNhJl05rKAZ49ejG3TIfhw1aOJ94AOeaIn8s0ctllwvsejGGbWvieh1a5/P0atuktvW+bYfQEwpvD2XxwGb6wmKqIGQaRZovOM6a2nCHbPQz2kdhntSjqtD2DuDGyw==","original_type":"transaction","nonce":"TCDdVDAwZ2CP","algorithm":"AEAD_AES_256_GCM"},"resource_type":"encrypt-resource","id":"1bea3a0c-1bb8-5b5e-8296-f205b1e8e179"} ] sign=[qGSxHdENezW46sw6swGKvUnrYTW+HgSfdvIfPdqZPWktsE+ezKeDoFs6DgoibbE7QHtW9h6qRHTVvoKbPBRNv76oIsyroVGt1bMfFkkiaFMd2MYK/YGUWBV04bMjW84PraWTJxABC9hKBEJlJTd2nksKYGLp1pFbbkRmFIClcxdJYyl7RI/yeFhL9s+1KZYERjoE9NqaAI0URtOW268t9tdiiN+NvgKQx7kjXn29i7FTEk1sV1AKsEnWqfLUWJ924vW4O6sHYXvgWWJf5zCClC3bNRyZ4DbQ0P5tl3x8StVtjMsBtTPy8kE8w6Y+y9sSnGYa0CthEroM6gVM4Nqwng==]

疑问点:
从header 中拿到的Wechatpay-Signature,不能正常解析; 也没有像文档上说的那样有换行符,但是解析不出一个正常的字符串;

请先看看过去关于回调的 issue

@xy-peng 已经看过一边了,依然没有解决问题; 就差换掉@RequestBody 用输入流来读取参数了

就差换掉@requestbody 用输入流来读取参数了

你发起验签的 body 跟实际发送的并不一样,推测是从 JSON 成为 requestbody 再 toString() ,得到的数据已经跟报文不一样了。建议用原始输入流来验签试试看。

另外,再咨询一个问题,你使用的是何种 WEB 服务框架?

在 README 中我们也会补充对应 FAQ,确实这是个经常做错的事情。

感谢 @xy-peng 的支持
@requestbody 换成从原始输入流来获取body ,成功通过验签,也拿到解密数据了【感动】【流泪】
用的是 spring boot 2.6.9 ,jdk 版本17.0.3.1