thinkPHP框架对接支付宝即时到账接口回调操作示例


Posted in PHP onNovember 14, 2016

本文实例讲述了thinkPHP框架对接支付宝即时到账接口回调操作。分享给大家供大家参考,具体如下:

关于支付宝即时收款接口的对接过程,很简单,也有很多人发过,我这里就不在??铝耍?越油瓿珊螅?谙咧Ц冻晒?蟮幕氐鳎?喽岳此担?歉瞿训悖??抑氐惴窒硐挛业木?椤?/p>

我在开发二代旅游CMS(http://www.erdaicms.com)的时候,在回调的时候,也花了不少时间。

不管是支付宝接口好是微信支付接口,回调都分为跳转回调和异步通知回调,跳转回调是不保险的,加入客人支付完成后马上把支付页面关闭,没跳转,就通知不到你这个订单已经支付了,所以我们要用异步通知回调:

$alipay_config['notify_url'] = "".$ss['web_url']."/v.php/Index-alipay_notify_url.html";

首先设置介绍异步回调的地址

异步回调的具体处理函数,我这里也贴处理,供参考:

/* 支付宝异步通知*/
public function alipay_notify_url()
{
  vendor('Alipay.Corefunction');
  vendor('Alipay.Md5function');
  vendor('Alipay.Notify');
  vendor('Alipay.Submit');
  $info=M('rewrite')->where(array('name'=>'alipay'))->find();
  $info=json_decode($info['content'],true);;
  //↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
//合作身份者ID,签约账号,以2088开头由16位纯数字组成的字符串,查看地址:https://b.alipay.com/order/pidAndKey.htm
$alipay_config['partner']    = $info['alipay_pid'];
//收款支付宝账号,以2088开头由16位纯数字组成的字符串,一般情况下收款账号就是签约账号
$alipay_config['seller_id'] = $info['alipay_pid'];
// MD5密钥,安全检验码,由数字和字母组成的32位字符串,查看地址:https://b.alipay.com/order/pidAndKey.htm
$alipay_config['key'] = $info['alipay_key'];
$ss=S('config');
// 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
$alipay_config['notify_url'] = "".$ss['web_url']."/v.php/Index-alipay_notify_url.html";
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
$alipay_config['return_url'] = "".$ss['web_url']."/member.php";
//签名方式
$alipay_config['sign_type'] = strtoupper('MD5');
//字符编码格式 目前支持 gbk 或 utf-8
$alipay_config['input_charset']= strtolower('utf-8');
//ca证书路径地址,用于curl中ssl校验
//请保证cacert.pem文件在当前文件夹目录中
$alipay_config['cacert'] = getcwd().'\\cacert.pem';
//访问模式,根据自己的服务器是否支持ssl访问,若支持请选择https;若不支持请选择http
$alipay_config['transport'] = 'http';
// 支付类型 ,无需修改
$alipay_config['payment_type'] = "1";
// 产品类型,无需修改
$alipay_config['service'] = "create_direct_pay_by_user";
//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//↓↓↓↓↓↓↓↓↓↓ 请在这里配置防钓鱼信息,如果没开通防钓鱼功能,为空即可 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// 防钓鱼时间戳 若要使用请调用类文件submit中的query_timestamp函数
$alipay_config['anti_phishing_key'] = "";
// 客户端的IP地址 非局域网的外网IP地址,如:221.0.0.1
$alipay_config['exter_invoke_ip'] = "";
  $alipayNotify = new \AlipayNotify($alipay_config);
  $verify_result = $alipayNotify->verifyNotify();
  if($verify_result) {//验证成功
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //请在这里加上商户的业务逻辑程序代
  //——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
  //获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表
  //商户订单号
  $out_trade_no = $_POST['out_trade_no'];
  //支付宝交易号
  $trade_no = $_POST['trade_no'];
  //交易状态
  $trade_status = $_POST['trade_status'];
  $total_fee=$_POST['total_fee'];
  //if( $info['alipay_pid']!=$seller_id) return ''; //收款账户不一致
  $info=M('order')->where(array('no'=>$out_trade_no))->find();
  if(!$info) return ''; //订单号不存在
  if($_POST['trade_status'] == 'TRADE_FINISHED') {
    //判断该笔订单是否在商户网站中已经做过处理
      //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
      //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
      //如果有做过处理,不执行商户的业务程序
       $data='';
      $data['status']=2;
      $data['pay_price']=$total_fee;
      $data['pay_type']='支付宝';
      $data['buyer']=$_POST['buyer_email'];
      $data['trade_no']=$trade_no;
      $data['pay_time']=time();
      M('order')->where(array('no'=>$out_trade_no))->save($data);
      $c=M('smtp_templates')->where(array('id'=>5))->find();
      if($c['status']==1)
      {
        $content = str_replace('{title}', $info['goods_name'], $c['content']);
        $content = str_replace('{id}', $info['goods_id'], $content);
        $content = str_replace('{price}',$total_fee, $content);
        $content = str_replace('{time}',date('Y-m-d H:i:s',time()), $content);
       $c=M('email_note')->where(array('pay_id'=>$out_trade_no))->find();
       if(!$c)
       {
       $e='';
       $e['email']=$info['c_email'];
       $e['content']=$content;
       $e['pay_id']=$out_trade_no;
       M('email_note')->add($e);
       $m=explode('|',$c['ather']);
       foreach($m as $mail)
       {
        if(validate_email($mail))
        {
         $e['email']=$mail;
         M('email_note')->add($e);
        }
       }
       }
      }
    //注意:
    //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
    //调试用,写文本函数记录程序运行情况是否正常
    //logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
  }
  else if ($_POST['trade_status'] == 'TRADE_SUCCESS') {
    //判断该笔订单是否在商户网站中已经做过处理
      //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
      //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
      //如果有做过处理,不执行商户的业务程序
      $data='';
      $data['status']=2;
      $data['pay_price']=$total_fee;
      $data['pay_type']='支付宝';
      $data['buyer']=$_POST['buyer_email'];
      $data['trade_no']=$trade_no;
      $data['pay_time']=time();
      M('order')->where(array('no'=>$out_trade_no))->save($data);
       $c=M('smtp_templates')->where(array('id'=>5))->find();
      if($c['status']==1)
      {
        $content = str_replace('{title}', $info['goods_name'], $c['content']);
        $content = str_replace('{id}', $info['goods_id'], $content);
        $content = str_replace('{price}',$total_fee, $content);
        $content = str_replace('{time}',date('Y-m-d H:i:s',time()), $content);
       $c=M('email_note')->where(array('pay_id'=>$out_trade_no))->find();
       if(!$c)
       {
       $e='';
       $e['email']=$info['c_email'];
       $e['content']=$content;
       $e['pay_id']=$out_trade_no;
       M('email_note')->add($e);
       $m=explode('|',$c['ather']);
       foreach($m as $mail)
       {
        if(validate_email($mail))
        {
         $e['email']=$mail;
         M('email_note')->add($e);
        }
       }
       }
      }
    //注意:
    //付款完成后,支付宝系统发送该交易状态通知
    //调试用,写文本函数记录程序运行情况是否正常
    //logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
  }
  //——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
  echo "success";    //请不要修改或删除
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
else {
  //验证失败
  echo "fail";
  //调试用,写文本函数记录程序运行情况是否正常
  //logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
}
}

因为是异步通知,所以调试是个麻烦事,不能所见即所得,也就是说,一般情况下没办法echo或者print_r打印输出结果,没办法知道他执行到哪里或者执行结果,这个时候,我们就用到log文件输出,代码:

$file = './log.txt';//要写入文件的文件名(可以是任意文件名),如果文件不存在,将会创建一个
$content = "支付成功".$bdata['total_fee']."\n"; //要写入的内容
file_put_contents($file, $content,FILE_APPEND);//写入文件

以上代码会在根目录下自动生成一个log.txt的文件,这样,就可以轻松知道执行结果,方便调试了

支付宝的异步通知接口,会多次通知,直到你返回success为止,也就是说,你提交一个测试订单,可以测试很多次,因为你没有返回success的话,他会每隔一定时间,通知一次

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。

PHP 相关文章推荐
实现“上一页”和“下一页按钮
Oct 09 PHP
xml在joomla表单中的应用详解分享
Jul 19 PHP
深入理解用mysql_fetch_row()以数组的形式返回查询结果
Jun 05 PHP
基于PHP中的常用函数回顾
Jul 11 PHP
CI框架中集成CKEditor编辑器的教程
Jun 09 PHP
ThinkPHP3.1新特性之多层MVC的支持
Jun 19 PHP
ThinkPHP调试模式与日志记录概述
Aug 22 PHP
浅谈PHP中JSON数据操作
Jul 01 PHP
php版银联支付接口开发简明教程
Oct 14 PHP
PHP redis实现超迷你全文检索
Mar 04 PHP
PHP调用微博接口实现微博登录的方法示例
Sep 22 PHP
php实现的支付宝网页支付功能示例【基于TP5框架】
Sep 16 PHP
Symfony2获取web目录绝对路径、相对路径、网址的方法
Nov 14 #PHP
CodeIgniter开发实现支付宝接口调用的方法示例
Nov 14 #PHP
PHP实现无限分类的实现方法
Nov 14 #PHP
php mysql获取表字段名称和字段信息的三种方法
Nov 13 #PHP
PHP编写daemon process 实例详解
Nov 13 #PHP
php版微信小店API二次开发及使用示例
Nov 12 #PHP
PHP Mysqli 常用代码集合
Nov 12 #PHP
You might like
PHP脚本的10个技巧(5)
2006/10/09 PHP
linux下安装php的memcached客户端
2014/08/03 PHP
PHP实现获取文件mime类型多种方法解析
2020/05/28 PHP
JavaScript函数、方法、对象代码
2008/10/29 Javascript
xml转json的js代码
2012/08/28 Javascript
node.js中的fs.statSync方法使用说明
2014/12/16 Javascript
JS实现的简洁二级导航菜单雏形效果
2015/10/13 Javascript
解决JS无法调用Controller问题的方法
2015/12/31 Javascript
AngularJS中如何使用$parse或$eval在运行时对Scope变量赋值
2016/01/25 Javascript
Vue2几种常见开局方式详解
2017/09/09 Javascript
Element-UI Table组件上添加列拖拽效果实现方法
2018/04/14 Javascript
JavaScript设计模式之享元模式实例详解
2019/01/17 Javascript
微信小程序开发的基本流程步骤
2019/01/31 Javascript
JavaScript数组、json对象、eval()函数用法实例分析
2019/02/21 Javascript
js判断一个对象是数组(函数)的方法实例
2019/12/19 Javascript
Vue基于iview实现登录密码的显示与隐藏功能
2020/03/06 Javascript
在vue项目中 实现定义全局变量 全局函数操作
2020/10/26 Javascript
python使用pil生成图片验证码的方法
2015/05/08 Python
Python算法之求n个节点不同二叉树个数
2017/10/27 Python
Python使用smtp和pop简单收发邮件完整实例
2018/01/09 Python
Python Xml文件添加字节属性的方法
2018/03/31 Python
Python3实现的简单验证码识别功能示例
2018/05/02 Python
Python基础学习之基本数据结构详解【数字、字符串、列表、元组、集合、字典】
2019/06/18 Python
pycharm配置当鼠标悬停时快速提示方法参数
2019/07/31 Python
python批量解压zip文件的方法
2019/08/20 Python
python中的线程threading.Thread()使用详解
2019/12/17 Python
PyTorch 随机数生成占用 CPU 过高的解决方法
2020/01/13 Python
基于tensorflow __init__、build 和call的使用小结
2021/02/26 Python
骨干教师培训感言
2014/01/16 职场文书
小学生开学第一课活动方案
2014/03/27 职场文书
大专生求职信
2014/06/29 职场文书
建筑工程造价专业自荐信
2014/07/08 职场文书
廉洁自律心得体会2016
2016/01/13 职场文书
小学记事作文之200字
2019/08/06 职场文书
Windows11插耳机没反应怎么办? win11耳机没声音的多种解决办法
2021/11/21 数码科技
virtualenv隔离Python环境的问题解析
2022/06/21 Python