收藏
回答

下载电子回单接口调用问题[以解决]

最近对接这个批量转账到零钱的文档,其他的接口都对接好了卡在了这个 下载电子回单接口

问题描述:

我对接的这些接口都是通过一样的签名方式,但是就是这个接口一直返回 "code":"INVALID REQUEST","message":"错误的签名,导致验签失败"

我仔细看了这个接口的签名方式是正确的 文档描述这个接口的GET请求的URL是通过 查询转账电子回单 查询过来的down_url后面有带token参数 我签名的时候也是把这个参数都加上了的 就是过不了签名 请问有人之前碰到过一样的问题吗!!!

最后一次编辑于  2021-04-19
回答关注问题邀请回答
收藏

4 个回答

  • K
    K
    2022-03-24

    如果你用的 php,并且是 laravel 框架,可以尝试一下下边的代码:

    public function test_receipt_query()
    {
        $res = $this->getApi()->receiptQuery('xxx4d0fb9fd745de8d1dff937755x xx', 'xxxf925a72b740e5ba943e7f40efdxxx');
        if ($res->isSuccess()) {
            // 商户号
            $merchantId = 'xxx27xxxxx';
            // 商户序列号
            $serialNo = 'xxxxxBA3B465F51D1F5B4CF825580F1409xxxxxx';
            $nonceStr = unsigned_uuid();
            $time = time();
            // 下载地址拆分,取路径和参数去签名
            $url_parts = parse_url($res->getDownloadUrl());
            $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
            $sign = $this->sign($canonical_url, $nonceStr, $time);
    
            $res = Http::withHeaders([
                'Authorization' => 'WECHATPAY2-SHA256-RSA2048 mchid="' . $merchantId . '",serial_no="' . $serialNo . '",nonce_str="' . $nonceStr . '",timestamp="' . $time . '",signature="' . $sign . '"'
            ])->get($res->getDownloadUrl());
    
            if (!is_dir(storage_path('app/public/test'))) {
                Storage::makeDirectory('public/test');
            }
            file_put_contents(storage_path('app/public/test/' . $time . '.pdf'), $res->body());
        }
    
    }
    
    public function sign($url, $nonceStr, $time)
    {
        $str = "GET" . "\n"
            . $url . "\n"
            . $time . "\n"
            . $nonceStr . "\n";
        
        if (!openssl_sign($str, $signature, $this->merchantPrivateKeyInstance, OPENSSL_ALGO_SHA256)) {
            throw new \Exception('Signing the input $message failed, please checking your $privateKey whether or nor correct.');
        }
    }
    
    


    写的时候折腾了半天,不想吐槽了,👋

    2022-03-24
    有用
    回复
  • zkinghao
    zkinghao
    2021-12-18
    package com.util;
    
    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 zkinghao
     * @Date 2021/12/18 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());
        }
    }
    



    这是我写的工具源码,downloadUrl是你获取到的下载地址,你用我的这个工具,就可以获取到流了,这个流你要存本地还是存oss都是可以的。

    官方文档写的根本就没有代码,只有一个postman的脚本,还是我自己看脚本,然后看规则,然后自己抓包来看那个Authorization在来自己写一个没有脚本的postman调试出来的,问技术基本也是没有回过声的,

    真的,没有文档的东西,开发起来,真的是让人疲惫,耗时间,希望后面的人可以不要踩坑了。也希望微信能好好更新文档,弄的更通俗易懂,V3版本的demo真的是少的可怜,开发起来都要从头到尾看一遍。看的是都以为自己是腾讯人员的开发人员一样,要从头到尾的来读你的源码。


    2021-12-18
    有用
    回复
  • @w
    @w
    2021-04-19
    您好,请按照以下几点排查:
    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编码
    
    上面是客服的回复
    1.我接的是V3,然后用下载了签名验证工具,验证了自己代码中生成的签名跟明文进行过比对了是一致的
    
    
    2. 参数我也看过了是token那个参数在请求的url里面跟签名的参数是一直的
    3. 没有encode
    
    
    2021-04-19
    有用
    回复 5
    • @w
      @w
      2021-04-19
      2021-04-19
      回复
    • @w
      @w
      2021-04-19
      已解决  这个接口的签名方式不一样 因为签名里面写了GET方式时,没有body也有换行符,但是这个接口是不需要换行符的,所以在构建签名的明文的时候 把最后body的换行符去掉就可以了。
      2021-04-19
      回复
    • ..
      ..
      2021-09-14
      请问使用的SDK是如何吧body里面的换行符去掉的?
      2021-09-14
      回复
    • ZRR
      ZRR
      2021-10-27回复..
      你好,这个问题您解决了吗
      2021-10-27
      回复
    • P.Peng
      P.Peng
      2021-12-03回复..
      你好,这个问题您解决了吗
      2021-12-03
      回复
  • Memory
    Memory
    2021-04-19

    这个业务,在你的对接群问

    2021-04-19
    有用
    回复
登录 后发表内容