baker95935

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

<?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 = \'<xml>
         <appid>\'.$appid.\'</appid>
         <body>\'.$body.\'</body>
         <mch_id>\'.$mch_id.\'</mch_id>
         <nonce_str>\'.$nonce_str.\'</nonce_str>
         <notify_url>\'.$notify_url.\'</notify_url>
         <openid>\'.$openid.\'</openid>
         <out_trade_no>\'.$out_trade_no.\'</out_trade_no>
         <spbill_create_ip>\'.$spbill_create_ip.\'</spbill_create_ip>
         <total_fee>\'.$total_fee.\'</total_fee>
         <trade_type>\'.$trade_type.\'</trade_type>
         <sign>\'.$sign.\'</sign>
        </xml>\';
    
    //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;
    }
     
}

 

分类:

技术点:

相关文章: