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

Yii 扩展支付宝快速支付接口

2014-09-24 16:31 357 查看
使用的是官方提供方的php接口:create_direct_pay_by_user-PHP-UTF-8

http://pan.baidu.com/s/1o60qASU

将lib下的四个文件复制至:yii项目\protected\vendor\下
四个文件分别是:alipay_core.function.php、alipay_md5.function.php、alipay_notify.class.php、alipay_submit.class.php
将CA证书文件:cacert.pem在yii项目\目录和 yii项目\protected\controllers下各复制一份
在main.php的项目配置文件中加入支付宝的相关配置参数:

'params'=>array(
'alipay_config'=>array(
'partner' =>'',//必填
'key'=>'',//必填
'sign_type'=>strtoupper('MD5'),//必填
'input_charset'=> strtolower('utf-8'),//必填
'cacert'=>getcwd().'/cacert.pem',//必填且CA证书文件能有效访问,否则会有sign错误
'transport'=>'http',//如果你的服务器支持https请填写https
),
'alipay'   =>array(
'seller_email'=>'',//必填
'notify_url'=>'http://res.locoy.com/index.php?r=pay/notifyUrl',
'return_url'=>'http://res.locoy.com/index.php?r=pay/returnUrl',//必填
'successpage'=>'account/list',//处理成功后的页面
'errorpage'=>'shopcart/list',//处理失败的页面
),
),

然后写一个支付的控制器:

<?php
/**
*author:xiaojiang
*create_time:2014/9/19 16:06
*/
class PayController extends Controller {

public function ActionAlipay($id) {
$model = Shopcart::model()->findByPk($id);
header("Content-type:text/html;charset=utf-8");
Yii::import('application.vendor.*');
require_once('alipay_core.function.php');
require_once('alipay_md5.function.php');
require_once('alipay_notify.class.php');
require_once('alipay_submit.class.php');
$alipay_config = Yii::app()->params['alipay_config'];
$payment_type = "1";
$notify_url = Yii::app()->params['alipay']['notify_url'];
//需http://格式的完整路径,不能加?id=123这类自定义参数
//页面跳转同步通知页面路径
$return_url = Yii::app()->params['alipay']['return_url'];
//需http://格式的完整路径,不能加?id=123这类自定义参数,不能写成http://localhost/
//卖家支付宝帐户
$seller_email = Yii::app()->params['alipay']['seller_email'];
//必填
//商户订单号
$out_trade_no = $model->trade_id;
//商户网站订单系统中唯一订单号,必填
//订单名称
$subject = $model->trade_name;
//必填
//付款金额
$total_fee = $model->trade_money;
//必填
//订单描述
$body = $model->trade_name.':'.$model->trade_money;
//商品展示地址
$show_url = '';
//需以http://开头的完整路径,例如:http://www.xxx.com/myorder.html
//防钓鱼时间戳
$anti_phishing_key = "";
//若要使用请调用类文件submit中的query_timestamp函数
//客户端的IP地址
$exter_invoke_ip = "";
//非局域网的外网IP地址,如:221.0.0.1

/************************************************************/

//构造要请求的参数数组,无需改动
$parameter = array(
"service" => "create_direct_pay_by_user",
"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,
"total_fee"   => $total_fee,
"body"    => $body,
"show_url"    => $show_url,
"anti_phishing_key"   => $anti_phishing_key,
"exter_invoke_ip" => $exter_invoke_ip,
"_input_charset"  => trim(strtolower($alipay_config['input_charset']))
);
//        print_r($parameter);die;
//建立请求
$alipaySubmit = new AlipaySubmit($alipay_config);
$html_text = $alipaySubmit->buildRequestForm($parameter,"get", "确认");
echo $html_text;

}

public function actionNotifyUrl() {
header("Content-type:text/html;charset=utf-8");
Yii::import('application.vendor.*');
require_once('alipay_core.function.php');
require_once('alipay_md5.function.php');
require_once('alipay_notify.class.php');
require_once('alipay_submit.class.php');
$alipay_config = Yii::app()->params['alipay_config'];
//计算得出通知验证结果
$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'];         //交易金额
$notify_id      = $_POST['notify_id'];         //通知校验ID。
$notify_time    = $_POST['notify_time'];       //通知的发送时间。格式为yyyy-MM-dd HH:mm:ss。
$buyer_email    = $_POST['buyer_email'];       //买家支付宝帐号;
$parameter = array(
"out_trade_no"     => $out_trade_no, //商户订单编号;
"trade_no"     => $trade_no,     //支付宝交易号;
"total_fee"     => $total_fee,    //交易金额;
"trade_status"     => $trade_status, //交易状态
"notify_id"     => $notify_id,    //通知校验ID。
"notify_time"   => $notify_time,  //通知的发送时间。
"buyer_email"   => $buyer_email,  //买家支付宝帐号;
);

if ($_POST['trade_status'] == 'TRADE_FINISHED') {
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//如果有做过处理,不执行商户的业务程序
if(!checkorderstatus($out_trade_no)){
orderhandle($parameter);  //进行订单处理,并传送从支付宝返回的参数;
}
//注意:
//该种交易状态只在两种情况下出现
//1、开通了普通即时到账,买家付款成功后。
//2、开通了高级即时到账,从该笔交易成功时间算起,过了签约时的可退款时限(如:三个月以内可退款、一年以内可退款等)后。

//调试用,写文本函数记录程序运行情况是否正常
// logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
} else if ($_POST['trade_status'] == 'TRADE_SUCCESS') {
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//如果有做过处理,不执行商户的业务程序
if(!checkorderstatus($out_trade_no)){
orderhandle($parameter);  //进行订单处理,并传送从支付宝返回的参数;
}
//注意:
//该种交易状态只在一种情况下出现——开通了高级即时到账,买家付款成功后。

//调试用,写文本函数记录程序运行情况是否正常
//logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
}

//——请根据您的业务逻辑来编写程序(以上代码仅作参考)——

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

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
} else {
//验证失败
echo "fail";
}
}

public function actionReturnUrl(){
header("Content-type:text/html;charset=utf-8");
Yii::import('application.vendor.*');
require_once('alipay_core.function.php');
require_once('alipay_md5.function.php');
require_once('alipay_notify.class.php');
require_once('alipay_submit.class.php');
$alipay_config = Yii::app()->params['alipay_config'];
$alipayNotify = new AlipayNotify($alipay_config);//计算得出通知验证结果
$verify_result = $alipayNotify->verifyReturn();
if($verify_result) {
//验证成功
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表
$out_trade_no   = $_GET['out_trade_no'];      //商户订单号
$trade_no       = $_GET['trade_no'];          //支付宝交易号
$trade_status   = $_GET['trade_status'];      //交易状态
$total_fee      = $_GET['total_fee'];         //交易金额
$notify_id      = $_GET['notify_id'];         //通知校验ID。
$notify_time    = $_GET['notify_time'];       //通知的发送时间。
$buyer_email    = $_GET['buyer_email'];       //买家支付宝帐号;

$parameter = array(
"out_trade_no"     => $out_trade_no,      //商户订单编号;
"trade_no"     => $trade_no,          //支付宝交易号;
"total_fee"      => $total_fee,         //交易金额;
"trade_status"     => $trade_status,      //交易状态
"notify_id"      => $notify_id,         //通知校验ID。
"notify_time"    => $notify_time,       //通知的发送时间。
"buyer_email"    => $buyer_email,       //买家支付宝帐号
);

if($_GET['trade_status'] == 'TRADE_FINISHED' || $_GET['trade_status'] == 'TRADE_SUCCESS') {
if(!checkorderstatus($out_trade_no)){
orderhandle($parameter);  //进行订单处理,并传送从支付宝返回的参数;
}
$this->redirect(Yii::app()->createUrl(Yii::app()->params['alipay']['successpage']));//跳转到配置项中配置的支付成功页面;
}else {
echo "trade_status=".$_GET['trade_status'];
$this->redirect(Yii::app()->createUrl(Yii::app()->params['alipay']['errorpage']));//跳转到配置项中配置的支付失败页面;
}
}else {
//验证失败
//如要调试,请看alipay_notify.php页面的verifyReturn函数
echo "验证失败!";
}
}

}
一下是两个上面控制器中用到的两个处理方法:我是写在了一个可以定义全局方法的functions.php文件中
你可以把这两个方法写在购物车或者其他的模型中进行调用
//在线交易订单支付处理函数
//函数功能:根据支付接口传回的数据判断该订单是否已经支付成功;
//返回值:如果订单已经成功支付,返回true,否则返回false;
function checkorderstatus($ordid){
$criteria = new CDbCriteria;
$criteria->addCondition('trade_id = :ordid');
$criteria->params[':ordid'] = $ordid;
$criteria->select = 'status';
$ordstatus = Shopcart::model()->find($criteria);
if($ordstatus->status == 1){
return true;
}else{
return false;
}
}
//处理订单函数
//更新订单状态,写入订单支付后返回的数据
function orderhandle($parameter){
$ordid = $parameter['out_trade_no'];
$buyer = $parameter['buyer_email'];
$status = 1;
$criteria = new CDbCriteria;
$criteria->addCondition('trade_id = :ordid');
$criteria->params[':ordid'] = $ordid;
$model = Shopcart::model()->find($criteria);
$model->trade_account = $buyer;
$model->status = $status;
if($model->update()){
$income = new Income();
$income->uid = $model->uid;
$income->recharge_money = $model->trade_money;
$income->time = time();
$income->detail = "你在".$model->trade_paytime.
" ,充值了".$model->trade_money." 个积分";
if($income->save()) {
$user = User::model()->findByPk(Yii::app()->user->id);
$have = $user->credit;
$add = $model->trade_money;
$user->credit = $have + $add;
if($user->update()){
return true;
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
由于yii初始路由方式为index.php?r=XX/XX 所以后面也算是带参的url,在支付成功后会出现验证失败的情况,解决办法是更改alipy_core.function.php中的paraFilter()方法
function paraFilter($para) {
$para_filter = array();
while (list ($key, $val) = each ($para)) {
if($key == "sign" || $key == "sign_type" || $val == "" || $key == 'r')continue;
else   $para_filter[$key] = $para[$key];
}
return $para_filter;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: