codeigniter版支付宝接口源代码v0.1

来源:互联网 发布:腾讯游戏平台for mac 编辑:程序博客网 时间:2024/04/29 09:49

版本:CodeIgniter_2.0.1
最近使用CodeIgniter写商城系统的代码需要集成支付宝即时到账功能进去
看了下支付宝官方发布的代码主要包括2部分
第一部分:
支付宝外部服务接口控制类
alipay_service.php
付款过程中服务器通知类
alipay_notify.php
以及支付宝接口公用函数
alipay_function.php
第二部分:
支付宝主动通知调用页面(服务器异步通知页面)
notify_url.php
付完款后跳转的页面(页面跳转同步通知页面)
return_url.php
其次就是alipay的配置文件
alipay_config.php

下面是我按codeigniter框架的思路构建:

1.创建自己的类库到codeigniter, 同样是两个类Alipay_service和Alipay_notify

2.创建alipay模型,主要功能是构建支付提交表单,通知函数,及数据库更新支付宝交易号功能

3.创建alipay配置文件

4.最后就是调用了,控制层调用alipay模型就可以了

使用示例:

控制层代码
application/controllers/product.php 代码片段

//生成在线支付链接      $this->load->model('alipay_model');$data['alipay_form'] = $this->alipay_model->build_form($data['order_sn'], $data['product_name'], $data['total']);$this->load->view('product/quick_buy', $data);

上面代码的意思是给alipay_model的build_form函数传入参数订单号,产品名,金额

显示层代码
application/views/product/quick_buy.php 代码片段

<?php if ('online' == $payment) {    echo $alipay_form;}?>

(上面代码意思是如果是在线支付就显示使用支付宝支付)

下面是codeigniter版支付宝接口源代码v0.1分享给大家, 希望对有需要的人有所帮助, 因为我的数据库环境不同,你需要修改的地方主要是交易成功数据库的更新,其他代码你也可以根据需要进行修改
(小技巧:双击可以选择所有代码)
application/libraries/alipay/Alipay_service.php

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');/** * Codeigiter的支付宝外部服务接口控制 * @author http://blog.runphp.net * @version 0.1 */require_once("alipay_function.php");class Alipay_service {         var $gateway;           //网关地址    var $_key;              //安全校验码    var $mysign;            //签名结果    var $sign_type;         //签名类型    var $parameter;         //需要签名的参数数组    var $_input_charset;    //字符编码格式     function __construct($parameter)    {        self::Alipay_service(            $parameter['parameter'],             $parameter['key'],             $parameter['sign_type']        );    }         /**     * 构造函数     * 从配置文件及入口文件中初始化变量     * @param array $parameter 需要签名的参数数组     * @param string $key 安全校验码     * @param string $sign_type 签名类型     */     public function Alipay_service($parameter, $key, $sign_type)     {                 $this->gateway      = "https://www.alipay.com/cooperate/gateway.do?";        $this->_key        = $key;        $this->sign_type   = $sign_type;                 $this->parameter   = para_filter($parameter);         //设定_input_charset的值,为空值的情况下默认为GBK        if($this->parameter['_input_charset'] == '')            $this->parameter['_input_charset'] = 'GBK';         $this->_input_charset   = $this->parameter['_input_charset'];         //获得签名结果        $sort_array   = arg_sort($this->parameter);    //得到从字母a到z排序后的签名参数数组        $this->mysign = build_mysign($sort_array,$this->_key,$this->sign_type);    }      /**     *      * Enter description here ...     */    function build_form() {        //GET方式传递        $sHtml = "<form id='alipaysubmit' name='alipaysubmit' action='".$this->gateway."_input_charset=".$this->parameter['_input_charset']."' method='get'>";        //POST方式传递(GET与POST二必选一)        //$sHtml = "<form id='alipaysubmit' name='alipaysubmit' action='".$this->gateway."_input_charset=".$this->parameter['_input_charset']."' method='post'>";         while (list ($key, $val) = each ($this->parameter)) {            $sHtml.= "<input type='hidden' name='".$key."' value='".$val."'/>";        }         $sHtml = $sHtml."<input type='hidden' name='sign' value='".$this->mysign."'/>";        $sHtml = $sHtml."<input type='hidden' name='sign_type' value='".$this->sign_type."'/>";         //submit按钮控件请不要含有name属性        $sHtml = $sHtml."<input type='submit' value='支付宝确认付款'></form>";                 //$sHtml = $sHtml."<script>document.forms['alipaysubmit'].submit();</script>";                 return $sHtml;    } }

application/libraries/alipay/Alipay_notify.php

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');/** * Codeigiter付款过程中服务器通知类 * @author http://blog.runphp.net * @version 0.1 */ require_once("alipay_function.php"); class Alipay_notify {    var $gateway;           //网关地址    var $_key;              //安全校验码    var $partner;           //合作伙伴ID    var $sign_type;         //签名方式 系统默认    var $mysign;            //签名结果    var $_input_charset;    //字符编码格式    var $transport;         //访问模式     function __construct($parameter)    {               self::Alipay_notify(            $parameter['partner'],             $parameter['key'],             $parameter['sign_type'],             $parameter['_input_charset'],             $parameter['transport']        );    }    /**构造函数    *从配置文件中初始化变量    *$partner 合作身份者ID    *$key 安全校验码    *$sign_type 签名类型    *$_input_charset 字符编码格式    *$transport 访问模式     */    function Alipay_notify($partner,$key,$sign_type,$_input_charset = "GBK",$transport= "https") {         $this->transport = $transport;        if($this->transport == "https") {            $this->gateway = "https://www.alipay.com/cooperate/gateway.do?";        }else {            $this->gateway = "http://notify.alipay.com/trade/notify_query.do?";        }        $this->partner          = $partner;        $this->_key    = $key;        $this->mysign           = "";        $this->sign_type     = $sign_type;        $this->_input_charset   = $_input_charset;    }     /********************************************************************************/     /**对notify_url的认证    *返回的验证结果:true/false     */    function notify_verify() {        //获取远程服务器ATN结果,验证是否是支付宝服务器发来的请求        if($this->transport == "https") {            $veryfy_url = $this->gateway. "service=notify_verify" ."&partner=" .$this->partner. "¬ify_id=".$_POST["notify_id"];        } else {            $veryfy_url = $this->gateway. "partner=".$this->partner."¬ify_id=".$_POST["notify_id"];        }        $veryfy_result = $this->get_verify($veryfy_url);         //生成签名结果        if(empty($_POST)) {                         //判断POST来的数组是否为空            return false;        }        else {                  $post          = para_filter($_POST);       //对所有POST返回的参数去空            $sort_post     = arg_sort($post);       //对所有POST反馈回来的数据排序            $this->mysign  = build_mysign($sort_post,$this->_key,$this->sign_type);   //生成签名结果                 //写日志记录            log_result("veryfy_result=".$veryfy_result."\n notify_url_log:sign=".$_POST["sign"]."&mysign=".$this->mysign.",".create_linkstring($sort_post));                 //判断veryfy_result是否为ture,生成的签名结果mysign与获得的签名结果sign是否一致            //$veryfy_result的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关            //mysign与sign不等,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关            if (preg_match("/true$/i",$veryfy_result) && $this->mysign == $_POST["sign"]) {                return true;            } else {                return false;            }        }    }     /********************************************************************************/     /**对return_url的认证    *return 验证结果:true/false     */    function return_verify() {        //获取远程服务器ATN结果,验证是否是支付宝服务器发来的请求        if($this->transport == "https") {            $veryfy_url = $this->gateway. "service=notify_verify" ."&partner=" .$this->partner. "¬ify_id=".$_GET["notify_id"];        } else {            $veryfy_url = $this->gateway. "partner=".$this->partner."¬ify_id=".$_GET["notify_id"];        }        $veryfy_result = $this->get_verify($veryfy_url);         //生成签名结果        if(empty($_GET)) {                          //判断GET来的数组是否为空            return false;        }        else {            $get          = para_filter($_GET);     //对所有GET反馈回来的数据去空            $sort_get     = arg_sort($get);         //对所有GET反馈回来的数据排序            $this->mysign  = build_mysign($sort_get,$this->_key,$this->sign_type);    //生成签名结果                 //写日志记录            //log_result("veryfy_result=".$veryfy_result."\n return_url_log:sign=".$_GET["sign"]."&mysign=".$this->mysign."&".create_linkstring($sort_get));                 //判断veryfy_result是否为ture,生成的签名结果mysign与获得的签名结果sign是否一致            //$veryfy_result的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关            //mysign与sign不等,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关            if (preg_match("/true$/i",$veryfy_result) && $this->mysign == $_GET["sign"]) {                            return true;            }else {                return false;            }        }    }     /********************************************************************************/     /**获取远程服务器ATN结果    *$url 指定URL路径地址    *return 服务器ATN结果集     */    function get_verify($url,$time_out = "60") {        $urlarr     = parse_url($url);        $errno      = "";        $errstr     = "";        $transports = "";        if($urlarr["scheme"] == "https") {            $transports = "ssl://";            $urlarr["port"] = "443";        } else {            $transports = "tcp://";            $urlarr["port"] = "80";        }        $fp=@fsockopen($transports . $urlarr['host'],$urlarr['port'],$errno,$errstr,$time_out);        if(!$fp) {            die("ERROR: $errno - $errstr<br />\n");        } else {            fputs($fp, "POST ".$urlarr["path"]." HTTP/1.1\r\n");            fputs($fp, "Host: ".$urlarr["host"]."\r\n");            fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");            fputs($fp, "Content-length: ".strlen($urlarr["query"])."\r\n");            fputs($fp, "Connection: close\r\n\r\n");            fputs($fp, $urlarr["query"] . "\r\n\r\n");            while(!feof($fp)) {                $info[]=@fgets($fp, 1024);            }            fclose($fp);            $info = implode(",",$info);            return $info;        }    }     /********************************************************************************/ }?>

application/libraries/alipay/alipay_function.php

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');/** *功能:支付宝接口公用函数 * @author http://blog.runphp.net * @version 0.1 */  /**生成签名结果 *$array要签名的数组 *return 签名结果字符串*/function build_mysign($sort_array,$key,$sign_type = "MD5") {    $prestr = create_linkstring($sort_array);       //把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串    $prestr = $prestr.$key;                         //把拼接后的字符串再与安全校验码直接连接起来    $mysgin = sign($prestr,$sign_type);             //把最终的字符串签名,获得签名结果    return $mysgin;}    /********************************************************************************/ /**把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串    *$array 需要拼接的数组    *return 拼接完成以后的字符串*/function create_linkstring($array) {    $arg  = "";    while (list ($key, $val) = each ($array)) {        $arg.=$key."=".$val."&";    }    $arg = substr($arg,0,count($arg)-2);             //去掉最后一个&字符    return $arg;} /********************************************************************************/ /**除去数组中的空值和签名参数    *$parameter 签名参数组    *return 去掉空值与签名参数后的新签名参数组 */function para_filter($parameter) {    $para = array();    while (list ($key, $val) = each ($parameter)) {        if($key == "sign" || $key == "sign_type" || $val == "")continue;        else    $para[$key] = $parameter[$key];    }    return $para;} /********************************************************************************/ /**对数组排序    *$array 排序前的数组    *return 排序后的数组 */function arg_sort($array) {    ksort($array);    reset($array);    return $array;} /********************************************************************************/ /**签名字符串    *$prestr 需要签名的字符串    *return 签名结果 */function sign($prestr,$sign_type) {    $sign='';    if($sign_type == 'MD5') {        $sign = md5($prestr);    }elseif($sign_type =='DSA') {        //DSA 签名方法待后续开发        die("DSA 签名方法待后续开发,请先使用MD5签名方式");    }else {        die("支付宝暂不支持".$sign_type."类型的签名方式");    }    return $sign;} /********************************************************************************/ // 日志消息,把支付宝返回的参数记录下来// 请注意服务器是否开通fopen配置function  log_result($word) {    $fp = fopen("log.txt","a");    flock($fp, LOCK_EX) ;    fwrite($fp,"执行日期:".strftime("%Y%m%d%H%M%S",time())."\n".$word."\n");    flock($fp, LOCK_UN);    fclose($fp);}    /********************************************************************************/ /**实现多种字符编码方式    *$input 需要编码的字符串    *$_output_charset 输出的编码格式    *$_input_charset 输入的编码格式    *return 编码后的字符串 */function charset_encode($input,$_output_charset ,$_input_charset) {    $output = "";    if(!isset($_output_charset) )$_output_charset  = $_input_charset;    if($_input_charset == $_output_charset || $input ==null ) {        $output = $input;    } elseif (function_exists("mb_convert_encoding")) {        $output = mb_convert_encoding($input,$_output_charset,$_input_charset);    } elseif(function_exists("iconv")) {        $output = iconv($_input_charset,$_output_charset,$input);    } else die("sorry, you have no libs support for charset change.");    return $output;} /********************************************************************************/ /**实现多种字符解码方式    *$input 需要解码的字符串    *$_output_charset 输出的解码格式    *$_input_charset 输入的解码格式    *return 解码后的字符串 */function charset_decode($input,$_input_charset ,$_output_charset) {    $output = "";    if(!isset($_input_charset) )$_input_charset  = $_input_charset ;    if($_input_charset == $_output_charset || $input ==null ) {        $output = $input;    } elseif (function_exists("mb_convert_encoding")) {        $output = mb_convert_encoding($input,$_output_charset,$_input_charset);    } elseif(function_exists("iconv")) {        $output = iconv($_input_charset,$_output_charset,$input);    } else die("sorry, you have no libs support for charset changes.");    return $output;} /*********************************************************************************/ /**用于防钓鱼,调用接口query_timestamp来获取时间戳的处理函数注意:由于低版本的PHP配置环境不支持远程XML解析,因此必须服务器、本地电脑中装有支持DOMDocument、SSL的PHP配置环境。建议本地调试时使用PHP开发软件*$partner 合作身份者ID*return 时间戳字符串*/function query_timestamp($partner) {    $URL = "https://mapi.alipay.com/gateway.do?service=query_timestamp&partner=".$partner;    $encrypt_key = "";//若要使用防钓鱼,请取消下面的4行注释//    $doc = new DOMDocument();//    $doc->load($URL);//    $itemEncrypt_key = $doc->getElementsByTagName( "encrypt_key" );//    $encrypt_key = $itemEncrypt_key->item(0)->nodeValue;//    return $encrypt_key;} ?>

application/models/alipay_model.php

<?php/** * 支付宝模型 * @version 0.1 * @author http://blog.runphp.net * */class Alipay_model extends CI_Model{         var $alipay_config;            function __construct ()    {        parent::__construct();        $this->config->load('alipay', TRUE);        $this->alipay_config = $this->config->item('alipay');    }    /**     *      * 服务器异步通知     */    function notify_verify ()    {        $tmp = array(            'partner'        => $this->alipay_config['partner'],             'key'            => $this->alipay_config['key'],             'sign_type'      => $this->alipay_config['sign_type'],            '_input_charset' => $this->alipay_config['sign_type'],            'transport'      => $this->alipay_config['transport'],        );                             $this->load->library('alipay/alipay_notify', $tmp);        $verify_result = $this->alipay_notify->notify_verify();                 if($verify_result) {            $dingdan           = $_POST['out_trade_no'];    //获取支付宝传递过来的订单号            $total             = $_POST['total_fee'];       //获取支付宝传递过来的总价格                 if($_POST['trade_status'] == 'TRADE_FINISHED' ||$_POST['trade_status'] == 'TRADE_SUCCESS') {    //交易成功结束                echo "success";     //请不要修改或删除                } else {                echo "success";     //其他状态判断。普通即时到帐中,其他状态不用判断,直接打印success。            }            self::update_status($_POST['trade_no'], $dingdan);        } else {            echo "fail";         }    }         /**     *      * 页面跳转同步通知     */    function return_verify ()    {        $tmp = array(            'partner'        => $this->alipay_config['partner'],             'key'            => $this->alipay_config['key'],             'sign_type'      => $this->alipay_config['sign_type'],            '_input_charset' => $this->alipay_config['sign_type'],            'transport'      => $this->alipay_config['transport'],        );                             $this->load->library('alipay/alipay_notify', $tmp);        $verify_result = $this->alipay_notify->return_verify();        if($verify_result) {//验证成功                 $dingdan           = $_GET['out_trade_no'];    //获取订单号            $total_fee         = $_GET['total_fee'];        //获取总价格             if($_GET['trade_status'] == 'TRADE_FINISHED' || $_GET['trade_status'] == 'TRADE_SUCCESS') {                         } else {                return  $_GET['trade_status'];            }            self::update_status($_GET['trade_no'], $dingdan);        } else {            return "fail";        }    }         /**     *      * 更新订单状态(更新支付宝订单号)     * @param string $alipay_trade_no 支付宝订单号     * @param string $order_sn 商户订单号     */    function update_status ($alipay_trade_no, $order_id)    {        //请在这里加上商户的业务逻辑程序代        $this->db->where('name', $order_id);        $this->db->update('sl_order', array('trade_no' => $alipay_trade_no));     }         /**     *      * 构造提交表单     * @param 订单编号 $order_id     * @param 订单名 $order_name     * @param 订单金额 $money     */    function build_form ($order_id, $order_name, $money)    {                 /*以下参数是需要通过下单时的订单数据传入进来获得*/        //必填参数        $out_trade_no = $order_id;      //请与贵网站订单系统中的唯一订单号匹配        $subject      = $order_name;    //订单名称,显示在支付宝收银台里的“商品名称”里,显示在支付宝的交易管理的“商品名称”的列表里。        $body         = ''; //订单描述、订单详细、订单备注,显示在支付宝收银台里的“商品描述”里        $total_fee    = $money; //订单总金额,显示在支付宝收银台里的“应付总额”里                 //扩展功能参数——默认支付方式        /*        $pay_mode     = $_POST['pay_bank'];        if ($pay_mode == "directPay") {            $paymethod    = "directPay";    //默认支付方式,四个值可选:bankPay(网银); cartoon(卡通); directPay(余额); CASH(网点支付)            $defaultbank  = "";        }        else {            $paymethod    = "bankPay";      //默认支付方式,四个值可选:bankPay(网银); cartoon(卡通); directPay(余额); CASH(网点支付)            $defaultbank  = $pay_mode;      //默认网银代号,代号列表见http://club.alipay.com/read.php?tid=8681379        }*/        $paymethod    = "directPay";        $defaultbank  = "";                 //扩展功能参数——防钓鱼        //请慎重选择是否开启防钓鱼功能        //exter_invoke_ip、anti_phishing_key一旦被使用过,那么它们就会成为必填参数        //开启防钓鱼功能后,服务器、本机电脑必须支持远程XML解析,请配置好该环境。        //若要使用防钓鱼功能,请打开class文件夹中alipay_function.php文件,找到该文件最下方的query_timestamp函数,根据注释对该函数进行修改        //建议使用POST方式请求数据        $anti_phishing_key  = '';           //防钓鱼时间戳        $exter_invoke_ip =  $this->input->ip_address();               //获取客户端的IP地址,建议:编写获取客户端IP地址的程序        //如:        //$exter_invoke_ip = '202.1.1.1';        //$anti_phishing_key = query_timestamp($partner);       //获取防钓鱼时间戳函数                 //扩展功能参数——其他        $extra_common_param = '';           //自定义参数,可存放任何内容(除=、&等特殊字符外),不会显示在页面上        $buyer_email        = '';           //默认买家支付宝账号                 //扩展功能参数——分润(若要使用,请按照注释要求的格式赋值)        $royalty_type       = "";           //提成类型,该值为固定值:10,不需要修改        $royalty_parameters = "";        //提成信息集,与需要结合商户网站自身情况动态获取每笔交易的各分润收款账号、各分润金额、各分润说明。最多只能设置10条        //各分润金额的总和须小于等于total_fee        //提成信息集格式为:收款方Email_1^金额1^备注1|收款方Email_2^金额2^备注2        //如:        //royalty_type = "10"        //royalty_parameters    = "111@126.com^0.01^分润备注一|222@126.com^0.01^分润备注二"                 //$alipay_config = $this->alipay_config;        $parameter = array(            "service"           => "create_direct_pay_by_user",  //接口名称,不需要修改            "payment_type"      => "1",                          //交易类型,不需要修改                 //获取配置文件中的值            "partner"           => $this->alipay_config['partner'],            "seller_email"      => $this->alipay_config['seller_email'],            "return_url"        => $this->alipay_config['return_url'],            "notify_url"        => $this->alipay_config['notify_url'],            "_input_charset"    => $this->alipay_config['_input_charset'],            "show_url"          => $this->alipay_config['show_url'],                 //从订单数据中动态获取到的必填参数            "out_trade_no"      => $out_trade_no,            "subject"           => $subject,            "body"              => $body,            "total_fee"         => $total_fee,                 //扩展功能参数——网银提前            "paymethod"         => $paymethod,            "defaultbank"       => $defaultbank,                 //扩展功能参数——防钓鱼            "anti_phishing_key" => $anti_phishing_key,            "exter_invoke_ip"   => $exter_invoke_ip,                 //扩展功能参数——自定义参数            "buyer_email"       => $buyer_email,            "extra_common_param"=> $extra_common_param,                 //扩展功能参数——分润            "royalty_type"      => $royalty_type,            "royalty_parameters"=> $royalty_parameters        );                 $tmp = array('parameter' => $parameter, 'key' => $this->alipay_config['key'], 'sign_type' =>$this->alipay_config['sign_type']);                             $this->load->library('alipay/alipay_service', $tmp);        return $this->alipay_service->build_form();           }      }

最好别丢了配置文件了(自己按注释填好)
application/config/alipay.php

<?php//合作身份者ID,以2088开头的16位纯数字$config['partner']      = ""; //安全检验码,以数字和字母组成的32位字符$config['key']              = ""; //签约支付宝账号或卖家支付宝帐户$config['seller_email'] = ""; //交易过程中服务器通知的页面 要用 http://格式的完整路径,不允许加?id=123这类自定义参数$config['notify_url']       = ""; //付完款后跳转的页面 要用 http://格式的完整路径,不允许加?id=123这类自定义参数$config['return_url']       = ""; //网站商品的展示地址,不允许加?id=123这类自定义参数$config['show_url']     = "http://blog.runphp.net"; //收款方名称,如:公司名称、网站名称、收款人姓名等$config['mainname']     = "heui"; //↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑//$config['total_fee']    = 1;  //订单总金额,显示在支付宝收银台里的“应付总额”里 //签名方式 不需修改$config['sign_type']        = "MD5"; //字符编码格式 目前支持 GBK 或 utf-8$config['_input_charset']   = "utf-8"; //访问模式,根据自己的服务器是否支持ssl访问,若支持请选择https;若不支持请选择http$config['transport']        = "http"; ?>



0 0
原创粉丝点击