thinkcmf+jsapi 实现微信支付

首先从小程序端接收订单号、金额等参数,然后后台进行统一下单,把微信支付的订单号返回,在把订单号发送给前台,前台拉起支付,返回参数后更改支付状态。。。

回调

 public function notify() {
 $wechat=Db::name('wechat')->where('status',1)->find();

        //$post = $GLOBALS['HTTP_RAW_POST_DATA']; 
        $post = file_get_contents("php://input"); //接受POST数据XML个数


        // $order_over_test['openid']=$post;
        // Db::name('order_over')->insert($order_over_test);

        $post_data  = $this->xml_to_array($post);
       
     


        //输出订单号
        $order_sn = $post_data['out_trade_no'];

        $order_over['order_sn']=$order_sn;
        $order_over['money']=$post_data['total_fee'];
        $order_over['openid']=$post_data['openid'];
        $order_over['time_end']=$post_data['time_end'];

        $order_update['status']='1';

       // Db::name('order_over')->insert($order_over);

        $order_info=Db::name('order')->where('order_id',$order_sn)->find();

         if ($post_data['return_code'] == 'SUCCESS') {
         
            //判断证书是否正确
            // if ($postSign != $user_sign) {
            //     Log::write('签名不匹配');
            //     exit;
            // }
           if ($order_info['status'] != '1') {
               
               Db::name('order_over')->insert($order_over);
               $result=Db::name('order')->where('order_id', $order_sn)->update($order_update);
           }
            
             return 'success';
         
        } else {
          
            return 'error';
             //$this->error('error!');
        }
}

     public function xmlToArray($xml)
     {
         $p = xml_parser_create();
         xml_parse_into_struct($p, $xml, $vals, $index);
         xml_parser_free($p);
         $data = "";
         foreach ($index as $key => $value) {
             if ($key == 'xml' || $key == 'XML') continue;
             $tag = $vals[$value[0]]['tag'];
             $value = $vals[$value[0]]['value'];
             $data[$tag] = $value;
         }
         return $data;

     }


   public function xml_to_array($xml){
        if(!$xml){
            return false;
        }
        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $data;
    }

   public static function ToUrlParams($data)
               {
                   $buff = "";
                   foreach ($data as $k => $v)
                   {
                       if($k != "sign" && $v != "" && !is_array($v)){
                           $buff .= $k . "=" . $v . "&";
                       }
                   }

                   $buff = trim($buff, "&");
                   return $buff;
               }
         

统一下单

 public function getwxpay($orderSn,$money)
{
   // $orderSn=$orderSn;
  $body='广告投放';
   //$orderSn='HB14257311281654';
   //$money= '1';  
  $money=$money*100;
   $wechat=Db::name('wechat')->where('status',1)->find();
   $order_id=$orderSn;
   
   // $money= $money;                     //充值金额 微信支付单位为分
  
   $appid  = $wechat['appid'];    //应用APPID
   $mch_id =$wechat['mch_id'];                  //微信支付商户号
   $KEY    = $wechat['key'];                 //微信商户API密钥
   $out_trade_no = $orderSn ;//平台内部订单号
   $nonce_str = $this->rand_code();//随机字符串
  // $openid='oM0TH0nyMtlyrP_J8cOL70oLYaCw';
   $openid=session('openid');

           //获取系统的配置
         
           //$nonce_str = $this->rand_str(12);//随机字符串
           $notify_url = "http://**********************t/Wxnotify/notify";  //支付完成回调地址url,不能带参数
         
           $spbill_create_ip = get_client_ip();
           $trade_type = 'JSAPI';//交易类型 默认JSAPI

           //这里是按照顺序的 因为下面的签名是按照(字典序)顺序 排序错误 肯定出错
           $post['appid'] = $appid;
           $post['body'] = $body;
           $post['mch_id'] = $mch_id;
           $post['nonce_str'] = $nonce_str;//随机字符串
           $post['notify_url'] = $notify_url;
           $post['openid'] = $openid;
           $post['out_trade_no'] = $out_trade_no;
           $post['spbill_create_ip'] = $spbill_create_ip;//服务器终端的ip
           $post['total_fee'] = intval($money);        //总金额 最低为一分钱 必须是整数
           $post['trade_type'] = $trade_type;
           $sign = $this->MakeSign($post, $KEY);              //签名
           $this->sign = $sign;

           $post_xml = "
                   
                       $appid 
                       $mch_id
                       $nonce_str
                       $body
                       $notify_url
                       $openid
                       $out_trade_no
                       $spbill_create_ip
                       {$post["total_fee"]}
                       $trade_type
                       $sign
                   ";

           //统一下单接口prepay_id
           $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
           $xml = $this->http_request($url, $post_xml);     //POST方式请求http

           $array = $this->xml2array($xml);               //将【统一下单】api返回xml数据转换成数组,全要大写

           $array['my_sign'] = $sign;
           $array['post_xml'] = $post_xml;
           $array['source_xml'] = $xml;
           
           if ($array['RETURN_CODE'] == 'SUCCESS' && $array['RESULT_CODE'] == 'SUCCESS') {
               $time = time();
               $tmp = '';                            //临时数组用于签名
               $tmp['appId'] = $appid;
               $tmp['nonceStr'] = $nonce_str;
               $tmp['package'] = 'prepay_id=' . $array['PREPAY_ID'];
               $tmp['signType'] = 'MD5';
               $tmp['timeStamp'] = "$time";


               // $data['state'] = 1;
               $data['timeStamp'] = "$time";           //时间戳
               $data['nonceStr'] = $nonce_str;         //随机字符串
               $data['signType'] = 'MD5';              //签名算法,暂支持 MD5
               $data['package'] = 'prepay_id='.$array['PREPAY_ID'];   //统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
               $data['paySign'] = $this->MakeSign($tmp, $KEY);       //签名,具体签名方案参见微信公众号支付帮助文档;
               $data['prepay_id'] = $array['PREPAY_ID'];
               $data['out_trade_no'] = $out_trade_no;
               $data['order_id'] = $order_id;
           } else {
               // $data['statusCode'] = ;
               $data['statusMsg'] = "请求错误";
               $data['data']['RETURN_CODE'] = $array['RETURN_CODE'];
               $data['data']['RETURN_MSG'] = $array['RETURN_MSG'];
           }

         
           return $data;
       
       }
   







    public function postXmlCurl($xml,$url,$second = 30){
       $ch = curl_init();
       //设置超时
       curl_setopt($ch, CURLOPT_TIMEOUT, $second);
       curl_setopt($ch,CURLOPT_URL, $url);
       curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
       curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
       //设置header
       curl_setopt($ch, CURLOPT_HEADER, FALSE);
       //要求结果为字符串且输出到屏幕上
       curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
       //post提交方式
       curl_setopt($ch, CURLOPT_POST, TRUE);
       curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
       //运行curl
       $data = curl_exec($ch);
       //返回结果
       if($data){
           curl_close($ch);
           return $data;
       }else{
           $error = curl_errno($ch);
           curl_close($ch);
           echo "curl出错,错误码:$error"."
"; } } //生成签名 public function MakeSign($params, $KEY) { //签名步骤一:按字典序排序数组参数 ksort($params); $string = $this->ToUrlParams($params); //参数进行拼接key=value&k=v //签名步骤二:在string后加入KEY $string = $string . "&key=" . $KEY; //签名步骤三:MD5加密 $string = md5($string); //签名步骤四:所有字符转为大写 $result = strtoupper($string); return $result; } /** * 格式化参数格式化成url参数 */ public static function ToUrlParams($data) { $buff = ""; foreach ($data as $k => $v) { if($k != "sign" && $v != "" && !is_array($v)){ $buff .= $k . "=" . $v . "&"; } } $buff = trim($buff, "&"); return $buff; } //发送http请求 public function http_request($url, $data = null, $headers = array()) { $curl = curl_init(); if (count($headers) >= 1) { curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); } curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); // $zs1 = CMF_ROOT . "cert/apiclient_cert.pem"; $zs2 = CMF_ROOT . "cert/apiclient_key.pem"; // curl_setopt ( $curl, CURLOPT_SSLCERT, $zs1 ); // curl_setopt ( $curl, CURLOPT_SSLKEY, $zs2 ); //设置证书 //使用证书:cert 与 key 分别属于两个.pem文件 curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'PEM'); curl_setopt($curl, CURLOPT_SSLCERT, $zs1); curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM'); curl_setopt($curl, CURLOPT_SSLKEY, $zs2); 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; } //获取xml里面数据,转换成array public function xml2array($xml) { $p = xml_parser_create(); xml_parse_into_struct($p, $xml, $vals, $index); xml_parser_free($p); $data = ""; foreach ($index as $key => $value) { if ($key == 'xml' || $key == 'XML') continue; $tag = $vals[$value[0]]['tag']; $value = $vals[$value[0]]['value']; $data[$tag] = $value; } return $data; } //随机字符串 public function rand_code($length = 16) { $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; $str = ""; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } public function ToXml($data=array()) { if(!is_array($data) || count($data) <= 0) { return '数组异常'; } $xml = ""; foreach ($data as $key=>$val) { if (is_numeric($val)){ $xml.="<".$key.">".$val.""; }else{ $xml.="<".$key.">"; } } $xml.=""; return $xml; }

前台页面拉起微信支付




  订单支付 {$site_info.site_name|default=''}
    
    
 









 


核实订单

订单号 {$order_info['order_id']}
金额 {$order_info['money']}¥

你可能感兴趣的:(php)