收藏
回答

使用 CertificateDownloader 获取 的 wechatpay.pem 不对?

使用 以下命令

/data/www/server/php/72/bin/php /data/www/mall/vendor/wechatpay/wechatpay/bin/CertificateDownloader.php -k 9c7f4682xxxxx4e5 -m 1608184161 -f /data/wwww/mall/Application/Library/Payment/Wxpay/fenzhang_cert/apiclient_key.pem -s 1CB0716D6A7xxxxxxxxx0DD -o /data/wwww/mall/Application/Library/Payment/Wxpay/fenzhang_cert/

生成了 wechatpay.pem 已经下载到本地,但是通过

openssl x509 -in wechatpay.pem -noout -serial 查看证书序列号时,和你们文档上的结果不一致。

文档地址:https://pay.weixin.qq.com/doc/v3/partner/4012365874

生成结果:Wechatpay-Serial: 4DF076AC5A7D968D4A8B0B9C599A74CB4CF8EE8A

而我用同样的命令,生成的是

缺少 Wechatpay-

造成我添加分账接收方 (v3/profitsharing/receivers/add)出现 “HTTP header缺少微信支付平台证书序列号(Wechatpay-Serial)” 的错误 ,完全走不下去。

回答关注问题邀请回答
收藏

4 个回答

  • 微信支付质量运营助手
    微信支付质量运营助手
    07-14

    截取上获取到的平台证书序列号是正确的。HTTP header缺少微信支付平台证书序列号(Wechatpay-Serial)”报错请检查wechatpay-serial传值是否是XXX81E4这个序列号

    07-14
    有用
    回复
  • 支付社区运营
    支付社区运营
    07-14

    您好,请提供下列资料供这边帮您定位问题。

    1、调用的接口对应的接口文档

    2、调用接口时传入的完整请求参数以及接口的响应报文

    请以文字形式提供上述信息,不要发截图。

    辛苦看下调接口添加分账接收方 (v3/profitsharing/receivers/add)时代码中是怎么传递请求头Wechatpay-Serial参数呢

    07-14
    有用
    回复 7
    • 无名小卒
      无名小卒
      07-14
      07-14
      回复
    • 无名小卒
      无名小卒
      07-14
      代码已经贴在最下面了
      07-14
      回复
    • 支付社区运营
      支付社区运营
      07-14回复无名小卒
      你好,不是要代码,需要请求时间+请求和响应参数
      07-14
      回复
    • 无名小卒
      无名小卒
      07-14
      Array
      (
          [appid] => wx117a0cd90e23f60c
          [type] => PERSONAL_OPENID
          [account] => oGUbk5Xkm91XL_gb-urq8JPrjdr8
          [relation_type] => DISTRIBUTOR
          [name] => pWd4mdOBKhiIOXzuR06CFIdmdZ74W1BOTbGq78T1ns93EOlMLPDvYJw0vhaYgM+TiX/RMtQ4CD5L2d3O/jTgERg0DZFFzssCYHQGdeUa5dq30FWkx0ZdszQ7q3BE3/9zTDNnVYbe6oo/ON0Fw8Zy735cq1Lon22vef75PaEayYHQ8XNv3moVaLO+wyyi9qYh0zhKyqRFxzXlPlkGeuibHBPByLKTK0sMnvPdg6GnPmdF1dhavbYYH7hiXwdN6oCv4aNjXXC+8dQajGuw5JM46yKlNJRg5QmimrtEsnj1bewZ6g16/ykwuDDI5iKG+oqgAupfnSUHwqsgXNsAC8FE8A==
      )
      <br>----------------------------<br>Array
      (
          [0] => Authorization: WECHATPAY2-SHA256-RSA2048 mchid="1608184161",nonce_str="fxpw2bhqtmvdt38600stukquvhgugb0m",signature="MOsmL6Bih7zBWxR3eL8uuvClCa6zBdoTys0exZcrfh5QFCePZ8do5ebfLJAn1o0rOz8GEeJFu+yO2h2TNGpZBMWD7RywDgeDjOlVLJ9N/zZ1pfUM6Wr3t0srarm6CXKWJzfaHDJCfuQsKn5LD4VU1MAlV+1Zhpw8egpRvH+9d/A7FV1mJ8Eeq+HBoe7GTCl6SfX+G4U5sfQMo9tTEBSMXFSvTg5tflXyLzhhGtsSRvmFnWSKnDZoON5Zddbtc8iEtmgP5iGzDlGgm9F0VA22Zc30I4xkeTLHomOoOn2bffWffl3b03AklK/qxB9Pa+EkiR5MDY6O3jeIIclBP0T3+w==",timestamp="1752476572",serial_no="1CB0716D6A73B6B546C7D80AB3751D652974D0DD"
          [1] => Content-Type: application/json
          [2] => Accept: application/json
          [3] => Wechatpay-Serial:34E8192B9ED93477FA02ED40D51D2A7F8AC481E4
      )
      <br>----------------------------<br>Array
      (
          [code] => 400
          [message] => Client error: `POST https://api.mch.weixin.qq.com/v3/profitsharing/receivers/add` resulted in a `400 Bad Request` response:
      {"code":"PARAM_ERROR","message":"HTTP header缺少微信支付平台证书序列号(Wechatpay-Serial)"}
          [data] => Bad Request
      )
      <br>2025-07-14 15:02:52
      07-14
      回复
    • 无名小卒
      无名小卒
      07-14
      代码的运行结果
      07-14
      回复
    查看更多(2)
  • 无名小卒
    无名小卒
    07-14
        
        //添加分帐用户
        public function add(){
            $type = "PERSONAL_OPENID";
            $account = "oGUbk5Xkm91XL_gb-urq8JPrjdr8";
            $name ="郑先生";
            $relation_type = "DISTRIBUTOR";
            list($Request,$body,$header) = SpliTheBill::add($type,$account,$name,$relation_type);
            $res = SpliTheBill::send($Request,$body,$header);
            print_r($res);
        }
        //SpliTheBill::__initializtion
        //配置证书
        public function __initializtion(){
            $cert = [];
            $cert['merchantId'] = C('PAY_YIGUO')['wxpay_mch_id'];
            // 从本地文件中加载「商户API私钥」,「商户API私钥」会用来生成请求的签名
            $cert['merchantPrivateKeyFilePath'] = 'file://'.APP.'Application/Library/Payment/Wxpay/fenzhang_cert/apiclient_key.pem';
            $cert['merchantPrivateKeyInstance'] = Rsa::from($cert['merchantPrivateKeyFilePath'], Rsa::KEY_TYPE_PRIVATE);
            // 「商户API证书」的「证书序列号」
            $cert['merchantCertificateSerial'] = '1CB071xxxx73B6B546C7D80AB3751D652974D0DD';
            // 从本地文件中加载「微信支付平台证书」,可由内置CLI工具下载到,用来验证微信支付应答的签名
            $cert['platformCertificateFilePath']  = 'file://'.APP.'Application/Library/Payment/Wxpay/fenzhang_cert/certificate.pem';
            $cert['onePlatformPublicKeyInstance'] = Rsa::from($cert['platformCertificateFilePath'], Rsa::KEY_TYPE_PUBLIC);
            // 「微信支付平台证书」的「平台证书序列号」
            // 可以从「微信支付平台证书」文件解析,也可以在 商户平台 -> 账户中心 -> API安全 查询到
            $cert['platformCertificateSerial'] = '34E81xxxxED93477FA02ED40D51D2A7F8AC481E4';
            // 从本地文件中加载「微信支付公钥」,用来验证微信支付应答的签名
            $cert['platformPublicKeyFilePath']    = 'file://'.APP.'Application/Library/Payment/Wxpay/fenzhang_cert/pub_key.pem';
            $cert['twoPlatformPublicKeyInstance'] = Rsa::from($cert['platformPublicKeyFilePath'], Rsa::KEY_TYPE_PUBLIC);
            // 「微信支付公钥」的「微信支付公钥ID」
            // 需要在 商户平台 -> 账户中心 -> API安全 查询
            $cert['platformPublicKeyId'] = 'PUB_KEY_ID_011xxxx841612025062200111535000000';
            //wechatpay证书配置
            $cert['wechatpayFilePath'] = 'file://'.APP.'Application/Library/Payment/Wxpay/fenzhang_cert/wechatpay.pem';
            $cert['wechatpayKeyInstance'] = Rsa::from($cert['wechatpayFilePath'], Rsa::KEY_TYPE_PUBLIC);
            $cert['wechatpayKeyId'] = '34E8192B9ED9xxxxFA02ED40D51D2A7F8AC481E4';
            return $cert;
        }
        /**
         * 添加分账接收方  SpliTheBill::add
         */
        public function add($type,$account,$name="",$relation_type){
            $method = 'POST';
            $Request  = "/v3/profitsharing/receivers/add";
            $random = self::random(); //随机字符串
            $time = self::unixtime(); //unix时间
            $isheader = 0;
            $body = [
                "appid" => C('PAY_YIGUO')['wxpay_app_id'],
                "type"=>$type,//MERCHANT_ID:商户ID   PERSONAL_OPENID:个人openid,
                "account" => $account,
                "relation_type"=>$relation_type
            ];
            if(!empty($name)):
                $isheader = 1;
                $body['name'] = self::getEncrypt($name);
            endif;
            $sign_res = json_decode(self::sign([$method,$Request,$random,$time,$body],$isheader),true);//签名
            $header = self::setheader(['random'=>$random,"time"=>$time,"Signature"=>$sign_res['Signature'],"isheader"=>$isheader]);//设置header
            return [$Request,$body,$header];
        }
        //SpliTheBill::getEncrypt
        //敏感信息加密
        private function getEncrypt($str) {
            $cert = self::__initializtion();
            $public_key_path = $cert['platformPublicKeyFilePath'];
            $public_key = file_get_contents($public_key_path);
            $encrypted = '';
            if (openssl_public_encrypt($str, $encrypted, $public_key, OPENSSL_PKCS1_OAEP_PADDING)) {
                //base64编码
                $sign = base64_encode($encrypted);
            } else {
                throw new Exception('encrypt failed');
            }
            return $sign;
        }
        //SpliTheBill::sign
        /**
         * 签名
         */
        public function sign($params,$isheader){
            $cert = self::__initializtion();
            $params += ['Signature' => Rsa::sign(
                Formatter::joinedByLineFeed(...array_values($params)),
                $cert['merchantPrivateKeyInstance']//$merchantPrivateKeyInstance
            ), 'signType' => 'RSA'];
            return json_encode($params);
        }
        //SpliTheBill::random
        /**
         * 随机字符串,签名需要
         */
        public function random($length=32){
            $characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
            $randomString = '';
            for ($i = 0; $i < $length; $i++) {
                $index = rand(0, strlen($characters) - 1);
                $randomString .= $characters[$index];
            }
            return $randomString;
        }
        //SpliTheBill::unixtime  
        //当前时间 
        public function unixtime(){
            return time();
        }
        /**
         * 向腾讯云发送数据
         */
        public function send($Request,$body,$header){
            $sert = SpliTheBill::__initializtion();
            $instance = Builder::factory([
                'mchid'      => $sert['merchantId'],
                'serial'     => $sert['merchantCertificateSerial'],
                'privateKey' => $sert['merchantPrivateKeyInstance'],
                'certs'      => [
                    $sert['platformCertificateSerial'] => $sert['onePlatformPublicKeyInstance'],
                    $sert['platformPublicKeyI']       => $sert['twoPlatformPublicKeyInstance'],
                ],
            ]);
            try {
                $resp = $instance
                    ->chain($Request)
                    ->post([
                        'json' => $body,
                        'headers'=>$header,
                    ]);
                //成功返回200
                return ['code'=>$resp->getStatusCode(),"message"=>"成功","data"=>$resp->getBody()];
            } catch (\Exception $e) {
                // 进行错误处理
                $message = $e->getMessage();
                if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
                    $r = $e->getResponse();
                    return ['code'=>$r->getStatusCode(),"message"=>$message,"data"=>$r->getReasonPhrase()];
                }
            }
        }
        /**
         * 设置header
         */
        public function setheader($param){
            $cert = self::__initializtion();
            switch ($param['isheader']){
                case('1'):
                    //添加分帐用户 
                    $header = [
                        "Authorization: WECHATPAY2-SHA256-RSA2048 mchid=\"{$cert['merchantId']}\",nonce_str=\"{$param['random']}\",signature=\"{$param['Signature']}\",timestamp=\"{$param['time']}\",serial_no=\"{$cert['merchantCertificateSerial']}\"",
                        "Content-Type: application/json",
                        "Accept: application/json",
                        "Wechatpay-Serial:".$cert['platformPublicKeyId']."",
                        //"User-Agent"=>"User-Agent:Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1",
                    ];
    
    
                    break;
                default:
                    $header = [
                        "Authorization: WECHATPAY2-SHA256-RSA2048 mchid=\"{$cert['merchantId']}\",nonce_str=\"{$param['random']}\",signature=\"{$param['Signature']}\",timestamp=\"{$param['time']}\",serial_no=\"{$cert['merchantPrivateKeyInstance']}\"",
                        "Wechatpay-Serial:".$cert['merchantPrivateKeyInstance']."",
                        "Content-Type: application/json",
                        "Accept: application/json",
                        //"User-Agent"=>"User-Agent:Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1",
                    ];
                    break;
            }
            return $header;
        }
    
    07-14
    有用
    回复
  • Memory
    Memory
    07-14

    每个商户号签发的平台证书是不同的,示例只是个示例

    07-14
    有用
    回复 4
    • 无名小卒
      无名小卒
      07-14
      但是能过  openssl x509 -in wechatpay.pem -noout -serial 生成的 证书序列号 还是报   HTTP header缺少微信支付平台证书序列号(Wechatpay-Serial)”  我能够想到的办法都想了。完全走不下去
      07-14
      回复
    • Memory
      Memory
      07-14回复无名小卒
      建议使用sdk 并搭配 https://wechatpay.im/ 使用
      07-14
      回复
    • 无名小卒
      无名小卒
      07-14
      所有的证书序列号都用过,而且header参数中也有  Wechatpay-Serial  所有想到的方法都试过了
      07-14
      回复
    • Memory
      Memory
      07-14回复无名小卒
      直接去上面cv代码
      07-14
      回复
登录 后发表内容