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 addons\epay\library;
use fast\Http;

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(/[\r\n]/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就结束了   下一篇讲支付宝的流程以及代码操作

posted @ 2021-07-13 11:05  穷帅哥依然纵横一方  阅读(757)  评论(0编辑  收藏  举报