PHP微信扫码支付V3接口开发过程!!坑很多更新中

PHP微信扫码支付V3接口开发过程!!坑很多更新中

Ezra
2021-06-16 / 0 评论 / 337 阅读 / 正在检测是否收录...

最近公司又一个项目需要微信扫码支付,之前没做过这种东西所以我先去看了文档,先说明一下本人只是一个菜鸟,遇事直接百度的那种,于是这次我像往常一样打开百度搜索微信扫码支付。此时我发现了一丝不对劲,怎么百度搜到的文档和微信官方的文档不一样呢?一个是用xml传递参数一个是用json传递参数,这一下给我搞蒙了,于是我去微信开放社区问了问,结果是微信支付有V2和V3之分,有没有V1我不清楚,用xml传参的是V2用json传参的是V3。建议我用V3,不过这个看个人喜好,也有人说V2更好。但是对比了两个文档后我还是选择了V3,因为文档看起来要传的参数少。。。。。。(只是看起来)
首先贴个文档: 微信支付-开发者文档
然后在贴个图
5_0.png
这个图是业务流程图自己看看理解,因为是扫码支付所以我需要用户下单后获取code_url然后使用code_url来生成二维码
看起来很简单是吧,然后这个是文档中给出的参数

{
    "mchid": "1900006XXX",
    "out_trade_no": "native12177525012014070332333",
    "appid": "wxdace645e0bc2cXXX",
    "description": "Image形象店-深圳腾大-QQ公仔",
    "notify_url": "https://weixin.qq.com/",
    "amount": {
        "total": 1,
        "currency": "CNY"
    }
}

看起来也很少,但是如果我按照文档中写得发出请求呢?
答案是会报错: 400 "Http头缺少Accept或User-Agent" ,ok,因为我在写这块代码的时候公众号并没有申请下来,所以我觉得很正常,但是后来一想不对劲,没申请下来应该报的是 appid和mch_id不匹配 才对啊,于是我在请求里又加了accept和user-agent,然后报 401 Http头Authorization值格式错误,请参考《微信支付商户REST API签名规则》 我当时直接黑人问号,这是个什么东西啊?于是我又去微信开发社区问,结果是V3接口在调用的时候需要签名。好家伙刚说完你V3接口简单,结果你偷摸藏了个规则
关于签名的文档在这: 签名生成
要签名就必须要申请证书,方法在上面这个文档里,写得更详细,下载好证书之后保存好,之后就可以进行我们的开发了
接下来我就直接上代码了

public function xiadan(Request $request){//测试下单哦,根据需要自己改
        $data=[];
        $data['mchid']='';
        $data['out_trade_no']='pai1234567';
        $data['appid']='';
        $data['description']='商品描述:测试用';
        $data['notify_url']='';//通知地址
        $data['amount']['total']=1;//订单总金额,单位为分。
        $data['amount']['currency']='CNY';
        $url="https://api.mch.weixin.qq.com/v3/pay/transactions/native";
        $data_string=json_encode($data);
        $qianming=$this->qianming('POST',$url,$data_string);
        $code=$this->http_post_data($url,$data_string,$qianming);
        // dd($qianming);
        return $code;
        // return json_encode($data);
    }
public function qianming($http_method,$url,$body){
        // Authorization: <schema> <token>
        //获取HTTP请求的方法(GET,POST,PUT等)$http_method
        
        //获取请求的绝对URL
        $url_parts = parse_url($url);
        $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
        //时间戳
        $timestamp=time();
        //生成随机串
        $nonce=$this->createNoncestr();

        $message = $http_method."\n".
            $canonical_url."\n".
            $timestamp."\n".
            $nonce."\n".
            $body."\n";

        $mch_private_key=$this->getPrivateKey();
        openssl_sign($message, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption');
        $sign = base64_encode($raw_sign);//计算签名

        $schema = 'WECHATPAY2-SHA256-RSA2048';
        //serial_no为商户证书序列号
        $serial_no = '你商户证书的序列号';
        $merchant_id = $this->mch_id;
        $token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
        $merchant_id, $nonce, $timestamp, $serial_no, $sign);

        $msg['schema']=$schema;
        $msg['token']=$token;
        return $msg['schema'].' '.$token;;
    }

    /**
     *     作用:产生随机字符串,不长于32位
     */
     public function createNoncestr( $length = 32 ) 
     {
         $chars = "abcdefghijklmnopqrstuvwxyz0123456789";  
         $str ="";
         for ( $i = 0; $i < $length; $i++ )  {  
             $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);  
         }  
         return $str;
     }

    //查看证书序列号
    public static function getCertificate($filepath="apiclient_cert.pem") {//改成自己的地址哦
        // return file_get_contents($filepath);die;
        $str = openssl_x509_parse(file_get_contents($filepath));
        return $str['serialNumberHex'];
        // return openssl_x509_read(file_get_contents($filepath));
    }
    //获取私钥
    public static function getPrivateKey($filepath="apiclient_key.pem") {//改成自己的地址哦
        $private_key=openssl_get_privatekey(file_get_contents($filepath));
        return $private_key;
    }
   /**
     * 发送数据
     */
    public function http_post_data($url,$data_string,$qianming) {
 
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36',
            'Accept:*/*',
            'Authorization:' ."$qianming",
            'Content-Type: application/json; charset=utf-8',
            'Content-Length: ' . strlen($data_string))
            
        );
        ob_start();
        curl_exec($ch);
        $return_content = ob_get_contents();
        ob_end_clean();
 
        $return_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        return array($return_code, $return_content);
    }

这样起码报错是 appid和mch_id不匹配 了,之后可能有更新,但感觉悬哈哈

0

评论 (0)

取消