php微信支付之V3版本jsapi支付(微信环境内H5支付)

该文章已生成可运行项目,

场景描述:

H5网站需要在微信环境里,调取微信支付!

首先我们需要准备几个东西!

1:公众appid+公众号appsecrt!

注意:设置公众号服务器白名单ip,设置回调域名白名单!

2:准备微信支付商户号,并且需要和公众号绑定再一起!

3:在微信支付平台开通jsapi支付功能!!!!!!

4:下载API V3证书!

这次我们倒着来,微信在微信环境里提供了JS支付的前端代码!如图:


function onBridgeReady(){
   WeixinJSBridge.invoke(
      'getBrandWCPayRequest', {
         "appId":{$appId},     //公众号ID,由商户传入     
         "timeStamp":{$time},         //时间戳,自1970年以来的秒数     
         "nonceStr":{$nonceStr}, //随机串     
         "package":"prepay_id="{$prepay_id},     
         "signType":{$signType},         //微信签名方式:     
         "paySign":{$paySign} //微信签名 
      },
      function(res){
      if(res.err_msg == "get_brand_wcpay_request:ok" ){
      // 使用以上方式判断前端返回,微信团队郑重提示:
            //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
      } 
   }); 
}
if (typeof WeixinJSBridge == "undefined"){
   if( document.addEventListener ){
       document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
   }else if (document.attachEvent){
       document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
       document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
   }
}else{
   onBridgeReady();
}      

那么我们就需要准备,6个参数!

1:参数appId           //公众号ID,由商户传入     
2:参数imeStamp   //时间戳,自1970年以来的秒数     
3:参数nonceStr    //随机串     
4:参数package     //prepay_id 
5:参数signType    //微信签名方式:     
6:参数paySign     //微信签名 

当我们极齐6个龙珠,我们就可以召唤神龙了!

那么我们就开始吧!

第一关:

我们需要拿用户的openid,是不是很迷糊来拿用户id?哈哈哈

 public function getUserOpenid($money){
        $backUrl             =  urlencode('回调域名地址');回调的域名需要urlencode
        $appid               = 公众号appid  
        $money               = state携带的参数
        $url                 = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appid.'&redirect_uri='.$backUrl.'&response_type=code&scope=snsapi_base&state='.$money.'#wechat_redirect';
        return header("Location:".$url);
    }

回调回来

public function 接收方法(){

        $date         = request()->param();
        $url          ='https://api.weixin.qq.com/sns/oauth2/access_token?appid='.公众号appid.'&secret='.公众号appsecrt.'&code='.$date['code'].'&grant_type=authorization_code';
        $openid       =$this->curlGet($url); //通过get方法请求,CURL get方法自己写一下

}

静默拿到用户openid组合--订单参数--,极简版!

需要准备2项参数:Header ,Data= 去换prepay_id 

Data

        $data          = [
            "appid"        => 公众号id,
            "mchid"        => 微信商户号,
            "description"  => 描述,
            'out_trade_no' => 订单编号,
            'notify_url'   => 异步通知地址,
            "amount"       => [
                "total"    => 金额,
                "currency" => "CNY"
            ],
            'payer' => [
                  'openid' => 用户openid
             ]
        ];

Header

protected function headers($data){ $data 就是上面方法传进来的 

        $timestamp     = time();
        $nonceStr      = date('YmdHis', time()) . rand(1000, 9999);
        $url           = 'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi';
        $url_parts     = parse_url($url);
        $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
        $data          = json_encode($data);


        $header        = array(
            "Authorization: " . $this->getSign($nonceStr,$timestamp,$canonical_url,$data),//这个参数要复杂一点,需要加密
            "Accept:application/json",
            "Content-Type:application/json",
            "User-Agent:application/json",
        );
}

    //公共签名 第一次签名!
private function getSign($nonceStr,$timeStamp,$canonical_url,$data){  
        
        $key     = openssl_get_privatekey(file_get_contents('这个是微信证书的路径apiclient_key.pem'));//这里是打开商户私钥证书
        $method  = 'POST'; //请求的方式
        $message = $method . "\n" .$canonical_url. "\n" .$timeStamp . "\n" . $nonceStr . "\n" . $data . "\n"; //组合成一字符串 \n 需要每行携带,官方要求的
        openssl_sign($message, $rawSign, $key,'sha256WithRSAEncryption'); //sha256WithRSA 加密
        $sign    = base64_encode($rawSign); //收到上面加密值做base64
        return  'WECHATPAY2-SHA256-RSA2048 mchid=商户号,nonce_str="'.$nonceStr.'",timestamp="'.$timeStamp.'",serial_no=证书序列号,signature="'.$sign.'"';//最后这一步,组合头部参数字符串,
        
}
    

上面证书序列号:获取方法

上文提及到的 serial_no是证书序列号!可以通过网站证书查看去查看证书序列号

1:上传apiclient_cert.pem证书

2:显示出信息的第三项 证书信息里查看 序列号,保存好使用即可!

然后headers + data 都准备好了就POST请求

地址:https://api.mch.weixin.qq.com/v3/pay/transactions/native

方式:POST

获取:

微信会给我们返回:prepay_id 

protected function 准备参数($prepay_id){
        $paydata = [
            'appId'     => $this->appid,
            'timeStamp' => $timeStamp,
            'nonceStr'  => md5(rand(100000,999999)),
            'package'   => 'prepay_id='.$prepay_id, //这里注意写的方式!
        ];
        $sign                 = $this->getPaySign($paydata);//给小程序生成验证签名
        $paydata['signType']  = 'RSA';
        $paydata['paySign']   = $sign;

}

二次制作签名,这个是制作 paySign 签名为了提交支付
    
protected function getPaySign($paydata) {
        $tmpstr = $paydata['appId'] . "\n" . $paydata['timeStamp'] . "\n" . $paydata['nonceStr'] . "\n" . $paydata['package'] . "\n";
        $privateKey         = file_get_contents('这里也是证书地址apiclient_key.pem');
        $binary_signature   = "";
        $algo               = "SHA256";
        openssl_sign($tmpstr, $binary_signature, $privateKey, $algo);
        $sign               = base64_encode($binary_signature);
        return $sign;
}

这样参数就齐全了:神龙就会出现了!

1:参数appId           //公众号ID,由商户传入     
2:参数imeStamp   //时间戳,自1970年以来的秒数     
3:参数nonceStr    //随机串     
4:参数package     //prepay_id 
5:参数signType    //微信签名方式:     
6:参数paySign     //微信签名 

微信环境里调用这个JS就会唤起支付!


function onBridgeReady(){
   WeixinJSBridge.invoke(
      'getBrandWCPayRequest', {
         "appId":'{$text.appId}',     //公众号ID,由商户传入     
         "timeStamp":'{$text.timeStamp}',         //时间戳,自1970年以来的秒数     
         "nonceStr":'{$text.nonceStr}', //随机串     
         "package":'{$text.package}',     
         "signType":"RSA",         //微信签名方式:     
         "paySign":'{$text.paySign}', //微信签名 
      },
      function(res){
      if(res.err_msg == "get_brand_wcpay_request:ok" ){
      // 使用以上方式判断前端返回,微信团队郑重提示:
            //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
      } 
   }); 
}
if (typeof WeixinJSBridge == "undefined"){
   if( document.addEventListener ){
       document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
   }else if (document.attachEvent){
       document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
       document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
   }
}else{
   onBridgeReady();
}      

最后重要说明: 一定要把传入前端的JS参数‘ ’包裹起来,不然无法提交支付!

本文章已经生成可运行项目
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值