<?php
/**
* 微信支付驱动
* @author Devil
* @version v_1.0.0
*/
class WeiXin
{
private $config;
/**
* [__construct 从数据库读取微信申请的密钥]
*/
public function __construct()
{
$this->config = array(
'partner_id' => '',
'partner_key' => '',
'appid' => '',
'secret' => '',
'pay_sign_key' => '',
'notify_url' => '',
);
}
/**
* [Get_App_Code 生成支付信息]
* @param [array] $order [订单数据]
* @return [string] [支付信息]
*/
public function Get_App_Code($order)
{
/* 标题空格处理 */
if(!empty($order['subject'])) $order['subject'] = str_replace(array(' ', "\n", "\r"), '', $order['subject']);
$access_token = $this->Get_Access_Token();
$param = array(
'appid' => $this->config['appid'],
'traceid' => $order['out_trade_no'],
'noncestr' => md5(time().rand()),
'package' => $this->GetParamData($order),
'timestamp' => time(),
'sign_method' => 'sha1',
);
/* 获取支付签名 */
$param['app_signature'] = $this->GetAppSign($param);
/* 生成预支付 */
$data = $this->GenprePayInsert($param, $access_token);
/* 生成支付信息 */
if(!empty($data['prepayid']) && !empty($data['errmsg']) && $data['errmsg'] == 'Success')
{
$pay = array(
'appid' => $this->config['appid'],
'noncestr' => $param['noncestr'],
'package' => 'Sign=WXPay',
'partnerid' => $this->config['partner_id'],
'prepayid' => $data['prepayid'],
'timestamp' => $param['timestamp']
);
$pay['sign'] = $this->GetAppSign($pay);
return $pay;
}
return '';
}
/**
* [GenprePayInsert 生成预支付]
* @param [array] $param [请求参数]
* @param [token] $access_token [token]
*/
private function GenprePayInsert($param, $access_token)
{
return json_decode($this->Curl_Post('https://api.weixin.qq.com/pay/genprepay?access_token='.$access_token, json_encode($param)), true);
}
/**
* [GetAppSign signature签名生成]
* @param [array] $param [参数数据]
*/
private function GetAppSign($param)
{
unset($param['sign_method']);
$param['appkey'] = $this->config['pay_sign_key'];
ksort($param);
return sha1($this->SetParam($param));
}
/**
* [GetParamData 获取参数数据]
* @param [array] $data [订单数据]
* @return [array] [参数和sign]
*/
private function GetParamData($data)
{
$order = array(
'bank_type' => 'WX',
'body' => $data['subject'],
'total_fee' => $data['total_fee']*100, /* 微信要求需要乘以100 */
'spbill_create_ip' => $GLOBALS['pz_log']->Getip(),
'out_trade_no' => $data['out_trade_no'],
'notify_url' => $this->config['notify_url'],
'partner' => $this->config['partner_id'],
'fee_type' => 1,
'input_charset' => 'UTF-8',
'attach' => 'weixin',
);
ksort($order);
$sgin = strtoupper(md5($this->SetParam($order).'&key='.$this->config['partner_key']));
return $this->SetParam($order, true).'&sign='.$sgin;
}
/**
* [Curl_Post curl模拟post]
* @param [string] $url [请求地址]
* @param [array] $post [发送的post数据]
*/
private function Curl_Post($url, $post) {
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => false,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post,
);
$ch = curl_init($url);
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* [SetParam url模式字符串拼接]
* @param [array] $param [需要拼接的参数]
* @param [boolean] $is_urlencode [是否urlencode转义value]
*/
private function SetParam($param, $is_urlencode = false)
{
$str = '';
foreach($param as $k=>$v)
{
if($is_urlencode)
{
$str .= $k.'='.urlencode($v).'&';
} else {
$str .= $k.'='.$v.'&';
}
}
return substr($str, 0, -1);
}
/**
* [Get_Access_Token 获取微信支付token]
* @return [string] [token]
*/
private function Get_Access_Token()
{
if(file_exists('/tmp/weixin_pay_token.json'))
{
$temp = json_decode(file_get_contents('/tmp/weixin_pay_token.json'), true);
if($temp['time'] > time()) $token = $temp['token'];
}
if(empty($token)) $token = $this->Set_Access_Token();
return $token;
}
/**
* [Set_Access_Token token设置]
* @return [string] [token]
*/
private function Set_Access_Token()
{
$temp = json_decode(file_get_contents('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$this->config["appid"].'&secret='.$this->config['secret']), true);
if(!empty($temp['access_token']))
{
$data = array(
'token' => $temp['access_token'],
'time' => time()+7000
);
if(!is_dir('/tmp')) mkdir('/tmp');
file_put_contents('/tmp/weixin_pay_token.json', json_encode($data));
return $temp['access_token'];
}
return '';
}
/**
* [Respond 响应操作]
* @return [string] [响应处理结果]
*/
public function Respond()
{
$param = $_GET;
if(empty($param)) return;
$param_sign = $param['sign']; unset($param['sign']);
ksort($param);
$sign = strtoupper(md5($this->SetParam($param).'&key='.$this->config['partner_key']));
if($param_sign != $sign) return;
/* check_money方法 价格校验是否一致 */
if(isset($param['trade_state']) && $param['trade_state'] == 0 && check_money($param['out_trade_no'], $param['total_fee']/100))
{
//如果成功这里就可以处理自己的订单了,标识符是 $param['out_trade_no']
}
}
}
?>