龚哥哥 - 山里男儿 爱生活、做自己!
PHP支付宝支付接口pc+wap MD5加密方式
发表于 2015-8-31 | PHP
<?php

/**
 * 支付宝支付驱动
 * @author  Devil
 * @version V_1.0.0
 */
class AlipayLibrary
{
    /**
     * [__construct 构造方法]
     */
    public function __construct(){}

    /**
     * [SoonPay 立即支付]
     * @param [array] $data [支付信息]
     */
    public function SoonPay($data, $config)
    {
        if(empty($data) || empty($config)) return false;

                //这里判断是否是手机访问,自己写一个方法接口。根据访问终端类型进行区分pc或wap
        if(IsMobile())
        {
            $this->SoonPayMobile($data, $config);
        } else {
            $this->SoonPayWeb($data, $config);
        }
    }

    /**
     * [SoonPayMobile wap支付]
     * @param  [array] $data   [参数列表]
     * @param  [array] $config [配置信息]   
     */
    private function SoonPayMobile($data, $config)
    {
        $request_token = $this->GetRequestToken($data, $config);

        $req_data = '<auth_and_execute_req><request_token>'.$request_token.'</request_token></auth_and_execute_req>';
        $parameter = array(
            'service'               =>   'alipay.wap.auth.authAndExecute',
            'format'                =>   'xml',
            'v'                     =>   '2.0',
            'partner'               =>   $config['id'],
            'sec_id'                =>   'MD5',
            'req_data'              =>   $req_data,
            'request_token'         =>   $request_token
        );

        $param = $this->GetParamSign($parameter, $config);
        header('location:http://wappaygw.alipay.com/service/rest.htm?'.$param['param']. '&sign='.md5($param['sign']));

    }

    /**
     * [GetRequestToken 获取临时token]
     * @param  [array] $data   [参数列表]
     * @param  [array] $config [配置信息]
     * @return [string]        [返回临时token]
     */
    private function GetRequestToken($data, $config)
    {
        $parameter = array(
            'service'               =>   'alipay.wap.trade.create.direct',
            'format'                =>   'xml',
            'v'                     =>   '2.0',
            'partner'               =>   $config['id'],
            'req_id'                =>   $data['order_sn'],
            'sec_id'                =>   'MD5',
            'req_data'              =>   $this->GetReqData($data, $config),
            'subject'               =>   $data['name'],
            'out_trade_no'          =>   $data['order_sn'],
            'total_fee'             =>   $data['total_price'],
            'seller_account_name'   =>   $config['name'],
            'call_back_url'         =>   $data['call_back_url'],
            'notify_url'            =>   $data['notify_url'],
            'out_user'              =>   $data['out_user'],
            'merchant_url'          =>   $data['merchant_url'],
        );

        $param = $this->GetParamSign($parameter, $config);
        $ret = urldecode(file_get_contents('http://wappaygw.alipay.com/service/rest.htm?'.$param['param'].'&sign='.md5($param['sign'])));

        $para_split = explode('&',$ret);
        //把切割后的字符串数组变成变量与数值组合的数组
        foreach ($para_split as $item) {
            //获得第一个=字符的位置
            $nPos = strpos($item,'=');
            //获得字符串长度
            $nLen = strlen($item);
            //获得变量名
            $key = substr($item,0,$nPos);
            //获得数值
            $value = substr($item,$nPos+1,$nLen-$nPos-1);
            //放入数组中
            $para_text[$key] = $value;
        }

        $req = Xml_Array($para_text['res_data']);
        if(empty($req['request_token']))
        {
            exit(header('location:'.__ROOT__.'index.php?g=Info&c=Prompt&f=PromptInfo&state=error&content=支付宝异常错误&url='.__ROOT__));
        }

        return $req['request_token'];
    }

    private function GetReqData($data, $config)
    {
        return '<direct_trade_create_req>
                    <subject>'.$data['name'].'</subject>
                    <out_trade_no>'.$data['order_sn'].'</out_trade_no>
                    <total_fee>'.$data['total_price'].'</total_fee>
                    <seller_account_name>'.$config['name'].'</seller_account_name>
                    <call_back_url>'.$data['call_back_url'].'</call_back_url>
                    <notify_url>'.$data['notify_url'].'</notify_url>
                    <out_user>'.$data['out_user'].'</out_user>
                    <merchant_url>'.$data['merchant_url'].'</merchant_url>
                    <pay_expire>3600</pay_expire>
                    <agent_id>0</agent_id>
                </direct_trade_create_req>';
    }

    /**
     * [SoonPayWeb web支付]
     * @param [array] $data   [订单信息]
     * @param [array] $config [配置信息]
     */
    private function SoonPayWeb($data, $config)
    {
        $parameter = array(
            'service'           => 'create_direct_pay_by_user',
            'partner'           => $config['id'],
            '_input_charset'    => ML_CHARSET,
            'notify_url'        => $data['notify_url'],
            'return_url'        => $data['call_back_url'],

            /* 业务参数 */
            'subject'           => $data['name'],
            'out_trade_no'      => $data['order_sn'],
            'price'             => $data['total_price'],

            'quantity'          => 1,
            'payment_type'      => 1,

            /* 物流参数 */
            'logistics_type'    => 'EXPRESS',
            'logistics_fee'     => 0,
            'logistics_payment' => 'BUYER_PAY_AFTER_RECEIVE',

            /* 买卖双方信息 */
            'seller_email'      => $config['name']
        );

        $param = $this->GetParamSign($parameter, $config);
        header('location:https://mapi.alipay.com/gateway.do?'.$param['param']. '&sign='.md5($param['sign']).'&sign_type=MD5');
    }

    /**
     * [GetParamSign 生成参数和签名]
     * @param  [array] $data   [待生成的参数]
     * @param  [array] $config [配置信息]
     * @return [array]         [生成好的参数和签名]
     */
    private function GetParamSign($data, $config)
    {
        $param = '';
        $sign  = '';
        ksort($data);

        foreach($data AS $key => $val)
        {
            $param .= "$key=" .urlencode($val). "&";
            $sign  .= "$key=$val&";
        }

        return array(
            'param' =>   substr($param, 0, -1),
            'sign'  =>   substr($sign, 0, -1).$config['key']
        );
    }

    /**
     * [Respond 异步处理]
     * @param  [array] $config [配置信息]
     * @return [array|string] [成功返回数据列表,失败返回no]
     */
    public function Respond($config)
    {
        if(empty($config)) return 'no';

        $data = empty($_POST) ? $_GET :  array_merge($_GET, $_POST);
        ksort($data);

        $sign = '';
        $sec = isset($data['sec_id']) ? $data['sec_id'] : '';
        if($sec == 'MD5')
        {
            $data_xml = json_decode(json_encode((array) simplexml_load_string($data['notify_data'])), true);
            $data = array_merge($data, $data_xml);
            $sign = 'service='.$data['service'].'&v='.$data['v'].'&sec_id='.$data['sec_id'].'&notify_data='.$data['notify_data'];
        } else {
            foreach($data AS $key=>$val)
            {
                if ($key != 'sign' && $key != 'sign_type' && $key != 'code')
                {
                    $sign .= "$key=$val&";
                }
            }
            $sign = substr($sign, 0, -1);
        }
        if(!isset($data['sign']) || md5($sign.$config['key']) != $data['sign']) return 'no';

        /* 支付状态 */
        $state = isset($data['trade_status']) ? $data['trade_status'] : $data['result'];
        switch($state)
        {
            case 'TRADE_SUCCESS':
                return $data;
                break;

            case 'TRADE_FINISHED':
                return $data;
                break;

               case 'success':
                return $data;
                break;
        }
        return 'no';
    }

}
?>

发表评论:

TOP