Thinkphp 5.0版本整合微信扫码支付接口,含模型验证异步通知等完整实例

2018-1-22 0 PHP代码 蓝优

先创建模型(Pay.php):

<?php
namespace app\index\model;
use think\Validate;
use think\Log;
class Pay extends \think\Model
{
	private function _weixin_config(){//微信支付公共配置函数
		define('WXPAY_APPID', "");//微信公众号APPID
		define('WXPAY_MCHID', "");//微信商户号MCHID
		define('WXPAY_KEY', "");//微信商户自定义32位KEY
		define('WXPAY_APPSECRET', "");//微信公众号appsecret
		vendor('wxpay.WxPay_Api');
		vendor('wxpay.WxPay_NativePay');
	}

	public function weixin($data=[])
	{//发起微信支付,如果成功,返回微信支付字符串,否则范围错误信息
		$validate = new Validate([
			['body','require','请输入订单描述'],
			['attach','require','请输入订单标题'],
			['out_trade_no','require|alphaNum','订单编号输入错误|订单编号输入错误'],
			['total_fee','require|number|gt:0','金额输入错误|金额输入错误|金额输入错误'],
			['notify_url','require','异步通知地址不为空'],
			['trade_type','require|in:JSAPI,NATIVE,APP','交易类型错误'],
		]);
		if (!$validate->check($data)) {
			return ['code'=>0,'msg'=>$validate->getError()];
		}
		$this->_weixin_config();
		$notify = new \NativePay();
		$input = new \WxPayUnifiedOrder();
		$input->SetBody($data['body']);
		$input->SetAttach($data['attach']);
		$input->SetOut_trade_no($data['out_trade_no']);
		$input->SetTotal_fee($data['total_fee']);
		$input->SetTime_start($data['time_start']);
		$input->SetTime_expire($data['time_expire']);
		$input->SetGoods_tag($data['goods_tag']);
		$input->SetNotify_url($data['notify_url']);
		$input->SetTrade_type($data['trade_type']);
		$input->SetProduct_id($data['product_id']);
		$result = $notify->GetPayUrl($input);
		if($result['return_code'] != 'SUCCESS'){
			return ['code'=>0,'msg'=> $result['return_msg']];
		}
		if($result['result_code'] != 'SUCCESS'){
			return ['code'=>0,'msg'=> $result['err_code_des']];
		}
		return ['code'=>1,'msg'=>$result["code_url"]];
	}

	public function notify_weixin($data='')
	{//微信支付异步通知
		if(!$data){
			return false;
		}
		$this->_weixin_config();
    	$doc = new \DOMDocument();
		$doc->loadXML($data);
		$out_trade_no = $doc->getElementsByTagName("out_trade_no")->item(0)->nodeValue;
		$transaction_id = $doc->getElementsByTagName("transaction_id")->item(0)->nodeValue;
		$openid = $doc->getElementsByTagName("openid")->item(0)->nodeValue;
		$input = new \WxPayOrderQuery();
		$input->SetTransaction_id($transaction_id);
		$result = \WxPayApi::orderQuery($input);
		if(array_key_exists("return_code", $result) && array_key_exists("result_code", $result) && $result["return_code"] == "SUCCESS" && $result["result_code"] == "SUCCESS"){
			// 处理支付成功后的逻辑业务
			Log::init([
				'type'  =>  'File',
				'path'  =>  LOG_PATH.'../paylog/'
			]);
			Log::write($result,'log');
			return 'SUCCESS';
		}
		return false;
	}
}
?>
创建好模型后,在控制器(Index.php)调用上面模型来实现微信支付功能:
<?php
namespace app\index\controller;
use app\index\model\Pay;
error_reporting(0);
class Index extends \think\Controller
{

	public function weixin()
	{//发起微信支付,得到微信支付字符串,直接输出字符串,在模板中通过jquery生成支付二维码
		if(request()->isPost()){
			$Pay = new Pay;
			$result = $Pay->weixin([
				'body' => input('post.body/s','','trim,strip_tags'),
				'attach' => input('post.attach/s','','trim,strip_tags'),
				'out_trade_no' => input('post.orderid/s','','trim,strip_tags'),
				'total_fee' => input('post.total_fee/f',0,'trim,strip_tags')*100,//订单金额,单位为分,如果你的订单是100元那么此处应该为 100*100
				'time_start' => date("YmdHis"),//交易开始时间
				'time_expire' => date("YmdHis", time() + 604800),//一周过期
				'goods_tag' => '在线充值余额',
				'notify_url' => request()->domain().url('index/index/weixin_notify'),
				'trade_type' => 'NATIVE',
				'product_id' => rand(1,999999),
			]);
			if(!$result['code']){
				return $this->error($result['msg']);
			}
			return $this->success($result['msg']);
		}
		$this->view->orderid = date("YmdHis").rand(100000,999999);
		return $this->fetch();
	}

	public function weixin_notify()
	{//微信订单异步通知
		$notify_data = file_get_contents("php://input");//获取由微信传来的数据
		if(!$notify_data){
			$notify_data = $GLOBALS['HTTP_RAW_POST_DATA'] ?: '';//以防上面函数获取到的内容为空
		}
		if(!$notify_data){
			exit('');
		}
		$Pay = new Pay;
		$result = $Pay->notify_weixin($notify_data);//调用模型中的异步通知函数
		exit($result);
	}
}

在控制器中我们并没有直接生成二维码,而是把微信支付的字符串直接输出,因此我们在模板需要通过jquery.qrcode.js来将微信支付字符串转化为二维码,并展示给用户(weixin.html):

<!doctype html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
	<title>微信支付测试</title>
    <base href="{:request()->domain()}" />
    <link href="static/css/bootstrap.css" rel="stylesheet">
    <link href="static/css/common.css" rel="stylesheet">
    <link href="static/css/admin.css" rel="stylesheet">
	<script src="static/js/jquery-1.12.0.min.js"></script>
    <script src="static/js/bootstrap.min.js"></script>
    <script src="static/js/jquery.qrcode.min.js"></script>
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
</head>
<body>
<div class="container">
	<div class="panel panel-default">
		<div class="panel-heading">
			<strong>微信支付测试</strong>
		</div>
		<div class="panel-body">
			<form class="form-horizontal weixin-form" method="post" action="{:url('index/index/weixin')}">
				<div class="form-group">
					<label class="col-sm-2 control-label">订单编号</label>
					<div class="col-sm-10">
						<input type="text" class="form-control" name="orderid" value="{$orderid}" readonly>
					</div>
				</div>
				<div class="form-group">
					<label class="col-sm-2 control-label">支付标题</label>
					<div class="col-sm-10">
						<input type="text" class="form-control" name="attach" value="账户余额充值">
					</div>
				</div>
				<div class="form-group">
					<label class="col-sm-2 control-label">支付描述</label>
					<div class="col-sm-10">
						<input type="text" class="form-control" name="body" value="在线充值金额到账户余额">
					</div>
				</div>
				<div class="form-group">
					<label class="col-sm-2 control-label">支付金额</label>
					<div class="col-sm-10">
						<input type="text" class="form-control" name="total_fee" value="0.01">
					</div>
				</div>
				<div class="form-group">
					<div class="col-sm-offset-2 col-sm-10">
						<button type="submit" class="btn btn-success">立即支付</button>
					</div>
				</div>
			</form>
		</div>
		<div class="panel-footer">&nbsp;</div>
	</div>
</div>
<script>
	$(function(){
		$('.weixin-form').submit(function(){
			var $this = $(this);
			if(!$this.hasClass('lock-form')){
				$this.addClass('lock-form');//锁定表单
				var formData = new FormData($this[0]);
				$.ajax({
					url:$this.attr("action"),
					type:'POST',
					data:formData,
					dataType:'json',
					cache: false,
					contentType: false,
					processData: false,
					success:function(s){
						$this.removeClass('lock-form');//解锁表单
						if(s.code != 1){
							$('.panel-footer').html(s.msg);
							return false;
						}
						if(!s.msg){
							$('.panel-footer').html('二维码生成失败,请重新提交!');
							return false;
						}
						var html = '<div class="modal-header"><a class="close" data-dismiss="modal" aria-label="Close" href="javascript:;"><span aria-hidden="true">&times;</span></a><h4 class="modal-title">微信支付</h4></div>';
						html += '<div class="modal-body weixin-qrcode text-center"></div>';
						html += '<div class="modal-footer"><p class="text-center">请使用微信扫描二维码完成支付</p></div>';
						if($('.ajax-form-modal').length > 0){
							content = $('.ajax-form-modal .modal-content');
						}else{
							fade = $('<div></div>').addClass('modal fade ajax-form-modal').appendTo('body');
							dialog = $('<div></div>').addClass('modal-dialog').appendTo(fade);
							content = $('<div></div>').addClass('modal-content').appendTo(dialog);
						}
						content.html(html);
						$('.weixin-qrcode').qrcode({width:300,height: 300,text: s.msg});
						$('.ajax-form-modal').modal('show');
						return false;
					}
				});
			}
			return false;
		});
	});
</script>
</body>
</html>
关于模板内容这里不做过多解释,如果不明白请下载下方DEMO文件查看(访问:域名/index/index/weixin)
由于异步通知需要在公网内执行,因此请将代码上传至服务器上测试

特别注意事项:
微信支付中需要提供签名文件,apiclient_cert.pem 和 apiclient_key.pem,这两个文件在vendor\wxpay目录下,需替换成对于微信商户的密钥文件才能成功调用微信支付。



附件信息  密码: 4ne7 来源: 蓝奏 声明: 本站所有资源都经过安全检测,请放心下载!
标签: 转载 代码整理 整站源码
版权声明:若无特殊注明,本文皆《蓝优》原创,转载请保留文章出处。
本文链接:Thinkphp 5.0版本整合微信扫码支付接口,含模型验证异步通知等完整实例 - http://www.92mo.cn/daima/101.html

发表新评论

快捷功能: