• php微信jsapi支付 支付宝支付 两码合一


    产品开会提出了这样的需求:一个二维码可以微信支付也可以支付宝支付

    经过自己的钻研以及询问技术高人(本人代码一般般)和网上搜索 最终实现其功能  我用微信jsapi 和 支付宝网页支付

    其实并不怎么难:

      1.微信jsapi支付流程(微信官方文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

      2.支付宝支付流程

    好了废话不多说 开始开发 代码上(Tp5开发)

    首先 需要生成一个二维码这个想必大家都会吧!!! phpqrcode(下载地址:https://sourceforge.net/projects/phpqrcode/ )

     1         require_once ROOT_PATH.'/phpqrcode/phpqrcode.php';
     2             $value='http://'.$_SERVER['HTTP_HOST'].'/admin.php/pay/wx_zfb; //二维码链接   (这个是重中之重!!!)
     3             $errorCorrectionLevel = 'H';//容错级别
     4             $matrixPointSize = 6;//生成图片大小
     5             //生成二维码图片
     6             QRcode::png($value, 'code/1.png', $errorCorrectionLevel, $matrixPointSize, 2);
     7             $logo = 'code/kunchuan.png';//准备好的logo图片
     8             $QR = 'code/1.png';//已经生成的原始二维码图
     9             if ($logo !== FALSE) {
    10                 $QR = imagecreatefromstring(file_get_contents($QR));
    11                 $logo = imagecreatefromstring(file_get_contents($logo));
    12                 /* $QR = imagecreatefrompng($QR);
    13                 $logo = imagecreatefrompng($logo);*/
    14                 if (imageistruecolor($logo))
    15                 {
    16                     imagetruecolortopalette($logo, false, 65535);//添加这行代码来解决颜色失真问题
    17                 }
    18 
    19                 $QR_width = imagesx($QR);//二维码图片宽度
    20                 $QR_height = imagesy($QR);//二维码图片高度
    21                 $logo_width = imagesx($logo);//logo图片宽度
    22                 $logo_height = imagesy($logo);//logo图片高度
    23                 $logo_qr_width = $QR_width / 5;
    24                 $scale = $logo_width/$logo_qr_width;
    25                 $logo_qr_height = $logo_height/$scale;
    26                 $from_width = ($QR_width - $logo_qr_width) / 2;
    27                 //重新组合图片并调整大小
    28                 imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width,
    29                     $logo_qr_height, $logo_width, $logo_height);
    30             }
    31 
    32             $lujing =  'code/merge1'.png';
    33 
    34             //输出图片
    35             imagepng($QR,$lujing);
    36             return  '<img src="http://'.$_SERVER['HTTP_HOST'].'/'.$lujing.'" alt="使用微信或者支付宝扫描支付">';

    ok我们就生成一个二维码  因为个人隐私 我就生成了一个百度的二维码

    通过扫描二维码 我们跳转到 wx_zfb方法:

     public function wx_zfb()
        {
          //根据自己的需求  链接上边有参数就接值 没有就不做判断
            // if($this->request->isGet()) 
          // {
              //在PHP中HTTP_USER_AGENT是用来获取用户的相关信息的,包括用户使用的浏览器,操作系统等信息,
                  $http_user_agent = $_SERVER['HTTP_USER_AGENT'];
                  if (strpos($http_user_agent, 'MicroMessenger')) 
           {
             
    $url="code”;//处理微信支付的方法 header("location:{$url}"); exit; }elseif (strpos($http_user_agent, 'AlipayClient')) { //支付宝链接  
             $url="aliyun”;//处理微信支付的方法
             header("location:{$url}"); exit

             }else{ $this->assign('error_data','请使用微信或者支付宝扫码哦!'); return $this->view->fetch('pay/error'); } // }else{ // $this->assign('error_data','暂时没有哦'); // return $this->view->fetch('pay/error'); //} }

    接下来精彩的代码即将上线(微信jsapi支付)

      damo下载:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

      首先我们要了解微信jsapi的开发流程

      

     好了这些你们就了解一下就可以了

    public function code()
        {
            $appid = '*******';//微信的appid
            $appKey = '******';//APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置, 登录公众平台,进入开发者中心可设置), 请妥善保管, 避免密钥泄露获取地址:https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN
            $mchid='*******';//商户平台的id
            $apiKey='*******';//KEY:商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置), 请妥善保管, 避免密钥泄露设置地址:https://pay.weixin.qq.com/index.php/account/api_cert
            $wxPay = new WxpayService($mchid,$appid,$appKey,$apiKey);
            $openid = $wxPay->GetOpenid();  
            if($openid){
                Session::set("openid", $openid);
            }else{
                $openid=session('openid');
            }
             //公众号中的话可以授权-获取用户信息
            // $wxPays=new WxPayUser($appid,$appKey);
            // $data = $wxPays->GetOpenid();   
            // $user = $WxPayUser->getUserInfo($data['openid'],$data['access_token']);
        $this->assign('openid',$openid);        
        $this->assign('ip_user',$ip_user);        
        return $this->view->fetch();
    
    }
    WxpayService.php
    <?php
    namespace addonsepaylibrary;
    use fastHttp;
    
    class WxpayService
    {
        protected $mchid;
        protected $appid;
        protected $appKey;
        protected $apiKey;
        public $data = null;
        public function __construct($mchid, $appid, $appKey,$key)
        {
            $this->mchid = $mchid; //https://pay.weixin.qq.com 产品中心-开发配置-商户号
            $this->appid = $appid; //微信支付申请对应的公众号的APPID
            $this->appKey = $appKey; //微信支付申请对应的公众号的APP Key
            $this->apiKey = $key;   //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥
        }
        /**
         * 通过跳转获取用户的openid,跳转流程如下:
         * 1、设置自己需要调回的url及其其他参数,跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize
         * 2、微信服务处理完成之后会跳转回用户redirect_uri地址,此时会带上一些参数,如:code
         * @return 用户的openid
         */
        public function GetOpenid()
        {
            //通过code获得openid
            if (!isset($_GET['code'])){
                //触发微信返回code码
                $_SERVER['HTTPS']=isset($_SERVER['HTTPS'])?$_SERVER['HTTPS']:'';
                $scheme = $_SERVER['HTTPS']=='on' ? 'https://' : 'http://';
                $uri = $_SERVER['PHP_SELF'].$_SERVER['QUERY_STRING'];
                if($_SERVER['REQUEST_URI']) $uri = $_SERVER['REQUEST_URI'];
                $baseUrl = urlencode($scheme.$_SERVER['HTTP_HOST'].$uri);
                $url = $this->__CreateOauthUrlForCode($baseUrl);
                Header("Location: $url");
                exit();
            } else {
                //获取code码,以获取openid
                $code = $_GET['code'];
                $openid = $this->getOpenidFromMp($code);
                return $openid;
            }
        }
        /**
         * 通过code从工作平台获取openid机器access_token
         * @param string $code 微信跳转回来带上的code
         * @return openid
         */
        public function GetOpenidFromMp($code)
        {
            $url = $this->__CreateOauthUrlForOpenid($code);
            $res = self::curlGet($url);
            //取出openid
            $data = json_decode($res,true);
            $this->data = $data;
            $data['openid']=isset($data['openid'])?$data['openid']:'';
            $openid = $data['openid'];
            return $openid;
        }
        /**
         * 构造获取open和access_toke的url地址
         * @param string $code,微信跳转带回的code
         * @return 请求的url
         */
        private function __CreateOauthUrlForOpenid($code)
        {
            $urlObj["appid"] = $this->appid;
            $urlObj["secret"] = $this->appKey;
            $urlObj["code"] = $code;
            $urlObj["grant_type"] = "authorization_code";
            $bizString = $this->ToUrlParams($urlObj);
            return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;
        }
        /**
         * 构造获取code的url连接
         * @param string $redirectUrl 微信服务器回跳的url,需要url编码
         * @return 返回构造好的url
         */
        private function __CreateOauthUrlForCode($redirectUrl)
        {
            $urlObj["appid"] = $this->appid;
            $urlObj["redirect_uri"] = "$redirectUrl";
            $urlObj["response_type"] = "code";
            $urlObj["scope"] = "snsapi_base";
            $urlObj["state"] = "STATE"."#wechat_redirect";
            $bizString = $this->ToUrlParams($urlObj);
            return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;
        }
        /**
         * 拼接签名字符串
         * @param array $urlObj
         * @return 返回已经拼接好的字符串
         */
        private function ToUrlParams($urlObj)
        {
            $buff = "";
            foreach ($urlObj as $k => $v)
            {
                if($k != "sign") $buff .= $k . "=" . $v . "&";
            }
            $buff = trim($buff, "&");
            return $buff;
        }
        /**
         * 统一下单
         * @param string $openid 调用【网页授权获取用户信息】接口获取到用户在该公众号下的Openid
         * @param float $totalFee 收款总费用 单位元
         * @param string $outTradeNo 唯一的订单号
         * @param string $orderName 订单名称
         * @param string $notifyUrl 支付结果通知url 不要有问号
         * @param string $timestamp 支付时间
         * @return string
         */
        public function createJsBizPackage($openid, $totalFee, $outTradeNo, $orderName, $notifyUrl, $timestamp)
        {
            $config = array(
                'mch_id' => $this->mchid,
                'appid' => $this->appid,
                'key' => $this->apiKey,
            );
            // $orderName = iconv('GBK','UTF-8',$orderName);
            $unified = array(
                'appid' => $config['appid'],
                'attach' => 'pay',             //商家数据包,原样返回,如果填写中文,请注意转换为utf-8
                'body' => $orderName,
                'mch_id' => $config['mch_id'],
                'nonce_str' => self::createNonceStr(),
                'notify_url' => $notifyUrl,
                'openid' => $openid,            //rade_type=JSAPI,此参数必传
                'out_trade_no' => $outTradeNo,
                'spbill_create_ip' => '127.0.0.1',
                'total_fee' => floatval($totalFee) * 100,       //单位 转为分
                'trade_type' => 'JSAPI',
            );
            $unified['sign'] = self::getSign($unified, $config['key']);
    
            $responseXml = self::curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', self::arrayToXml($unified));
    
            //禁止引用外部xml实体
            libxml_disable_entity_loader(true);        
            $unifiedOrder = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA);
            if ($unifiedOrder === false) {
                die('parse xml error');
            }
            if ($unifiedOrder->return_code != 'SUCCESS') {
                die($unifiedOrder->return_msg);
            }
            if ($unifiedOrder->result_code != 'SUCCESS') {
                die($unifiedOrder->err_code);
            }
            $arr = array(
                "appId" => $config['appid'],
                "timeStamp" => "$timestamp",        //这里是字符串的时间戳,不是int,所以需加引号
                "nonceStr" => self::createNonceStr(),
                "package" => "prepay_id=" . $unifiedOrder->prepay_id,
                "signType" => 'MD5',
            );
            $arr['paySign'] = self::getSign($arr, $config['key']);
            return $arr;
        }
        public static function curlGet($url = '', $options = array())
        {
            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_TIMEOUT, 30);
            if (!empty($options)) {
                curl_setopt_array($ch, $options);
            }
            //https请求 不验证证书和host
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            $data = curl_exec($ch);
            curl_close($ch);
            return $data;
        }
        public static function curlPost($url = '', $postData = '', $options = array())
        {
            if (is_array($postData)) {
                $postData = http_build_query($postData);
            }
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
            curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数
            if (!empty($options)) {
                curl_setopt_array($ch, $options);
            }
            //https请求 不验证证书和host
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            $data = curl_exec($ch);
            curl_close($ch);
            return $data;
        }
        public static function createNonceStr($length = 16)
        {
            $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
            $str = '';
            for ($i = 0; $i < $length; $i++) {
                $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
            }
            return $str;
        }
        public static function arrayToXml($arr)
        {
            $xml = "<xml>";
            foreach ($arr as $key => $val) {
                if (is_numeric($val)) {
                    $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
                } else
                    $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
            }
            $xml .= "</xml>";
            return $xml;
        }
        public function notify()
        {
            $config = array(
                'mch_id' =>  $this->mchid,
                'appid' =>  $this->appid,
                'key' =>  $this->apiKey,
            );
            $postStr = file_get_contents('php://input');
            //禁止引用外部xml实体
            libxml_disable_entity_loader(true);        
            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
            $result_1 = json_encode(simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA));
            file_put_contents("1.txt",$result_1, FILE_APPEND);
            
            $arr = (array)$postObj;
                return $arr;
        }
    
        public static function getSign($params, $key)
        {
            ksort($params, SORT_STRING);
            $unSignParaString = self::formatQueryParaMap($params, false);
            $signStr = strtoupper(md5($unSignParaString . "&key=" . $key));
            return $signStr;
        }
        protected static function formatQueryParaMap($paraMap, $urlEncode = false)
        {
            $buff = "";
            ksort($paraMap);
            foreach ($paraMap as $k => $v) {
                if (null != $v && "null" != $v) {
                    if ($urlEncode) {
                        $v = urlencode($v);
                    }
                    $buff .= $k . "=" . $v . "&";
                }
            }
            $reqPar = '';
            if (strlen($buff) > 0) {
                $reqPar = substr($buff, 0, strlen($buff) - 1);
            }
            return $reqPar;
        }
    
    
    
    
        
    }
    View Code

    code.html

    <html>
    
    <head>
        <meta charset="utf-8" />
        <meta name="viewport"  content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
        <title>微信支付</title>
        <style>
    * {margin:0;padding:0;}
    body {font-size:12px;font-family:"Microsoft YaHei","微软雅黑",sans-serif;color:#333;background-color:#f7f7f7;width:100%;}
    .clearfix:after { content: "."; display: block; font-size: 0; height: 0; clear: both; visibility: hidden; }
    .clearfix { display: inline-table;}
    *html .clearfix { height: 1%; }
    .clearfix { display: block; }
    *+html .clearfix { min-height: 1%; }
    ul,li{ list-style:none;border:0; box-sizing:border-box; }
    .main {margin:0 auto;width:100%;max-width:750px;min-width:320px;background-color:#f7f7f7;}
    .btnpay {margin:0.8rem auto 0;width:100%;}
    .btnpay span {display:block;margin:0 auto;width:6.74rem;height:0.8rem;line-height:0.8rem;background-color:#80D983;border-radius:0.1rem;color:#fff;font-size:0.34rem;letter-spacing:0.06rem;text-align:center;}
    
    .xinxi{ margin:0 auto; width: 90%; line-height: 46px; display: flex; flex-direction: row; font-size: 0.32rem; border-bottom: #ccc solid 1px; color: #333;}
    .moneychose{ margin:0 auto; width: 90%;}
    .moneychose p {font-size:16px;color:#8D8D8F; line-height: 42px;}
    .moneychose .list{ display: flex; }
    .moneychose .list li{ width: 45%; margin-right:5%; border: #ccc solid 1px; background-color: #fff; border-radius:3px; text-align: center; padding:10px 0;}
    .moneychose .list li span{ font-size: 0.32rem;display: block;}
    .moneychose .list li.active{border: #e56d33 solid 1px; color:#e56d33;}
    .tipbox{ margin:10px auto 0; width: 90%;}
    .tipbox a{ text-decoration:none; color: #999; font-size:0.28rem;}
    
    .tkbox .mask,.tkknowbox .mask{margin:0 auto;width:100%;height:100%;position:fixed;left:0px;top:0px;opacity:0.85;z-index:9998;background-color:rgb(0,0,0);}
    .tkbox .mymodel,.tkknowbox .mytk{width:6.2rem; padding: 0.25rem 0 0.25rem 0; position:fixed;z-index:10000;display:block;border-radius:5px;background-color:#FFFFFF;}
    .mymodel .inputblock{ margin:0 auto 0.3rem; width:5.6rem;}
    .mymodel .inputs {width:100%;height:0.8rem;line-height:0.8rem;font-size:0.32rem;border:1px solid #CFCFCF;text-indent:0.2rem;outline:none;white-space:pre;overflow-x:scroll;}
    .frminput {margin:0.3rem auto 0;display:flex;flex-direction:row;}
    .frminput input {margin-left:0.3rem;width:2.4rem;height:0.8rem;line-height:0.8rem;font-size:0.30rem;padding-left:0.2rem;border:1px solid #CFCFCF; outline:none; }
    .frminput .sendCodeBtn {margin-left:0.3rem;width:2rem;height:0.8rem;line-height:0.8rem;background-color:#e56d33;border-radius:5upx;color:#fff;text-align:center;font-size:0.26rem;}
    .btnconfrm {margin:0.5rem auto 0;width:5rem;}
    .btnconfrm span {display:block;margin:0 auto;width:100%;height:0.8rem;line-height:0.8rem;background-color:#80D983;border-radius:0.1rem;color:#fff;font-size:0.34rem;letter-spacing:0.06rem;text-align:center;}
    .topcar{ width: 100%; display: flex; flex-direction: row; margin-bottom: 0.15rem;}
    .topcar .cartip{ font-size: 0.32rem;width:1.1rem;height:0.6rem; line-height:0.6rem; padding-left: 0.3rem;}
    .che_tit{ text-align:center; padding:20px;}
    .ul_pro{ background-color:#CED3D9; text-align:center; padding:4px 2px; font-size:0.32rem;}
    .ul_pro li{ float:left; width:11.11%; padding:2px;box-sizing: border-box;}
    .ul_pro .li_close{  float:right; width:22.22%;}
    .ul_pro .li_close span{ background-color:#ACB3BB;}
    .ul_pro .li_clean{  float:right; width:22.22%;}
    .ul_pro li span{ display:block; background-color:#fff; border-radius:4px;line-height:32px; padding-top:2px; }
    .ul_pro li span:active{ background-color:#4DA9F2; color:#fff;}
    .ul_input{ width:4.6rem; margin:0 auto; }
    .ul_input li{ float:left; width:14%; padding:0.02rem;text-align:center; }
    .ul_input li span{ display:block; background-color:#fff; border:1px solid #ccc; border-radius:4px; width:0.5rem; margin:0 auto; height:0.5rem; line-height:0.5rem;font-size: 0.36rem;}
    .ul_keybord{ background-color:#CED3D9; text-align:center; padding:4px 2px; font-size:14px;}
    .ul_keybord li{ float:left; width:10%; padding:2px;box-sizing: border-box;}
    .ul_keybord .ikey20{ margin-left:5%;}
    .ul_keybord .li_w{ width:11.11%; }
    .ul_keybord .li_close{  float:right; width:22.22%;}
    .ul_keybord .li_close span{ background-color:#ACB3BB;}
    .ul_keybord .li_clean{  float:right; width:22.22%;}
    .ul_keybord li span{ display:block; background-color:#fff; border-radius:4px; box-shadow: 2px 2px 2px #888888;line-height:32px; padding-top:2px;  }
    .ul_keybord li span:active{ background-color:#4DA9F2; color:#fff;}
    
    .tkknowbox .closetk{ width: 0.58rem; height: 0.58rem; position: absolute; top:-39px;right:-9px;z-index: 10001;}
    .tkknowbox .closetk .icon{width: 0.58rem; height: 0.58rem;}
    .tkknowbox .knowmain{ padding:5px 5% 0;  font-size: 0.28rem; color: #666; line-height:24px;}
    .tkknowbox .knowmain .tit{ font-size: 0.30rem;}
    </style>
        <script type="text/javascript">
            //调用微信JS api 支付
            function jsApiCall(msg) {
                WeixinJSBridge.invoke(
                    'getBrandWCPayRequest',
                    msg,
                    function (res) {
                        WeixinJSBridge.log(res.err_msg);
                        if (res.err_msg == 'get_brand_wcpay_request:ok') {
                            window.location.href="www.baidu.com";
                            // alert('支付成功!');
                        } else if(res.err_msg=='get_brand_wcpay_request:cancel') {
                            layer.msg('支付取消');
                        }else{
                            layer.msg('支付失败');
                            // alert('支付失败:' + res.err_code + res.err_desc + res.err_msg);                        
                        }
                    }
                );
            }
            function callpay(msg) {
                if (typeof WeixinJSBridge == "undefined") {
                    if (document.addEventListener) {
                        document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
                    } else if (document.attachEvent) {
                        document.attachEvent('WeixinJSBridgeReady', jsApiCall);
                        document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
                    }
                } else {
                    jsApiCall(msg);
                }
            }
        </script>
    </head>
    
    <body>
        <section class="main">
            <section class="xinxi">
                <span>手机号:</span>
                <span id="phones"></span>
            </section>
            <section class="moneychose">
                <p>选择套餐</p>
                <ul class="list">
                    <li class="active" data-type='1'><span>12次洗车次卡</span><span>300元</span></li>
                    <li data-type='2'><span>25次洗车次卡</span><span>588元</span></li>
                </ul>
                <input type="hidden" name="openid" id='openid' value="<?php echo $openid;?>">
                <input type="hidden" name="car_num_id" id='car_num_id' value="">
            </section>
            <section class="tipbox" id="tipbox"><span>《支付须知》</span></section>
            <div class="btnpay" onclick="telypay()"><span>立即支付</span></div>
        </section>
        <!-- 弹框开始 -->
        <section class="tkbox"  >
            <section class="mask"></section>
            <section class="mymodel">
                <section class="tipinput">
                    <section class="topcar">
                        <div class="cartip">车牌号:</div>
                        <div class="car_input">
                            <ul class="clearfix ul_input">
                                <li class="input_pro"><span></span></li>
                                <li class="input_pp input_zim"><span></span></li>
                                <li class="input_pp"><span></span></li>
                                <li class="input_pp"><span></span></li>
                                <li class="input_pp"><span></span></li>
                                <li class="input_pp"><span></span></li>
                                <li class="input_pp"><span></span></li>
                            </ul>
                        </div>
                    </section>
                    <div class="inputblock"><input id="phone" type="number" maxlength="11" autocomplete="off" class="inputs" placeholder="请输入手机号" onfocus="closePro()"   ></div>
                    <section class="frminput">
                        <input type="number" id="code" class="inputcode" onfocus="closePro()" placeholder="请输入验证码" />
                        <section class="sendCodeBtn" datamark="0" id="sendCodeBtn">发送验证码</section>
                    </section>
                </section>
                <section class="btnconfrm" id="btnconfrm"><span>确定</span></section>
            </section>
        </section>
    
        <!-- 须知弹窗 -->
        <section class="tkknowbox" style="display:none;">
            <section class="mask"></section>
            <section class="mytk">
                <section class="closetk" onclick="$('.tkknowbox').hide();" ><img src="/code/iconclose.png" alt="关闭须知弹框" class="icon" /></section>
                <section class="knowmain">
                    <p><span class="tit" >1)次卡:</span><br>
                        <span style="font-weight: bold;">轿车</span>:300元套餐(内含12次洗车服务);588元套餐(内含25次洗车服务且赠送一次打蜡)<br>
                        <span style="font-weight: bold;">SUV</span>: 350元套餐(内含12次洗车服务);688元套餐(内含25次洗车服务且赠送一次打蜡)<br>
                        
                    </p>
         
                    <p><span class="tit" >2)次卡升级为年卡:</span><br>将剩余次卡数折合为钱数,并支付所差金额;即可升级为年卡且次卡剩余次数清空;<br></p>
                    <p>3)其他问题,请联系客服热线 ********** 咨询</p>
                </section>
            </section>
        </section>
        <!-- 弹框结束 -->
        <script type="text/javascript" src="/assets/js/jquery.min.js"></script>
        <script src="/assets/js/shop.js" ></script>
    
        <script type="text/javascript">
            var isClick = true;
            function telypay() {
                if(!isClick){
                  return false;
                }
                // 这里可以写你onclick事件需要获取传到后台的值
                var openid = $('#openid').val();
              var price;
                $(".list li").each(function(){
                     if($(this).hasClass('active')){
                       console.log($(this).attr("data-type"));
                       price = $(this).attr("data-type");
                     }
                });
    
                $.ajax({
                    type: 'post',
                    url: "/admin.php/pay/sub_pay",
                    data: { 'price': price, 'openid': openid},
                    dataType: 'json',
                    success: function (msg) {
                        isClick = true;
                        callpay(msg);
                    }
                });
            }
            $(function () {
                //隐藏弹框
                var is_user=<?php echo $is_user;?>;
                var car_num_id=<?php echo $car_num_id;?>;
                var phone=<?php echo $phone;?>;
                if(is_user - 1 == 0){
                    $("#car_num_id").val(car_num_id);
                    $('#phones').text(phone);
                    $(".tkbox").hide();
                }
    
    
                var W = $('.mymodel').width();
                var H = $('.mymodel').height();
                var winWid = $(window).width() / 2 - W / 2;
                var winHig = $(window).height() / 2 - H / 2;
                $(".mymodel").css({ 'left': winWid, 'top': winHig });
    
                 $(".list li").click(function(){
                     $(".list li").removeClass('active');
                     $(this).addClass('active');
                     console.log($(this).attr("data-type"));
    
                });
    
                //发送验证码
                $("#sendCodeBtn").click(function(){
                    var datamark = $(this).attr('datamark');
                    //console.log(datamark);
                    if(datamark - 1 == 0){
                      return false;
                    }
                    var phone = $("#phone").val();
                    if(!phone){
                        layer.msg('请填写您的手机号');
                        return false; 
                    }
                    var myreg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/;
                    if (!myreg.test(phone)) {
                        layer.msg('请填写正确的手机号');
                        return false; 
                    }
                    $.ajax({
                        type: 'post',
                        url: "/admin.php/pay/send_code",
                        data: { 'phone': phone},
                        dataType: 'json',
                        success: function (msg) {
                            if(msg.code < 0){
                                layer.msg(msg.msg);
                            }else if(msg.code > 0){
                                settime($("#sendCodeBtn"));
                                layer.msg('发送验证码成功');
                            }
                            return false;
                        }
                    });
                    //settime($("#sendCodeBtn"));
    
                    //此处请求接口,成功后下面
                    
                });
                var countdown = 60;
                function settime(obj) 
                {
                    if (countdown == 0) {
                        $(obj).attr("datamark", "0");
                        $(obj).html("获取验证码");
                        countdown = 60;
                        return;
                    } else {
                        $(obj).attr("datamark", "1");
                        $(obj).html(countdown + "s后重新获取");
                        countdown--;
                    }
                setTimeout(function () { settime(obj) }, 1000);
               }
           
                //确定按钮点击
                $("#btnconfrm").click(function () {
    
                    var carnum = $(".car_input").attr("data-pai");
                    if(carnum == undefined){
                        layer.msg('请填写您的车牌号');
                        return false;
                    }
                    carnum = carnum.replace(/[
    ]/g,"").replace(/s*/g,"");
                  //  console.log(carnum);
                    if(carnum.length - 7 < 0){
                        layer.msg('请填写您的车牌号');
                        return false;
                    }
                    var phone = $("#phone").val();
                    var code = $("#code").val();
                    if(!phone){
                        layer.msg('请填写您的手机号');
                        return false; 
                    }
                    var myreg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/;
                    if (!myreg.test(phone)) {
                        layer.msg('请填写正确的手机号');
                        return false; 
                    }
                    if(!code){
                        layer.msg('请填写您的验证码');
                        return false; 
                    }
                    $('#pro').remove();
                   
                    $.ajax({
                        type: 'post',
                        url: "/admin.php/pay/car_num",
                        data: { 'carnum': carnum, 'phone': phone, 'code': code},
                        dataType: 'json',
                        success: function (message) {
    
                            msgs=JSON.parse(message);
                            if(msgs.status=='0'){
                                layer.msg(msgs.msg);
                                return false;
                            }else{
                                $("#car_num_id").val(msgs.id);
                                $('#phones').text(msgs.phone);
                                $(".tkbox").hide();
                                layer.msg('提交成功');
                                // console.log(msg.id +"手机号"+"验证码"+msg.phone);
                                return true;
                            }
                            
                        }
                    });
    
                     //console.log(carnum +"手机号"+phone+"验证码"+code);
                    return false;
                    
                });
    
    
                $("#tipbox").click(function(){
                    $(".tkknowbox").show();
                    var W1 = $('.mytk').width();
                    var H1 = $('.mytk').height();
                    var winWid1 = $(window).width() / 2 - W1 / 2;
                    var winHig1 = $(window).height() / 2 - H1 / 2;
                    $(".mytk").css({ 'left': winWid1, 'top': winHig1 });
                });
                
            });
    
    
            (function (doc, win) {
                var docEl = doc.documentElement,
                    resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
                    recalc = function () {
                        var clientWidth = docEl.clientWidth;
                        if (!clientWidth) return;
                        if (clientWidth >= 750) {
                            docEl.style.fontSize = '100px';
                        } else {
                            docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
                        }
                    };
                if (!doc.addEventListener) return;
                win.addEventListener(resizeEvt, recalc, false);
                doc.addEventListener('DOMContentLoaded', recalc, false);
            })(document, window);
        </script>
    </body>
    </html>

    (个人的需求 你们可以删除手机短信的验证 send_code 和car_num 的入库)

    你们只用sub_pay方法

     public function sub_pay()
        {
            $openid=$this->request->post('openid'); 
            $price=$this->request->post('price');
            $price=0.01;//测试金额
            // $outTradeNo = uniqid();     //你自己的商品订单号
            //今日日期+时间戳后五位+毫秒从第三位到第八位+
            $outTradeNo = date('Ymd').substr(time(), -5) . substr(microtime(), 2, 5) . sprintf('%02d', rand(1000, 9999));
            $orderName = '支付测试';    //订单标题
            $notifyUrl = 'http://'.$_SERVER['HTTP_HOST'].'/admin.php/Pay/callback';     //付款成功后的回调地址(不要有问号)
            $payTime = time();      //提交时间
            $order_price=$price*100; //测试
            $sql="INSERT INTO order(`pay_type`,`order_status`,`order_num`,`shop_id`,`pay_status`,`order_price`,`create_time`) VALUES('2','0','$outTradeNo','$ip_user','0','$order_price','$payTime')";
            Db::execute($sql);
            //处理一下数据
        
    $conf = $this->payconfig($orderName,$openid,$outTradeNo,$order_price,$orderName,$notifyUrl);      $jsApiObj["appId"] =$conf['appid']; $timeStamp = time(); $jsApiObj["timeStamp"] = "$timeStamp"; $jsApiObj["nonceStr"] = $this->createNoncestr(); $jsApiObj["package"] ="prepay_id=".$conf['prepay_id']; $jsApiObj["signType"] = "MD5"; $jsApiObj["paySign"] = $this->MakeSign($jsApiObj,'KunLunqifuWangRUIHua162588080619'); echo json_encode($jsApiObj); }
    payconfig方法
    #微信JS支付参数获取-注意下面是支付方法可以不需要管!!!#
        protected function payconfig($title,$openid,$no, $fee, $body,$notifyUrl)
        {
            $config = array(
                'mch_id' => '********',
                'appid' => '*******',
                'key' => '**************',
            );
            $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
            $data['appid'] =$config['appid'];
            $data['mch_id'] =$config['mch_id'];         //商户号
            $data['device_info'] ='WEB';
            $data['body'] = $body;
            $data['out_trade_no'] =$no;             //订单号
            $data['total_fee'] = $fee;              //金额
            $data['spbill_create_ip'] = $_SERVER["REMOTE_ADDR"];
            $data['notify_url'] =$notifyUrl;
            $data['trade_type'] = 'JSAPI';
            $data['openid'] = $openid;   //获取openid
            $data['nonce_str'] = $this->createNoncestr();
            $data['sign'] = $this->MakeSign($data,$config['key']);
    
    
    
            //print_r($data);
            $xml = $this->ToXml($data);
            $curl = curl_init(); // 启动一个CURL会话
            curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
            //设置header
           // curl_setopt($curl, CURLOPT_HEADER, FALSE);
            //要求结果为字符串且输出到屏幕上
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
            curl_setopt($curl, CURLOPT_POST, TRUE);       //发送一个常规的Post请求
            curl_setopt($curl, CURLOPT_POSTFIELDS, $xml); // Post提交的数据包
            curl_setopt($curl, CURLOPT_TIMEOUT, 30);      // 设置超时限制防止死循环
            $tmpInfo = curl_exec($curl); // 执行操作
            curl_close($curl); //关闭CURL会话
            $arr = $this->FromXml($tmpInfo);
            return $arr;
        }

    /**
         * 异步回调通知
         * 说明:需要在支付文件中(如native.php或者jsapi.php)的填写回调地址。例如:http://www.xxx.com/wx/notify.php
         * 付款成功后,微信服务器会将付款结果通知到该页面 我的是 callback方法
         */

     

     public function callback()
        {
    
            $xml = file_get_contents("php://input");
            $log = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
            $log_1=json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA));
            file_put_contents('1.txt',$log_1,FILE_APPEND);//只有返回参数写进文件中才可以打印 切记切记切记
          3.1根据返回的信息在生成签名防止数据泄漏导致出现“假通知”,造成资金损失。
         $apiKey="*******";
            $newSign = $this->verifySign($log,$apiKey);
         //判断数据库金额和支付金额是否一致 判断签名是否一致
         if (($yorder_data['order_price']) == (int)$trade['total_fee']&& $newSign == $trade["sign"] ) //
                {
            直接写你的操作数据库逻辑就ok了

         }
         //
    必须加这个!!!
         $str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';  
            echo $str; }
    /* $log=array ( 'appid' => 'wx3c3f93ddce1e7845', 'bank_type' => 'OTHERS', 'cash_fee' => '1', 'device_info' => 'WEB', 'fee_type' => 'CNY', 'is_subscribe' => 'Y', 'mch_id' => '1602777325', 'nonce_str' => 'oz5dzyotw0qyz2a8x2elenbki268cyt5', 'openid' => 'os2J15vmqW1KXHLZAL4IwBtP7hL8', 'out_trade_no' => '2021070824865563665180', 'result_code' => 'SUCCESS', 'return_code' => 'SUCCESS', 'sign' => '02B66C17D8A31D0F943448979357DDEB', 'time_end' => '20210708141109', 'total_fee' => '1', 'trade_type' => 'JSAPI', 'transaction_id' => '4200001181202107085997485076', );*/

    相关的方法

      /**
         *    作用:产生随机字符串,不长于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;
        }
    
        /**
         *    作用:产生随机字符串,不长于32位
         */
        public function randomkeys($length)
        {
            $pattern = '1234567890123456789012345678905678901234';
            $key = null;
            for ($i = 0; $i < $length; $i++) {
                $key .= $pattern{mt_rand(0, 30)};    //生成php随机数
            }
            return $key;
        }
        /**
         * 将xml转为array
         * @param string $xml
         * @throws WxPayException
         */
        public function FromXml($xml)
        {
            //将XML转为array
            return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)),true);
        }
        /**
         * 输出xml字符
         * @throws WxPayException
         **/
        public function ToXml($arr)
        {
            $xml = "<xml>";
            foreach ($arr as $key => $val) {
                if (is_numeric($val)) {
                    $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
                } else {
                    $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
                }
            }
            $xml .= "</xml>";
            return $xml;
        }
        /**
         * 生成签名
         * @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
         */
        protected function MakeSign($arr,$key)
        {
            ksort($arr);
            $string = $this->ToUrlParams($arr);
            //签名步骤二:在string后加入KEY
            $string = $string."&key=$key"; //key秘钥
            //签名步骤三:MD5加密
            $string = md5($string);
            //签名步骤四:所有字符转为大写
            $result = strtoupper($string);
            return $result;
        }
        /**
         * 格式化参数格式化成url参数
         */
        protected function ToUrlParams($arr)
        {
            $buff = "";
            foreach ($arr as $k => $v){
                if ($k != "sign" && $v != "" && !is_array($v)) {
                    $buff .= $k . "=" . $v . "&";
                }
            }
            $buff = trim($buff, "&");
            return $buff;
        }
        // 判断返回的签名和根据数据生成的数据判断是否相同,防止数据泄漏导致出现“假通知”,造成资金损失。
        function verifySign($params, $apikey)
        {
            ksort($params);
            $string = "";
            foreach ($params as $k => $v) {
    
                if ($k != "sign" && $v != "" && !is_array($v)) {
                    $string .= $k . "=" . $v . "&";
                }
            }
            $string = $string . "key=" . $apikey;
            $string = md5($string);
            $result = strtoupper($string);
            return $result;
        }

    到这里 微信jsapi就结束了   下一篇讲支付宝的流程以及代码操作

  • 相关阅读:
    https://www.unavco.org/projects/projectsupport/boreholeservices/bsmliterature/bsmliterature.html
    SpringBoot+log4j2+MDC+AOP记录requestId
    CVE_2020_0796 SMBGhost浅析
    CVE20201301 SMBLost漏洞浅析
    Alpine容器安装运行ssh
    cut用法详细解析
    #、##、__VA_ARGS__的使用
    电子地图监控
    mybatisgeneratorgui selectkey
    Native.loadLibrary
  • 原文地址:https://www.cnblogs.com/yx520zhao/p/15005539.html
Copyright © 2020-2023  润新知