• 【微信支付批量转账到零钱】下载电子回单API 签名成功,status code = 200,但是没有文件流?


    接口地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter4_3.shtml

    在下载电子回单API 中,接口状态 status code = 200,但是业务请求400是什么原因呢?

    排查方式:

    1、 V2使用签名检查工具:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=20_1)校验签名算法是否有误
       V3请下载文档中的校验工具:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay6_0.shtml
    2、确认秘钥是否有误(服务商模式使用服务商商户号秘钥,秘钥是在商户平台配置,如果同一商户号调用其它接口成功可排除是秘钥问题),商户设置的密钥长度为32个字节
    3、确认接口实际的请求参数与生成签名原串的参数一致,不能增加或缺少参数(可通过打印签名原串进行排查)
    4、确认参数的大小写,参数名与接口文档一致
    5、签名原串的参数值使用原始值,不需要encode
    6、接口需要使用UTF-8编码

    最终原因:

    这个接口的签名方式不一样 因为签名里面写了GET方式时,没有body也有换行符,但是这个接口是不需要换行符的,所以在构建签名的明文的时候 把最后body的换行符去掉就可以了。

     用wechatpay-apiv3同样会报错

     然后我重新写了一套

    import cn.hutool.http.HttpRequest;
    import cn.hutool.http.HttpResponse;
    import org.apache.http.client.methods.HttpGet;
    
    import java.io.InputStream;
    import java.security.PrivateKey;
    import java.security.Signature;
    import java.util.Base64;
    import java.util.UUID;
    
    /**
     * 微信电子回单下载
     * @Author xiaoqiang
     * @Date 2022/02/12 17:50
     */
    public class DownLoadBillUtil {
    
        //商户号
        private String merchantId;
        //商户序列号
        private String certificateSerialNo;
        //商户私钥
        private PrivateKey privateKey;
    
        public DownLoadBillUtil(String merchantId, String certificateSerialNo, PrivateKey privateKey){
            this.merchantId = merchantId;
            this.certificateSerialNo = certificateSerialNo;
            this.privateKey = privateKey;
        }
    
        public InputStream downloadBill(String downloadUrl) throws Exception{
            String timestamp = String.valueOf(System.currentTimeMillis());
            String nonceStr =  UUID.randomUUID().toString().replace("-", "");;
            HttpGet httpGet = new HttpGet(downloadUrl);
            String path = httpGet.getURI().getPath();
            String canonicalUrl = httpGet.getURI().getQuery();
            if (canonicalUrl != null) {
                path += "?" + canonicalUrl;
            }
            String billSign = this.createBillSign(nonceStr, timestamp, path);
            StringBuilder sb = new StringBuilder("WECHATPAY2-SHA256-RSA2048 mchid=").append("\"").append(this.merchantId).append("\",");
            sb.append("serial_no=").append("\"").append(this.certificateSerialNo).append("\",");
            sb.append("nonce_str=").append("\"").append(nonceStr).append("\",");
            sb.append("timestamp=").append("\"").append(timestamp).append("\",");
            sb.append("signature=").append("\"").append(billSign).append("\"");
            String auth = sb.toString();
            HttpResponse execute = HttpRequest.get(downloadUrl).auth(auth).execute();
            return execute.bodyStream();
        }
    
        public String createBillSign(String nonceStr, String timestamp, String download) throws Exception{
            String plain_text =  "GET" + "\n"
                    + download + "\n"
                    + timestamp + "\n"
                    + nonceStr + "\n";
            Signature sign = Signature.getInstance("SHA256withRSA");
            sign.initSign(this.privateKey);
            sign.update(plain_text.getBytes("utf-8"));
            return Base64.getEncoder().encodeToString(sign.sign());
        }
    }
  • 相关阅读:
    定时任务的分布式调度
    springmvc 静态资源 配置
    activemq 持久化
    函数式编程与面向对象编程的比较
    LeetCode 108——将有序数组转化为二叉搜索树
    LeetCode 104——二叉树中的最大深度
    LeetCode 700——二叉搜索树中的搜索
    线性代数之——四个基本子空间
    线性代数之——线性相关性、基和维数
    线性代数之——秩和解的结构
  • 原文地址:https://www.cnblogs.com/SparkMore/p/15895427.html
Copyright © 2020-2023  润新知