龚哥哥 爱生活、做自己!
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