微信内置浏览器支付

前端页面

//验证是否是微信内置浏览器
        function is_weixn(){
            var ua = navigator.userAgent.toLowerCase();
            if(ua.match(/MicroMessenger/i) == "micromessenger"){
                return true;
            } else {
                return false;
            }
        }

PHP

            case '3':             //微信内置浏览器JSAPI支付
                $sHtml = '
'; $sHtml .= '$order['order_sn'].'" />'; $sHtml .= '$goods_name.'" />'; $sHtml .= '$order['payable_amount'].'" />'; $sHtml .= '
'; $sHtml .= ''; echo $sHtml; break;

DEOM

php
namespace Mobile\Controller;
use Think\Controller;
class WechatController extends Controller{
    //$stime = microtime(true);
    //$etime = microtime(true); echo ($etime - $stime);
    //需先设置好微信支付授权目录和网页授权域名,扫码支付模式一需设置支付回调URL,模式二不需要设置
    const TOKEN = 'StupidLi';    //token令牌
    //const ORIGINAL_ID = 'gh_63e349ac0af5';    //微信公众号原始ID
    const APP_ID = 'wx8d7d0d6d81dc5056';    //微信公众号应用ID
    const APP_SECRET = 'cc41f16e6620443dcb7a4f6e85efbbca';    //微信公众号应用密钥
    //const ENCODING_AES_KEY = 'S1X0CAP7JlNInE6NKyglXdZWt2rrh0g1oIIpOOil3rH';    //消息加解密密钥
    const MCH_ID = '1420243602';    //微信支付商户号
    const MCH_KEY = '0MrxTO6bhOikziaGnAMgr1xec9bIFRxP';    //微信支付商户密钥
    const RETURN_URL = 'http://m.tthwine.com/Wechat/wxpayReturn.html';    //支付结果同步通知地址
    const NOTIFY_URL = 'http://m.tthwine.com/Wechat/wxpayNotify.html';    //支付结果异步通知地址
    /**
     * TODO:设置商户证书路径
     * 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要,可登录商户平台下载,
     * API证书下载地址:https://pay.weixin.qq.com/index.php/account/api_cert,下载之前需要安装商户操作证书)
     */
    const SSLCERT_PATH = './ThinkPHP/Library/Vendor/Wechat/cert/apiclient_cert.pem';
    const SSLKEY_PATH = './ThinkPHP/Library/Vendor/Wechat/cert/apiclient_key.pem';
    /**
     * TODO:这里设置CURL代理机器,只有需要代理的时候才设置,不需要代理,请设置为0.0.0.0和0
     * 本例程通过curl使用HTTP POST方法,此处可修改代理服务器,
     * 默认CURL_PROXY_HOST=0.0.0.0和CURL_PROXY_PORT=0,此时不开启代理(如有需要才设置)
     */
    const CURL_PROXY_HOST = '0.0.0.0';          //"10.152.18.220"
    const CURL_PROXY_PORT = 0;                  //8080

    private $access_token = '';      //公共基础开发的access_token
    private $access_token_a = '';    //用户授权凭证,即用code换取的access_token,
    private $curl_timeout = 30;      //curl超时

    public function _initialize(){
        header("Content-type: text/html; charset=utf-8");
        vendor("Wechat.WxPayException");    //异常处理类
        vendor("Wechat.WxPayFunction");    //基础方法类
    }

    //微信应用基础开发服务地址
    public function index(){
        //file_put_contents('./Data/paylog/wechatlog.txt', $_SERVER['REMOTE_ADDR'].'   '.$_SERVER['QUERY_STRING']."\r\n", FILE_APPEND);
        if(isset($_GET['echostr'])){    //验证token
            $checkResult = $this->checkSignature($_GET['signature'], TOKEN, $_GET['timestamp'], $_GET['nonce']);
            if($checkResult == true){
                echo $_GET['echostr'];
                exit;
            }
        }else{
            $this->reponseMsg();
            //其他基础开发程序
            //libxml_disable_entity_loader(true);
            //$values = json_decode(json_encode(simplexml_load_string($res, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
            //file_put_contents("./Data/paylog/TEXTQ.txt", "1111333", FILE_APPEND );
        }
    }
    //应用开发验证签名
    protected function checkSignature($signature, $token, $timestamp, $nonce){
        $tmpArr = array($token, $timestamp, $nonce);
        sort($tmpArr, SORT_STRING);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);
        if($tmpStr == $signature){
            return true;
        }else{
            return false;
        }
    }
    //回复事件
    public function reponseMsg(){
        //1.获取到微信推送过来post数据(xml格式)
        $postArr = $GLOBALS['HTTP_RAW_POST_DATA'];
        //2.处理消息类型,并设置回复类型和内容
        $postObj = simplexml_load_string( $postArr );
        //判断该数据包是否是订阅的事件推送
        if( strtolower( $postObj->MsgType) == 'event'){
            //如果是关注 subscribe 事件
            if( strtolower($postObj->Event == 'subscribe') ){
                //回复用户消息(纯文本格式)
                $toUser   = $postObj->FromUserName;
                $fromUser = $postObj->ToUserName;
                $arr = array(
                array(
                    'title'=>'中秋月醇-月饼礼盒套装可预定啦',
                    'description'=>"中秋月醇-十二星座红酒配月饼礼盒套装可以预定了",
                    'picUrl'=>'https://mmbiz.qlogo.cn/mmbiz_jpg/gOCpHN587Z330josics98BkbFntIeVHq795A4ibqicANzzicdOico79kqOaHHicdMeFD9CwyKhk1BYTw4sS7icuTg0V1g/0?wx_fmt=jpeg',
                    'url'=>'https://mp.weixin.qq.com/s?__biz=MzIzMTY5MzI3Ng==&mid=2247483661&idx=1&sn=7e51c19aa3ec2672986c4b35d07e74b1&chksm=e8a10fbedfd686a8cd571951b64abcf2f680e6bdcbfdf4fb764dae22a961d9c91b78e471b5a3#rd',
                ),
                array(
                    'title'=>'百葡汇--名庄红酒价格搜索中心',
                    'description'=>"百葡汇--名庄红酒价格搜索中心",
                    'picUrl'=>'http://www.baipuhui.com/Public/Home/Images/logo.png',
                    'url'=>'http://www.baipuhui.com/',
                ),
                array(
                    'title'=>'萄萄汇--红酒商城',
                    'description'=>"葡葡汇--红酒商城",
                    'picUrl'=>'http://www.tthwine.com/Public/Home/img/logo.png',
                    'url'=>'http://m.tthwine.com',
                ),
            );
            $template = "
                        
                        
                        %s
                        
                        ".count($arr)."
                        ";
            foreach($arr as $k=>$v){
                $template .="
                            <![CDATA[</span>".<span style="color:#800080;">$v</span>['title']."<span style="color:#000000;">]]>
                            ".$v['description']."]]>
                            ".$v['picUrl']."]]>
                            ".$v['url']."]]>
                            ";
            }

            $template .="
                         ";
            echo sprintf($template, $toUser, $fromUser, time(), 'news');
            }elseif( strtolower($postObj->Event == 'unsubscribe') ){
                //回复用户消息(纯文本格式)
                $toUser   = $postObj->FromUserName;
                $fromUser = $postObj->ToUserName;
                $time     = time();
                $msgType  =  'event';
                $event    =     'unsubscribe';
                $content  = '欢迎关注我们的微信公众账号';
                $template = "
                            
                            
                            %s
                            
                            
                            ";
                $info     = sprintf($toUser, $fromUser, $time, $msgType, $event, $content, $template);
                echo $info;
            }

        }

        //内容的回复多图文的
        if( strtolower($postObj->MsgType) == 'text' && strtolower($postObj->Content)=='tw' ){
            $toUser = $postObj->FromUserName;
            $fromUser = $postObj->ToUserName;
            $arr = array(
                array(
                    'title'=>'再见科比,再见青春',
                    'description'=>"再见科比,再见青春",
                    'picUrl'=>'http://img1.gtimg.com/sports/pics/hv1/226/138/2052/133466716.jpg',
                    'url'=>'http://sports.qq.com/a/20160414/040599.htm',
                ),
                array(
                    'title'=>'百葡汇--红酒搜索中心',
                    'description'=>"百葡汇--红酒搜索中心",
                    'picUrl'=>'http://www.baipuhui.com/Public/Home/Images/logo.png',
                    'url'=>'http://www.baipuhui.com/',
                ),
                array(
                    'title'=>'淘淘wine',
                    'description'=>"淘淘wine",
                    'picUrl'=>'http://www.tthwine.com/Public/Home/img/logo.png',
                    'url'=>'http://www.tthwine.com/',
                ),
            );
            $template = "
                        
                        
                        %s
                        
                        ".count($arr)."
                        ";
            foreach($arr as $k=>$v){
                $template .="
                            <![CDATA[</span>".<span style="color:#800080;">$v</span>['title']."<span style="color:#000000;">]]>
                            ".$v['description']."]]>
                            ".$v['picUrl']."]]>
                            ".$v['url']."]]>
                            ";
            }

            $template .="
                         ";
            echo sprintf($template, $toUser, $fromUser, time(), 'news');

            //注意:进行多图文发送时,子图文个数不能超过10个
        }else{
            switch( strtolower($postObj->Content) ){
                case 1:
                    $content = '您输入的数字是1';
                break;
                case 2:
                    $content = '您输入的数字是2';
                break;
                case 3:
                    $content = '您输入的数字是3';
                break;
                case 4:
                    $content = "慕课";
                break;
                case '英文':
                    $content = 'imooc is ok';
                break;
            }
                $template = "
                        
                        
                        %s
                        
                        
                        ";
            //注意模板中的中括号 不能少 也不能多
                $fromUser = $postObj->ToUserName;
                $toUser   = $postObj->FromUserName;
                $time     = time();
                $msgType  = 'text';
                echo sprintf($template, $toUser, $fromUser, $time, $msgType, $content);

        }//if end
        // 付款推送
        if( strtolower( $postObj->MsgType) == 'event'){
            if( strtolower( $postObj->Event) == 'merchant_order'){
                    $toUser   = $postObj->FromUserName;
                    $fromUser = $postObj->ToUserName;
                    $time     = time();
                    $msgType  = 'event';
                    $event    = 'merchant_order';
                    $OrderId  = $postObj->OrderId;
                    $OrderStatus = '2';
                    $ProductId = $postObj->ProductId;
                    $SkuInfo  = $postObj->SkuInfo;
                    $template = "
                                
                                
                                %s
                                
                                
                                
                                %s
                                
                                
                                ";
                    echo sprintf($template, $toUser, $fromUser, $time, $msgType, $event, $OrderId, $OrderStatus, $ProductId, $SkuInfo);
            }
        }
        return $postArr;
    }//reponseMsg 括号
    //获取AccessToken
    public function getWxAccessToken(){
        //1.请求url地址
        $appid = 'wx8d7d0d6d81dc5056';
        $appsecret =  'cc41f16e6620443dcb7a4f6e85efbbca';
        if (time()-S('expires_in')<7000) {
                $access_token = S('access_token');
                //var_dump($access_token);
                  return $access_token;
            }else{
                $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $appid . "&secret=" . $appsecret . "";
                $data = webCurl($url);
                $arr = json_decode($data,true);
                S('access_token',$arr['access_token'],7000);
                $access_token = S('access_token');
                $data = array(
                    "access_token" => $access_token,
                    "expires_in"=> time(),
                );
                S('expires_in',$data['expires_in'],7000);
                //var_dump($access_token);
                //$_SESSION['access_token_expires_in'] = $data['expires_in'];
                return $data['access_token'];
            }
    }
    //自定义菜单栏
    public function setmenu()
    {
        $access_token = $this->getWxAccessToken();
        $url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=".$access_token;
        $data = array(
            'button'=>array(
                array(
                    "name"=>"微信商城",
                       "sub_button"=>array(
                           array(
                               "type"=>"view",
                            "name"=>"中秋月醇",
                            "url"=>"http://m.tthwine.com/Goods/index/W_category/376.html"
                               ),
                           array(
                               "type"=>"view",
                            "name"=>"生肖套装",
                            "url"=>"http://m.tthwine.com/Goods/detail/id/413.html"
                               ),
                           array(
                               "type"=>"view",
                            "name"=>"萄萄汇商城",
                            "url"=>"http://m.tthwine.com/"
                               ),
                           array(
                               "type"=>"view",
                            "name"=>"特价优惠",
                            "url"=>"http://m.tthwine.com/Goods/index.html"
                               ),

                           )
                    ),
                array(
                    "name"=>"名庄报价",
                       "sub_button"=>array(
                           array(
                               "type"=>"view",
                            "name"=>"价格查询",
                            "url"=>"http://m.baipuhui.com/"
                               ),
                           array(
                               "type"=>"view",
                            "name"=>"供应商报价",
                            "url"=>"http://m.baipuhui.com/ProductPrice/indexs.html"
                               ),
                           array(
                               "type"=>"view",
                            "name"=>"全球货源",
                            "url"=>"http://m.baipuhui.com/BusinessList/index.html"
                               ),

                           )
                    ),
                array(
                    "name"=>"用户中心",
                       "sub_button"=>array(
                           // array(
                           //     "type"=>"view",
                           //  "name"=>"小店订单",
                           //  "url"=>"http://mp.weixin.qq.com/bizmall/mallshelf?id=&t=mall/list&biz=MzIzMTY5MzI3Ng==&shelf_id=2&showwxpaytitle=1#wechat_redirect"
                           //     ),
                           array(
                               "type"=>"view",
                            "name"=>"商城订单",
                            "url"=>"http://m.tthwine.com/Member/order.html"
                               ),
                           array(
                                "type"=>"view",
                            "name"=>"物流跟踪",
                             "url"=>"https://m.kuaidi100.com/index.jsp"
                                ),
                           array(
                               "type"=>"view",
                            "name"=>"个人中心",
                            "url"=>"http://m.tthwine.com/Member/index.html"
                               ),

                           )
                    ),
                ),
            );
        $data = webCurl($url,1,json_encode($data,JSON_UNESCAPED_UNICODE));
    }
    //登录获取用户信息
    public function login()
    {
        $appid = 'wx8d7d0d6d81dc5056';
        $redirect_uri = "http://m.tthwine.com/index.php/Wechat/weixinreturn";
        $redirect_uri = urlencode($redirect_uri);
        $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=".$appid."&redirect_uri=".$redirect_uri."&response_type=code&scope=snsapi_userinfo&state=1&connect_redirect=1#wechat_redirect";
        header('Location: ' . $url . '');
    }
    public function weixinreturn()
    {
        $appid = 'wx8d7d0d6d81dc5056';
        $SECRET =  'cc41f16e6620443dcb7a4f6e85efbbca';
        $code = $_GET['code'];
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" .$appid. "&secret=" .$SECRET. "&code=". $code ."&grant_type=authorization_code";
        $data = json_decode(wcurl($url),true);
        $_SESSION['access_token'] = $data['access_token'];
        $_SESSION['openid'] = $data['openid'];
        $url = "https://api.weixin.qq.com/sns/userinfo?access_token=".$_SESSION['access_token']."&openid=".$_SESSION['openid']."&lang=zh_CN";
        $user = json_decode(wcurl($url),true);
        $this->assign('user',$user);
        $this->display();
        return $user;
    }

    //微信小店下单信息
    public function order(){
        $obj = $this-> gOrderAll($data = array());
            foreach ($obj['order_list'] as $key => $value) {
            $sql = " SELECT order_id FROM oph_wxshop WHERE order_id = '{$value['order_id']}' ";
            $res = M('wxshop')->query($sql);
            if ($res[0]['order_id'] == $value['order_id'] ) {
                 unset($value);
             }else{
                 M('wxshop')->add($value);
             }
        }
        $get['type']= $_GET['type'] ? $_GET['type'] : 0 ;
        switch ($get['type']){
            case 0:
                $where = '';
                break;
            case 1:
                $where = ' AND order_status = 1 ';
                break;
            case 2:
                $where = ' AND order_status = 2 ';
                break;
            case 3:
                $where = ' AND order_status = 3 ';
                break;
            case 4:
                $where = ' AND order_status = 4 ';
                break;
            default:
                break;
        }
        $orderlist = M('wxshop')->query(" SELECT * FROM oph_wxshop WHERE buyer_openid = '{$_SESSION['openid']}' $where");
        $this->assign('orderlist',$orderlist);
        $this->assign('get',$get);
        $this->display();
    }

    //微信小店的订单详情
    public function orderinfo(){
        $oid = $_GET['order_id'] ? $_GET['order_id'] : $this->error("非法访问");
        $info = M('wxshop')->query(" SELECT * FROM oph_wxshop WHERE order_id = '{$oid}' ");
        $this->assign('info', $info);
        $this->display();
    }

    //获取微信订单信息
    public function gOrderAll($data = array()){
      $access_token = $this->getWxAccessToken();
      $url = "https://api.weixin.qq.com/merchant/order/getbyfilter?access_token=".$access_token;
      if(!empty($data)){
        $data = json_encode($data);
      }
      else{
        $firstday = strtotime(date("Y-m-01",time()));
        $data = array('begintime' => $firstday,'endtime' => strtotime("$firstday +1 month -1 day"));
        $data = json_encode($data);
      }
      $ResData = $this->cUrlRequest($url,$data);
      $obj = objarray_to_array(json_decode($ResData));
        return $obj;
    }

    public function cUrlRequest($url,$data = null){
      $curl = curl_init();
      curl_setopt($curl, CURLOPT_URL, $url);
      curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
      curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
      if (!empty($data)){
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
      }
      curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
      $output = curl_exec($curl);
      curl_close($curl);
      return $output;
    }

    //微信订单确认
    public function returnInfo(){
        if($_GET['oid']){
            M()->execute("UPDATE oph_wxshop SET order_status = 4 WHERE  order_id = '{$_GET['oid']}'");
        }
        $orderlist = M('wxshop')->query(" SELECT * FROM oph_wxshop WHERE buyer_openid = '{$_SESSION['openid']}' AND order_status = 4");
        $this->assign('orderlist',$orderlist);
        $this->display('wechat/order');
    }
    //微信小店发货
    public function sLogisticsList(){
            $this->Logistics['Fsearch_code'] = "邮政EMS";
            $this->Logistics['002shentong'] = "申通快递";
            $this->Logistics['066zhongtong'] = "中通速递";
            $this->Logistics['056yuantong'] = "圆通速递";
            $this->Logistics['042tiantian'] = "天天快递";
            $this->Logistics['003shunfeng'] = "顺丰速运";
            $this->Logistics['059Yunda'] = "韵达快运";
            $this->Logistics['064zhaijisong'] = "宅急送";
            $this->Logistics['020huitong'] = "汇通快运";
            $this->Logistics['zj001yixun'] = "易迅快递";

    }
    //发货设置
    public function sOrderDelivery($data = array("need_delivery" => '0')){
      $access_token = $this->getWxAccessToken();
      $url = "https://api.weixin.qq.com/merchant/order/setdelivery?access_token=".$access_token;
      if(!empty($data)){
        $data = json_encode($data);
      }
      else{
        $data = array("need_delivery" => '0');
        $data = json_encode($data);
      }
      $ResData = $this->cUrlRequest($url,$data);
      print_r( json_decode($ResData) );
    }
    //发货订单
    public function send()
    {
        $data['need_delivery'] = '1';
        $data['order_id'] = '13880016931595576467';
        $data['delivery_company'] = '003shunfeng';
        $data['delivery_track_no'] = '5185457726';
        $data['is_others']         = '0';
        $this->sOrderDelivery($data);
    }

    //获取订单详情
    // public function gOrderInfo($order){
    //         $access_token = $this->getWxAccessToken();
    //         $url = "https://api.weixin.qq.com/merchant/order/getbyid?access_token=".$access_token;
    //         $ResData = $this->cUrlRequest($url,'{"order_id": "'.$order.'"}');
    //         return(objarray_to_array(json_decode($ResData)) );
    // }

    //模板消息发送
    public function sendtpl_msg(){
        if (is_weixin() == false) {
            echo "

请用微信浏览器打开

"; exit; } $access_token = $this->getWxAccessToken(); $getOpenid = $this->getOpenid(); //$postArr = $this->reponseMsg(); //$res = $this->gOrderInfo($postArr['OrderId']); //模板消息 $template=array( 'touser'=>$getOpenid, 'template_id'=>"t2j4tatkUhqCvsTVr290P04rXNWg3WnMWXOHiLW6tSg", 'url'=>"http://m.tthwine.com/index.php/Wechat/login/", 'topcolor'=>"#7B68EE", 'data'=>array( 'first' => array( 'value' => '尊敬的用户,您好,欢迎购买我们的产品', 'color' => '#FF0000' ), 'keyword1' => array( 'value' => $data['order_no'], 'color' => '#000' ), 'keyword2' => array( 'value' => $data['pay_amount'].元, 'color' => '#000000' ), 'remark' => array( 'value' => '广州欧葡汇祝您节日快乐!', 'color' => '#FF0000' ) ) ); $json_template=json_encode($template); $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=".$access_token; $res = http_request($url,urldecode($json_template)); } /** * 以post方式提交xml到对应的接口url * @param string $xml 需要post的xml数据 * @param string $url url * @param bool $useCert 是否需要证书,默认不需要 * @param int $second url执行超时时间,默认30s * @throws WxPayException */ protected static function curlPostXml($xml, $url, $useCert = false, $second = 30){ $ch = curl_init(); curl_setopt($ch, CURLOPT_TIMEOUT, $second); //设置超时 if(self::CURL_PROXY_HOST != "0.0.0.0" && self::CURL_PROXY_PORT != 0){ //如果有配置代理这里就设置代理 curl_setopt($ch, CURLOPT_PROXY, self::CURL_PROXY_HOST); curl_setopt($ch, CURLOPT_PROXYPORT, self::CURL_PROXY_PORT); } curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //严格校验2 curl_setopt($ch, CURLOPT_HEADER, FALSE); //设置header curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); //要求结果为字符串且输出到屏幕上 if($useCert == true){ //设置证书,使用证书:cert 与 key 分别属于两个.pem文件 curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM'); curl_setopt($ch, CURLOPT_SSLCERT, self::SSLCERT_PATH); curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM'); curl_setopt($ch, CURLOPT_SSLKEY, self::SSLKEY_PATH); } curl_setopt($ch, CURLOPT_POST, TRUE); //post提交方式 curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); $result = curl_exec($ch); //运行curl if($result){ //返回结果 curl_close($ch); return $result; }else{ $error = curl_errno($ch); curl_close($ch); throw new \WxPayException("curl出错,错误码:".$error); } } /** * 通过跳转获取用户的openid,跳转流程如下: * 1、设置自己需要调回的url及其其他参数,跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize * 2、微信服务处理完成之后会跳转回用户redirect_uri地址,此时会带上一些参数,如:code * 3、通过code请求微信服务器https://api.weixin.qq.com/sns/oauth2/access_token获取openid和access_token用户授权凭证 * @param string $state 自定义参数 * @return 用户的openid */ protected function getOpenid($state=''){ $tools = new \WxPayFunction(); if(!isset($_GET['code'])){ //触发微信返回code码 $redirectUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']); $urlObj = array( 'appid' => self::APP_ID, 'redirect_uri' => $redirectUrl, 'response_type' => 'code', 'scope' => 'snsapi_base', 'state' => $state.'#wechat_redirect' ); $bizString = $tools->ToUrlStr($urlObj); $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?'.$bizString; header('Location:'.$url); exit(); }else{ //获取code码,以获取openid $urlObj = array( 'appid' => self::APP_ID, 'secret' => self::APP_SECRET, 'code' => $_GET['code'], 'grant_type' => 'authorization_code' ); $bizString = $tools->ToUrlStr($urlObj); $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?'.$bizString; $ch = curl_init(); //初始化curl curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout); //设置超时 curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_HEADER, FALSE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); if(self::CURL_PROXY_HOST != '0.0.0.0' && self::CURL_PROXY_PORT != 0){ curl_setopt($ch,CURLOPT_PROXY, self::CURL_PROXY_HOST); curl_setopt($ch,CURLOPT_PROXYPORT, self::CURL_PROXY_PORT); } $result = curl_exec($ch); //运行curl,结果以json形式返回 curl_close($ch); $data = json_decode($result, true); $this->access_token_a = $data['access_token']; //赋值access_token_a属性,此access_token为用户授权凭证,与基础开发的access_token不同 return $data['openid']; //返回openid } } /** * 统一下单,unifiedOrder中out_trade_no、body、total_fee、trade_type必填 * appid、mchid、spbill_create_ip、nonce_str不需要填入 * @param WxPayUnifiedOrder $inputObj * @param int $timeOut * @throws WxPayException 抛出异常 * @return array 成功时返回结果 */ protected function unifiedOrder($requestArr, $timeOut = 10){ //检测参数 if(!array_key_exists('out_trade_no', $requestArr)){ throw new \WxPayException("缺少统一支付接口必填参数out_trade_no!"); }else if(!array_key_exists('body', $requestArr)){ throw new \WxPayException("缺少统一支付接口必填参数body!"); }else if(!array_key_exists('total_fee', $requestArr)){ throw new \WxPayException("缺少统一支付接口必填参数total_fee!"); }else if(!array_key_exists('trade_type', $requestArr)){ throw new \WxPayException("缺少统一支付接口必填参数trade_type!"); } //关联参数 if($requestArr['trade_type'] == "JSAPI" && !array_key_exists('openid', $requestArr)){ throw new WxPayException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!"); } if($requestArr['trade_type'] == "NATIVE" && !array_key_exists('product_id', $requestArr)){ throw new WxPayException("统一支付接口中,缺少必填参数product_id!trade_type为JSAPI时,product_id为必填参数!"); } $tools = new \WxPayFunction(); $url= 'https://api.mch.weixin.qq.com/pay/unifiedorder'; //统一下单API请求地址 $requestArr['appid'] = self::APP_ID; //String(32) 应用ID $requestArr['mch_id'] = self::MCH_ID; //String(32) 商户ID $requestArr['nonce_str'] = $tools->createNonceStr(32); //String(32) 随机字符串 $requestArr['spbill_create_ip'] = $_SERVER['REMOTE_ADDR']; //String(16) 终端IP $requestArr['notify_url'] = self::NOTIFY_URL; //String(256) 异步通知地址 $requestArr['sign'] = $tools->createSign($requestArr, self::MCH_KEY); //String(32) 签名 $requestXml = $tools->arrToXml($requestArr); $responseXml = self::curlPostXml($requestXml, $url, false, $timeOut); $responseArr = $tools->xmlToArr($responseXml); return $responseArr; } /** * 获取jsApi的json参数 * @param string $prepay_id 预支付交易标识 * @return jsApi前端json参数 */ protected function getJsApiParameters($prepay_id){ $tools = new \WxPayFunction(); $jsApiArr = array( 'appId' => self::APP_ID, //String(16) 应用ID 'timeStamp' => strval(time()), //String(32) 时间戳 'nonceStr' => $tools->createNonceStr(32), //String(32) 随机字符串 'package' => 'prepay_id='.$prepay_id, //String(128) 订单详情扩展字符串 'signType' => 'MD5' //String(32) 签名方式 ); $jsApiArr['paySign'] = $tools->createSign($jsApiArr, self::MCH_KEY); //String(64) 签名 return json_encode($jsApiArr); } /** * 获取共享地址json参数 * @param string $access_token 用户授权凭证 * @return 共享地址前段json参数 */ protected function getEditAddrParameters($access_token){ $tools = new \WxPayFunction(); $addrSignArr = array( 'appid' => self::APP_ID, //String(16) 应用ID 'url' => 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'], //当前网页URL 'timestamp' => strval(time()), //String(32) 时间戳 'noncestr' => $tools->createNonceStr(32), //String(32) 随机字符串 'accesstoken' => $access_token //String(256) 用户授权凭证 ); ksort($addrSignArr); $addrSignStr = $tools->toUrlStr($addrSignArr); $addrSign = sha1($addrSignStr); $editAddrArr = array( 'appId' => self::APP_ID, //String(16) 应用ID 'scope' => 'jsapi_address', //String(32) 编辑地址权限 'signType' => 'sha1', //String(32) 签名方式 'addrSign' => $addrSign, //String(40) 签名 'timeStamp' => $addrSignArr['timestamp'], //String(32) 时间戳 'nonceStr' => $addrSignArr['noncestr'] //String(32) 随机字符串 ); return json_encode($editAddrArr); } //微信支付外部浏览器H5页面MWEB支付接口(微信内测阶段,还未对外开放) public function wxpayH5Api(){ $requestArr = array( 'body' => $_POST['body'], //String(128) 商品描述 'out_trade_no' => $_POST['out_trade_no'], //String(32) 商户订单号 'total_fee' => intval(floatval($_POST['total_fee'])*100), //Int 订单金额(单位为分) 'trade_type' => 'MWEB' //String(16) 交易类型 ); $responseArr = $this->unifiedOrder($requestArr); //统一下单API $tools = new \WxPayFunction(); if($responseArr['return_code'] == 'SUCCESS'){ //判断返回是否成功 if(array_key_exists('sign', $responseArr) && $tools->createSign($responseArr, self::MCH_KEY) == $responseArr['sign']){ header('Location:'.$responseArr['mweb_url'].'&redirect_url='.urlencode(self::RETURN_URL)); //跳转启动微信APP支付 }else{ throw new \WxPayException("签名验证失败!"); } }else{ //$responseArr['return_code'] == 'FAIL' //记录日志$responseArr;打印出错参数 //file_put_contents('./Data/paylog/wechatlog.txt', $_SERVER['REMOTE_ADDR'].' '.$_SERVER['QUERY_STRING']."\r\n", FILE_APPEND); throw new \WxPayException("响应失败!"); foreach($responseArr as $key => $val){ echo $key.': '.$val.'
'; } } } //微信支付内置浏览器H5页面JSAPI支付接口 public function wxpayJsApi(){ //获取openId需跳转,所以将post参数存入获取openid的自定义参数中 if(!empty($_POST['body']) && !empty($_POST['out_trade_no']) && !empty($_POST['total_fee'])){ $state = json_encode($_POST); } //解析获取openid返回的自定义参数,从而获取最初的订单信息 if(!empty($_GET['state'])){ $orderData = json_decode($_GET['state'], true); } $openid = $this->getOpenid($state); //获取openid $requestArr = array( 'body' => $orderData['body'], //String(128) 商品描述 'out_trade_no' => $orderData['out_trade_no'], //String(32) 商户订单号 'total_fee' => intval(floatval($orderData['total_fee'])*100), //Int 订单金额(单位为分) 'trade_type' => 'JSAPI', //String(16) 交易类型 'openid' => $openid //String(128) trade_type=JSAPI时(即公众号支付),此参数必传,此参数为微信用户在商户对应appid下的唯一标识 ); $responseArr = $this->unifiedOrder($requestArr); //统一下单API if(!array_key_exists('appid', $responseArr) || !array_key_exists('prepay_id', $responseArr) || $responseArr['prepay_id'] == ""){ throw new \WxPayException("参数错误!"); } //获取调用jsApi的参数(json格式输出) $jsApiParameters = $this->getJsApiParameters($responseArr['prepay_id']); //获取共享收货地址的参数(json格式输出)(由于支付场景不适合,暂不使用) //$editAddrParameters = $this->getEditAddrParameters($this->access_token_a); //传递给同步通知页面的信息 $returnData = array( // 'out_trade_no' => $orderData['body'], 'out_trade_no' => $orderData['out_trade_no'], 'total_fee' => $orderData['total_fee'], 'return_url' => self::RETURN_URL ); $this->assign('jsApiParameters', $jsApiParameters); //$this->assign('editAddrParameters', $editAddrParameters); $this->assign('returnData', $returnData); $this->display('Order/wxpay_js'); } //微信支付原生支付接口(采用模式二扫码支付) public function wxpayNativeApi(){ $requestArr = array( 'body' => $_POST['body'], //String(128) 商品描述 'out_trade_no' => $_POST['out_trade_no'], //String(32) 商户订单号 'total_fee' => intval(floatval($_POST['total_fee'])*100), //Int 订单金额(单位为分) 'trade_type' => 'NATIVE', //String(16) 交易类型 'product_id' => $_POST['out_trade_no'] //String(32) 商品标识,商户自定义 ); $responseArr = $this->unifiedOrder($requestArr); //统一下单API $tools = new \WxPayFunction(); if($responseArr['return_code'] == 'SUCCESS'){ //判断返回是否成功 if(array_key_exists('sign', $responseArr) && $tools->createSign($responseArr, self::MCH_KEY) == $responseArr['sign']){ //验证签名 $returnData = array( //获取订单信息和扫码支付地址 'out_trade_no' => $_POST['out_trade_no'], 'total_fee' => $_POST['total_fee'], 'code_url' => $responseArr['code_url'] ); }else{ throw new \WxPayException("签名验证失败!"); } }else{ //$responseArr['return_code'] == 'FAIL' throw new \WxPayException("响应失败!"); foreach($responseArr as $key => $val){ echo $key.': '.$val.'
'; } } $this->assign('returnData', $returnData); $this->display('Order/wxpay_native'); } //微信支付同步通知 public function wxpayReturn(){ $payResult = array( 'order_no' => htmlspecialchars($_GET['out_trade_no']), 'status' => $_GET['status'], 'pay_type' => '微信支付', 'pay_amount' => $_GET['total_fee'] ); if($payResult['status'] == 'success'){ //支付完成 M('order')->where('`order_sn`="'.$payResult['order_no'].'" AND `pay_status`=0')->setField('pay_status', 1); $crowd = M('order')->alias('o')->where('(o.`is_crowd`<>0 OR o.`is_cab`<>0) AND o.`order_sn`="'.$payResult['order_no'].'"')->join('`oph_order_goods` AS og ON og.`order_id`=o.`id`','left')->join('`oph_crowd` AS c ON (c.`id`=o.`is_crowd` OR c.`id`=o.`is_cab`)','left')->field('og.`goods_id`,og.`number`,og.`box`,o.`id` oid,o.`is_crowd`,o.`is_cab`,c.*')->find(); // var_dump($crowd);exit; if(!$_COOKIE[$payResult['order_no']]){ setcookie($payResult['order_no'],1); if ($crowd) { $upNum['nownum'] = $crowd['nownum'] + $crowd['number']; $myCrowd = array(); M()->startTrans(); if ($crowd['is_crowd']) { $res = M('crowd')->where('id='.$crowd['is_crowd'])->setField($upNum); $myCrowd['cid'] = $crowd['is_crowd']; }else{ $res = M('crowd')->where('id='.$crowd['is_cab'])->setField($upNum); $myCrowd['cid'] = $crowd['is_cab']; } $myCrowd['myprice'] = $payResult['pay_amount']; $myCrowd['uid'] = $_SESSION['user']['uid']; $myCrowd['mobile'] = $_SESSION['user']['mobile']; $myCrowd['num'] = $crowd['number']; $order['total'] = $myCrowd['num']; $myCrowd['create_time'] = time(); $myCrowd['oid'] = $crowd['oid']; if ($res) { M('crowd_join')->add($myCrowd); M()->commit(); }else{ M()->rollback(); } } $order['total'] = M('order')->alias('o')->where('o.`order_sn`="'.$payResult['order_no'].'" AND og.`goods_id`<>0')->join('oph_order_goods AS og ON og.`order_id`=o.`id`')->sum('number'); $jiage = $payResult['pay_amount']; D('member')->upLevel($jiage,$order['total']); } $payResult['msg'] = '付款完成!我们将第一时间安排发货!'; //发送模板消息 $access_token = $this->getWxAccessToken(); $getOpenid = $this->getOpenid(); //模板消息 $template=array( 'touser'=>$getOpenid, 'template_id'=>"t2j4tatkUhqCvsTVr290P04rXNWg3WnMWXOHiLW6tSg", 'url'=>"http://m.tthwine.com/Member/order", 'topcolor'=>"#7B68EE", 'data'=>array( 'first' => array( 'value' => '尊敬的用户,您好,欢迎购买我们的产品', 'color' => '#FF0000' ), 'keyword1' => array( 'value' => $payResult['pay_amount'].元, 'color' => '#000' ), 'keyword2' => array( 'value' => $payResult['order_no'], 'color' => '#000000' ), 'remark' => array( 'value' => '广州十二星祝您节日快乐!', 'color' => '#FF0000' ) ) ); $json_template=json_encode($template); $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=".$access_token; http_request($url,urldecode($json_template)); }else if($payResult['status'] == 'failure'){ //支付失败或出错 $payResult['msg'] = '支付失败,请到我的订单重新发起支付!'; } $this->assign('payResult', $payResult); //print_r($payResult); $this->display('Order/result'); } //微信支付异步通知 public function wxpayNotify(){ $notifyXml = $GLOBALS['HTTP_RAW_POST_DATA']; //获取返回的xml数据 $tools = new \WxPayFunction(); $notifyArr = $tools->xmlToArr($notifyXml); if($notifyArr['return_code'] == 'SUCCESS'){ //判断通知成功 if($notifyArr['result_code'] == 'SUCCESS' && $tools->createSign($notifyArr, self::MCH_KEY) == $notifyArr['sign']){ //支付成功和验证签名 $pay_status = M('order')->where('`order_sn`="'.$notifyArr['out_trade_no'].'"')->getField('pay_status'); if(self::MCH_ID == $notifyArr['mch_id'] && $pay_status != 1){ $data = array( 'pay_type' => 3, 'pay_status' => 1, 'payreal_amount' => floatval($notifyArr['total_fee']/100), //单位为分,换算成元 'pay_sn' => $notifyArr['transaction_id'], 'pay_time' => strtotime($notifyArr['time_end']) ); $result = M('order')->where('order_sn="'.$notifyArr['out_trade_no'].'"')->save($data); } } //写入日志文件(订单编号,微信交易号,交易状态,交易金额,微信用户openId,付款时间) file_put_contents('./Data/paylog/wxpaylog.txt', $notifyArr['out_trade_no'].' '.$data['pay_sn'].' '.$notifyArr['result_code'].' '.$data['payreal_amount'].' '.$notifyArr['openid'].' '.$data['pay_time'].' 微信支付'."\r\n", FILE_APPEND); $responseXml = $tools->arrToXml(array('return_code'=>'SUCCESS', 'return_msg'=>'OK')); echo $responseXml; }else{ return false; } } //分享接口 public function sharOne(){ //获取商品id $shopId = I('get.sid'); $getgm = I('get.gm'); $jsapi_ticket = $this->getJsApiTicket(); $timestamp = time(); $noncestr = $this->getRandCode(); // 注意 URL 一定要动态获取,不能 hardcode. $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; $signature = "jsapi_ticket=$jsapi_ticket&noncestr=$noncestr×tamp=$timestamp&url=$url"; $signature = sha1( $signature ); if($shopId > 0){ //获取用户微信getOpenid $getOpenid = $this->getOpenid(); $getOpenid = str_replace('-','',$getOpenid); //获取上级分享的用户openid if($upOpenid = I('get.u')) $this->assign('upOpenid',$upOpenid); $newUrl = $protocol.$_SERVER[HTTP_HOST].'/Wechat/sharOne/u/'.$getOpenid.'/sid/'.$shopId.'.html'; $this->assign('shopId',$shopId); $this->assign('getOpenid',$getOpenid); $this->assign('newUrl',$newUrl); } //获取地区三级联动 $province = M('region_china')->where('pid=0')->getField('id,region_name'); $showVive = 'sharOne'.$shopId; $this->assign('getgm',$getgm); $this->assign('province',$province); $this->assign('timestamp',$timestamp); $this->assign('noncestr',$noncestr); $this->assign('signature',$signature); $this->assign('sharOnesid',$shopId); $this->display($showVive); } //获取随机码 public function getRandCode(){ $array = array( 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z', 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','d','u','v','w','x','y','z', '0','1','2','3','4','5','6','7','8','9' ); $tmpstr = ''; $max = count($array); for($i =1; $i <= 16; $i++){ $key = rand(0,$max-1); $tmpstr .= $array[$key]; } return $tmpstr; } public function getJsApiTicket(){ //如果session中保存有效的jsapi_ticket $access_token = $this->getWxAccessToken(); if($_SESSION['jsapi_ticket_expire_time'] > time()){ $jsapi_ticket = S('jsapi_ticket'); }else{ $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$access_token&type=jsapi"; $data = webCurl($url); $res = json_decode($data,true); $jsapi_ticket = $res['ticket']; S('jsapi_ticket',$jsapi_ticket,7000); $_SESSION['jsapi_ticket_expire_time'] = time()+7000; } return $jsapi_ticket; } } ?>

 

转载于:https://www.cnblogs.com/jierong12/p/9888294.html

你可能感兴趣的:(微信内置浏览器支付)