<?php
namespace app\api\controller;
use think\Db;
class WxPay{
public function pay($body_name='',$order_number='',$fee='') {
$wxdata = Db::name('wxpay')->find();
$appid = $wxdata['appid']; //应用的appid
$mch_id = $wxdata['mch_id']; // 您的商户账号
$nonce_str = $this -> nonce_str(); //随机字符串
$body = $body_name; // 举例: 服务预约
$out_trade_no = $order_number; //商户订单号
$total_fee = $fee*100;
$spbill_create_ip = '122.114.62.70'; // IP白名单
$notify_url = 'http://app.ggg.com/api/Notify/Wx_notify'; // 回调的url【自己填写,如若回调不成功请注意查看服务器是否开启防盗链,回调地址用http】
$trade_type = 'APP'; //交易类型 默认
//这里是按照顺序的 因为下面的签名是按照顺序 排序错误 肯定出错
$post['appid'] = $appid;
$post['body'] = $body;
$post['mch_id'] = $mch_id;
$post['nonce_str'] = $nonce_str; //随机字符串
$post['notify_url'] = $notify_url;
$post['out_trade_no'] = $out_trade_no;
$post['spbill_create_ip'] = $spbill_create_ip; //终端的ip
$post['total_fee'] = $total_fee; //总金额 最低为一块钱 必须是整数
$post['trade_type'] = $trade_type;
$sign = $this -> sign($post,$wxdata['key']); //签名
$post_xml = "<xml>
<appid><![CDATA[$appid]]></appid>
<body><![CDATA[$body]]></body>
<mch_id><![CDATA[$mch_id]]></mch_id>
<nonce_str><![CDATA[$nonce_str]]></nonce_str>
<notify_url><![CDATA[$notify_url]]></notify_url>
<out_trade_no><![CDATA[$out_trade_no]]></out_trade_no>
<spbill_create_ip><![CDATA[$spbill_create_ip]]></spbill_create_ip>
<total_fee><![CDATA[$total_fee]]></total_fee>
<trade_type><![CDATA[$trade_type]]></trade_type>
<sign><![CDATA[$sign]]></sign>
</xml>";
//统一接口prepay_id
$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
$xml = $this -> http_request($url, $post_xml);
$array = $this -> xml($xml); //全要大写
// dump($array);die;
if ($array['RETURN_CODE'] == 'SUCCESS' && $array['RESULT_CODE'] == 'SUCCESS') {
$time = time();
$tmp = []; //临时数组用于签名
$tmp['appid'] = $appid;
$tmp['noncestr'] = $nonce_str;
$tmp['package'] = 'Sign=WXPay';
$tmp["partnerid"] = $mch_id;
$tmp['prepayid'] = $array['PREPAY_ID'];
$tmp['timestamp'] = "$time";
$data['appid'] = $appid;
$data['noncestr'] = $nonce_str; //随机字符串
// $data['package'] = 'prepay_id='.$array['PREPAY_ID']; //统一接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
$data['package'] = "Sign=WXPay";
$data['partnerid']= $mch_id;
$data['prepayid'] = $array['PREPAY_ID'];
$data['timestamp'] = "$time"; //时间戳
$data['sign'] = $this ->sign($tmp,$wxdata['key']);//签名
} else {
$data['status'] = 0;
$data['text'] = "错误";
$data['RETURN_CODE'] = $array['RETURN_CODE'];
$data['RETURN_MSG'] = $array['RETURN_MSG'];
}
return json_encode($data);
}
public function sign($data,$wx_key)
{
//签名 $data要先排好顺序
$stringA = '';
ksort($data);
foreach($data as $key => $value) {
if (!$value) continue;
if ($stringA)
$stringA.= '&'.$key."=".$value;
else
$stringA = $key."=".$value;
}
$stringSignTemp = $stringA.'&key='.$wx_key; //申请支付后有给予一个商户账号和密码,登陆后自己设置key
return strtoupper(md5($stringSignTemp));
}
//随机32位字符串
private function nonce_str() {
$result = '';
$str = 'QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz';
for ($i = 0; $i < 32; $i++) {
$result.= $str[rand(0, 48)];
}
return $result;
}
//curl请求啊
public function http_request($url, $data = null, $headers = array()) {
$curl = curl_init();
if (count($headers) >= 1) {
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
}
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
if (!empty($data)) {
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($curl);
curl_close($curl);
return $output;
}
//获取xml
private function xml($xml) {
$p = xml_parser_create();
xml_parse_into_struct($p, $xml, $vals, $index);
xml_parser_free($p);
$data = "";
foreach($index as $key => $value) {
if ($key == 'xml' || $key == 'XML') continue;
$tag = $vals[$value[0]]['tag'];
$value = $vals[$value[0]]['value'];
$data[$tag] = $value;
}
return $data;
}
}