thinkphp实现支付宝接口功能(担保交易),(即时交易)@托米,已经有人发过了。这个不是我写的,是在csdn上看到的,顺便转载过来,有什么问题,可以到原作者博客提问http://blog.csdn.net/ssrc0604hx/article/details/16887607。本人也是为了方便大家,忘各位别喷!!!
开发环境
thinkphp 3.1.2 (我用的是标准版)
win7 + apache2
mysql 5.1
这里说一下数据库的设计。
部署支付宝
我用的是支付宝担保交易(即时到账的门槛有点高=.=).先从支付宝网站下载担保交易的demo(要注意编码,我用的是utf-8)。
前往thinkphp目录下的extend,找到vendor目录(这个目录是第三方类库的存放目录,如果没有,手动创建一个,要标准版本里面是没有的),然后在vendor下创建alipay目录存在支付宝相关的文件。
目录结构如下:
接着修改 alipay.config.php 文件:
支付请求
配置好支付宝后,就可以进行支付请求了。支付宝的示例代码很是详细,很多可以直接用。
首先,创建orderaction.class.php 来处理订单相关的业务操作。
定义pay方法: /**
* 支付订单
*/
public function pay(){
$this->checklogin();
header('content-type: text/html; charset=utf-8');
$id = args(id, 0);
$dao = new ordermodel();
$order = $dao->where(id=.$id)->find();
$error = ;
if(!isset($order)){
$error = 订单不存在;
}else if($order['status'] == 1){
$error = 此订单已经完成,无需再次支付!;
} else if($order['status'] == 2){
$error = 此订单已经取消,无法支付,请重新下单!;
}
if($error != ){
$this->_fail(系统错误,$error,$this->geterrorlinks());
return ;
}
//支付宝
if($order['payment'] == 'alipay'){
$this->paywithalipay($order);
}
else if($order['payment'] == 'ecpss'){
$this->paywithecpss($order);
}
else if($order['payment'] == 'dinpay'){
$this->paywithdinpay($order);
}
}然后再定义 paywithalipay($order) 方法(根据具体情况修改相关的参数即可):/**
* 以支付宝形式支付
* @param unknown_type $order
*/
private function paywithalipay($order){
//引入支付宝相关的文件
require_once(vendor_path.alipay/alipay.config.php);
require_once(vendor_path.alipay/lib/alipay_submit.class.php);
//支付类型
$payment_type = 1;
//必填,不能修改
//服务器异步通知页面路径
$notify_url = c(host).index.php/order/notifyonalipay;
//页面跳转同步通知页面路径
$return_url = c(host).index.php/order;
//卖家支付宝帐户
$seller_email = $alipay_config['seller_email'];
//必填
//商户订单号, 从订单对象中获取
$out_trade_no = $order['tradeno'];
//商户网站订单系统中唯一订单号,必填
//订单名称
$subject = $order['subject'];
//必填
//付款金额
$price = $order['price'];
//必填
$body = $order['subject'];
//商品展示地址
$show_url = c('host');
//构造要请求的参数数组,无需改动
$parameter = array(
service => create_partner_trade_by_buyer,
partner => trim($alipay_config['partner']),
payment_type=> $payment_type,
notify_url=> $notify_url,
return_url=> $return_url,
seller_email=> $seller_email,
out_trade_no=> $out_trade_no,
subject=> $subject,
price=> $price,
quantity=> 1,
logistics_fee=> 0.00,
logistics_type=> express,
logistics_payment=> seller_pay,
body=> $body,
show_url=> $show_url,
receive_name=> ,
receive_address=> ,
receive_zip=> ,
receive_phone=> ,
receive_mobile=> ,
_input_charset=> trim(strtolower($alipay_config['input_charset']))
);
//建立请求
$alipaysubmit = new alipaysubmit($alipay_config);
$html_text = $alipaysubmit->buildrequestform($parameter,get, 去支付);
echo $html_text;
}支付宝返回处理
最后是支付宝异步通知的处理函数(这里,我只对异步返回作处理):/**
* 支付宝异步通知
*/
public function notifyonalipay(){
require_once(vendor_path.alipay/alipay.config.php);
require_once(vendor_path.alipay/lib/alipay_notify.class.php);
$orderlogdao = new orderlogmodel();
//计算得出通知验证结果
$alipaynotify = new alipaynotify($alipay_config);
$verify_result = $alipaynotify->verifynotify();
if($verify_result) {//验证成功
//商户订单号
$out_trade_no = $_post['out_trade_no'];
//支付宝交易号
$trade_no = $_post['trade_no'];
//根据订单号获取订单
$dao = new ordermodel();
$order = $dao->where(tradeno='.$out_trade_no.')->find();
//如果订单不存在,设置为0
if(!isset($order)){
$orderid = 0;
}
else{
$orderid = $order['id'];
}
//交易状态
$trade_status = $_post['trade_status'];
$log = notify from alipay, trade_status=.$trade_status. alipay sign=.$_post['sign'];
$orderlog['order_id'] = $orderid;
$orderlog['adddate'] = sqldate();
if($_post['trade_status'] == 'wait_buyer_pay') {
//该判断表示买家已在支付宝交易管理中产生了交易记录,但没有付款
}
/*
* 成功付款后,进行积分操作
*/
else if($_post['trade_status'] == 'wait_seller_send_goods') {
//该判断表示买家已在支付宝交易管理中产生了交易记录且付款成功,但卖家没有发货
if(isset($order) && $order['status'] == 0){
$resultinfo = $this->doafterpaysuccess($dao, $order);
$log.= $resultinfo;
}
}
else if($_post['trade_status'] == 'wait_buyer_confirm_goods') {
//该判断表示卖家已经发了货,但买家还没有做确认收货的操作
}
else if($_post['trade_status'] == 'trade_finished') {
//该判断表示买家已经确认收货,这笔交易完成
}
else {
}
/*
* 保存orderlog
*/
$orderlog['log'] = $log;
$orderlogdao->add($orderlog);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
echo success; //返回成功标记给支付宝
}
else {
//验证不通过时,也记录下来
$orderlog['log'] = notify from alipay, 但是验证不通过,sign=.$_post['sign'];
$orderlog['order_id'] = -1;
$orderlog['adddate'] = sqldate();
$orderlogdao->add($orderlog);
//验证失败
echo fail;
}
}测试一笔,得到如下的结果:
总结
支付宝的集成还是比较简单的,官方的教程很详细。
这里要注意的是,
1、alipay.config.php 下的 cacert.pem 文件的路径一定要对,之前我没注意这点,结果出来以下的错误:
2、在notify_url中,一定只能返回 success或者fail,也不能对这个url作登录验证的处理。
3、还要注意对网站订单的反重复处理
ad:真正免费,域名+虚机+企业邮箱=0元