2017年6月10日

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.     public static $alipay_config = [
  8.         'partner'           => '2088************',//支付宝partner,2088开头数字
  9.         'seller_id'         => '2088************',//支付宝partner,2088开头数字
  10.         'key'               => '****************',//支付宝密钥
  11.         'sign_type'         => 'MD5',
  12.         'input_charset'     => 'utf-8',
  13.         'cacert'            => '',
  14.         'transport'         => 'http',
  15.         'payment_type'      => '1',
  16.         'service'           => 'create_direct_pay_by_user',
  17.         'anti_phishing_key' => '',
  18.         'exter_invoke_ip'   => '',
  19.     ];
  20.     public function alipay($data=[])
  21.     {//发起支付宝支付
  22.         $validate = new Validate([
  23.             ['out_trade_no','require|alphaNum','订单编号输入错误|订单编号输入错误'],
  24.             ['total_fee','require|number|gt:0','金额输入错误|金额输入错误|金额输入错误'],
  25.             ['subject','require','请输入标题'],
  26.             ['body','require','请输入描述'],
  27.             ['notify_url','require','异步通知地址不为空'],
  28.         ]);
  29.         if (!$validate->check($data)) {
  30.             return ['code'=>0,'msg'=>$validate->getError()];
  31.         }
  32.         $config = self::$alipay_config;
  33.         vendor('alipay.alipay');
  34.         $parameter = [
  35.             "service"           => $config['service'],
  36.             "partner"           => $config['partner'],
  37.             "seller_id"         => $config['seller_id'],
  38.             "payment_type"      => $config['payment_type'],
  39.             "notify_url"        => $data['notify_url'],
  40.             "return_url"        => $data['return_url'],
  41.             "anti_phishing_key" => $config['anti_phishing_key'],
  42.             "exter_invoke_ip"   => $config['exter_invoke_ip'],
  43.             "out_trade_no"      => $data['out_trade_no'],
  44.             "subject"           => $data['subject'],
  45.             "total_fee"         => $data['total_fee'],
  46.             "body"              => $data['body'],
  47.             "_input_charset"    => $config['input_charset']
  48.         ];
  49.         $alipaySubmit = new \AlipaySubmit($config);
  50.         return ['code'=>1,'msg'=>$alipaySubmit->buildRequestForm($parameter,"get""确认")];
  51.     }
  52.     public function notify_alipay()
  53.     {//异步订单结果通知
  54.         $config = self::$alipay_config;
  55.         vendor('alipay.alipay');
  56.         $alipayNotify = new \AlipayNotify($config);
  57.         if($result = $alipayNotify->verifyNotify()){
  58.             if(input('trade_status') == 'TRADE_FINISHED' || input('trade_status') == 'TRADE_SUCCESS') {
  59.                 // 处理支付成功后的逻辑业务
  60.                 Log::init([
  61.                     'type'  =>  'File',
  62.                     'path'  =>  LOG_PATH.'../paylog/'
  63.                 ]);
  64.                 Log::write($result,'log');
  65.                 return 'success';
  66.             }
  67.             return 'fail';
  68.         }
  69.         return 'fail';
  70.     }
  71. }
  72. ?>

创建好模型后,我们可在任何需要的位置直接调用模型,实现支付宝订单提交以及用户支付完成后的异步通知逻辑处理

接下来我们创建一个示例控制器(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.     public function alipay()
  8.     {//发起支付宝支付
  9.         if(request()->isPost()){
  10.             $Pay = new Pay;
  11.             $result = $Pay->alipay([
  12.                 'notify_url' => request()->domain().url('index/index/alipay_notify'),
  13.                 'return_url' => '',
  14.                 'out_trade_no' => input('post.orderid/s','','trim,strip_tags'),
  15.                 'subject' => input('post.subject/s','','trim,strip_tags'),
  16.                 'total_fee' => input('post.total_fee/f'),//订单金额,单位为元
  17.                 'body' => input('post.body/s','','trim,strip_tags'),
  18.             ]);
  19.             if(!$result['code']){
  20.                 return $this->error($result['msg']);
  21.             }
  22.             return $result['msg'];
  23.         }
  24.         $this->view->orderid = date("YmdHis").rand(100000,999999);
  25.         return $this->fetch();
  26.     }
  27.     public function alipay_notify()
  28.     {//异步订单通知
  29.         $Pay = new Pay;
  30.         $result = $Pay->notify_alipay();
  31.         exit($result);
  32.     }
  33. }

最后一步,创建测试模板(alipay.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.     <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
  13. </head>
  14. <body>
  15. <div class="container">
  16.     <div class="panel panel-default">
  17.         <div class="panel-heading">
  18.             <strong>支付宝支付测试</strong>
  19.         </div>
  20.         <div class="panel-body">
  21.             <form class="form-horizontal send-form" method="post" action="{:url('index/index/alipay')}" target="_blank">
  22.                 <div class="form-group">
  23.                     <label class="col-sm-2 control-label">订单编号</label>
  24.                     <div class="col-sm-10">
  25.                         <input type="text" class="form-control" name="orderid" value="{$orderid}" readonly>
  26.                     </div>
  27.                 </div>
  28.                 <div class="form-group">
  29.                     <label class="col-sm-2 control-label">支付标题</label>
  30.                     <div class="col-sm-10">
  31.                         <input type="text" class="form-control" name="subject" value="账户余额充值">
  32.                     </div>
  33.                 </div>
  34.                 <div class="form-group">
  35.                     <label class="col-sm-2 control-label">支付描述</label>
  36.                     <div class="col-sm-10">
  37.                         <input type="text" class="form-control" name="body" value="在线充值金额到账户余额">
  38.                     </div>
  39.                 </div>
  40.                 <div class="form-group">
  41.                     <label class="col-sm-2 control-label">支付金额</label>
  42.                     <div class="col-sm-10">
  43.                         <input type="text" class="form-control" name="total_fee" value="0.1">
  44.                     </div>
  45.                 </div>
  46.                 <div class="form-group">
  47.                     <div class="col-sm-offset-2 col-sm-10">
  48.                         <button type="submit" class="btn btn-success">立即支付</button>
  49.                     </div>
  50.                 </div>
  51.             </form>
  52.         </div>
  53.     </div>
  54. </div>
  55. </body>
  56. </html>

当提交订单到控制后,控制器调用支付宝模型向支付宝发起支付,用户完成支付后,支付宝向预设的链接地址发起异步通知(异步通知仅支持在公网内测试,因此以上内容请在公网中进行)

在其他控制器或者模型或任何地方调用,请直接实例化支付模型

  1. $Pay = new Pay;//实例化前请先导入类或者使用use语法
  2. $result = $Pay->alipay([
  3.     'notify_url' => request()->domain().url('index/index/alipay_notify'),//支付结果通知地址,完整url
  4.     'return_url' => '',//同步通知地址
  5.     'out_trade_no' => input('post.orderid/s','','trim,strip_tags'),//本站订单编号
  6.     'subject' => input('post.subject/s','','trim,strip_tags'),//支付标题
  7.     'total_fee' => input('post.total_fee/f'),//订单金额,单位为元例如:0.1
  8.     'body' => input('post.body/s','','trim,strip_tags'),//支付说明
  9. ]);
  10. if(!$result['code']){//模型会对提交的数据进行验证,如果code=0那么$result['msg']的结果为验
  11.     return $this->error($result['msg']);
  12. }
  13. //如果验证成功,$result['msg']为支付宝提交表单,直接输出即可
  14. return $result['msg'];
Tagged on:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*