您的位置:首页 > 编程语言 > PHP开发

服务器端Thinkphp3.2.3集成支付宝第三方支付

2015-10-27 17:57 561 查看
    近期做的一个项目,需要在自己的app里面接入支付宝支付功能,根据支付宝提供的不同收款方案,我们最终选择了移动支付,以下的经验仅限于移动支付,其他的支付请自行研究。

  移动支付,分为客户端和服务器端,客户端通过设置异步通知url,支付宝服务器会在用户支付的过程中,将支付状态发给APP的服务器,作为后台人员,就需要根据这个状态,来进行订单等数据库的更新操作。 所以这次集成仅讨论了服务器端的集成方法,客户端请参考其他资料。

通过下载支付宝的php-utf8接口的demo,根据文档,按道理说就可以进行简单的测试了,但是实际有很多的坑。。。。

1. key文件夹里面的支付宝公钥不要修改,,,虽然文档上提示说可以从商家账号里面查看和复制支付宝公钥,自己生成一个文件,但是最后还是报错,所以公钥文件直接用demo里面的key文件夹西的公钥文件,不要修改!!!!

2. notify_url.php里面引入了两个文件

 require_once("alipay.config.php");

require_once("lib/alipay_notify.class.php");

在运行过程中会发现,第二个引入文件会出错! 因为这样的引用方式会导致一个php的引入文件错误,因为alipay_notify.class.php这个文件又引入了一个lib下的两个文件:

require_once("alipay_core.function.php");

require_once("alipay_rsa.function.php");

这种嵌套引入,带来的后果就是alipay_notify.class.php文件无法找到alipay_core.function.php和alipay_rsa.function.php文件,因为它默认的搜索是在当前目录下搜索,而这个两个文件是在lib下面,,,解决的方法要么是把lib下的alipay_notify.class.php,alipay_core.function.php和alipay_rsa.function.php都放到跟alipay_notify.class.php文件同级目录,或者讲引用文件的路径设为绝对路径。 

支付宝这块是不是有点坑呢?

     虽然采用这种原生的php代码做支付可以实现功能,但是我们一般都会选用框架,比如我用的是Thinkphp3.2.3.  要想集成到Thinkphp3.2.3,可以采用如下流程。

1. 把lib下的3个文件放到Thinkphp3.2.3的 Library/vendor目录下,可以修改下文件名,和vendor里面的库文件格式类似,修改文件名后,要同时修改alipay_notify文件里面的引入文件的文件名。注意三个文件里,如AlipayNotify,是要在外面引用的,需要在AlipayNotify文件顶部加上命名空间: namespace  Vendor\AlipayNotify. 否则无法在外面引用成功。

2.把key文件夹下的修改好的私钥文件和原始的公钥文件,以及cacert.pem文件,放到服务器接口项目的根目录下的文件夹下,如key.也可以放到其他地方,但是一定要确保有权限访问。

3.修改alipay.config.php文件里面的内容,或者直接去掉这个文件,把里面的配置数组,放到我们的自定义的Controller文件里。

4.创建我们自己的支付接口Controller,也就是客户端需要设置的异步通知url。 里面的引入路径和实例化vendor下的支付相关的类的方法,要特别注意路径。

5. 根据支付宝的demo的提示,获取支付状态,写我们的处理逻辑。

6.不要在处理阿里云服务器异步通知的函数里出错,不要打印输出其他内容,,,特别是调用其他函数,如果出错,错误内容会直接抛给支付宝那边了,那边就以为你的处理结束了!!!!

说了那么多,我直接给出我的自定义的控制器的代码,大家一眼看明白了,,,可以作为参考:

 

namespace Home\Controller;
use Think\Controller;

class AlipayController extends Controller {

/******************************
服务器异步通知页面方法
其实这里就是将notify_url.php文件中的代码复制过来进行处理

*******************************/
function notifyurl(){
//↓请在这里配置您的基本信息↓
//合作身份者id,以2088开头的16位纯数字
$alipay_config['partner'] = '';

//商户的私钥(后缀是.pen),如果采用这种形式,文件必须放在接口项目的根目录下
$alipay_config['private_key_path']	= getcwd().'/key/rsa_private_key.pem';

//支付宝公钥(后缀是.pen)如果采用这种形式,文件必须放在接口项目的根目录下</span>

$alipay_config['ali_public_key_path']= getcwd().'/key/rsa_public_key.pem';

//↑请在这里配置您的基本信息↑
//签名方式 不需修改
$alipay_config['sign_type']    = strtoupper('RSA');

//字符编码格式 目前支持 gbk 或 utf-8
$alipay_config['input_charset']= strtolower('utf-8');

//ca证书路径地址,用于curl中ssl校验
//如果采用这种形式,文件必须放在接口项目的根目录下</span>
$alipay_config['cacert']    = getcwd().'/key/cacert.pem';

//访问模式,根据自己的服务器是否支持ssl访问,若支持请选择https;若不支持请选择http
$alipay_config['transport']    = 'http';

//计算得出通知验证结果

//引入我们加入的支付相关的类库的方法
Vendor('Alipay.AlipayNotify') or die("引入失败");</span>
$alipayNotify = new \Vendor\Alipay\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'];         //交易金额
$notify_id      = $_POST['notify_id'];         //通知校验ID。
$notify_time    = $_POST['notify_time'];       //通知的发送时间。格式为yyyy-MM-dd HH:mm:ss。
$buyer_email    = $_POST['buyer_email'];       //买家支付宝帐号;

if ($_POST['trade_status'] == 'TRADE_SUCCESS') {

//支付成功后的自己的后台逻辑代码,,,我采用的支付产品,只会返回一个TRADE_SUCCESS的交易成功的提示。

}

echo "success"; //请不要修改或删除

}else {
//验证失败
//$log_text = "验证失败,配置参数是:";
//	$log_text = $log_text.createLinkString($alipay_config);
//	logResult($log_text);
echo "fail";
}
}

}


 

 

后记: 在集成的过程中,是不能输出测试信息的,只能采用他们提供的logResult记录日志的方法来查看和调试程序。

集成很多坑,如果走过来,会发现支付宝的文档写的不//完善,他们的技术人员的解决问题的能力也值得商榷,,不是黑阿里!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息