A-A+

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

2017年06月10日 PHP 暂无评论 阅读 62 views 次
php category

Thinkphp 5.0版本整合微信扫码支付接口,

发起支付前:

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

点击立即支付后

同样的,我们还要先创建模型(Pay.php

  1. <?php  
  2. namespace app\index\model;  
  3. use think\Validate;  
  4. use think\Log;  
  5. class Pay extends \think\Model  
  6. {  
  7.     private function _weixin_config(){//微信支付公共配置函数  
  8.         define('WXPAY_APPID', "");//微信公众号APPID  
  9.         define('WXPAY_MCHID', "");//微信商户号MCHID  
  10.         define('WXPAY_KEY', "");//微信商户自定义32位KEY  
  11.         define('WXPAY_APPSECRET', "");//微信公众号appsecret  
  12.         vendor('wxpay.WxPay_Api');  
  13.         vendor('wxpay.WxPay_NativePay');  
  14.     }  
  15.   
  16.     public function weixin($data=[])  
  17.     {//发起微信支付,如果成功,返回微信支付字符串,否则范围错误信息  
  18.         $validate = new Validate([  
  19.             ['body','require','请输入订单描述'],  
  20.             ['attach','require','请输入订单标题'],  
  21.             ['out_trade_no','require|alphaNum','订单编号输入错误|订单编号输入错误'],  
  22.             ['total_fee','require|number|gt:0','金额输入错误|金额输入错误|金额输入错误'],  
  23.             ['notify_url','require','异步通知地址不为空'],  
  24.             ['trade_type','require|in:JSAPI,NATIVE,APP','交易类型错误'],  
  25.         ]);  
  26.         if (!$validate->check($data)) {  
  27.             return ['code'=>0,'msg'=>$validate->getError()];  
  28.         }  
  29.         $this->_weixin_config();  
  30.         $notify = new \NativePay();  
  31.         $input = new \WxPayUnifiedOrder();  
  32.         $input->SetBody($data['body']);  
  33.         $input->SetAttach($data['attach']);  
  34.         $input->SetOut_trade_no($data['out_trade_no']);  
  35.         $input->SetTotal_fee($data['total_fee']);  
  36.         $input->SetTime_start($data['time_start']);  
  37.         $input->SetTime_expire($data['time_expire']);  
  38.         $input->SetGoods_tag($data['goods_tag']);  
  39.         $input->SetNotify_url($data['notify_url']);  
  40.         $input->SetTrade_type($data['trade_type']);  
  41.         $input->SetProduct_id($data['product_id']);  
  42.         $result = $notify->GetPayUrl($input);  
  43.         if($result['return_code'] != 'SUCCESS'){  
  44.             return ['code'=>0,'msg'=> $result['return_msg']];  
  45.         }  
  46.         if($result['result_code'] != 'SUCCESS'){  
  47.             return ['code'=>0,'msg'=> $result['err_code_des']];  
  48.         }  
  49.         return ['code'=>1,'msg'=>$result["code_url"]];  
  50.     }  
  51.   
  52.     public function notify_weixin($data='')  
  53.     {//微信支付异步通知  
  54.         if(!$data){  
  55.             return false;  
  56.         }  
  57.         $this->_weixin_config();  
  58.         $doc = new \DOMDocument();  
  59.         $doc->loadXML($data);  
  60.         $out_trade_no = $doc->getElementsByTagName("out_trade_no")->item(0)->nodeValue;  
  61.         $transaction_id = $doc->getElementsByTagName("transaction_id")->item(0)->nodeValue;  
  62.         $openid = $doc->getElementsByTagName("openid")->item(0)->nodeValue;  
  63.         $input = new \WxPayOrderQuery();  
  64.         $input->SetTransaction_id($transaction_id);  
  65.         $result = \WxPayApi::orderQuery($input);  
  66.         if(array_key_exists("return_code"$result) && array_key_exists("result_code"$result) && $result["return_code"] == "SUCCESS" && $result["result_code"] == "SUCCESS"){  
  67.             // 处理支付成功后的逻辑业务  
  68.             Log::init([  
  69.                 'type'  =>  'File',  
  70.                 'path'  =>  LOG_PATH.'../paylog/'  
  71.             ]);  
  72.             Log::write($result,'log');  
  73.             return 'SUCCESS';  
  74.         }  
  75.         return false;  
  76.     }  
  77. }  
  78. ?>  

创建好模型后,接下来我们创建一个示例控制器(Index.php):

  1. <?php  
  2. namespace app\index\controller;  
  3. use app\index\model\Pay;  
  4. error_reporting(0);  
  5. class Index extends \think\Controller  
  6. {  
  7.   
  8.     public function weixin()  
  9.     {//发起微信支付,得到微信支付字符串,直接输出字符串,在模板中通过jquery生成支付二维码  
  10.         if(request()->isPost()){  
  11.             $Pay = new Pay;  
  12.             $result = $Pay->weixin([  
  13.                 'body' => input('post.body/s','','trim,strip_tags'),  
  14.                 'attach' => input('post.attach/s','','trim,strip_tags'),  
  15.                 'out_trade_no' => input('post.orderid/s','','trim,strip_tags'),  
  16.                 'total_fee' => input('post.total_fee/f',0,'trim,strip_tags')*100,//订单金额,单位为分,如果你的订单是100元那么此处应该为 100*100  
  17.                 'time_start' => date("YmdHis"),//交易开始时间  
  18.                 'time_expire' => date("YmdHis", time() + 604800),//一周过期  
  19.                 'goods_tag' => '在线充值余额',  
  20.                 'notify_url' => request()->domain().url('index/index/weixin_notify'),  
  21.                 'trade_type' => 'NATIVE',  
  22.                 'product_id' => rand(1,999999),  
  23.             ]);  
  24.             if(!$result['code']){  
  25.                 return $this->error($result['msg']);  
  26.             }  
  27.             return $this->success($result['msg']);  
  28.         }  
  29.         $this->view->orderid = date("YmdHis").rand(100000,999999);  
  30.         return $this->fetch();  
  31.     }  
  32.   
  33.     public function weixin_notify()  
  34.     {//微信订单异步通知  
  35.         $notify_data = file_get_contents("php://input");//获取由微信传来的数据  
  36.         if(!$notify_data){  
  37.             $notify_data = $GLOBALS['HTTP_RAW_POST_DATA'] ?: '';//以防上面函数获取到的内容为空  
  38.         }  
  39.         if(!$notify_data){  
  40.             exit('');  
  41.         }  
  42.         $Pay = new Pay;  
  43.         $result = $Pay->notify_weixin($notify_data);//调用模型中的异步通知函数  
  44.         exit($result);  
  45.     }  
  46. }  

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

  1. <!doctype html>  
  2. <html lang="zh-CN">  
  3. <head>  
  4.     <meta charset="utf-8">  
  5.     <title>微信支付测试</title>  
  6.     <base href="{:request()->domain()}" />  
  7.     <link href="static/css/bootstrap.css" rel="stylesheet">  
  8.     <link href="static/css/common.css" rel="stylesheet">  
  9.     <link href="static/css/admin.css" rel="stylesheet">  
  10.     <script src="static/js/jquery-1.12.0.min.js"></script>  
  11.     <script src="static/js/bootstrap.min.js"></script>  
  12.     <script src="static/js/jquery.qrcode.min.js"></script>  
  13.     <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>  
  14. </head>  
  15. <body>  
  16. <div class="container">  
  17.     <div class="panel panel-default">  
  18.         <div class="panel-heading">  
  19.             <strong>微信支付测试</strong>  
  20.         </div>  
  21.         <div class="panel-body">  
  22.             <form class="form-horizontal weixin-form" method="post" action="{:url('index/index/weixin')}">  
  23.                 <div class="form-group">  
  24.                     <label class="col-sm-2 control-label">订单编号</label>  
  25.                     <div class="col-sm-10">  
  26.                         <input type="text" class="form-control" name="orderid" value="{$orderid}" readonly>  
  27.                     </div>  
  28.                 </div>  
  29.                 <div class="form-group">  
  30.                     <label class="col-sm-2 control-label">支付标题</label>  
  31.                     <div class="col-sm-10">  
  32.                         <input type="text" class="form-control" name="attach" value="账户余额充值">  
  33.                     </div>  
  34.                 </div>  
  35.                 <div class="form-group">  
  36.                     <label class="col-sm-2 control-label">支付描述</label>  
  37.                     <div class="col-sm-10">  
  38.                         <input type="text" class="form-control" name="body" value="在线充值金额到账户余额">  
  39.                     </div>  
  40.                 </div>  
  41.                 <div class="form-group">  
  42.                     <label class="col-sm-2 control-label">支付金额</label>  
  43.                     <div class="col-sm-10">  
  44.                         <input type="text" class="form-control" name="total_fee" value="0.01">  
  45.                     </div>  
  46.                 </div>  
  47.                 <div class="form-group">  
  48.                     <div class="col-sm-offset-2 col-sm-10">  
  49.                         <button type="submit" class="btn btn-success">立即支付</button>  
  50.                     </div>  
  51.                 </div>  
  52.             </form>  
  53.         </div>  
  54.         <div class="panel-footer">&nbsp;</div>  
  55.     </div>  
  56. </div>  
  57. <script>  
  58.     $(function(){  
  59.         $('.weixin-form').submit(function(){  
  60.             var $this = $(this);  
  61.             if(!$this.hasClass('lock-form')){  
  62.                 $this.addClass('lock-form');//锁定表单  
  63.                 var formData = new FormData($this[0]);  
  64.                 $.ajax({  
  65.                     url:$this.attr("action"),  
  66.                     type:'POST',  
  67.                     data:formData,  
  68.                     dataType:'json',  
  69.                     cache: false,  
  70.                     contentType: false,  
  71.                     processData: false,  
  72.                     success:function(s){  
  73.                         $this.removeClass('lock-form');//解锁表单  
  74.                         if(s.code != 1){  
  75.                             $('.panel-footer').html(s.msg);  
  76.                             return false;  
  77.                         }  
  78.                         if(!s.msg){  
  79.                             $('.panel-footer').html('二维码生成失败,请重新提交!');  
  80.                             return false;  
  81.                         }  
  82.                         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>';  
  83.                         html += '<div class="modal-body weixin-qrcode text-center"></div>';  
  84.                         html += '<div class="modal-footer"><p class="text-center">请使用微信扫描二维码完成支付</p></div>';  
  85.                         if($('.ajax-form-modal').length > 0){  
  86.                             content = $('.ajax-form-modal .modal-content');  
  87.                         }else{  
  88.                             fade = $('<div></div>').addClass('modal fade ajax-form-modal').appendTo('body');  
  89.                             dialog = $('<div></div>').addClass('modal-dialog').appendTo(fade);  
  90.                             content = $('<div></div>').addClass('modal-content').appendTo(dialog);  
  91.                         }  
  92.                         content.html(html);  
  93.                         $('.weixin-qrcode').qrcode({width:300,height: 300,text: s.msg});  
  94.                         $('.ajax-form-modal').modal('show');  
  95.                         return false;  
  96.                     }  
  97.                 });  
  98.             }  
  99.             return false;  
  100.         });  
  101.     });  
  102. </script>  
  103. </body>  
  104. </html>  

关于模板内容这里不做过多解释,如果不明白请下载下方DEMO文件查看(访问:域名/index/index/weixin)

由于异步通知需要在公网内执行,因此请将代码上传至服务器上测试

特别注意事项:

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

扫码直接访问:

声明:本站内容为原创。下载内容来自网络,仅作为预览参考之用,版权归原作者和出版社所有,下载后请自觉在24小时内删除.本站信箱:share#lwxshow.com(#换成@)

  • 转载请注明:Thinkphp 5.0版本整合微信扫码支付接口,含模型验证异步通知等完整实例;?> +复制链接
  • 给我留言

    *