/**
* 组合微信app支付 获得prepayid
* @param int $order_num
*/
private function _wxpay_request($order_num = 0)
{
//判断订单编号必须是数组并且不为0
check_order_num($order_num);
//引入微信支付类
libraries_include(wxpay/, wxpayhelper.app.php);
//支付接口发起url
$pay_url = $this->config->item(pay_url);
//通知地址
$notify_url = $this->config->item(weixin_notify_url);
//微信配置
$pay_config = $this->config->item(weixin_pay_need);
$helper = new wxpayhelper();
//随机字符串
$nonce_str = $helper->getrandchar(32);
//获得订单数据
$order_data = $this->order_model->get_one($order_num);
$data[appid] = $pay_config['appid'];//微信开放平台审核通过的应用appid
$data[body] = $pay_config['body'];//商品或支付单简要描述
$data[mch_id] = $pay_config['mch_id'];//商户号
$data[nonce_str] = $nonce_str;//随机字符串
$data[notify_url] = $notify_url;//通知地址
$data[out_trade_no] = $order_data[order_num];//商户订单号
$data[spbill_create_ip] = $helper->get_client_ip();//终端ip
$data[total_fee] = $order_data['total'] * 100;//总金额
$data[trade_type] = app;//交易类型
$data[sign] = $helper->getsign($data, $pay_config['partner']);//签名
$xml = $helper->arraytoxml($data);
$response = $helper->postxmlcurl($xml, $pay_url);
//将微信返回的结果xml转成数组
$responsearr = $helper->xmltoarray($response);
if(isset($responsearr[return_code]) && $responsearr[return_code]=='success' && isset($responsearr['result_code']) && $responsearr[result_code]=='success'){
$data_pay[appid] = $pay_config['appid'];
$data_pay[noncestr] = $nonce_str;
$data_pay[package] = sign=wxpay;
$data_pay[partnerid] = $pay_config['mch_id'];
$data_pay[prepayid] = $responsearr['prepay_id'];
$data_pay[timestamp] = time();
$data_pay[sign] = $helper->getsign($data_pay, $pay_config['partner']);//二次签名
$this->response = array('status'=>0, 'msg'=>'success', 'data'=>$data_pay);
}else{
$return_msg = $responsearr['err_code_des'];
$this->response = array('status'=>0, 'msg'=>$return_msg, 'data'=>$responsearr);
}
}
//helper.php
formatparameters($data, false);
//签名步骤二:在string后加入key
$string = $string . &key= . $key;
//签名步骤三:md5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
function formatparameters($paramap, $urlencode)
{
$buff = ;
ksort($paramap);
foreach ($paramap as $k => $v) {
if($k==sign){
continue;
}
if ($urlencode) {
$v = urlencode($v);
}
$buff .= $k . = . $v . &;
}
$reqpar;
if (strlen($buff) > 0) {
$reqpar = substr($buff, 0, strlen($buff) - 1);
}
return $reqpar;
}
/**
* 得到签名
* @param object $obj
* @param string $api_key
* @return string
*/
function getsign($obj, $api_key)
{
foreach ($obj as $k => $v)
{
$parameters[strtolower($k)] = $v;
}
//签名步骤一:按字典序排序参数
ksort($parameters);
$string = $this->formatbizqueryparamap($parameters, false);
//签名步骤二:在string后加入key
$string = $string.&key=.$api_key;
//签名步骤三:md5加密
$result = strtoupper(md5($string));
return $result;
}
/**
* 获取指定长度的随机字符串
* @param int $length
* @return ambigous
*/
function getrandchar($length){
$str = null;
$strpol = abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz;
$max = strlen($strpol)-1;
for($i=0;$i $str.=$strpol[rand(0,$max)];//rand($min,$max)生成介于min和max两个数之间的一个随机整数
}
return $str;
}
/**
* 数组转xml
* @param array $arr
* @return string
*/
function arraytoxml($arr)
{
header(content-type: text/xml);
$xml = '';
foreach ($arr as $key=>$val)
{
if (is_numeric($val))
{
$xml.=.$val..$key.>;
}
else
$xml.=.$key.>;
}
$xml.= '';
return $xml;
}
/**
* 以post方式提交xml到对应的接口url
*
* @param string $xml 需要post的xml数据
* @param string $url url
* @param bool $usecert 是否需要证书,默认不需要
* @param int $second url执行超时时间,默认30s
* @throws wxpayexception
*/
function postxmlcurl($xml, $url, $second=30, $usecert=false, $sslcert_path='', $sslkey_path='')
{
$ch = curl_init();
//设置超时
curl_setopt($ch, curlopt_timeout, $second);
curl_setopt($ch,curlopt_url, $url);
//设置header
curl_setopt($ch, curlopt_header, false);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, curlopt_returntransfer, true);
curl_setopt($ch,curlopt_ssl_verifypeer,false);
curl_setopt($ch,curlopt_ssl_verifyhost,false);
if($usecert == true){
curl_setopt($ch,curlopt_ssl_verifypeer,true);
curl_setopt($ch,curlopt_ssl_verifyhost,2);//严格校验
//设置证书
//使用证书:cert 与 key 分别属于两个.pem文件
curl_setopt($ch,curlopt_sslcerttype,'pem');
curl_setopt($ch,curlopt_sslcert, $sslcert_path);
curl_setopt($ch,curlopt_sslkeytype,'pem');
curl_setopt($ch,curlopt_sslkey, $sslkey_path);
}
//post提交方式
curl_setopt($ch, curlopt_post, true);
curl_setopt($ch, curlopt_postfields, $xml);
//运行curl
$data = curl_exec($ch);
//返回结果
if($data){
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
return false;
}
}
/**
* 获取当前服务器的ip
* @return ambigous
*/
function get_client_ip()
{
if (isset($_server['remote_addr'])) {
$cip = $_server['remote_addr'];
} elseif (getenv(remote_addr)) {
$cip = getenv(remote_addr);
} elseif (getenv(http_client_ip)) {
$cip = getenv(http_client_ip);
} else {
$cip = 127.0.0.1;
}
return $cip;
}
/**
* 将数组转成uri字符串
* @param array $paramap
* @param bool $urlencode
* @return string
*/
function formatbizqueryparamap($paramap, $urlencode)
{
$buff = ;
ksort($paramap);
foreach ($paramap as $k => $v)
{
if($urlencode)
{
$v = urlencode($v);
}
$buff .= strtolower($k) . = . $v . &;
}
$reqpar;
if (strlen($buff) > 0)
{
$reqpar = substr($buff, 0, strlen($buff)-1);
}
return $reqpar;
}
/**
* xml转数组
* @param unknown $xml
* @return mixed
*/
function xmltoarray($xml)
{
//将xml转为array
$array_data = json_decode(json_encode(simplexml_load_string($xml, 'simplexmlelement', libxml_nocdata)), true);
return $array_data;
}
}
?>
//异步通知
/**
* 微信消息地址
*/
public function weixin_notify()
{
libraries_include(wxpay/, wxpayhelper.app.php);
$helper = new wxpayhelper();
//微信配置
$pay_config = $this->config->item(weixin_pay_need);
$xml = file_get_contents(php://input);
if(!$xml){
exit('');
}
$wx_back = $helper->xmltoarray($xml);
if(empty($wx_back)){
exit('');
}
$checksign = $helper->getverifysign($wx_back, $pay_config['partner']);
//验证签名
if($checksign==$wx_back['sign']){
if (isset($wx_back['result_code']) && $wx_back['result_code']=='success') {
$requestreturndata = file_get_contents(php://input);
//商户订单号
$out_trade_no = $wx_back['out_trade_no'];
//第三方订单编号
$third_order_num = $wx_back[transaction_id];
//交易状态
$trade_status = $wx_back['result_code'];
//订单金额 保留小数点后两位
$total_fee = sprintf(%.2f, $wx_back['total_fee']/100);
//公司业务处理
//处理后同步返回给微信
exit('');
}
}
exit('');
}