PHP小程序后端支付代码亲测可用

小程序后端支付代码亲测可用

php
namespace Home\Controller;
use Think\Controller;

class WechatpayController extends Controller 
{
    //微信支付
    public function pay()
    {
        //参数定义
        $appid='111111';
        $appsecret='1111111';
        $mch_id='1111111';
        $notify_url='https://www.123.com/index.php/Home/Wechatpay/wechatNotify/';
        
        //获取openid
        /*if(I("post.userid"))
        {  
            $infos=M('weixin_users')->find(I("post.userid"));
            $openid = $infos->openid;
        }*/
        $openid='oOnZO5Q8OBzoZYj-1CW_6c1S86zA';
        
        //支付相关设置
        //$fee = I("post.total_fee");
        $fee = 0.01;//举例支付0.01
        $body ='test';
        $nonce_str=$this->nonce_str();//随机字符串
 
        $out_trade_no = $this->order_number();//商户订单号
        $spbill_create_ip = '47.105.151.242';//服务器的ip【自己填写】;
        $total_fee =$fee*100;// 微信支付单位是分,所以这里需要*100
        $trade_type = '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'] = $total_fee;//总金额 
        $post['trade_type'] = $trade_type;
        
        
        //插入微信支付表
        $pay=M('weixin_pay');
        $count=$pay->where("out_trade_no='".$out_trade_no."'")->count();
 
        $sign = $this->sign($post);//签名
 
        if($count==0)
        {
            $data=array();
            $data['out_trade_no']=$out_trade_no;
            $data['status']=1;
            $data['create_time']=time();
            $data['sign']=$sign;
            $data['openid']=$openid;
            $data['total_fee']=$total_fee;
            $data['trade_type']=$trade_type;
            $data['notify_url']=$notify_url;
            $pay->add($data);
        }
        
        
        $post_xml = '
         '.$appid.'
         '.$body.'
         '.$mch_id.'
         '.$nonce_str.'
         '.$notify_url.'
         '.$openid.'
         '.$out_trade_no.'
         '.$spbill_create_ip.'
         '.$total_fee.'
         '.$trade_type.'
         '.$sign.'
        ';
    
    //var_dump($post_xml);
        //print_r($post_xml);die;
        //统一接口prepay_id
        $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        $xml = $this->http_request($url,$post_xml);
    
    
    
        $array = $this->xml($xml);//全要大写
 
    
        //print_r($array);
        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'] = 200;
            $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->sign($tmp);//签名,具体签名方案参见微信公众号支付帮助文档;
            $data['out_trade_no'] = $out_trade_no;
    
    
        }else{
            $data['state'] = 0;
            $data['text'] = "错误";
            $data['RETURN_CODE'] = $array['RETURN_CODE'];
            $data['RETURN_MSG'] = $array['RETURN_MSG'];
        }
    
        echo json_encode($data);
    }
 


    //随机32位字符串
    private function nonce_str(){
        $result = '';
        $str = 'QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz';
        
        for($i=0;$i<32;$i++){
            
            $result .= $str[rand(0,48)];
        }
        return $result;
    }
    
    
    
    //生成订单号
    private function order_number($openid){
        //date('Ymd',time()).time().rand(10,99);//18位
        return md5($openid.time().rand(10,99));//32位
    }
    
    
    
    //签名 $data要先排好顺序
    private function sign($data){
        $stringA = '';
        foreach ($data as $key=>$value){
            if(!$value) continue;
            if($stringA) $stringA .= '&'.$key."=".$value;
            else $stringA = $key."=".$value;
        }
        //echo $stringA; 
        $wx_key='1111111';//申请支付后有给予一个商户账号和密码,登陆后自己设置的key
        $stringSignTemp = $stringA.'&key='.$wx_key;
        return strtoupper(md5($stringSignTemp));
    }
    
    
    //curl请求
    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);
    
    
        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
    private function xml($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 wechatNotify()
    {
        //存储微信的回调
        $xml = file_get_contents("php://input");
        
        $arr = $this -> XmlToArr($xml);
        
        
        $out_trade_no    = $arr['out_trade_no'];
        $openid=$arr['openid'];//openid
        $sign=$arr['sign'];//校验码
        $total_fee=$arr['total_fee'];//订单金额
        $transaction_id=$arr['transaction_id'];//微信支付号
        
        
        $pay=M('weixin_pay');
        $count=$pay->where(array('out_trade_no'=>$out_trade_no))->count();
        
        
        $myfile = fopen("newfile.txt", "w") or die("Unable to open file!");
        $txt = $out_trade_no."\n";
        fwrite($myfile, $txt);
        $txt = $openid."\n";
        fwrite($myfile, $txt);
        $txt='count:'.$count;
        fwrite($myfile, $txt);
        fclose($myfile);
        
        
        if($count==1)
        {
            $info=$pay->where(array('out_trade_no'=>$out_trade_no))->field('id,openid,total_fee')->find();
            if($info['openid']==$openid && $total_fee==$info['total_fee']) {
                //更新微信支付表
                $data=array();
                $data['update_time']=time();
                $data['status']=2;
                $data['transaction_id']=$transaction_id;
                $pay->where("openid='".$openid."' and out_trade_no='".$out_trade_no."'")->save($data);
         
            }
            
        }
        echo 'success';
    }
    
    
    
    private function XmlToArr($xml)
    {    
        if($xml == '') return '';
        libxml_disable_entity_loader(true);
        $arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);        
        return $arr;
    }
     
}

 

你可能感兴趣的:(PHP小程序后端支付代码亲测可用)