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

来源:互联网 发布:max数据库尚未运行 编辑:程序博客网 时间:2024/04/29 03:12

使用的是官方提供方的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;}
0 1