<?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'].'¬ify_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';
}
}
?>