thinkPHP3 微信Native扫码支付

微信支付主要分为四大部分:
1.html 页面用来展示支付二维码
2.controller 引入微信支付api及支付代码 (微信Native支付SDK与DEMO下载地址)
3.将微信支付api放到thinkphp的Vendor目录下

(将/example目录下WxPay.Config.php文件中的APPID,MCHID,KEY,APPSECRET替换成自己公众平台和商户号的)

4.在微信公众平台和微信商户平台配置相关域名及回调地址

1.html页面部分

<div class="col-sm-4">
	//生成二维码类在微信下载的demo中/example/phpqrcode/phpqrcode.php
	<img alt="微信扫码支付" src="<?php echo $_SERVER['REQUEST_SCHEME'] ?>://<?php echo $_SERVER['SERVER_NAME'] ?>/index.php/Home/Wxpay/qrcode?data=<?php echo urlencode($url);?>" style="width:220px;text-align: center;"/>
</div>

2.controller部分

<?php

namespace Home\Controller;
use Think\Controller;
class WxpayController extends Controller {
	private $ordObj;
	public function __construct() {
        parent::__construct();
        //引入Vendor下面的微信支付类
        header("Content-type:text/html;charset=utf-8");
        require_once VENDOR_PATH.'/Wxpay/lib/WxPay.Api.php';
        require_once VENDOR_PATH.'/Wxpay/lib/WxPay.Notify.php';
        require_once VENDOR_PATH.'/Wxpay/lib/WxPay.Data.php';
        require_once VENDOR_PATH.'/Wxpay/example/WxPay.Config.php';
        require_once VENDOR_PATH.'/Wxpay/example/phpqrcode/phpqrcode.php';
        $this->ordObj=D('order');
    }

    //生成二维码
    public function qrcode(){
        $url = urldecode($_GET["data"]);
        if(substr($url, 0, 6) == "weixin"){
            \QRcode::png($url);
        }else{
             header('HTTP/1.1 404 Not Found');
        }
        exit();
    }


	/**
	 * 调起微信支付
	 * @param int $id 订单id
	 * 订单验证成功后调起支付
	 */
	public function wxpay($id){
		layout(false);
		$whe = array('id'=>$id,);
		$data = $this->ordObj->where($whe)->find();
		/**
		此处写支付前的逻辑验证代码
		*/
		$param =array(
			'out_trade_no'=>$data['order_id'], //订单号
			'price'=>$data['order_money'], //订单金额
			'subject'=>C('configs.preliminary_title'), // 商品名称标题
		);
		
		//调用微信支付代码
		$this->wxpays($param);

	}

	
	public function wxpays($param){

        $input = new \WxPayUnifiedOrder();
        $input->SetBody($param['subject']);
        $input->SetAttach("test");
        $input->SetOut_trade_no($param['out_trade_no']);
        $input->SetTotal_fee($param['price']*100);
        $input->SetTime_start(date("YmdHis"));
        $input->SetTime_expire(date("YmdHis", time() + 600));
        $input->SetGoods_tag("test");
        $input->SetNotify_url($_SERVER['REQUEST_SCHEME']."://".$_SERVER['SERVER_NAME']."/index.php/Home/Wxpay/notify");
        $input->SetTrade_type("NATIVE");
        $input->SetProduct_id($param['out_trade_no']);

        $result = $this->GetPayUrl($input);
        if( $result['result_code'] == 'FAIL' ){
        	redirect(U("Home/Signup/orderlistx") ,3, $result['err_code_des']);
        	exit();
        }
        $url = $result["code_url"];
        $this -> assign('url',$url);
        $this -> assign('out_trade_no',$param['out_trade_no']);
        $this -> assign('price',$param['price']);
        $this -> assign('preliminary_title',C('configs.preliminary_title'));
        $this -> display();
	}

	/**
     * 微信回调接口
     * logPays是自己封装记录log的方法
     */
    public function notify(){
        //获取接口数据,如果$_REQUEST拿不到数据,则使用file_get_contents函数获取
	    $post = $_REQUEST;
	    if ( isset($post) || empty($post) ) {
	        $post = file_get_contents("php://input");
	    }
	    libxml_disable_entity_loader(true); //禁止引用外部xml实体
 
	    $data = simplexml_load_string($post, 'SimpleXMLElement', LIBXML_NOCDATA);//XML转数组

	    $data = json_encode($data);
        $json = '微信同步回调: '. $data;
        logPays($json,'Wxpaylog.json'); // json日志
        $data = json_decode($data,true);
        //TODO 1、进行参数校验
        if(!array_key_exists("return_code", $data) && $data['return_code'] != "SUCCESS") {
            //TODO失败,不是支付成功的通知
            //如果有需要可以做失败时候的一些清理处理,并且做一些监控
            $json = '微信同步回调: 订单状态异常!';
        	logPays($json,'Wxpaylog.json'); // json日志
            redirect(U("Home/Signup/orderlistx") ,3, '订单状态异常...');
        	exit();
        }
        if(!array_key_exists("transaction_id", $data)){
        	$json = '微信同步回调: 订单号异常!';
        	logPays($json,'Wxpaylog.json'); // json日志
            redirect(U("Home/Signup/orderlistx") ,3, '订单号异常...');
            exit();
        }
        // //TODO 2、进行签名验证
        $config = new \WxPayConfig();
        try {
        	$WxPayResults = new \WxPayResults();
            $setsign = $WxPayResults->SetSign($config);
            $checkResult = $WxPayResults->CheckSign($config);
            if($checkResult == false){
            	$json = '微信同步回调: 签名错误!';
        		logPays($json,'Wxpaylog.json'); // json日志
                //签名错误
                redirect(U("Home/Signup/orderlistx") ,3, '签名错误...');
        		exit();
            }
        } catch(Exception $e) {
            redirect(U("Home/Signup/orderlistx") ,3, $e);
        	exit();
        }

        // //TODO 3、处理业务逻辑
        //查询订单,判断订单真实性
        $res = $this->Queryorder($data["transaction_id"]);
        if(!$res){
        	$json = '微信同步回调: 订单查询失败!';
        	logPays($json,'Wxpaylog.json'); // json日志
            redirect(U("Home/Signup/orderlistx") ,3, '订单查询失败...');
            exit();
        }else{
        	// 查询成功
        	$json = '微信同步回调: 查询成功!';
        	logPays($json,'Wxpaylog.json'); // json日志
        	$whe = array('order_id'=>$res['out_trade_no'],);
			$data1 = $this->ordObj->where($whe)->find();
        	// 支付成功
			if( $res['trade_state'] == 'SUCCESS' && $data1['order_money']*100 == $res['total_fee'] ){ 
				$json = '微信同步回调: 支付成功!';
        		logPays($json,'Wxpaylog.json'); // json日志
				// 交易支付成功,同步回调完成,处理订单
				$out_trade_no = $res['out_trade_no']; // 商户订单号
				$trade_no = $res['transaction_id']; //微信交易号
				$trade_status = $res['trade_state'];//交易状态
				$result = $this->ordObj->pay_success($out_trade_no,$trade_no,2);
				redirect(U("Home/User/paysuccess"), 1, '支付成功!');
			}else{
				$json = '微信同步回调: 支付失败或金额错误!';
        		logPays($json,'Wxpaylog.json'); // json日志
			}
        }

        exit();

    }

    //查询订单
    public function Queryorder($transaction_id)
    {
        $input = new \WxPayOrderQuery();
        $input->SetTransaction_id($transaction_id);

        $config = new \WxPayConfig();
        $result = \WxPayApi::orderQuery($config, $input);
        if( array_key_exists("return_code", $result) && array_key_exists("result_code", $result) && $result["return_code"] == "SUCCESS" && $result["result_code"] == "SUCCESS" )
        {
            return $result;
        }
        return false;
    }

    /**
     * 
     * 生成直接支付url,支付url有效期为2小时,模式二
     * @param UnifiedOrderInput $input
     */
    public function GetPayUrl($input)
    {
        if($input->GetTrade_type() == "NATIVE")
        {
            try{
                $config = new \WxPayConfig();
                $result = \WxPayApi::unifiedOrder($config, $input);
                return $result;
            } catch(Exception $e) {
                Log::ERROR(json_encode($e));
            }
        }
        return false;
    }

    
    /**
     * 
     * 参数数组转换为url参数
     * @param array $urlObj
     */
    private function ToUrlParams($urlObj)
    {
        $buff = "";
        foreach ($urlObj as $k => $v)
        {
            $buff .= $k . "=" . $v . "&";
        }
        
        $buff = trim($buff, "&");
        return $buff;
    }


    public function getstatus(){
    	$get = I('get.');
    	$whe = array('order_id'=>$get['out_trade_no'],);
		$data = $this->ordObj->where($whe)->find();
		if( $data['order_state'] == 1 ){
			echo 1;//已支付
		}else{
			echo 0;//待支付
		}
    	exit();
    }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值