Yii 支付宝接口

十度 Yii 2016年01月22日 收藏

这是网页支付接口
1、先把下载的支付宝集成包解压至protected/extensions/alipay下
2、在yii配置文件中main.php配置好相关参数:

'alipay'=>array(
    'class'=>'application.extensions.alipay.Alipay',
    'partner'=>'xxx', // your partner id
    'key'=>'xxx', // your key
    'seller_email'=>'xxx',// your email
    'call_back_url'=>'http://xxx/order/backalipay',//同步回调地址
    'notify_url'=>'http://xxx/order/notifyalipay', //异步通知地址,注意设置权限为Alipay可返回数据
    'merchant_url'=>'http://xxx/order/', //支付完后自动跳回商户地址
),

3、在extensions/alipay下写一个Alipay.php类

<?php
class Alipay {
    private $format = "xml";
    private $_input_charset = "utf-8";
    private $sign_type = "MD5";
    private $v = "2.0";
    public $partner;
    public $key;
    public $merchant_url;
    public $notify_url;
    public $call_back_url;
    public $seller_email;
    public $alipay_config;
 
 
    public function init()
    {
        require_once("alipay.config.php");
        require_once("lib/alipay_notify.class.php");
        require_once("lib/alipay_core.function.php");
        require_once("lib/alipay_md5.function.php");
        require_once("lib/alipay_submit.class.php");
        $this->alipay_config = $alipay_config;
        $this->alipay_config['key'] = $this->key;
        $this->alipay_config['partner'] = $this->partner;
    }
 
    public function buildForm($request)
    {
        //构造要请求的参数数组,无需改动
        $req_id = date('Ymdhis');
        $req_data = '<direct_trade_create_req><notify_url>' . $this->notify_url . '</notify_url><call_back_url>' . $this->call_back_url . '</call_back_url><seller_account_name>' . $this->seller_email . '</seller_account_name><out_trade_no>' . $request->out_trade_no . '</out_trade_no><subject>' . $request->subject . '</subject><total_fee>' . $request->total_fee . '</total_fee><merchant_url>' . $this->merchant_url . '</merchant_url></direct_trade_create_req>';
        $para_token = array(
                "service" => "alipay.wap.trade.create.direct",
                "partner" => trim($this->partner),
                "key" => $this->key,
                'sec_id'  => $this->sign_type,
                "format"  => $this->format,
                "v" => $this->v,
                "req_id"    => $req_id,
                "req_data"  => $req_data,
                "_input_charset"    => trim(strtolower($this->_input_charset))
        );
 
        //建立请求
        $alipaySubmit = new AlipaySubmit($this->alipay_config);
        $html_text = $alipaySubmit->buildRequestHttp($para_token);
 
        //URLDECODE返回的信息
        $html_text = urldecode($html_text);
 
        //解析远程模拟提交后返回的信息
        $para_html_text = $alipaySubmit->parseResponse($html_text);
 
        //获取request_token
        $request_token = $para_html_text['request_token'];
 
        /**************************根据授权码token调用交易接口alipay.wap.auth.authAndExecute**************************/
 
        //业务详细
        $req_data = '<auth_and_execute_req><request_token>' . $request_token . '</request_token></auth_and_execute_req>';
        //必填
 
        //构造要请求的参数数组,无需改动
        $parameter = array(
                "service" => "alipay.wap.auth.authAndExecute",
                "partner" => trim($this->partner),
                'sec_id'  => $this->sign_type,
                "format"  => $this->format,
                "v" => $this->v,
                "req_id"    => $req_id,
                "req_data"  => $req_data,
                "_input_charset"    => trim(strtolower($this->_input_charset))
        );
 
        //建立请求
        $alipaySubmit = new AlipaySubmit($this->alipay_config);
        return $alipaySubmit->buildRequestForm($parameter,"get", "确认");
    }
 
    public function verifyNotify(){
        $alipayNotify = new AlipayNotify($this->alipay_config);
        return $alipayNotify->verifyNotify();        
    }
 
    public function verifyReturn(){
        $alipayNotify = new AlipayNotify($this->alipay_config);
        return $alipayNotify->verifyReturn();
    }
 
    public function  log_result($word) {
        $file = Yii::getPathOfAlias('ext').DIRECTORY_SEPARATOR.'alipay'. DIRECTORY_SEPARATOR .'log_alipay.txt';
        $fp = fopen($file,"a");    
        flock($fp, LOCK_EX) ;
        fwrite($fp,$word.":执行日期:".strftime("%Y%m%d%H%I%S",time())."\t\n");
        flock($fp, LOCK_UN); 
        fclose($fp);
    }
}

4、在OrderController.php中完成回调操作

public function actionAlipay(){
        $uid = Yii::app()->user->id;
        //相关逻辑
        $this->alipayRequest($total, $order_id, $uid);
    }
 
    public function alipayRequest($total,$order_id,$uid){
        $alipay = Yii::app()->alipay;
        $request->out_trade_no = $order_id;
        $request->subject = "订单号:" . $order_id;
        $request->body = "订单金额" . $total . "元";
        $request->total_fee = $total;
        $form = $alipay->buildForm($request);
        echo $form;
        exit();
    }
 
    public function actionNotifyalipay(){
        $user_id = Yii::app()->user->id;
        $alipay = Yii::app()->alipay;
        $verify_result = $alipay->verifyNotify();
        if($verify_result) {
            $doc = new DOMDocument();
            $doc->loadXML($notify_data);
 
            if( ! empty($doc->getElementsByTagName( "notify" )->item(0)->nodeValue) ) {
                //商户订单号
                $out_trade_no = $doc->getElementsByTagName( "out_trade_no" )->item(0)->nodeValue;
                //支付宝交易号
                $trade_no = $doc->getElementsByTagName( "trade_no" )->item(0)->nodeValue;
                //交易状态
                $trade_status = $doc->getElementsByTagName( "trade_status" )->item(0)->nodeValue;
                //接口示例文件中,下面用的$_POST['trade_status'],但是我用POST获取不到值,直接用上面取出的$trade_status也可以。
                if($trade_status == 'TRADE_FINISHED' || $trade_status == 'TRADE_SUCCESS') { 
                    //判断该订单是否已处理
                    //处理业务逻辑
                    echo 'success';
                }
            }
        }else{
            echo 'fail';    
        }         
    }
 
    /**
     * 付款成功页
     * @return [type] [description]
     */
    public function actionBackalipay() {
        $user_id = Yii::app()->user->id;
        $alipay = Yii::app()->alipay;
        $verify_result = $alipay->verifyReturn();
        if($verify_result) {
            //商户订单号
            $out_trade_no = $_GET['out_trade_no'];
            //支付宝交易号
            $trade_no = $_GET['trade_no'];
            //交易状态
            $result = $_GET['result'];
            //判断该订单是否已处理
            //处理业务逻辑
        }else {
            $msg = '验证失败,稍后自动重试';
        }
        $this->render('backalipay',array(
            'msg'=>$msg,
            'order_id'=>$out_trade_no,
        ));
    }