php--tp5小程序支付

class Payment extends Apiclass
{
    public $config;
	
    function __construct()
    {
        //查询小程序配置信息
        $this->config=Db::name('payinfo')->where('type',1)->find();
    }

    //支付
    public function pay()
    {
    	//接收小程序端传的参数
        $id = input('id');
        $user_id = input('user_id');
        $goods_name = input('goods_name');
        //查询订单信息
        $order=Db::name('order')->where(['id'=>$id,'user_id'=>$user_id])->find();
        //获取openid
        $user=Db::name('users')->where('id',$user_id)->find();
        if (empty($user['open_id'])) {
            return $this->msg(false,'openid不存在');
        }
        $openid=$user['open_id'];
        $param=[
            'appid'=>$this->config['appid'], //小程序appid
            'mch_id'=>$this->config['mch_id'], //商户id
            'nonce_str'=>$this->getRand(20,true), //随机字符串
            'body'=>$goods_name, //商品名称
            'out_trade_no'=>$order['order_no'], //订单号
            'total_fee'=> 100, //支付金额(分)
            'spbill_create_ip'=>$this->get_client_ip(), //用户ip
            'notify_url'=>$this->config['notify_url'], //支付回调地址
            'trade_type'=>'JSAPI', //
            'openid'=>$openid //用户的openid
        ];
        //生成签名
        $sign=$this->makeSign($param,$this->config['mchkey']);
        $param['sign']=$sign;
        try{
        	//将数组转换成xml数据
            $xml=$this->ToXml($param);
        }catch (\Exception $e){
            return $this->msg('false',$e->getMessage());
        }
        //微信小程序支付接口地址
        $url="https://api.mch.weixin.qq.com/pay/unifiedorder";
        //请求微信支付接口
        $getXml=$this->curl_post($url,$xml,false);
        //将微信返回值转换成数组
        $getArr=$this->FromXml($getXml);
        if ($getArr['return_code']=='SUCCESS'&&$getArr['result_code']=='SUCCESS') {
        	//请求成功
            $prepay_id=$getArr['prepay_id'];
            $data['appId']=$this->config['appid'];
            $time = time();
            $data['timeStamp']="{$time}";
            $data['nonceStr']=$this->getRand(20,true);
            $data['package']="prepay_id=".$prepay_id;
            $data['signType']='MD5';
            $data['paySign']=$this->makeSign($data,$this->config['mchkey']);
        } else if($getArr['return_code']=='SUCCESS'&&$getArr['result_code']=='FAIL') {
            $data['code']=$getArr['err_code'];
            $data['msg']=$getArr['err_code_des'];
        } else {
            $data['code']=$getArr['return_code'];
            $data['msg']=$getArr['return_msg'];
        }
        return $this->msg('true','请求结果',$data);
    }

    //支付成功回调
    public function paysuccess()
    {
        //接收微信返回的数据数据,返回的xml格式
        $xmlData = file_get_contents('php://input');
		//下面四行代码可以将支付返回的xml数据写入一个文件,从文件中复制xml代码,赋值给 $xmlData 变量,就可以重复测试此接口,不用每次测试都执行支付接口
		// $myfile = fopen(__DIR__."newfile.txt", "w") or die("Unable to open file!");
		// $txt = $xmlData;
		// fwrite($myfile, $txt);
		// fclose($myfile);

        //将xml格式转换为数组
        $data = $this->FromXmls($xmlData);
        if ($data[0] == 'false') {
            return;
        }
        //记录一下,返回回来的签名,生成签名的时候,必须剔除sign字段。
        $data = $data[1];
        if (!isset($data['sign'])) {
            return;
        }
        $sign = $data['sign'];
        unset($data['sign']);

        if($sign == $this->makeSign($data,$this->config['mchkey'])){
            //签名验证成功后
            if ($data['result_code'] == 'SUCCESS') {
            	//支付成功
                $orderId = $data['out_trade_no'];
                Db::startTrans();
                try {
                   //在这里执行支付成功后的逻辑
                   Db::commit();
                } catch (\Exception $e) {
                    Db::rollback();
                }
            }else {
            	//支付失败,输出错误信息
                return json_encode(['false',$data['return_msg']]);
            }
        } else {
            return json_encode(['true','签名失败!']);
        }
    }
	//将xml转换成数组
    private function FromXmls($xml)
    {
        if(!$xml){
            return ['false','xml数据异常!'];
        }
        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return ['true',$data];
    }

    //将数组转换成xml数据
    public function ToXml($data)
    {
        if(!is_array($data)
            || count($data) <= 0)
        {
            throw new Exception("数组数据异常!");
        }

        $xml = "<xml>";
        foreach ($data as $key=>$val)
        {
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }
    
    //获取随机字符串
    protected function getRand( $length = 6,$isAll = false) 
    {
		
        if ($isAll) {
            $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        } else {
            $chars = '0123456789';
        }
        $randStr = '';
        for ( $i = 0; $i < $length; $i++ ) 
        {
            $randStr .= $chars[ mt_rand(0, strlen($chars) - 1) ];
        }
        return $randStr;
    }
    //生成签名
    protected function makeSign($param,$key)
    {
        ksort($param);
        $string=$this->toUrlParams($param);
        $string=$string.'&key='.$key;
        $string=md5($string);
        $result=strtoupper($string);
        return $result;
    }

    //拼接字符串
    protected function toUrlParams($param)
    {
        $string='';
        if (!empty($param)) {
            $array=array();
            foreach ($param as $key=>$v) {
                $array[]=$key.'='.$v;
            }
            $string=implode('&',$array);
        }
        return $string;
    }
    //获取哦用户的ip地址
    protected function get_client_ip(){
        if(!empty($_SERVER["HTTP_CLIENT_IP"]))
        {
            $cip = $_SERVER["HTTP_CLIENT_IP"];
        }
        else if(!empty($_SERVER["HTTP_X_FORWARDED_FOR"]))
        {
            $cip = $_SERVER["HTTP_X_FORWARDED_FOR"];
        }
        else if(!empty($_SERVER["REMOTE_ADDR"]))
        {
            $cip = $_SERVER["REMOTE_ADDR"];
        }
        else
        {
            $cip = '';
        }
        preg_match("/[\d\.]{7,15}/", $cip, $cips);
        $cip = isset($cips[0]) ? $cips[0] : '127.0.0.1';
        unset($cips);
        return $cip;
    }
    //curl请求模块
	protected function curl_post($url,$post_data,$isTrue = true)
    {
        if (is_array($post_data)) {
            $postData = http_build_query($post_data);
        }
        $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, $post_data);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }
    //统一返回
	public function msg($code,$msg,$data = [])
    {
        return ['code'=>$code,'msg'=>$msg,'data'=>$data];
    }

小程序端

 wx.requestPayment(
{
  "timeStamp":res.data.data.timeStamp,
  "nonceStr": res.data.data.nonceStr,
  "package": res.data.data.package,
  "signType": res.data.data.signType,
  "paySign": res.data.data.paySign,
  "success":function(res){
    wx.showModal({
      title: '提示',
      content: '支付成功',
      confirmText:'立即查看',
      success: function (res) {
        if (res.confirm) {  
          wx.navigateTo({
            url: '/pages/wode/quan'
          })
        }
      }
    })
  },
  "fail":function(res){},
  "complete":function(res){}
})
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值