作者 杨育虎

大修

正在显示 33 个修改的文件 包含 42 行增加2555 行删除

要显示太多修改。

为保证性能只显示 33 of 33+ 个文件。

@@ -5,7 +5,6 @@ namespace app\portal\controller; @@ -5,7 +5,6 @@ namespace app\portal\controller;
5 use cmf\controller\HomeBaseController; 5 use cmf\controller\HomeBaseController;
6 use EasyWeChat\Foundation\Application; 6 use EasyWeChat\Foundation\Application;
7 use EasyWeChat\Payment\Order; 7 use EasyWeChat\Payment\Order;
8 -use think\Db;  
9 8
10 /** 9 /**
11 * 微信支付,退款,提现DEMO 10 * 微信支付,退款,提现DEMO
@@ -19,9 +18,8 @@ class PayController extends HomeBaseController @@ -19,9 +18,8 @@ class PayController extends HomeBaseController
19 { 18 {
20 parent::_initialize(); 19 parent::_initialize();
21 $this->options = [ 20 $this->options = [
22 - 'app_id' => config('wechat_config.app_id'), // AppID  
23 - 'secret' => config('wechat_config.secret'), // AppSecret  
24 - // payment 21 + 'app_id' => config('wechat_config.app_id'),
  22 + 'secret' => config('wechat_config.secret'),
25 'payment' => config('wechat_config.payment'), 23 'payment' => config('wechat_config.payment'),
26 ]; 24 ];
27 } 25 }
@@ -30,16 +30,36 @@ class IndexController extends HomeBaseController @@ -30,16 +30,36 @@ class IndexController extends HomeBaseController
30 $oauth = $app->oauth; 30 $oauth = $app->oauth;
31 $user = $oauth->user(); 31 $user = $oauth->user();
32 $wechat_user = $user->toArray(); 32 $wechat_user = $user->toArray();
33 - //todo $wechat_user与数据库对比  
34 if(isset($wechat_user['id'])){ 33 if(isset($wechat_user['id'])){
35 $openid=$wechat_user['id']; 34 $openid=$wechat_user['id'];
36 $findThirdPartyUser = Db::name("third_party_user") 35 $findThirdPartyUser = Db::name("third_party_user")
37 ->where('openid', $openid) 36 ->where('openid', $openid)
38 ->where('app_id', $appId) 37 ->where('app_id', $appId)
39 ->find(); 38 ->find();
  39 + if ($findThirdPartyUser) {
  40 + $this->wechatUserLogin($findThirdPartyUser,$openid,$appId);
  41 + }else{
  42 + $this->wechatUserRegister($wechat_user,$openid,$appId);
  43 + }
  44 + $target_url=session('target_url');
  45 + $targetUrl = empty($target_url) ? '/' : $target_url;
  46 + header('location:'. $targetUrl);
  47 + }else{
  48 + Log::write('获取微信用户数据失败');
  49 + $this->error('获取微信用户数据失败');
  50 + }
  51 +
  52 + }
  53 +
  54 + /**
  55 + * 微信用户登录
  56 + * @param $findThirdPartyUser
  57 + * @param $openid
  58 + * @param $appId
  59 + */
  60 + protected function wechatUserLogin($findThirdPartyUser,$openid,$appId){
40 $currentTime = time(); 61 $currentTime = time();
41 $ip = $this->request->ip(0, true); 62 $ip = $this->request->ip(0, true);
42 - if ($findThirdPartyUser) {  
43 $token = cmf_generate_user_token($findThirdPartyUser['user_id'], 'public'); 63 $token = cmf_generate_user_token($findThirdPartyUser['user_id'], 'public');
44 $userData = [ 64 $userData = [
45 'last_login_ip' => $ip, 65 'last_login_ip' => $ip,
@@ -66,7 +86,17 @@ class IndexController extends HomeBaseController @@ -66,7 +86,17 @@ class IndexController extends HomeBaseController
66 }else{ 86 }else{
67 Db::rollback(); 87 Db::rollback();
68 } 88 }
69 - }else{ 89 + }
  90 +
  91 + /**
  92 + * 微信用户注册
  93 + * @param $wechat_user
  94 + * @param $openid
  95 + * @param $appId
  96 + */
  97 + protected function wechatUserRegister($wechat_user,$openid,$appId){
  98 + $currentTime = time();
  99 + $ip = $this->request->ip(0, true);
70 Db::startTrans(); 100 Db::startTrans();
71 $userId = Db::name("user")->insertGetId([ 101 $userId = Db::name("user")->insertGetId([
72 'create_time' => $currentTime, 102 'create_time' => $currentTime,
@@ -104,15 +134,6 @@ class IndexController extends HomeBaseController @@ -104,15 +134,6 @@ class IndexController extends HomeBaseController
104 Db::rollback(); 134 Db::rollback();
105 } 135 }
106 } 136 }
107 - $target_url=session('target_url');  
108 - $targetUrl = empty($target_url) ? '/' : $target_url;  
109 - header('location:'. $targetUrl);  
110 - }else{  
111 - Log::write('获取微信用户数据失败');  
112 - $this->error('获取微信用户数据失败');  
113 - }  
114 -  
115 - }  
116 137
117 /** 138 /**
118 * 前台用户首页(公开) 139 * 前台用户首页(公开)
1 -<?php  
2 -  
3 -namespace app\user\controller;  
4 -  
5 -use cmf\controller\HomeBaseController;  
6 -use think\Db;  
7 -use think\Log;  
8 -use think\Validate;  
9 -  
10 -/**  
11 - * 微信支付,退款,提现DEMO  
12 - * Class PayController  
13 - * @package app\portal\controller  
14 - */  
15 -class PayController extends HomeBaseController  
16 -{  
17 - public function _initialize(){  
18 - parent::_initialize();  
19 - require_once EXTEND_PATH . "WxpayAPI/lib/WxPay.Api.php";  
20 - require_once EXTEND_PATH . "WxpayAPI/example/WxPay.JsApiPay.php";  
21 - require_once EXTEND_PATH . "WxpayAPI/lib/WxPay.Notify.php";  
22 - require_once EXTEND_PATH . "WxpayAPI/lib/WxPay.Merch.php";  
23 - require_once EXTEND_PATH . "WxpayAPI/example/log.php";  
24 - }  
25 -  
26 - /**  
27 - * 微信支付  
28 - * @throws \WxPayException  
29 - * @throws \think\db\exception\DataNotFoundException  
30 - * @throws \think\db\exception\ModelNotFoundException  
31 - * @throws \think\exception\DbException  
32 - */  
33 - public function index(){  
34 - //todo 支付逻辑处理  
35 - $order_sn=cmf_get_order_sn();  
36 - $tools = new \JsApiPay();  
37 - $user=cmf_get_current_user();  
38 - if(empty($user)){  
39 - $this->error('用户尚未登录');  
40 - }  
41 - $openId = $user['openid'];  
42 - if(empty($openId)){  
43 - $this->error('微信OPENID不能为空');  
44 - }  
45 - $real_price=0.01;//测试金额  
46 - $total_fee=floatval($real_price)*100;  
47 - if($total_fee<=0){  
48 - $this->error('支付金额不能小于0');  
49 - }  
50 -  
51 - $timeStamp = time();  
52 - $randomStr = cmf_random_string(8);  
53 - $arithmetic['timeStamp']= $timeStamp;  
54 - $arithmetic['randomStr']= $randomStr;  
55 - $arithmetic['orderSn']= $order_sn;  
56 - $signature = arithmetic($arithmetic);  
57 - $notifyParam=array('t'=>$timeStamp,'r'=>$randomStr,'s'=>$signature,'o'=>$order_sn);  
58 - $url=url('portal/pay/notify',$notifyParam,true,true);  
59 - $input = new \WxPayUnifiedOrder();  
60 - $input->SetBody("服务器续费");  
61 - $input->SetAttach($order_sn);  
62 - $input->SetOut_trade_no($order_sn);  
63 - $input->SetTotal_fee($total_fee);  
64 - $input->SetTime_start(date("YmdHis"));  
65 - $input->SetTime_expire(date("YmdHis", time() + 600));  
66 - $input->SetGoods_tag($total_fee);  
67 - $input->SetNotify_url($url);  
68 - $input->SetTrade_type("JSAPI");  
69 - $input->SetOpenid($openId);  
70 -  
71 - $order = \WxPayApi::unifiedOrder($input);  
72 -  
73 - if(!empty($order['return_code'])){  
74 - if($order['return_code']=='FAIL'){  
75 - $this->error('支付参数错误','',$order);  
76 - }  
77 - }  
78 - $jsApiParameters = $tools->GetJsApiParameters($order);  
79 - $this->success('获取支付参数成功','',json_decode($jsApiParameters,true));  
80 - }  
81 -  
82 - /**  
83 - * 支付回调  
84 - */  
85 - public function notify(){  
86 - $param=$this->request->param();  
87 - $signature = $param['s'];  
88 - $arithmetic['timeStamp']= $param['t'];  
89 - $arithmetic['randomStr']= $param['r'];  
90 - $arithmetic['orderSn']= $param['o'];  
91 - $str = arithmetic($arithmetic);  
92 - if($str != $signature){  
93 - $data['code'] = 40002;  
94 - $data['msg'] = '签名验证失败';  
95 - Log::write('签名验证失败'.$param['o']);  
96 - exit;  
97 - }  
98 - $notify = new \WxPayNotify();  
99 - $notify->Handle(false);  
100 - $xml = file_get_contents("php://input");  
101 - $base = new \WxPayResults();  
102 - $data = $base->FromXml($xml);  
103 - if($base->CheckSign() == true){  
104 - if ($data["return_code"] == "FAIL") {  
105 - Log::write('支付失败1','error');  
106 - }elseif($data["result_code"] == "FAIL"){  
107 - Log::write('支付失败2','error');  
108 - }else{  
109 - //todo 回调处理  
110 - }  
111 - }  
112 - }  
113 -  
114 - /**  
115 - * 退款  
116 - * @throws \WxPayException  
117 - */  
118 - public function refund(){  
119 - $param = $this->request->param();  
120 - $signature = $param['s'];  
121 - $arithmetic['timeStamp']= $param['t'];  
122 - $arithmetic['randomStr']= $param['r'];  
123 - $arithmetic['orderSn']= $param['o'];  
124 - $str = arithmetic($arithmetic);  
125 - if($str != $signature){  
126 - $this->error('签名验证失败');  
127 - }  
128 -  
129 - /*微信退款*/  
130 - require_once EXTEND_PATH."WxpayAPI/lib/WxPay.Api.php";  
131 - require_once EXTEND_PATH."WxpayAPI/example/log.php";  
132 - if(isset($info["transaction_id"]) && empty($info["transaction_id"])){  
133 - $transaction_id = $info["transaction_id"];  
134 - $total_fee = $info["real_price"]*100;  
135 - $refund_fee = $info["real_price"]*100;  
136 - $input = new \WxPayRefund();  
137 - $input->SetTransaction_id($transaction_id);  
138 - $input->SetTotal_fee($total_fee);  
139 - $input->SetRefund_fee($refund_fee);  
140 - $input->SetOut_refund_no(\WxPayConfig::MCHID.date("YmdHis"));  
141 - $input->SetOp_user_id(\WxPayConfig::MCHID);  
142 - $ret=\WxPayApi::refund($input);  
143 - if($ret['result_code']=='SUCCESS'){  
144 - //todo 退款成功处理  
145 - $this->success('退款成功');  
146 - }else{  
147 - $this->error("退款失败:".$ret['err_code_des']);  
148 - }  
149 - }else{  
150 - $this->error('缺少退款标识');  
151 - }  
152 -  
153 - }  
154 -  
155 - /**  
156 - * 提现  
157 - */  
158 - public function withdraw_cash(){  
159 - $param = $this->request->param();  
160 - $signature = $param['s'];  
161 - $arithmetic['timeStamp']= $param['t'];  
162 - $arithmetic['randomStr']= $param['r'];  
163 - $arithmetic['orderSn']= $param['o'];  
164 - $str = arithmetic($arithmetic);  
165 - if($str != $signature){  
166 - $this->error('签名验证失败');  
167 - }  
168 - $price=1;  
169 - $openid='';  
170 -  
171 - $merch=new \MerchPay();  
172 - $trade_no = cmf_get_order_sn();  
173 - $res=$merch->pay($openid,$trade_no,$price,'提现');  
174 - if($res['result_code']=='SUCCESS'){  
175 - //todo 提现成功处理  
176 - }else{  
177 - $this->error('操作失败:'.$res['return_msg']);  
178 - }  
179 -  
180 - }  
181 -  
182 -}  
@@ -12,6 +12,7 @@ namespace app\user\controller; @@ -12,6 +12,7 @@ namespace app\user\controller;
12 12
13 13
14 use cmf\controller\WeChatBaseController; 14 use cmf\controller\WeChatBaseController;
  15 +use EasyWeChat\Foundation\Application;
15 16
16 class TestController extends WeChatBaseController 17 class TestController extends WeChatBaseController
17 { 18 {
@@ -23,7 +24,13 @@ class TestController extends WeChatBaseController @@ -23,7 +24,13 @@ class TestController extends WeChatBaseController
23 } 24 }
24 25
25 public function index(){ 26 public function index(){
  27 + $options=config('wechat_config');
  28 + $app = new Application($options);
26 29
  30 + $js = $app->js;
  31 + $jssdk=$js->config(array('onMenuShareQQ', 'onMenuShareWeibo'), false,false,true);
  32 + $js->setUrl('http://www.baidu.com');
  33 + $this->assign('jssdk',$jssdk);
27 } 34 }
28 35
29 36
1 -<!DOCTYPE html>  
2 -<html>  
3 -<head>  
4 - <title>微信支付</title>  
5 - <meta charset="utf-8" />  
6 - <meta name="viewport" content="initial-scale=1.0, width=device-width, user-scalable=no" />  
7 - <link rel="stylesheet" type="text/css" href="__TMPL__/public/assets/css/lanren.css">  
8 - <script type="text/javascript">  
9 - //调用微信JS api 支付  
10 - function jsApiCall()  
11 - {  
12 - WeixinJSBridge.invoke(  
13 - "getBrandWCPayRequest",  
14 - {$jsApiParameters},  
15 - function(res){  
16 - WeixinJSBridge.log(res.err_msg);  
17 - alert(res.err_code+res.err_desc+res.err_msg);  
18 - if (res.err_msg=='get_brand_wcpay_request:cancel'){  
19 - //支付取消逻辑  
20 - }else if (res.err_msg=='get_brand_wcpay_request:ok'){  
21 - //支付成功逻辑  
22 - }else{  
23 - //支付失败逻辑  
24 - }  
25 - }  
26 - );  
27 - }  
28 - function callpay()  
29 - {  
30 - if (typeof WeixinJSBridge == "undefined"){  
31 - if( document.addEventListener ){  
32 - document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);  
33 - }else if (document.attachEvent){  
34 - document.attachEvent('WeixinJSBridgeReady', jsApiCall);  
35 - document.attachEvent('onWeixinJSBridgeReady', jsApiCall);  
36 - }  
37 - }else{  
38 - jsApiCall();  
39 - }  
40 - }  
41 - </script>  
42 -</head>  
43 -<body>  
44 -  
45 -<div class="wenx_xx">  
46 - <div class="mz">{$info.order_sn}</div>  
47 - <div class="wxzf_price">¥{$info.real_price}</div>  
48 -</div>  
49 -<div class="skf_xinf">  
50 - <div class="all_w"> <span class="bt">收款方</span> <span class="fr">{$site_info.site_name}</span> </div>  
51 -</div>  
52 -<a onclick="callpay()" class="ljzf_but all_w">立即支付</a>  
53 -<script type="text/javascript">  
54 - callpay();  
55 -</script>  
56 -</body>  
57 -</html>  
1 -<!DOCTYPE html>  
2 -<html>  
3 -<head>  
4 - <title>微信支付成功</title>  
5 - <meta charset="utf-8" />  
6 - <meta name="viewport" content="initial-scale=1.0, width=device-width, user-scalable=no" />  
7 - <link rel="stylesheet" type="text/css" href="__TMPL__/public/assets/css/lanren.css">  
8 -</head>  
9 -<body >  
10 -<div class="zfcg_box ">  
11 - <div class="all_w">  
12 - <img src="__TMPL__/public/assets/images/cg_03.jpg" > 支付成功 </div>  
13 -  
14 -</div>  
15 -<div class="cgzf_info">  
16 - <div class="wenx_xx">  
17 - <div class="mz">{$site_info.site_name|default='请定义商品名称'}</div>  
18 - <div class="wxzf_price">¥{$info.real_price|default='请定义商品金额'}</div>  
19 - </div>  
20 -  
21 - <div class="spxx_shop">  
22 - <div class=" mlr_pm">  
23 - <table width="100%" border="0" cellspacing="0" cellpadding="0">  
24 - <tr>  
25 - <td>交易时间</td>  
26 - <td align="right">{$info.pay_time|date='Y-m-d H:i:s',###}</td>  
27 - </tr>  
28 - <tr>  
29 - <td>商户单号</td>  
30 - <td align="right">{$info.order_sn|default='请定义商户单号'}</td>  
31 - </tr>  
32 - <tr>  
33 - <td>交易单号</td>  
34 - <td align="right">{$info.transaction_id|default='请定义交易单号'}</td>  
35 - </tr>  
36 - </table>  
37 - </div>  
38 - </div>  
39 -</div>  
40 -<div class="wzxfcgde_tb"><img src="__TMPL__/public/assets/images/cg_07.jpg" ></div>  
41 -</body>  
42 -</html>  
@@ -197,181 +197,4 @@ class HomeBaseController extends BaseController @@ -197,181 +197,4 @@ class HomeBaseController extends BaseController
197 } 197 }
198 } 198 }
199 199
200 - /**  
201 - * 检查微信用户登录  
202 - * @param int $type 1-公众号普通登录,2-验证关注公众号才可登录  
203 - * @throws \think\Exception  
204 - * @throws \think\db\exception\DataNotFoundException  
205 - * @throws \think\db\exception\ModelNotFoundException  
206 - * @throws \think\exception\DbException  
207 - * @throws \think\exception\PDOException  
208 - */  
209 - public function checkWeChatUserLogin($type=2)  
210 - {  
211 -  
212 - if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') === false) {  
213 - //todo 取消下面注释可模拟用户在非微信浏览器下登录,方便本地测试  
214 - /*$userModel = new UserModel();  
215 - $userWhere = ['user_id' => 1, 'app_id' => config('wx_app_id')];  
216 - $user = $userModel->getUserInfo($userWhere);  
217 - cmf_update_current_user($user);*/  
218 - }  
219 -  
220 - $userId = cmf_get_current_user_id();  
221 - if (empty($userId)) {  
222 - $appId=config('wx_app_id');  
223 - $appSecret=config('wx_app_secret');  
224 - //通过code换取网页授权access_token和openid  
225 - $code = $this->request->get('code');  
226 - if(empty($code)){  
227 - $url = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);  
228 - header('Location: https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appId.'&redirect_uri='.$url.'&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect');  
229 - }  
230 - //通过code换取网页授权access_token和openid  
231 - $openidUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" .$appId . "&secret=" . $appSecret . "&code=" . $code . "&grant_type=authorization_code";  
232 - $openidData = json_decode(file_get_contents($openidUrl), true);  
233 - if (empty($openidData['openid'])) {  
234 - $this->error($openidData['errcode'].':'.$openidData['errmsg']);  
235 - }else {  
236 - $openid=$openidData['openid'];  
237 - $findThirdPartyUser = Db::name("third_party_user")  
238 - ->where('openid', $openid)  
239 - ->where('app_id', $appId)  
240 - ->find();  
241 - $currentTime = time();  
242 - $ip = $this->request->ip(0, true);  
243 - if ($findThirdPartyUser) {  
244 - $token = cmf_generate_user_token($findThirdPartyUser['user_id'], 'public');  
245 -  
246 - $userData = [  
247 - 'last_login_ip' => $ip,  
248 - 'last_login_time' => $currentTime,  
249 - 'login_times' => ['exp', 'login_times+1']  
250 - ];  
251 -  
252 - if (isset($openidData['unionId'])) {  
253 - $userData['union_id'] = $openidData['unionId'];  
254 - }  
255 -  
256 - $row1=Db::name("third_party_user")  
257 - ->where('openid', $openid)  
258 - ->where('app_id', $appId)  
259 - ->update($userData);  
260 - $userInfo=Db::name("third_party_user")  
261 - ->where('openid', $openid)  
262 - ->where('app_id', $appId)->find();  
263 - unset($userData['login_times']);  
264 - $userData['last_login_type']='public';  
265 - $row2=Db::name("user")  
266 - ->where('id', $userInfo['user_id'])  
267 - ->update($userData);  
268 -  
269 - if($row1!==false&&$row2!==false){  
270 - $userModel=new UserModel();  
271 - $user=$userModel->getUserInfo(['user_id'=>$userInfo['user_id'],'app_id'=>$appId]);  
272 - cmf_update_current_user($user);  
273 - session('token',$token);  
274 - Db::commit();  
275 - }else{  
276 - Db::rollback();  
277 - }  
278 - }else{  
279 - switch ($type){  
280 - case 1:  
281 - $userinfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" . $openidData['access_token'] . "&openid=" . $openidData['openid'] . "&lang=zh_CN";  
282 - $userinfoData = json_decode(file_get_contents($userinfoUrl), true);  
283 - $nickname=$userinfoData['nickname'];  
284 - Db::startTrans();  
285 - $userId = Db::name("user")->insertGetId([  
286 - 'create_time' => $currentTime,  
287 - 'user_status' => 1,  
288 - 'user_type' => 2,  
289 - 'sex' => $userinfoData['sex'],  
290 - 'user_nickname' => $nickname,  
291 - 'avatar' => $userinfoData['headimgurl'],  
292 - 'last_login_ip' => $ip,  
293 - 'last_login_time' => $currentTime,  
294 - 'union_id' => isset($userinfoData['unionid']) ? $userinfoData['unionid'] : '',  
295 - ]);  
296 -  
297 - $row=Db::name("third_party_user")->insert([  
298 - 'openid' => $openid,  
299 - 'user_id' => $userId,  
300 - 'third_party' => 'public',  
301 - 'nickname' => $nickname,  
302 - 'app_id' => $appId,  
303 - 'last_login_ip' => $ip,  
304 - 'union_id' => isset($userinfoData['unionid']) ? $userinfoData['unionid'] : '',  
305 - 'last_login_time' => $currentTime,  
306 - 'create_time' => $currentTime,  
307 - 'login_times' => 1,  
308 - 'status' => 1,  
309 - 'more' => json_encode($userinfoData)  
310 - ]);  
311 - if($userId && $row){  
312 - $token = cmf_generate_user_token($userId, 'public');  
313 - $userModel=new UserModel();  
314 - $user=$userModel->getUserInfo(['user_id'=>$userId,'app_id'=>$appId]);  
315 - cmf_update_current_user($user);  
316 - session('token',$token);  
317 - Db::commit();  
318 - }else{  
319 - Db::rollback();  
320 - }  
321 - break;  
322 - case 2:  
323 - $token = getAccessToken();  
324 - $userinfoUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" . $token . "&openid=" . $openidData['openid'] . "&lang=zh_CN";  
325 - $userinfoData = json_decode(file_get_contents($userinfoUrl), true);  
326 - if($userinfoData['subscribe']==1){  
327 - $nickname=$userinfoData['nickname'];  
328 - Db::startTrans();  
329 - $userId = Db::name("user")->insertGetId([  
330 - 'create_time' => $currentTime,  
331 - 'user_status' => 1,  
332 - 'user_type' => 2,  
333 - 'sex' => $userinfoData['sex'],  
334 - 'user_nickname' => $nickname,  
335 - 'avatar' => $userinfoData['headimgurl'],  
336 - 'last_login_ip' => $ip,  
337 - 'last_login_time' => $currentTime,  
338 - 'union_id' => isset($userinfoData['unionid']) ? $userinfoData['unionid'] : '',  
339 - ]);  
340 -  
341 - $row=Db::name("third_party_user")->insert([  
342 - 'openid' => $openid,  
343 - 'user_id' => $userId,  
344 - 'third_party' => 'public',  
345 - 'nickname' => $nickname,  
346 - 'app_id' => $appId,  
347 - 'last_login_ip' => $ip,  
348 - 'union_id' => isset($userinfoData['unionid']) ? $userinfoData['unionid'] : '',  
349 - 'last_login_time' => $currentTime,  
350 - 'create_time' => $currentTime,  
351 - 'login_times' => 1,  
352 - 'status' => 1,  
353 - 'more' => json_encode($userinfoData)  
354 - ]);  
355 - if($userId && $row){  
356 - $token = cmf_generate_user_token($userId, 'public');  
357 - $userModel=new UserModel();  
358 - $user=$userModel->getUserInfo(['user_id'=>$userId,'app_id'=>$appId]);  
359 - cmf_update_current_user($user);  
360 - session('token',$token);  
361 - Db::commit();  
362 - }else{  
363 - Db::rollback();  
364 - }  
365 - }else{  
366 - $this->redirect("https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzIzNDkzNzQzMg==#wechat_redirect");  
367 - }  
368 - break;  
369 - default:  
370 - $this->error("用户尚未登录", "https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzIzNDkzNzQzMg==&scene=110#wechat_redirect");  
371 - }  
372 - }  
373 - }  
374 - }  
375 - }  
376 -  
377 } 200 }
1 ------BEGIN CERTIFICATE-----  
2 -MIIEajCCA9OgAwIBAgIEAd9znzANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC  
3 -Q04xEjAQBgNVBAgTCUd1YW5nZG9uZzERMA8GA1UEBxMIU2hlbnpoZW4xEDAOBgNV  
4 -BAoTB1RlbmNlbnQxDDAKBgNVBAsTA1dYRzETMBEGA1UEAxMKTW1wYXltY2hDQTEf  
5 -MB0GCSqGSIb3DQEJARYQbW1wYXltY2hAdGVuY2VudDAeFw0xODA0MDgwNzE0Mjha  
6 -Fw0yODA0MDUwNzE0MjhaMIGZMQswCQYDVQQGEwJDTjESMBAGA1UECBMJR3Vhbmdk  
7 -b25nMREwDwYDVQQHEwhTaGVuemhlbjEQMA4GA1UEChMHVGVuY2VudDEOMAwGA1UE  
8 -CxMFTU1QYXkxLTArBgNVBAMUJOS4iua1t+mHkeWmmee9kee7nOenkeaKgOaciemZ  
9 -kOWFrOWPuDESMBAGA1UEBBMJMTAwMTI1MjEyMIIBIjANBgkqhkiG9w0BAQEFAAOC  
10 -AQ8AMIIBCgKCAQEA0W7E6vB8IkeM9GuBUTzux1aE9WNkehY4l73idtjPNBlKQTah  
11 -nIqPOp3rtaqHrk9eyDNCslzJ4UrVHK6oI+wT+qLBk6P1q9ThJjXuuxEXh63dhNoB  
12 -kD1BmqUhuc4VjLmy+BlfmFDWzayl4T5BlGug9aGUrewRbnt/Mn5KtrRy45nhD8WY  
13 -P5p5D/jK2hEQVPk0zgQFYuaDuNUuCW6m6pjuLTgPyD+gWIX4EXzNn+Vbc078YE5+  
14 -EcPVSl7hbUaMvR2Wq6xIwKM7nq+LkseiZthnrlLLJK11dRSoG24imJl5rea5fuB6  
15 -xGXdpaATKKMdNuHL9MsU8gO6/qvUvyHIxhzdIwIDAQABo4IBRjCCAUIwCQYDVR0T  
16 -BAIwADAsBglghkgBhvhCAQ0EHxYdIkNFUy1DQSBHZW5lcmF0ZSBDZXJ0aWZpY2F0  
17 -ZSIwHQYDVR0OBBYEFKVv0QBuVXvTkwFlYisjbo+J59dWMIG/BgNVHSMEgbcwgbSA  
18 -FD4FJvYiYrQVW4jNZH6w1GKn5YZ0oYGQpIGNMIGKMQswCQYDVQQGEwJDTjESMBAG  
19 -A1UECBMJR3Vhbmdkb25nMREwDwYDVQQHEwhTaGVuemhlbjEQMA4GA1UEChMHVGVu  
20 -Y2VudDEMMAoGA1UECxMDV1hHMRMwEQYDVQQDEwpNbXBheW1jaENBMR8wHQYJKoZI  
21 -hvcNAQkBFhBtbXBheW1jaEB0ZW5jZW50ggkAu1SXK7wA6FcwDgYDVR0PAQH/BAQD  
22 -AgbAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4GBAIDQ  
23 -zaEwqzWuUFVKS8uAug47XYZbo1du9IKkYnvwMv4GEpisqB/02YDSBZBPyPRKBVEY  
24 -r880RNPh7fCTIfPeGaygQ3hnujZ9uPhU0Cv9Io3pAvZ80uHz5y/gWdsuz2k3av5p  
25 -K09IOSM3kxLrEEOvw1MlWOgwQ4GFQVvhNYTD7i09  
26 ------END CERTIFICATE-----  
1 ------BEGIN PRIVATE KEY-----  
2 -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRbsTq8HwiR4z0  
3 -a4FRPO7HVoT1Y2R6FjiXveJ22M80GUpBNqGcio86neu1qoeuT17IM0KyXMnhStUc  
4 -rqgj7BP6osGTo/Wr1OEmNe67EReHrd2E2gGQPUGapSG5zhWMubL4GV+YUNbNrKXh  
5 -PkGUa6D1oZSt7BFue38yfkq2tHLjmeEPxZg/mnkP+MraERBU+TTOBAVi5oO41S4J  
6 -bqbqmO4tOA/IP6BYhfgRfM2f5VtzTvxgTn4Rw9VKXuFtRoy9HZarrEjAozuer4uS  
7 -x6Jm2GeuUsskrXV1FKgbbiKYmXmt5rl+4HrEZd2loBMoox024cv0yxTyA7r+q9S/  
8 -IcjGHN0jAgMBAAECggEAZkKv5AeIlTRanv3fJsuZy7tzMF5XsUUoXO9apK04fzfa  
9 -Cf2i68y8IuL5NLsPhQ08OoTNDEpCSL9BT7/4WZHsL3VJD83/JufLB91NtAmkc5tx  
10 -jmzkVomSfvAih5cY7p29xWaeRsEyITsrw8+iNdZXwZgkAMhDuq6SbRU9Zfi2IGsf  
11 -j5TBJEGLn/83e0d32SQoV0tFVh8FK49Brm57cEQpROWZUDpUSRTrr9nPzAg5DmCB  
12 -y6KilqXDNdHQ5YwRjEpzn1dp7OuvLYC4ASSP9bM6Bi5KVLhf7Hz0vcBVpF9CmQIi  
13 -sJurCeWnP4ukaJAZzpjXluu2/KPSdwT3aRVSdB6AAQKBgQD7wsiBAsKclcztfVkH  
14 -QbhXwBhUrtqEgE6YE+GwJP2I5do9ow33yy35a15KTRpxXLxhwlxO/RPIP1zK5t2X  
15 -EerSZBWZyjxCdH4WJnpNduNjmLqK+fXaaSeRI+6p5vUtalcnyOje/7B5OWpJeo+S  
16 -O2lzlzLzEsJ6X5WLcsX1WjAmwQKBgQDU9Ye1gGfcuIxx4t8M6Quah+Aye/KwzNeh  
17 -wPD7Ikg/UXzPqqs46Kl+GUZzqSDjw2yWKvdyNOB77STZqofAOdKC69oxfOKnCxcL  
18 -76hUuivuHwAN937dT8qFFtE8fwrl7P61JRWYZVfQq0p9/5OGIPPxlWA2io93s+RA  
19 -OdMoVoqA4wKBgQDYJHVRVVZRasaCSjBJ66FhLNl2spuGUEWpiMAlIszMYFHKwxc1  
20 -2ykATq6n6aQ/GRfecigf5GS8cbGvvR8XGNnagPSOkTLE9xBc4fH0WZKFKlVVBZ6O  
21 -QeMnV4sKMO/jar2iuXk8IpaWrLVUmjVynTE+fNvQFhYDS9au3v2XVDOswQKBgEfa  
22 -5MSAJAtclb7jnwE7LPgiOqquGdA//c4NTQJfqeL7etKTMpzMHEx4+MWT3o4bZWsx  
23 -6jY10zzdYl6zZISevgIA1Kl4Cv30Bv23CqQ0ARiiiyErTjocbygC7+yqrSGxmqvC  
24 -bIv0PfIhqcvjzYInYkg0b7dXf1sTbsOg/zeQI8GjAoGBAMeoth76l/M7aOoirnA+  
25 -z5GSOLgMoiMH7OidkzjZX5RUatfIe1jC2CJrKVvcOQrHpjv7vXSK9EEO6cw0hgUM  
26 -rCDTVVGjUus0Cys6NoT7DtKsC1zZ0Vr1tF/s4gxZ7vdbDjfiXyK2yH0W9PvDquB1  
27 -VaeCphPOGWYHObOQ7RQ5uApD  
28 ------END PRIVATE KEY-----  
1 -欢迎使用微信支付!  
2 -附件中的三份文件(证书pkcs12格式、证书pem格式、证书密钥pem格式),为接口中强制要求时需携带的证书文件。  
3 -证书属于敏感信息,请妥善保管不要泄露和被他人复制。  
4 -不同开发语言下的证书格式不同,以下为说明指引:  
5 - 证书pkcs12格式(apiclient_cert.p12)  
6 - 包含了私钥信息的证书文件,为p12(pfx)格式,由微信支付签发给您用来标识和界定您的身份  
7 - 部分安全性要求较高的API需要使用该证书来确认您的调用身份  
8 - windows上可以直接双击导入系统,导入过程中会提示输入证书密码,证书密码默认为您的商户ID(如:10010000)  
9 - 证书pem格式(apiclient_cert.pem)  
10 - 从apiclient_cert.p12中导出证书部分的文件,为pem格式,请妥善保管不要泄漏和被他人复制  
11 - 部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已为您直接提供  
12 - 您也可以使用openssl命令来自己导出:openssl pkcs12 -clcerts -nokeys -in apiclient_cert.p12 -out apiclient_cert.pem  
13 - 证书密钥pem格式(apiclient_key.pem)  
14 - 从apiclient_cert.p12中导出密钥部分的文件,为pem格式  
15 - 部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已为您直接提供  
16 - 您也可以使用openssl命令来自己导出:openssl pkcs12 -nocerts -in apiclient_cert.p12 -out apiclient_key.pem  
17 -备注说明:  
18 - 由于绝大部分操作系统已内置了微信支付服务器证书的根CA证书, 2018年3月6日后, 不再提供CA证书文件(rootca.pem)下载  
1 -<?php  
2 -require_once EXTEND_PATH . "WeChat/WxpayAPI/lib/WxPay.Api.php";  
3 -/**  
4 - *  
5 - * JSAPI支付实现类  
6 - * 该类实现了从微信公众平台获取code、通过code获取openid和access_token、  
7 - * 生成jsapi支付js接口所需的参数、生成获取共享收货地址所需的参数  
8 - *  
9 - * 该类是微信支付提供的样例程序,商户可根据自己的需求修改,或者使用lib中的api自行开发  
10 - *  
11 - * @author widy  
12 - *  
13 - */  
14 -class JsApiPay  
15 -{  
16 - /**  
17 - *  
18 - * 网页授权接口微信服务器返回的数据,返回样例如下  
19 - * {  
20 - * "access_token":"ACCESS_TOKEN",  
21 - * "expires_in":7200,  
22 - * "refresh_token":"REFRESH_TOKEN",  
23 - * "openid":"OPENID",  
24 - * "scope":"SCOPE",  
25 - * "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"  
26 - * }  
27 - * 其中access_token可用于获取共享收货地址  
28 - * openid是微信支付jsapi支付接口必须的参数  
29 - * @var array  
30 - */  
31 - public $data = null;  
32 -  
33 - /**  
34 - *  
35 - * 通过跳转获取用户的openid,跳转流程如下:  
36 - * 1、设置自己需要调回的url及其其他参数,跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize  
37 - * 2、微信服务处理完成之后会跳转回用户redirect_uri地址,此时会带上一些参数,如:code  
38 - *  
39 - * @return 用户的openid  
40 - */  
41 - public function GetOpenid()  
42 - {  
43 - //通过code获得openid  
44 - if (!isset($_GET['code'])){  
45 - //触发微信返回code码  
46 - $baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);  
47 - $url = $this->__CreateOauthUrlForCode($baseUrl);  
48 - Header("Location: $url");  
49 - exit();  
50 - } else {  
51 - //获取code码,以获取openid  
52 - $code = $_GET['code'];  
53 - $openid = $this->getOpenidFromMp($code);  
54 - return $openid;  
55 - }  
56 - }  
57 -  
58 - /**  
59 - *  
60 - * 获取jsapi支付的参数  
61 - * @param array $UnifiedOrderResult 统一支付接口返回的数据  
62 - * @throws WxPayException  
63 - *  
64 - * @return json数据,可直接填入js函数作为参数  
65 - */  
66 - public function GetJsApiParameters($UnifiedOrderResult)  
67 - {  
68 - if(!array_key_exists("appid", $UnifiedOrderResult)  
69 - || !array_key_exists("prepay_id", $UnifiedOrderResult)  
70 - || $UnifiedOrderResult['prepay_id'] == "")  
71 - {  
72 - throw new WxPayException("参数错误");  
73 - }  
74 - $jsapi = new WxPayJsApiPay();  
75 - $jsapi->SetAppid($UnifiedOrderResult["appid"]);  
76 - $timeStamp = time();  
77 - $jsapi->SetTimeStamp("$timeStamp");  
78 - $jsapi->SetNonceStr(WxPayApi::getNonceStr());  
79 - $jsapi->SetPackage("prepay_id=" . $UnifiedOrderResult['prepay_id']);  
80 - $jsapi->SetSignType("MD5");  
81 - $jsapi->SetPaySign($jsapi->MakeSign());  
82 - $parameters = json_encode($jsapi->GetValues());  
83 - return $parameters;  
84 - }  
85 -  
86 - /**  
87 - *  
88 - * 通过code从工作平台获取openid机器access_token  
89 - * @param string $code 微信跳转回来带上的code  
90 - *  
91 - * @return openid  
92 - */  
93 - public function GetOpenidFromMp($code)  
94 - {  
95 - $url = $this->__CreateOauthUrlForOpenid($code);  
96 - //初始化curl  
97 - $ch = curl_init();  
98 - //设置超时  
99 - curl_setopt($ch, CURLOPT_TIMEOUT,60);  
100 - curl_setopt($ch, CURLOPT_URL, $url);  
101 - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,FALSE);  
102 - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,FALSE);  
103 - curl_setopt($ch, CURLOPT_HEADER, FALSE);  
104 - curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);  
105 - if(WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"  
106 - && WxPayConfig::CURL_PROXY_PORT != 0){  
107 - curl_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST);  
108 - curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT);  
109 - }  
110 - //运行curl,结果以jason形式返回  
111 - $res = curl_exec($ch);  
112 - curl_close($ch);  
113 - //取出openid  
114 - $data = json_decode($res,true);  
115 - $this->data = $data;  
116 - $openid = $data['openid'];  
117 - return $openid;  
118 - }  
119 -  
120 - /**  
121 - *  
122 - * 拼接签名字符串  
123 - * @param array $urlObj  
124 - *  
125 - * @return 返回已经拼接好的字符串  
126 - */  
127 - private function ToUrlParams($urlObj)  
128 - {  
129 - $buff = "";  
130 - foreach ($urlObj as $k => $v)  
131 - {  
132 - if($k != "sign"){  
133 - $buff .= $k . "=" . $v . "&";  
134 - }  
135 - }  
136 -  
137 - $buff = trim($buff, "&");  
138 - return $buff;  
139 - }  
140 -  
141 - /**  
142 - *  
143 - * 获取地址js参数  
144 - *  
145 - * @return 获取共享收货地址js函数需要的参数,json格式可以直接做参数使用  
146 - */  
147 - public function GetEditAddressParameters()  
148 - {  
149 - $getData = $this->data;  
150 - $data = array();  
151 - $data["appid"] = WxPayConfig::APPID;  
152 - $data["url"] = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];  
153 - $time = time();  
154 - $data["timestamp"] = "$time";  
155 - $data["noncestr"] = "1234568";  
156 - $data["accesstoken"] = $getData["access_token"];  
157 - ksort($data);  
158 - $params = $this->ToUrlParams($data);  
159 - $addrSign = sha1($params);  
160 -  
161 - $afterData = array(  
162 - "addrSign" => $addrSign,  
163 - "signType" => "sha1",  
164 - "scope" => "jsapi_address",  
165 - "appId" => WxPayConfig::APPID,  
166 - "timeStamp" => $data["timestamp"],  
167 - "nonceStr" => $data["noncestr"]  
168 - );  
169 - $parameters = json_encode($afterData);  
170 - return $parameters;  
171 - }  
172 -  
173 - /**  
174 - *  
175 - * 构造获取code的url连接  
176 - * @param string $redirectUrl 微信服务器回跳的url,需要url编码  
177 - *  
178 - * @return 返回构造好的url  
179 - */  
180 - private function __CreateOauthUrlForCode($redirectUrl)  
181 - {  
182 - $urlObj["appid"] = WxPayConfig::APPID;  
183 - $urlObj["redirect_uri"] = "$redirectUrl";  
184 - $urlObj["response_type"] = "code";  
185 - $urlObj["scope"] = "snsapi_base";  
186 - $urlObj["state"] = "STATE"."#wechat_redirect";  
187 - $bizString = $this->ToUrlParams($urlObj);  
188 - return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;  
189 - }  
190 -  
191 - /**  
192 - *  
193 - * 构造获取open和access_toke的url地址  
194 - * @param string $code,微信跳转带回的code  
195 - *  
196 - * @return 请求的url  
197 - */  
198 - private function __CreateOauthUrlForOpenid($code)  
199 - {  
200 - $urlObj["appid"] = WxPayConfig::APPID;  
201 - $urlObj["secret"] = WxPayConfig::APPSECRET;  
202 - $urlObj["code"] = $code;  
203 - $urlObj["grant_type"] = "authorization_code";  
204 - $bizString = $this->ToUrlParams($urlObj);  
205 - return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;  
206 - }  
207 -}  
1 -<?php  
2 -require_once "../lib/WxPay.Api.php";  
3 -/**  
4 - *  
5 - * 刷卡支付实现类  
6 - * 该类实现了一个刷卡支付的流程,流程如下:  
7 - * 1、提交刷卡支付  
8 - * 2、根据返回结果决定是否需要查询订单,如果查询之后订单还未变则需要返回查询(一般反复查10次)  
9 - * 3、如果反复查询10订单依然不变,则发起撤销订单  
10 - * 4、撤销订单需要循环撤销,一直撤销成功为止(注意循环次数,建议10次)  
11 - *  
12 - * 该类是微信支付提供的样例程序,商户可根据自己的需求修改,或者使用lib中的api自行开发,为了防止  
13 - * 查询时hold住后台php进程,商户查询和撤销逻辑可在前端调用  
14 - *  
15 - * @author widy  
16 - *  
17 - */  
18 -class MicroPay  
19 -{  
20 - /**  
21 - *  
22 - * 提交刷卡支付,并且确认结果,接口比较慢  
23 - * @param WxPayMicroPay $microPayInput  
24 - * @throws WxpayException  
25 - * @return 返回查询接口的结果  
26 - */  
27 - public function pay($microPayInput)  
28 - {  
29 - //①、提交被扫支付  
30 - $result = WxPayApi::micropay($microPayInput, 5);  
31 - //如果返回成功  
32 - if(!array_key_exists("return_code", $result)  
33 - || !array_key_exists("out_trade_no", $result)  
34 - || !array_key_exists("result_code", $result))  
35 - {  
36 - echo "接口调用失败,请确认是否输入是否有误!";  
37 - throw new WxPayException("接口调用失败!");  
38 - }  
39 -  
40 - //签名验证  
41 - $out_trade_no = $microPayInput->GetOut_trade_no();  
42 -  
43 - //②、接口调用成功,明确返回调用失败  
44 - if($result["return_code"] == "SUCCESS" &&  
45 - $result["result_code"] == "FAIL" &&  
46 - $result["err_code"] != "USERPAYING" &&  
47 - $result["err_code"] != "SYSTEMERROR")  
48 - {  
49 - return false;  
50 - }  
51 -  
52 - //③、确认支付是否成功  
53 - $queryTimes = 10;  
54 - while($queryTimes > 0)  
55 - {  
56 - $succResult = 0;  
57 - $queryResult = $this->query($out_trade_no, $succResult);  
58 - //如果需要等待1s后继续  
59 - if($succResult == 2){  
60 - sleep(2);  
61 - continue;  
62 - } else if($succResult == 1){//查询成功  
63 - return $queryResult;  
64 - } else {//订单交易失败  
65 - return false;  
66 - }  
67 - }  
68 -  
69 - //④、次确认失败,则撤销订单  
70 - if(!$this->cancel($out_trade_no))  
71 - {  
72 - throw new WxpayException("撤销单失败!");  
73 - }  
74 -  
75 - return false;  
76 - }  
77 -  
78 - /**  
79 - *  
80 - * 查询订单情况  
81 - * @param string $out_trade_no 商户订单号  
82 - * @param int $succCode 查询订单结果  
83 - * @return 0 订单不成功,1表示订单成功,2表示继续等待  
84 - */  
85 - public function query($out_trade_no, &$succCode)  
86 - {  
87 - $queryOrderInput = new WxPayOrderQuery();  
88 - $queryOrderInput->SetOut_trade_no($out_trade_no);  
89 - $result = WxPayApi::orderQuery($queryOrderInput);  
90 -  
91 - if($result["return_code"] == "SUCCESS"  
92 - && $result["result_code"] == "SUCCESS")  
93 - {  
94 - //支付成功  
95 - if($result["trade_state"] == "SUCCESS"){  
96 - $succCode = 1;  
97 - return $result;  
98 - }  
99 - //用户支付中  
100 - else if($result["trade_state"] == "USERPAYING"){  
101 - $succCode = 2;  
102 - return false;  
103 - }  
104 - }  
105 -  
106 - //如果返回错误码为“此交易订单号不存在”则直接认定失败  
107 - if($result["err_code"] == "ORDERNOTEXIST")  
108 - {  
109 - $succCode = 0;  
110 - } else{  
111 - //如果是系统错误,则后续继续  
112 - $succCode = 2;  
113 - }  
114 - return false;  
115 - }  
116 -  
117 - /**  
118 - *  
119 - * 撤销订单,如果失败会重复调用10次  
120 - * @param string $out_trade_no  
121 - * @param 调用深度 $depth  
122 - */  
123 - public function cancel($out_trade_no, $depth = 0)  
124 - {  
125 - if($depth > 10){  
126 - return false;  
127 - }  
128 -  
129 - $clostOrder = new WxPayReverse();  
130 - $clostOrder->SetOut_trade_no($out_trade_no);  
131 - $result = WxPayApi::reverse($clostOrder);  
132 -  
133 - //接口调用失败  
134 - if($result["return_code"] != "SUCCESS"){  
135 - return false;  
136 - }  
137 -  
138 - //如果结果为success且不需要重新调用撤销,则表示撤销成功  
139 - if($result["result_code"] != "SUCCESS"  
140 - && $result["recall"] == "N"){  
141 - return true;  
142 - } else if($result["recall"] == "Y") {  
143 - return $this->cancel($out_trade_no, ++$depth);  
144 - }  
145 - return false;  
146 - }  
147 -}  
1 -<?php  
2 -require_once "../lib/WxPay.Api.php";  
3 -  
4 -/**  
5 - *  
6 - * 刷卡支付实现类  
7 - * @author widyhu  
8 - *  
9 - */  
10 -class NativePay  
11 -{  
12 - /**  
13 - *  
14 - * 生成扫描支付URL,模式一  
15 - * @param BizPayUrlInput $bizUrlInfo  
16 - */  
17 - public function GetPrePayUrl($productId)  
18 - {  
19 - $biz = new WxPayBizPayUrl();  
20 - $biz->SetProduct_id($productId);  
21 - $values = WxpayApi::bizpayurl($biz);  
22 - $url = "weixin://wxpay/bizpayurl?" . $this->ToUrlParams($values);  
23 - return $url;  
24 - }  
25 -  
26 - /**  
27 - *  
28 - * 参数数组转换为url参数  
29 - * @param array $urlObj  
30 - */  
31 - private function ToUrlParams($urlObj)  
32 - {  
33 - $buff = "";  
34 - foreach ($urlObj as $k => $v)  
35 - {  
36 - $buff .= $k . "=" . $v . "&";  
37 - }  
38 -  
39 - $buff = trim($buff, "&");  
40 - return $buff;  
41 - }  
42 -  
43 - /**  
44 - *  
45 - * 生成直接支付url,支付url有效期为2小时,模式二  
46 - * @param UnifiedOrderInput $input  
47 - */  
48 - public function GetPayUrl($input)  
49 - {  
50 - if($input->GetTrade_type() == "NATIVE")  
51 - {  
52 - $result = WxPayApi::unifiedOrder($input);  
53 - return $result;  
54 - }  
55 - }  
56 -}  
1 -<?php  
2 -require_once "../lib/WxPay.Api.php";  
3 -//require_once "../lib/WxPay.MicroPay.php";  
4 -  
5 -  
6 -if(isset($_REQUEST["bill_date"]) && $_REQUEST["bill_date"] != ""){  
7 - $bill_date = $_REQUEST["bill_date"];  
8 - $bill_type = $_REQUEST["bill_type"];  
9 - $input = new WxPayDownloadBill();  
10 - $input->SetBill_date($bill_date);  
11 - $input->SetBill_type($bill_type);  
12 - $file = WxPayApi::downloadBill($input);  
13 - echo $file;  
14 - //TODO 对账单文件处理  
15 - exit(0);  
16 -}  
17 -?>  
18 -<html>  
19 -<head>  
20 - <meta http-equiv="content-type" content="text/html;charset=utf-8"/>  
21 - <meta name="viewport" content="width=device-width, initial-scale=1" />  
22 - <title>微信支付样例-查退款单</title>  
23 -</head>  
24 -<body>  
25 - <form action="#" method="post">  
26 - <div style="margin-left:2%;">对账日期:</div><br/>  
27 - <input type="text" style="width:96%;height:35px;margin-left:2%;" name="bill_date" /><br /><br />  
28 - <div style="margin-left:2%;">账单类型:</div><br/>  
29 - <select style="width:96%;height:35px;margin-left:2%;" name="bill_type">  
30 - <option value ="ALL">所有订单信息</option>  
31 - <option value ="SUCCESS">成功支付的订单</option>  
32 - <option value="REFUND">退款订单</option>  
33 - <option value="REVOKED">撤销的订单</option>  
34 - </select><br /><br />  
35 - <div align="center">  
36 - <input type="submit" value="下载订单" style="width:210px; height:50px; border-radius: 15px;background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer; color:white; font-size:16px;" type="button" onclick="callpay()" />  
37 - </div>  
38 - </form>  
39 -</body>  
40 -</html>  
1 -<?php  
2 -ini_set('date.timezone','Asia/Shanghai');  
3 -//error_reporting(E_ERROR);  
4 -require_once "../lib/WxPay.Api.php";  
5 -require_once "WxPay.JsApiPay.php";  
6 -require_once 'log.php';  
7 -  
8 -//初始化日志  
9 -$logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log');  
10 -$log = Log::Init($logHandler, 15);  
11 -  
12 -//打印输出数组信息  
13 -function printf_info($data)  
14 -{  
15 - foreach($data as $key=>$value){  
16 - echo "<font color='#00ff55;'>$key</font> : $value <br/>";  
17 - }  
18 -}  
19 -  
20 -//①、获取用户openid  
21 -$tools = new JsApiPay();  
22 -$openId = $tools->GetOpenid();  
23 -  
24 -//②、统一下单  
25 -$input = new WxPayUnifiedOrder();  
26 -$input->SetBody("test");  
27 -$input->SetAttach("test");  
28 -$input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));  
29 -$input->SetTotal_fee("1");  
30 -$input->SetTime_start(date("YmdHis"));  
31 -$input->SetTime_expire(date("YmdHis", time() + 600));  
32 -$input->SetGoods_tag("test");  
33 -$input->SetNotify_url("http://paysdk.weixin.qq.com/example/notify.php");  
34 -$input->SetTrade_type("JSAPI");  
35 -$input->SetOpenid($openId);  
36 -$order = WxPayApi::unifiedOrder($input);  
37 -echo '<font color="#f00"><b>统一下单支付单信息</b></font><br/>';  
38 -printf_info($order);  
39 -$jsApiParameters = $tools->GetJsApiParameters($order);  
40 -  
41 -//获取共享收货地址js函数参数  
42 -$editAddress = $tools->GetEditAddressParameters();  
43 -  
44 -//③、在支持成功回调通知中处理成功之后的事宜,见 notify.php  
45 -/**  
46 - * 注意:  
47 - * 1、当你的回调地址不可访问的时候,回调通知会失败,可以通过查询订单来确认支付是否成功  
48 - * 2、jsapi支付时需要填入用户openid,WxPay.JsApiPay.php中有获取openid流程 (文档可以参考微信公众平台“网页授权接口”,  
49 - * 参考http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html)  
50 - */  
51 -?>  
52 -  
53 -<html>  
54 -<head>  
55 - <meta http-equiv="content-type" content="text/html;charset=utf-8"/>  
56 - <meta name="viewport" content="width=device-width, initial-scale=1"/>  
57 - <title>微信支付样例-支付</title>  
58 - <script type="text/javascript">  
59 - //调用微信JS api 支付  
60 - function jsApiCall()  
61 - {  
62 - WeixinJSBridge.invoke(  
63 - 'getBrandWCPayRequest',  
64 - <?php echo $jsApiParameters; ?>,  
65 - function(res){  
66 - WeixinJSBridge.log(res.err_msg);  
67 - alert(res.err_code+res.err_desc+res.err_msg);  
68 - }  
69 - );  
70 - }  
71 -  
72 - function callpay()  
73 - {  
74 - if (typeof WeixinJSBridge == "undefined"){  
75 - if( document.addEventListener ){  
76 - document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);  
77 - }else if (document.attachEvent){  
78 - document.attachEvent('WeixinJSBridgeReady', jsApiCall);  
79 - document.attachEvent('onWeixinJSBridgeReady', jsApiCall);  
80 - }  
81 - }else{  
82 - jsApiCall();  
83 - }  
84 - }  
85 - </script>  
86 - <script type="text/javascript">  
87 - //获取共享地址  
88 - function editAddress()  
89 - {  
90 - WeixinJSBridge.invoke(  
91 - 'editAddress',  
92 - <?php echo $editAddress; ?>,  
93 - function(res){  
94 - var value1 = res.proviceFirstStageName;  
95 - var value2 = res.addressCitySecondStageName;  
96 - var value3 = res.addressCountiesThirdStageName;  
97 - var value4 = res.addressDetailInfo;  
98 - var tel = res.telNumber;  
99 -  
100 - alert(value1 + value2 + value3 + value4 + ":" + tel);  
101 - }  
102 - );  
103 - }  
104 -  
105 - window.onload = function(){  
106 - if (typeof WeixinJSBridge == "undefined"){  
107 - if( document.addEventListener ){  
108 - document.addEventListener('WeixinJSBridgeReady', editAddress, false);  
109 - }else if (document.attachEvent){  
110 - document.attachEvent('WeixinJSBridgeReady', editAddress);  
111 - document.attachEvent('onWeixinJSBridgeReady', editAddress);  
112 - }  
113 - }else{  
114 - editAddress();  
115 - }  
116 - };  
117 -  
118 - </script>  
119 -</head>  
120 -<body>  
121 - <br/>  
122 - <font color="#9ACD32"><b>该笔订单支付金额为<span style="color:#f00;font-size:50px">1分</span></b></font><br/><br/>  
123 - <div align="center">  
124 - <button style="width:210px; height:50px; border-radius: 15px;background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer; color:white; font-size:16px;" type="button" onclick="callpay()" >立即支付</button>  
125 - </div>  
126 -</body>  
127 -</html>  
1 -<?php  
2 -//以下为日志  
3 -  
4 -interface ILogHandler  
5 -{  
6 - public function write($msg);  
7 -  
8 -}  
9 -  
10 -class CLogFileHandler implements ILogHandler  
11 -{  
12 - private $handle = null;  
13 -  
14 - public function __construct($file = '')  
15 - {  
16 - $this->handle = fopen($file,'a');  
17 - }  
18 -  
19 - public function write($msg)  
20 - {  
21 - fwrite($this->handle, $msg, 4096);  
22 - }  
23 -  
24 - public function __destruct()  
25 - {  
26 - fclose($this->handle);  
27 - }  
28 -}  
29 -  
30 -class Log  
31 -{  
32 - private $handler = null;  
33 - private $level = 15;  
34 -  
35 - private static $instance = null;  
36 -  
37 - private function __construct(){}  
38 -  
39 - private function __clone(){}  
40 -  
41 - public static function Init($handler = null,$level = 15)  
42 - {  
43 - if(!self::$instance instanceof self)  
44 - {  
45 - self::$instance = new self();  
46 - self::$instance->__setHandle($handler);  
47 - self::$instance->__setLevel($level);  
48 - }  
49 - return self::$instance;  
50 - }  
51 -  
52 -  
53 - private function __setHandle($handler){  
54 - $this->handler = $handler;  
55 - }  
56 -  
57 - private function __setLevel($level)  
58 - {  
59 - $this->level = $level;  
60 - }  
61 -  
62 - public static function DEBUG($msg)  
63 - {  
64 - self::$instance->write(1, $msg);  
65 - }  
66 -  
67 - public static function WARN($msg)  
68 - {  
69 - self::$instance->write(4, $msg);  
70 - }  
71 -  
72 - public static function ERROR($msg)  
73 - {  
74 - $debugInfo = debug_backtrace();  
75 - $stack = "[";  
76 - foreach($debugInfo as $key => $val){  
77 - if(array_key_exists("file", $val)){  
78 - $stack .= ",file:" . $val["file"];  
79 - }  
80 - if(array_key_exists("line", $val)){  
81 - $stack .= ",line:" . $val["line"];  
82 - }  
83 - if(array_key_exists("function", $val)){  
84 - $stack .= ",function:" . $val["function"];  
85 - }  
86 - }  
87 - $stack .= "]";  
88 - self::$instance->write(8, $stack . $msg);  
89 - }  
90 -  
91 - public static function INFO($msg)  
92 - {  
93 - self::$instance->write(2, $msg);  
94 - }  
95 -  
96 - private function getLevelStr($level)  
97 - {  
98 - switch ($level)  
99 - {  
100 - case 1:  
101 - return 'debug';  
102 - break;  
103 - case 2:  
104 - return 'info';  
105 - break;  
106 - case 4:  
107 - return 'warn';  
108 - break;  
109 - case 8:  
110 - return 'error';  
111 - break;  
112 - default:  
113 -  
114 - }  
115 - }  
116 -  
117 - protected function write($level,$msg)  
118 - {  
119 - if(($level & $this->level) == $level )  
120 - {  
121 - $msg = '['.date('Y-m-d H:i:s').']['.$this->getLevelStr($level).'] '.$msg."\n";  
122 - $this->handler->write($msg);  
123 - }  
124 - }  
125 -}  
1 -<html>  
2 -<head>  
3 - <meta http-equiv="content-type" content="text/html;charset=utf-8"/>  
4 - <meta name="viewport" content="width=device-width, initial-scale=1" />  
5 - <title>微信支付样例-查退款单</title>  
6 -</head>  
7 -<?php  
8 -require_once "../lib/WxPay.Api.php";  
9 -require_once "WxPay.MicroPay.php";  
10 -require_once 'log.php';  
11 -  
12 -//初始化日志  
13 -$logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log');  
14 -$log = Log::Init($logHandler, 15);  
15 -  
16 -//打印输出数组信息  
17 -function printf_info($data)  
18 -{  
19 - foreach($data as $key=>$value){  
20 - echo "<font color='#00ff55;'>$key</font> : $value <br/>";  
21 - }  
22 -}  
23 -  
24 -if(isset($_REQUEST["auth_code"]) && $_REQUEST["auth_code"] != ""){  
25 - $auth_code = $_REQUEST["auth_code"];  
26 - $input = new WxPayMicroPay();  
27 - $input->SetAuth_code($auth_code);  
28 - $input->SetBody("刷卡测试样例-支付");  
29 - $input->SetTotal_fee("1");  
30 - $input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));  
31 -  
32 - $microPay = new MicroPay();  
33 - printf_info($microPay->pay($input));  
34 -}  
35 -  
36 -/**  
37 - * 注意:  
38 - * 1、提交被扫之后,返回系统繁忙、用户输入密码等错误信息时需要循环查单以确定是否支付成功  
39 - * 2、多次(一半10次)确认都未明确成功时需要调用撤单接口撤单,防止用户重复支付  
40 - */  
41 -  
42 -?>  
43 -<body>  
44 - <form action="#" method="post">  
45 - <div style="margin-left:2%;">商品描述:</div><br/>  
46 - <input type="text" style="width:96%;height:35px;margin-left:2%;" readonly value="刷卡测试样例-支付" name="auth_code" /><br /><br />  
47 - <div style="margin-left:2%;">支付金额:</div><br/>  
48 - <input type="text" style="width:96%;height:35px;margin-left:2%;" readonly value="1分" name="auth_code" /><br /><br />  
49 - <div style="margin-left:2%;">授权码:</div><br/>  
50 - <input type="text" style="width:96%;height:35px;margin-left:2%;" name="auth_code" /><br /><br />  
51 - <div align="center">  
52 - <input type="submit" value="提交刷卡" style="width:210px; height:50px; border-radius: 15px;background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer; color:white; font-size:16px;" type="button" onclick="callpay()" />  
53 - </div>  
54 - </form>  
55 -</body>  
56 -</html>  
1 -<?php  
2 -ini_set('date.timezone','Asia/Shanghai');  
3 -//error_reporting(E_ERROR);  
4 -  
5 -require_once "../lib/WxPay.Api.php";  
6 -require_once "WxPay.NativePay.php";  
7 -require_once 'log.php';  
8 -  
9 -//模式一  
10 -/**  
11 - * 流程:  
12 - * 1、组装包含支付信息的url,生成二维码  
13 - * 2、用户扫描二维码,进行支付  
14 - * 3、确定支付之后,微信服务器会回调预先配置的回调地址,在【微信开放平台-微信支付-支付配置】中进行配置  
15 - * 4、在接到回调通知之后,用户进行统一下单支付,并返回支付信息以完成支付(见:native_notify.php)  
16 - * 5、支付完成之后,微信服务器会通知支付成功  
17 - * 6、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)  
18 - */  
19 -$notify = new NativePay();  
20 -$url1 = $notify->GetPrePayUrl("123456789");  
21 -  
22 -//模式二  
23 -/**  
24 - * 流程:  
25 - * 1、调用统一下单,取得code_url,生成二维码  
26 - * 2、用户扫描二维码,进行支付  
27 - * 3、支付完成之后,微信服务器会通知支付成功  
28 - * 4、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)  
29 - */  
30 -$input = new WxPayUnifiedOrder();  
31 -$input->SetBody("test");  
32 -$input->SetAttach("test");  
33 -$input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));  
34 -$input->SetTotal_fee("1");  
35 -$input->SetTime_start(date("YmdHis"));  
36 -$input->SetTime_expire(date("YmdHis", time() + 600));  
37 -$input->SetGoods_tag("test");  
38 -$input->SetNotify_url("http://paysdk.weixin.qq.com/example/notify.php");  
39 -$input->SetTrade_type("NATIVE");  
40 -$input->SetProduct_id("123456789");  
41 -$result = $notify->GetPayUrl($input);  
42 -$url2 = $result["code_url"];  
43 -?>  
44 -  
45 -<html>  
46 -<head>  
47 - <meta http-equiv="content-type" content="text/html;charset=utf-8"/>  
48 - <meta name="viewport" content="width=device-width, initial-scale=1" />  
49 - <title>微信支付样例-退款</title>  
50 -</head>  
51 -<body>  
52 - <div style="margin-left: 10px;color:#556B2F;font-size:30px;font-weight: bolder;">扫描支付模式一</div><br/>  
53 - <img alt="模式一扫码支付" src="http://paysdk.weixin.qq.com/example/qrcode.php?data=<?php echo urlencode($url1);?>" style="width:150px;height:150px;"/>  
54 - <br/><br/><br/>  
55 - <div style="margin-left: 10px;color:#556B2F;font-size:30px;font-weight: bolder;">扫描支付模式二</div><br/>  
56 - <img alt="模式二扫码支付" src="http://paysdk.weixin.qq.com/example/qrcode.php?data=<?php echo urlencode($url2);?>" style="width:150px;height:150px;"/>  
57 -  
58 -</body>  
59 -</html>  
1 -<?php  
2 -ini_set('date.timezone','Asia/Shanghai');  
3 -error_reporting(E_ERROR);  
4 -  
5 -require_once "../lib/WxPay.Api.php";  
6 -require_once '../lib/WxPay.Notify.php';  
7 -require_once 'log.php';  
8 -  
9 -//初始化日志  
10 -$logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log');  
11 -$log = Log::Init($logHandler, 15);  
12 -  
13 -class NativeNotifyCallBack extends WxPayNotify  
14 -{  
15 - public function unifiedorder($openId, $product_id)  
16 - {  
17 - //统一下单  
18 - $input = new WxPayUnifiedOrder();  
19 - $input->SetBody("test");  
20 - $input->SetAttach("test");  
21 - $input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));  
22 - $input->SetTotal_fee("1");  
23 - $input->SetTime_start(date("YmdHis"));  
24 - $input->SetTime_expire(date("YmdHis", time() + 600));  
25 - $input->SetGoods_tag("test");  
26 - $input->SetNotify_url("http://paysdk.weixin.qq.com/example/notify.php");  
27 - $input->SetTrade_type("NATIVE");  
28 - $input->SetOpenid($openId);  
29 - $input->SetProduct_id($product_id);  
30 - $result = WxPayApi::unifiedOrder($input);  
31 - Log::DEBUG("unifiedorder:" . json_encode($result));  
32 - return $result;  
33 - }  
34 -  
35 - public function NotifyProcess($data, &$msg)  
36 - {  
37 - //echo "处理回调";  
38 - Log::DEBUG("call back:" . json_encode($data));  
39 -  
40 - if(!array_key_exists("openid", $data) ||  
41 - !array_key_exists("product_id", $data))  
42 - {  
43 - $msg = "回调数据异常";  
44 - return false;  
45 - }  
46 -  
47 - $openid = $data["openid"];  
48 - $product_id = $data["product_id"];  
49 -  
50 - //统一下单  
51 - $result = $this->unifiedorder($openid, $product_id);  
52 - if(!array_key_exists("appid", $result) ||  
53 - !array_key_exists("mch_id", $result) ||  
54 - !array_key_exists("prepay_id", $result))  
55 - {  
56 - $msg = "统一下单失败";  
57 - return false;  
58 - }  
59 -  
60 - $this->SetData("appid", $result["appid"]);  
61 - $this->SetData("mch_id", $result["mch_id"]);  
62 - $this->SetData("nonce_str", WxPayApi::getNonceStr());  
63 - $this->SetData("prepay_id", $result["prepay_id"]);  
64 - $this->SetData("result_code", "SUCCESS");  
65 - $this->SetData("err_code_des", "OK");  
66 - return true;  
67 - }  
68 -}  
69 -  
70 -Log::DEBUG("begin notify!");  
71 -$notify = new NativeNotifyCallBack();  
72 -$notify->Handle(true);  
1 -<?php  
2 -ini_set('date.timezone','Asia/Shanghai');  
3 -error_reporting(E_ERROR);  
4 -  
5 -require_once "../lib/WxPay.Api.php";  
6 -require_once '../lib/WxPay.Notify.php';  
7 -require_once 'log.php';  
8 -  
9 -//初始化日志  
10 -$logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log');  
11 -$log = Log::Init($logHandler, 15);  
12 -  
13 -class PayNotifyCallBack extends WxPayNotify  
14 -{  
15 - //查询订单  
16 - public function Queryorder($transaction_id)  
17 - {  
18 - $input = new WxPayOrderQuery();  
19 - $input->SetTransaction_id($transaction_id);  
20 - $result = WxPayApi::orderQuery($input);  
21 - Log::DEBUG("query:" . json_encode($result));  
22 - if(array_key_exists("return_code", $result)  
23 - && array_key_exists("result_code", $result)  
24 - && $result["return_code"] == "SUCCESS"  
25 - && $result["result_code"] == "SUCCESS")  
26 - {  
27 - return true;  
28 - }  
29 - return false;  
30 - }  
31 -  
32 - //重写回调处理函数  
33 - public function NotifyProcess($data, &$msg)  
34 - {  
35 - Log::DEBUG("call back:" . json_encode($data));  
36 - $notfiyOutput = array();  
37 -  
38 - if(!array_key_exists("transaction_id", $data)){  
39 - $msg = "输入参数不正确";  
40 - return false;  
41 - }  
42 - //查询订单,判断订单真实性  
43 - if(!$this->Queryorder($data["transaction_id"])){  
44 - $msg = "订单查询失败";  
45 - return false;  
46 - }  
47 - return true;  
48 - }  
49 -}  
50 -  
51 -Log::DEBUG("begin notify");  
52 -$notify = new PayNotifyCallBack();  
53 -$notify->Handle(false);  
1 -<html>  
2 -<head>  
3 - <meta http-equiv="content-type" content="text/html;charset=utf-8"/>  
4 - <meta name="viewport" content="width=device-width, initial-scale=1" />  
5 - <title>微信支付样例-订单查询</title>  
6 -</head>  
7 -<?php  
8 -ini_set('date.timezone','Asia/Shanghai');  
9 -error_reporting(E_ERROR);  
10 -require_once "../lib/WxPay.Api.php";  
11 -require_once 'log.php';  
12 -  
13 -//初始化日志  
14 -$logHandler= new CLogFileHandler("./logs/".date('Y-m-d').'.log');  
15 -$log = Log::Init($logHandler, 15);  
16 -  
17 -function printf_info($data)  
18 -{  
19 - foreach($data as $key=>$value){  
20 - echo "<font color='#f00;'>$key</font> : $value <br/>";  
21 - }  
22 -}  
23 -  
24 -  
25 -if(isset($_REQUEST["transaction_id"]) && $_REQUEST["transaction_id"] != ""){  
26 - $transaction_id = $_REQUEST["transaction_id"];  
27 - $input = new WxPayOrderQuery();  
28 - $input->SetTransaction_id($transaction_id);  
29 - printf_info(WxPayApi::orderQuery($input));  
30 - exit();  
31 -}  
32 -  
33 -if(isset($_REQUEST["out_trade_no"]) && $_REQUEST["out_trade_no"] != ""){  
34 - $out_trade_no = $_REQUEST["out_trade_no"];  
35 - $input = new WxPayOrderQuery();  
36 - $input->SetOut_trade_no($out_trade_no);  
37 - printf_info(WxPayApi::orderQuery($input));  
38 - exit();  
39 -}  
40 -?>  
41 -<body>  
42 - <form action="#" method="post">  
43 - <div style="margin-left:2%;color:#f00">微信订单号和商户订单号选少填一个,微信订单号优先:</div><br/>  
44 - <div style="margin-left:2%;">微信订单号:</div><br/>  
45 - <input type="text" style="width:96%;height:35px;margin-left:2%;" name="transaction_id" /><br /><br />  
46 - <div style="margin-left:2%;">商户订单号:</div><br/>  
47 - <input type="text" style="width:96%;height:35px;margin-left:2%;" name="out_trade_no" /><br /><br />  
48 - <div align="center">  
49 - <input type="submit" value="查询" style="width:210px; height:50px; border-radius: 15px;background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer; color:white; font-size:16px;" type="button" onclick="callpay()" />  
50 - </div>  
51 - </form>  
52 -</body>  
53 -</html>  
1 -<?php  
2 -error_reporting(E_ERROR);  
3 -require_once 'phpqrcode/phpqrcode.php';  
4 -$url = urldecode($_GET["data"]);  
5 -QRcode::png($url);  
1 -<html>  
2 -<head>  
3 - <meta http-equiv="content-type" content="text/html;charset=utf-8"/>  
4 - <meta name="viewport" content="width=device-width, initial-scale=1" />  
5 - <title>微信支付样例-退款</title>  
6 -</head>  
7 -<?php  
8 -ini_set('date.timezone','Asia/Shanghai');  
9 -error_reporting(E_ERROR);  
10 -require_once "../lib/WxPay.Api.php";  
11 -require_once 'log.php';  
12 -  
13 -//初始化日志  
14 -$logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log');  
15 -$log = Log::Init($logHandler, 15);  
16 -  
17 -function printf_info($data)  
18 -{  
19 - foreach($data as $key=>$value){  
20 - echo "<font color='#f00;'>$key</font> : $value <br/>";  
21 - }  
22 -}  
23 -  
24 -if(isset($_REQUEST["transaction_id"]) && $_REQUEST["transaction_id"] != ""){  
25 - $transaction_id = $_REQUEST["transaction_id"];  
26 - $total_fee = $_REQUEST["total_fee"];  
27 - $refund_fee = $_REQUEST["refund_fee"];  
28 - $input = new WxPayRefund();  
29 - $input->SetTransaction_id($transaction_id);  
30 - $input->SetTotal_fee($total_fee);  
31 - $input->SetRefund_fee($refund_fee);  
32 - $input->SetOut_refund_no(WxPayConfig::MCHID.date("YmdHis"));  
33 - $input->SetOp_user_id(WxPayConfig::MCHID);  
34 - printf_info(WxPayApi::refund($input));  
35 - exit();  
36 -}  
37 -  
38 -//$_REQUEST["out_trade_no"]= "122531270220150304194108";  
39 -///$_REQUEST["total_fee"]= "1";  
40 -//$_REQUEST["refund_fee"] = "1";  
41 -if(isset($_REQUEST["out_trade_no"]) && $_REQUEST["out_trade_no"] != ""){  
42 - $out_trade_no = $_REQUEST["out_trade_no"];  
43 - $total_fee = $_REQUEST["total_fee"];  
44 - $refund_fee = $_REQUEST["refund_fee"];  
45 - $input = new WxPayRefund();  
46 - $input->SetOut_trade_no($out_trade_no);  
47 - $input->SetTotal_fee($total_fee);  
48 - $input->SetRefund_fee($refund_fee);  
49 - $input->SetOut_refund_no(WxPayConfig::MCHID.date("YmdHis"));  
50 - $input->SetOp_user_id(WxPayConfig::MCHID);  
51 - printf_info(WxPayApi::refund($input));  
52 - exit();  
53 -}  
54 -?>  
55 -<body>  
56 - <form action="#" method="post">  
57 - <div style="margin-left:2%;color:#f00">微信订单号和商户订单号选少填一个,微信订单号优先:</div><br/>  
58 - <div style="margin-left:2%;">微信订单号:</div><br/>  
59 - <input type="text" style="width:96%;height:35px;margin-left:2%;" name="transaction_id" /><br /><br />  
60 - <div style="margin-left:2%;">商户订单号:</div><br/>  
61 - <input type="text" style="width:96%;height:35px;margin-left:2%;" name="out_trade_no" /><br /><br />  
62 - <div style="margin-left:2%;">订单总金额(分):</div><br/>  
63 - <input type="text" style="width:96%;height:35px;margin-left:2%;" name="total_fee" /><br /><br />  
64 - <div style="margin-left:2%;">退款金额(分):</div><br/>  
65 - <input type="text" style="width:96%;height:35px;margin-left:2%;" name="refund_fee" /><br /><br />  
66 - <div align="center">  
67 - <input type="submit" value="提交退款" style="width:210px; height:50px; border-radius: 15px;background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer; color:white; font-size:16px;" type="button" onclick="callpay()" />  
68 - </div>  
69 - </form>  
70 -</body>  
71 -</html>  
1 -<html>  
2 -<head>  
3 - <meta http-equiv="content-type" content="text/html;charset=utf-8"/>  
4 - <meta name="viewport" content="width=device-width, initial-scale=1" />  
5 - <title>微信支付样例-查退款单</title>  
6 -</head>  
7 -<?php  
8 -ini_set('date.timezone','Asia/Shanghai');  
9 -error_reporting(E_ERROR);  
10 -require_once "../lib/WxPay.Api.php";  
11 -require_once 'log.php';  
12 -  
13 -//初始化日志  
14 -$logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log');  
15 -$log = Log::Init($logHandler, 15);  
16 -  
17 -  
18 -function printf_info($data)  
19 -{  
20 - foreach($data as $key=>$value){  
21 - echo "<font color='#f00;'>$key</font> : $value <br/>";  
22 - }  
23 -}  
24 -  
25 -if(isset($_REQUEST["transaction_id"]) && $_REQUEST["transaction_id"] != ""){  
26 - $transaction_id = $_REQUEST["transaction_id"];  
27 - $input = new WxPayRefundQuery();  
28 - $input->SetTransaction_id($transaction_id);  
29 - printf_info(WxPayApi::refundQuery($input));  
30 -}  
31 -  
32 -if(isset($_REQUEST["out_trade_no"]) && $_REQUEST["out_trade_no"] != ""){  
33 - $out_trade_no = $_REQUEST["out_trade_no"];  
34 - $input = new WxPayRefundQuery();  
35 - $input->SetOut_trade_no($out_trade_no);  
36 - printf_info(WxPayApi::refundQuery($input));  
37 - exit();  
38 -}  
39 -  
40 -if(isset($_REQUEST["out_refund_no"]) && $_REQUEST["out_refund_no"] != ""){  
41 - $out_refund_no = $_REQUEST["out_refund_no"];  
42 - $input = new WxPayRefundQuery();  
43 - $input->SetOut_refund_no($out_refund_no);  
44 - printf_info(WxPayApi::refundQuery($input));  
45 - exit();  
46 -}  
47 -  
48 -if(isset($_REQUEST["refund_id"]) && $_REQUEST["refund_id"] != ""){  
49 - $refund_id = $_REQUEST["refund_id"];  
50 - $input = new WxPayRefundQuery();  
51 - $input->SetRefund_id($refund_id);  
52 - printf_info(WxPayApi::refundQuery($input));  
53 - exit();  
54 -}  
55 -  
56 -?>  
57 -<body>  
58 - <form action="#" method="post">  
59 - <div style="margin-left:2%;color:#f00">微信订单号、商户订单号、微信订单号、微信退款单号选填至少一个,微信退款单号优先:</div><br/>  
60 - <div style="margin-left:2%;">微信订单号:</div><br/>  
61 - <input type="text" style="width:96%;height:35px;margin-left:2%;" name="transaction_id" /><br /><br />  
62 - <div style="margin-left:2%;">商户订单号:</div><br/>  
63 - <input type="text" style="width:96%;height:35px;margin-left:2%;" name="out_trade_no" /><br /><br />  
64 - <div style="margin-left:2%;">商户退款单号:</div><br/>  
65 - <input type="text" style="width:96%;height:35px;margin-left:2%;" name="out_refund_no" /><br /><br />  
66 - <div style="margin-left:2%;">微信退款单号:</div><br/>  
67 - <input type="text" style="width:96%;height:35px;margin-left:2%;" name="refund_id" /><br /><br />  
68 - <div align="center">  
69 - <input type="submit" value="查询" style="width:210px; height:50px; border-radius: 15px;background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer; color:white; font-size:16px;" type="button" onclick="callpay()" />  
70 - </div>  
71 - </form>  
72 -</body>  
73 -</html>  
1 -<html>  
2 -<head>  
3 - <meta http-equiv="content-type" content="text/html;charset=utf-8"/>  
4 - <meta name="viewport" content="width=device-width, initial-scale=1"/>  
5 - <title>微信支付样例</title>  
6 - <style type="text/css">  
7 - ul {  
8 - margin-left:10px;  
9 - margin-right:10px;  
10 - margin-top:10px;  
11 - padding: 0;  
12 - }  
13 - li {  
14 - width: 32%;  
15 - float: left;  
16 - margin: 0px;  
17 - margin-left:1%;  
18 - padding: 0px;  
19 - height: 100px;  
20 - display: inline;  
21 - line-height: 100px;  
22 - color: #fff;  
23 - font-size: x-large;  
24 - word-break:break-all;  
25 - word-wrap : break-word;  
26 - margin-bottom: 5px;  
27 - }  
28 - a {  
29 - -webkit-tap-highlight-color: rgba(0,0,0,0);  
30 - text-decoration:none;  
31 - color:#fff;  
32 - }  
33 - a:link{  
34 - -webkit-tap-highlight-color: rgba(0,0,0,0);  
35 - text-decoration:none;  
36 - color:#fff;  
37 - }  
38 - a:visited{  
39 - -webkit-tap-highlight-color: rgba(0,0,0,0);  
40 - text-decoration:none;  
41 - color:#fff;  
42 - }  
43 - a:hover{  
44 - -webkit-tap-highlight-color: rgba(0,0,0,0);  
45 - text-decoration:none;  
46 - color:#fff;  
47 - }  
48 - a:active{  
49 - -webkit-tap-highlight-color: rgba(0,0,0,0);  
50 - text-decoration:none;  
51 - color:#fff;  
52 - }  
53 - </style>  
54 -</head>  
55 -<body>  
56 - <div align="center">  
57 - <ul>  
58 - <li style="background-color:#FF7F24"><a href="http://paysdk.weixin.qq.com/example/jsapi.php">JSAPI支付</a></li>  
59 - <li style="background-color:#698B22"><a href="http://paysdk.weixin.qq.com/example/micropay.php">刷卡支付</a></li>  
60 - <li style="background-color:#8B6914"><a href="http://paysdk.weixin.qq.com/example/native.php">扫码支付</a></li>  
61 - <li style="background-color:#CDCD00"><a href="http://paysdk.weixin.qq.com/example/orderquery.php">订单查询</a></li>  
62 - <li style="background-color:#CD3278"><a href="http://paysdk.weixin.qq.com/example/refund.php">订单退款</a></li>  
63 - <li style="background-color:#848484"><a href="http://paysdk.weixin.qq.com/example/refundquery.php">退款查询</a></li>  
64 - <li style="background-color:#8EE5EE"><a href="http://paysdk.weixin.qq.com/example/download.php">下载订单</a></li>  
65 - </ul>  
66 - </div>  
67 -</body>  
68 -</html>  
1 -<?php  
2 -/*  
3 - * 小程序微信支付  
4 - */  
5 -class WeixinPay {  
6 - protected $appid;  
7 - protected $mch_id;  
8 - protected $key;  
9 - protected $openid;  
10 - protected $out_trade_no;  
11 - protected $body;  
12 - protected $total_fee;  
13 - protected $notify_url;  
14 - function __construct($appid, $openid, $mch_id, $key,$out_trade_no,$body,$total_fee,$notify_url) {  
15 - $this->appid = $appid;  
16 - $this->openid = $openid;  
17 - $this->mch_id = $mch_id;  
18 - $this->key = $key;  
19 - $this->out_trade_no = $out_trade_no;  
20 - $this->body = $body;  
21 - $this->total_fee = $total_fee;  
22 - $this->notify_url = $notify_url;  
23 - }  
24 - public function pay() {  
25 - //统一下单接口  
26 - $return = $this->weixinapp();  
27 - return $return;  
28 - }  
29 - //统一下单接口  
30 - private function unifiedorder() {  
31 - $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';  
32 - $parameters = array(  
33 - 'appid' => $this->appid, //小程序ID  
34 - 'mch_id' => $this->mch_id, //商户号  
35 - 'nonce_str' => $this->createNoncestr(), //随机字符串  
36 - 'body' => $this->body,  
37 - 'out_trade_no'=> $this->out_trade_no,  
38 - 'total_fee' => $this->total_fee,  
39 - 'spbill_create_ip' => get_client_ip(0,true),  
40 - 'notify_url' => $this->notify_url,  
41 - 'openid' => $this->openid, //用户id  
42 - 'trade_type' => 'JSAPI'//交易类型  
43 - );  
44 - //统一下单签名  
45 - $parameters['sign'] = $this->getSign($parameters);  
46 - $xmlData = $this->arrayToXml($parameters);  
47 - $return = $this->xmlToArray($this->postXmlCurl($xmlData, $url, 60));  
48 - return $return;  
49 - }  
50 - private static function postXmlCurl($xml, $url, $second = 30)  
51 - {  
52 - $ch = curl_init();  
53 - //设置超时  
54 - curl_setopt($ch, CURLOPT_TIMEOUT, $second);  
55 - curl_setopt($ch, CURLOPT_URL, $url);  
56 - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);  
57 - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //严格校验  
58 - //设置header  
59 - curl_setopt($ch, CURLOPT_HEADER, FALSE);  
60 - //要求结果为字符串且输出到屏幕上  
61 - curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);  
62 - //post提交方式  
63 - curl_setopt($ch, CURLOPT_POST, TRUE);  
64 - curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);  
65 - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);  
66 - curl_setopt($ch, CURLOPT_TIMEOUT, 40);  
67 - set_time_limit(0);  
68 - //运行curl  
69 - $data = curl_exec($ch);  
70 - //返回结果  
71 - if ($data) {  
72 - curl_close($ch);  
73 - return $data;  
74 - } else {  
75 - $error = curl_errno($ch);  
76 - curl_close($ch);  
77 - throw new WxPayException("curl出错,错误码:$error");  
78 - }  
79 - }  
80 - //数组转换成xml  
81 - private function arrayToXml($arr) {  
82 - $xml = "<root>";  
83 - foreach ($arr as $key => $val) {  
84 - if (is_array($val)) {  
85 - $xml .= "<" . $key . ">" . $this->arrayToXml($val) . "</" . $key . ">";  
86 - } else {  
87 - $xml .= "<" . $key . ">" . $val . "</" . $key . ">";  
88 - }  
89 - }  
90 - $xml .= "</root>";  
91 - return $xml;  
92 - }  
93 - //xml转换成数组  
94 - private function xmlToArray($xml) {  
95 - //禁止引用外部xml实体  
96 - libxml_disable_entity_loader(true);  
97 - $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);  
98 - $val = json_decode(json_encode($xmlstring), true);  
99 - return $val;  
100 - }  
101 - //微信小程序接口  
102 - private function weixinapp() {  
103 - //统一下单接口  
104 - $unifiedorder = $this->unifiedorder();  
105 - $parameters = array(  
106 - 'appId' => $this->appid, //小程序ID  
107 - 'timeStamp' => '' . time() . '', //时间戳  
108 - 'nonceStr' => $this->createNoncestr(), //随机串  
109 - 'package' => 'prepay_id=' . $unifiedorder['prepay_id'], //数据包  
110 - 'signType' => 'MD5'//签名方式  
111 - );  
112 - //签名  
113 - $parameters['paySign'] = $this->getSign($parameters);  
114 - return $parameters;  
115 - }  
116 - //作用:产生随机字符串,不长于32位  
117 - private function createNoncestr($length = 32) {  
118 - $chars = "abcdefghijklmnopqrstuvwxyz0123456789";  
119 - $str = "";  
120 - for ($i = 0; $i < $length; $i++) {  
121 - $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);  
122 - }  
123 - return $str;  
124 - }  
125 - //作用:生成签名  
126 - private function getSign($Obj) {  
127 - foreach ($Obj as $k => $v) {  
128 - $Parameters[$k] = $v;  
129 - }  
130 - //签名步骤一:按字典序排序参数  
131 - ksort($Parameters);  
132 - $String = $this->formatBizQueryParaMap($Parameters, false);  
133 - //签名步骤二:在string后加入KEY  
134 - $String = $String . "&key=" . $this->key;  
135 - //签名步骤三:MD5加密  
136 - $String = md5($String);  
137 - //签名步骤四:所有字符转为大写  
138 - $result_ = strtoupper($String);  
139 - return $result_;  
140 - }  
141 - ///作用:格式化参数,签名过程需要使用  
142 - private function formatBizQueryParaMap($paraMap, $urlencode) {  
143 - $buff = "";  
144 - ksort($paraMap);  
145 - foreach ($paraMap as $k => $v) {  
146 - if ($urlencode) {  
147 - $v = urlencode($v);  
148 - }  
149 - $buff .= $k . "=" . $v . "&";  
150 - }  
151 - $reqPar='';  
152 - if (strlen($buff) > 0) {  
153 - $reqPar = substr($buff, 0, strlen($buff) - 1);  
154 - }  
155 - return $reqPar;  
156 - }  
157 -}  
1 -<?php  
2 -require_once "WxPay.Exception.php";  
3 -require_once "WxPay.Config.php";  
4 -require_once "WxPay.Data.php";  
5 -  
6 -/**  
7 - *  
8 - * 接口访问类,包含所有微信支付API列表的封装,类中方法为static方法,  
9 - * 每个接口有默认超时时间(除提交被扫支付为10s,上报超时时间为1s外,其他均为6s)  
10 - * @author widyhu  
11 - *  
12 - */  
13 -class WxPayApi  
14 -{  
15 - /**  
16 - *  
17 - * 统一下单,WxPayUnifiedOrder中out_trade_no、body、total_fee、trade_type必填  
18 - * appid、mchid、spbill_create_ip、nonce_str不需要填入  
19 - * @param WxPayUnifiedOrder $inputObj  
20 - * @param int $timeOut  
21 - * @throws WxPayException  
22 - * @return 成功时返回,其他抛异常  
23 - */  
24 - public static function unifiedOrder($inputObj, $timeOut = 6)  
25 - {  
26 - $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";  
27 - //检测必填参数  
28 - if(!$inputObj->IsOut_trade_noSet()) {  
29 - throw new WxPayException("缺少统一支付接口必填参数out_trade_no!");  
30 - }else if(!$inputObj->IsBodySet()){  
31 - throw new WxPayException("缺少统一支付接口必填参数body!");  
32 - }else if(!$inputObj->IsTotal_feeSet()) {  
33 - throw new WxPayException("缺少统一支付接口必填参数total_fee!");  
34 - }else if(!$inputObj->IsTrade_typeSet()) {  
35 - throw new WxPayException("缺少统一支付接口必填参数trade_type!");  
36 - }  
37 -  
38 - //关联参数  
39 - if($inputObj->GetTrade_type() == "JSAPI" && !$inputObj->IsOpenidSet()){  
40 - throw new WxPayException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!");  
41 - }  
42 - if($inputObj->GetTrade_type() == "NATIVE" && !$inputObj->IsProduct_idSet()){  
43 - throw new WxPayException("统一支付接口中,缺少必填参数product_id!trade_type为JSAPI时,product_id为必填参数!");  
44 - }  
45 -  
46 - //异步通知url未设置,则使用配置文件中的url  
47 - if(!$inputObj->IsNotify_urlSet()){  
48 - $inputObj->SetNotify_url(WxPayConfig::NOTIFY_URL);//异步通知url  
49 - }  
50 -  
51 - $inputObj->SetAppid(WxPayConfig::APPID);//公众账号ID  
52 - $inputObj->SetMch_id(WxPayConfig::MCHID);//商户号  
53 - $inputObj->SetSpbill_create_ip($_SERVER['REMOTE_ADDR']);//终端ip  
54 - //$inputObj->SetSpbill_create_ip("1.1.1.1");  
55 - $inputObj->SetNonce_str(self::getNonceStr());//随机字符串  
56 -  
57 - //签名  
58 - $inputObj->SetSign();  
59 - $xml = $inputObj->ToXml();  
60 -  
61 - $startTimeStamp = self::getMillisecond();//请求开始时间  
62 - $response = self::postXmlCurl($xml, $url, false, $timeOut);  
63 - $result = WxPayResults::Init($response);  
64 - self::reportCostTime($url, $startTimeStamp, $result);//上报请求花费时间  
65 -  
66 - return $result;  
67 - }  
68 -  
69 - /**  
70 - *  
71 - * 查询订单,WxPayOrderQuery中out_trade_no、transaction_id至少填一个  
72 - * appid、mchid、spbill_create_ip、nonce_str不需要填入  
73 - * @param WxPayOrderQuery $inputObj  
74 - * @param int $timeOut  
75 - * @throws WxPayException  
76 - * @return 成功时返回,其他抛异常  
77 - */  
78 - public static function orderQuery($inputObj, $timeOut = 6)  
79 - {  
80 - $url = "https://api.mch.weixin.qq.com/pay/orderquery";  
81 - //检测必填参数  
82 - if(!$inputObj->IsOut_trade_noSet() && !$inputObj->IsTransaction_idSet()) {  
83 - throw new WxPayException("订单查询接口中,out_trade_no、transaction_id至少填一个!");  
84 - }  
85 - $inputObj->SetAppid(WxPayConfig::APPID);//公众账号ID  
86 - $inputObj->SetMch_id(WxPayConfig::MCHID);//商户号  
87 - $inputObj->SetNonce_str(self::getNonceStr());//随机字符串  
88 -  
89 - $inputObj->SetSign();//签名  
90 - $xml = $inputObj->ToXml();  
91 -  
92 - $startTimeStamp = self::getMillisecond();//请求开始时间  
93 - $response = self::postXmlCurl($xml, $url, false, $timeOut);  
94 - $result = WxPayResults::Init($response);  
95 - self::reportCostTime($url, $startTimeStamp, $result);//上报请求花费时间  
96 -  
97 - return $result;  
98 - }  
99 -  
100 - /**  
101 - *  
102 - * 关闭订单,WxPayCloseOrder中out_trade_no必填  
103 - * appid、mchid、spbill_create_ip、nonce_str不需要填入  
104 - * @param WxPayCloseOrder $inputObj  
105 - * @param int $timeOut  
106 - * @throws WxPayException  
107 - * @return 成功时返回,其他抛异常  
108 - */  
109 - public static function closeOrder($inputObj, $timeOut = 6)  
110 - {  
111 - $url = "https://api.mch.weixin.qq.com/pay/closeorder";  
112 - //检测必填参数  
113 - if(!$inputObj->IsOut_trade_noSet()) {  
114 - throw new WxPayException("订单查询接口中,out_trade_no必填!");  
115 - }  
116 - $inputObj->SetAppid(WxPayConfig::APPID);//公众账号ID  
117 - $inputObj->SetMch_id(WxPayConfig::MCHID);//商户号  
118 - $inputObj->SetNonce_str(self::getNonceStr());//随机字符串  
119 -  
120 - $inputObj->SetSign();//签名  
121 - $xml = $inputObj->ToXml();  
122 -  
123 - $startTimeStamp = self::getMillisecond();//请求开始时间  
124 - $response = self::postXmlCurl($xml, $url, false, $timeOut);  
125 - $result = WxPayResults::Init($response);  
126 - self::reportCostTime($url, $startTimeStamp, $result);//上报请求花费时间  
127 -  
128 - return $result;  
129 - }  
130 -  
131 - /**  
132 - *  
133 - * 申请退款,WxPayRefund中out_trade_no、transaction_id至少填一个且  
134 - * out_refund_no、total_fee、refund_fee、op_user_id为必填参数  
135 - * appid、mchid、spbill_create_ip、nonce_str不需要填入  
136 - * @param WxPayRefund $inputObj  
137 - * @param int $timeOut  
138 - * @throws WxPayException  
139 - * @return 成功时返回,其他抛异常  
140 - */  
141 - public static function refund($inputObj, $timeOut = 6)  
142 - {  
143 - $url = "https://api.mch.weixin.qq.com/secapi/pay/refund";  
144 - //检测必填参数  
145 - if(!$inputObj->IsOut_trade_noSet() && !$inputObj->IsTransaction_idSet()) {  
146 - throw new WxPayException("退款申请接口中,out_trade_no、transaction_id至少填一个!");  
147 - }else if(!$inputObj->IsOut_refund_noSet()){  
148 - throw new WxPayException("退款申请接口中,缺少必填参数out_refund_no!");  
149 - }else if(!$inputObj->IsTotal_feeSet()){  
150 - throw new WxPayException("退款申请接口中,缺少必填参数total_fee!");  
151 - }else if(!$inputObj->IsRefund_feeSet()){  
152 - throw new WxPayException("退款申请接口中,缺少必填参数refund_fee!");  
153 - }else if(!$inputObj->IsOp_user_idSet()){  
154 - throw new WxPayException("退款申请接口中,缺少必填参数op_user_id!");  
155 - }  
156 - $inputObj->SetAppid(WxPayConfig::APPID);//公众账号ID  
157 - $inputObj->SetMch_id(WxPayConfig::MCHID);//商户号  
158 - $inputObj->SetNonce_str(self::getNonceStr());//随机字符串  
159 -  
160 - $inputObj->SetSign();//签名  
161 - $xml = $inputObj->ToXml();  
162 - $startTimeStamp = self::getMillisecond();//请求开始时间  
163 - $response = self::postXmlCurl($xml, $url, true, $timeOut);  
164 - $result = WxPayResults::Init($response);  
165 - self::reportCostTime($url, $startTimeStamp, $result);//上报请求花费时间  
166 -  
167 - return $result;  
168 - }  
169 -  
170 - /**  
171 - *  
172 - * 查询退款  
173 - * 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,  
174 - * 用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。  
175 - * WxPayRefundQuery中out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个  
176 - * appid、mchid、spbill_create_ip、nonce_str不需要填入  
177 - * @param WxPayRefundQuery $inputObj  
178 - * @param int $timeOut  
179 - * @throws WxPayException  
180 - * @return 成功时返回,其他抛异常  
181 - */  
182 - public static function refundQuery($inputObj, $timeOut = 6)  
183 - {  
184 - $url = "https://api.mch.weixin.qq.com/pay/refundquery";  
185 - //检测必填参数  
186 - if(!$inputObj->IsOut_refund_noSet() &&  
187 - !$inputObj->IsOut_trade_noSet() &&  
188 - !$inputObj->IsTransaction_idSet() &&  
189 - !$inputObj->IsRefund_idSet()) {  
190 - throw new WxPayException("退款查询接口中,out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个!");  
191 - }  
192 - $inputObj->SetAppid(WxPayConfig::APPID);//公众账号ID  
193 - $inputObj->SetMch_id(WxPayConfig::MCHID);//商户号  
194 - $inputObj->SetNonce_str(self::getNonceStr());//随机字符串  
195 -  
196 - $inputObj->SetSign();//签名  
197 - $xml = $inputObj->ToXml();  
198 -  
199 - $startTimeStamp = self::getMillisecond();//请求开始时间  
200 - $response = self::postXmlCurl($xml, $url, false, $timeOut);  
201 - $result = WxPayResults::Init($response);  
202 - self::reportCostTime($url, $startTimeStamp, $result);//上报请求花费时间  
203 -  
204 - return $result;  
205 - }  
206 -  
207 - /**  
208 - * 下载对账单,WxPayDownloadBill中bill_date为必填参数  
209 - * appid、mchid、spbill_create_ip、nonce_str不需要填入  
210 - * @param WxPayDownloadBill $inputObj  
211 - * @param int $timeOut  
212 - * @throws WxPayException  
213 - * @return 成功时返回,其他抛异常  
214 - */  
215 - public static function downloadBill($inputObj, $timeOut = 6)  
216 - {  
217 - $url = "https://api.mch.weixin.qq.com/pay/downloadbill";  
218 - //检测必填参数  
219 - if(!$inputObj->IsBill_dateSet()) {  
220 - throw new WxPayException("对账单接口中,缺少必填参数bill_date!");  
221 - }  
222 - $inputObj->SetAppid(WxPayConfig::APPID);//公众账号ID  
223 - $inputObj->SetMch_id(WxPayConfig::MCHID);//商户号  
224 - $inputObj->SetNonce_str(self::getNonceStr());//随机字符串  
225 -  
226 - $inputObj->SetSign();//签名  
227 - $xml = $inputObj->ToXml();  
228 -  
229 - $response = self::postXmlCurl($xml, $url, false, $timeOut);  
230 - if(substr($response, 0 , 5) == "<xml>"){  
231 - return "";  
232 - }  
233 - return $response;  
234 - }  
235 -  
236 - /**  
237 - * 提交被扫支付API  
238 - * 收银员使用扫码设备读取微信用户刷卡授权码以后,二维码或条码信息传送至商户收银台,  
239 - * 由商户收银台或者商户后台调用该接口发起支付。  
240 - * WxPayWxPayMicroPay中body、out_trade_no、total_fee、auth_code参数必填  
241 - * appid、mchid、spbill_create_ip、nonce_str不需要填入  
242 - * @param WxPayWxPayMicroPay $inputObj  
243 - * @param int $timeOut  
244 - */  
245 - public static function micropay($inputObj, $timeOut = 10)  
246 - {  
247 - $url = "https://api.mch.weixin.qq.com/pay/micropay";  
248 - //检测必填参数  
249 - if(!$inputObj->IsBodySet()) {  
250 - throw new WxPayException("提交被扫支付API接口中,缺少必填参数body!");  
251 - } else if(!$inputObj->IsOut_trade_noSet()) {  
252 - throw new WxPayException("提交被扫支付API接口中,缺少必填参数out_trade_no!");  
253 - } else if(!$inputObj->IsTotal_feeSet()) {  
254 - throw new WxPayException("提交被扫支付API接口中,缺少必填参数total_fee!");  
255 - } else if(!$inputObj->IsAuth_codeSet()) {  
256 - throw new WxPayException("提交被扫支付API接口中,缺少必填参数auth_code!");  
257 - }  
258 -  
259 - $inputObj->SetSpbill_create_ip($_SERVER['REMOTE_ADDR']);//终端ip  
260 - $inputObj->SetAppid(WxPayConfig::APPID);//公众账号ID  
261 - $inputObj->SetMch_id(WxPayConfig::MCHID);//商户号  
262 - $inputObj->SetNonce_str(self::getNonceStr());//随机字符串  
263 -  
264 - $inputObj->SetSign();//签名  
265 - $xml = $inputObj->ToXml();  
266 -  
267 - $startTimeStamp = self::getMillisecond();//请求开始时间  
268 - $response = self::postXmlCurl($xml, $url, false, $timeOut);  
269 - $result = WxPayResults::Init($response);  
270 - self::reportCostTime($url, $startTimeStamp, $result);//上报请求花费时间  
271 -  
272 - return $result;  
273 - }  
274 -  
275 - /**  
276 - *  
277 - * 撤销订单API接口,WxPayReverse中参数out_trade_no和transaction_id必须填写一个  
278 - * appid、mchid、spbill_create_ip、nonce_str不需要填入  
279 - * @param WxPayReverse $inputObj  
280 - * @param int $timeOut  
281 - * @throws WxPayException  
282 - */  
283 - public static function reverse($inputObj, $timeOut = 6)  
284 - {  
285 - $url = "https://api.mch.weixin.qq.com/secapi/pay/reverse";  
286 - //检测必填参数  
287 - if(!$inputObj->IsOut_trade_noSet() && !$inputObj->IsTransaction_idSet()) {  
288 - throw new WxPayException("撤销订单API接口中,参数out_trade_no和transaction_id必须填写一个!");  
289 - }  
290 -  
291 - $inputObj->SetAppid(WxPayConfig::APPID);//公众账号ID  
292 - $inputObj->SetMch_id(WxPayConfig::MCHID);//商户号  
293 - $inputObj->SetNonce_str(self::getNonceStr());//随机字符串  
294 -  
295 - $inputObj->SetSign();//签名  
296 - $xml = $inputObj->ToXml();  
297 -  
298 - $startTimeStamp = self::getMillisecond();//请求开始时间  
299 - $response = self::postXmlCurl($xml, $url, true, $timeOut);  
300 - $result = WxPayResults::Init($response);  
301 - self::reportCostTime($url, $startTimeStamp, $result);//上报请求花费时间  
302 -  
303 - return $result;  
304 - }  
305 -  
306 - /**  
307 - *  
308 - * 测速上报,该方法内部封装在report中,使用时请注意异常流程  
309 - * WxPayReport中interface_url、return_code、result_code、user_ip、execute_time_必填  
310 - * appid、mchid、spbill_create_ip、nonce_str不需要填入  
311 - * @param WxPayReport $inputObj  
312 - * @param int $timeOut  
313 - * @throws WxPayException  
314 - * @return 成功时返回,其他抛异常  
315 - */  
316 - public static function report($inputObj, $timeOut = 1)  
317 - {  
318 - $url = "https://api.mch.weixin.qq.com/payitil/report";  
319 - //检测必填参数  
320 - if(!$inputObj->IsInterface_urlSet()) {  
321 - throw new WxPayException("接口URL,缺少必填参数interface_url!");  
322 - } if(!$inputObj->IsReturn_codeSet()) {  
323 - throw new WxPayException("返回状态码,缺少必填参数return_code!");  
324 - } if(!$inputObj->IsResult_codeSet()) {  
325 - throw new WxPayException("业务结果,缺少必填参数result_code!");  
326 - } if(!$inputObj->IsUser_ipSet()) {  
327 - throw new WxPayException("访问接口IP,缺少必填参数user_ip!");  
328 - } if(!$inputObj->IsExecute_time_Set()) {  
329 - throw new WxPayException("接口耗时,缺少必填参数execute_time_!");  
330 - }  
331 - $inputObj->SetAppid(WxPayConfig::APPID);//公众账号ID  
332 - $inputObj->SetMch_id(WxPayConfig::MCHID);//商户号  
333 - $inputObj->SetUser_ip($_SERVER['REMOTE_ADDR']);//终端ip  
334 - $inputObj->SetTime(date("YmdHis"));//商户上报时间  
335 - $inputObj->SetNonce_str(self::getNonceStr());//随机字符串  
336 -  
337 - $inputObj->SetSign();//签名  
338 - $xml = $inputObj->ToXml();  
339 -  
340 - $startTimeStamp = self::getMillisecond();//请求开始时间  
341 - $response = self::postXmlCurl($xml, $url, false, $timeOut);  
342 - return $response;  
343 - }  
344 -  
345 - /**  
346 - *  
347 - * 生成二维码规则,模式一生成支付二维码  
348 - * appid、mchid、spbill_create_ip、nonce_str不需要填入  
349 - * @param WxPayBizPayUrl $inputObj  
350 - * @param int $timeOut  
351 - * @throws WxPayException  
352 - * @return 成功时返回,其他抛异常  
353 - */  
354 - public static function bizpayurl($inputObj, $timeOut = 6)  
355 - {  
356 - if(!$inputObj->IsProduct_idSet()){  
357 - throw new WxPayException("生成二维码,缺少必填参数product_id!");  
358 - }  
359 -  
360 - $inputObj->SetAppid(WxPayConfig::APPID);//公众账号ID  
361 - $inputObj->SetMch_id(WxPayConfig::MCHID);//商户号  
362 - $inputObj->SetTime_stamp(time());//时间戳  
363 - $inputObj->SetNonce_str(self::getNonceStr());//随机字符串  
364 -  
365 - $inputObj->SetSign();//签名  
366 -  
367 - return $inputObj->GetValues();  
368 - }  
369 -  
370 - /**  
371 - *  
372 - * 转换短链接  
373 - * 该接口主要用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),  
374 - * 减小二维码数据量,提升扫描速度和精确度。  
375 - * appid、mchid、spbill_create_ip、nonce_str不需要填入  
376 - * @param WxPayShortUrl $inputObj  
377 - * @param int $timeOut  
378 - * @throws WxPayException  
379 - * @return 成功时返回,其他抛异常  
380 - */  
381 - public static function shorturl($inputObj, $timeOut = 6)  
382 - {  
383 - $url = "https://api.mch.weixin.qq.com/tools/shorturl";  
384 - //检测必填参数  
385 - if(!$inputObj->IsLong_urlSet()) {  
386 - throw new WxPayException("需要转换的URL,签名用原串,传输需URL encode!");  
387 - }  
388 - $inputObj->SetAppid(WxPayConfig::APPID);//公众账号ID  
389 - $inputObj->SetMch_id(WxPayConfig::MCHID);//商户号  
390 - $inputObj->SetNonce_str(self::getNonceStr());//随机字符串  
391 -  
392 - $inputObj->SetSign();//签名  
393 - $xml = $inputObj->ToXml();  
394 -  
395 - $startTimeStamp = self::getMillisecond();//请求开始时间  
396 - $response = self::postXmlCurl($xml, $url, false, $timeOut);  
397 - $result = WxPayResults::Init($response);  
398 - self::reportCostTime($url, $startTimeStamp, $result);//上报请求花费时间  
399 -  
400 - return $result;  
401 - }  
402 -  
403 - /**  
404 - *  
405 - * 支付结果通用通知  
406 - * @param function $callback  
407 - * 直接回调函数使用方法: notify(you_function);  
408 - * 回调类成员函数方法:notify(array($this, you_function));  
409 - * $callback 原型为:function function_name($data){}  
410 - */  
411 - public static function notify($callback, &$msg)  
412 - {  
413 - //获取通知的数据  
414 - $xml = file_get_contents("php://input");  
415 - //如果返回成功则验证签名  
416 - try {  
417 - $result = WxPayResults::Init($xml);  
418 - } catch (WxPayException $e){  
419 - $msg = $e->errorMessage();  
420 - return false;  
421 - }  
422 -  
423 - return call_user_func($callback, $result);  
424 - }  
425 -  
426 - /**  
427 - *  
428 - * 产生随机字符串,不长于32位  
429 - * @param int $length  
430 - * @return 产生的随机字符串  
431 - */  
432 - public static function getNonceStr($length = 32)  
433 - {  
434 - $chars = "abcdefghijklmnopqrstuvwxyz0123456789";  
435 - $str ="";  
436 - for ( $i = 0; $i < $length; $i++ ) {  
437 - $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);  
438 - }  
439 - return $str;  
440 - }  
441 -  
442 - /**  
443 - * 直接输出xml  
444 - * @param string $xml  
445 - */  
446 - public static function replyNotify($xml)  
447 - {  
448 - echo $xml;  
449 - }  
450 -  
451 - /**  
452 - *  
453 - * 上报数据, 上报的时候将屏蔽所有异常流程  
454 - * @param string $usrl  
455 - * @param int $startTimeStamp  
456 - * @param array $data  
457 - */  
458 - private static function reportCostTime($url, $startTimeStamp, $data)  
459 - {  
460 - //如果不需要上报数据  
461 - if(WxPayConfig::REPORT_LEVENL == 0){  
462 - return;  
463 - }  
464 - //如果仅失败上报  
465 - if(WxPayConfig::REPORT_LEVENL == 1 &&  
466 - array_key_exists("return_code", $data) &&  
467 - $data["return_code"] == "SUCCESS" &&  
468 - array_key_exists("result_code", $data) &&  
469 - $data["result_code"] == "SUCCESS")  
470 - {  
471 - return;  
472 - }  
473 -  
474 - //上报逻辑  
475 - $endTimeStamp = self::getMillisecond();  
476 - $objInput = new WxPayReport();  
477 - $objInput->SetInterface_url($url);  
478 - $objInput->SetExecute_time_($endTimeStamp - $startTimeStamp);  
479 - //返回状态码  
480 - if(array_key_exists("return_code", $data)){  
481 - $objInput->SetReturn_code($data["return_code"]);  
482 - }  
483 - //返回信息  
484 - if(array_key_exists("return_msg", $data)){  
485 - $objInput->SetReturn_msg($data["return_msg"]);  
486 - }  
487 - //业务结果  
488 - if(array_key_exists("result_code", $data)){  
489 - $objInput->SetResult_code($data["result_code"]);  
490 - }  
491 - //错误代码  
492 - if(array_key_exists("err_code", $data)){  
493 - $objInput->SetErr_code($data["err_code"]);  
494 - }  
495 - //错误代码描述  
496 - if(array_key_exists("err_code_des", $data)){  
497 - $objInput->SetErr_code_des($data["err_code_des"]);  
498 - }  
499 - //商户订单号  
500 - if(array_key_exists("out_trade_no", $data)){  
501 - $objInput->SetOut_trade_no($data["out_trade_no"]);  
502 - }  
503 - //设备号  
504 - if(array_key_exists("device_info", $data)){  
505 - $objInput->SetDevice_info($data["device_info"]);  
506 - }  
507 -  
508 - try{  
509 - self::report($objInput);  
510 - } catch (WxPayException $e){  
511 - //不做任何处理  
512 - }  
513 - }  
514 -  
515 - /**  
516 - * 以post方式提交xml到对应的接口url  
517 - *  
518 - * @param string $xml 需要post的xml数据  
519 - * @param string $url url  
520 - * @param bool $useCert 是否需要证书,默认不需要  
521 - * @param int $second url执行超时时间,默认30s  
522 - * @throws WxPayException  
523 - */  
524 - private static function postXmlCurl($xml, $url, $useCert = false, $second = 30)  
525 - {  
526 - $ch = curl_init();  
527 - //设置超时  
528 - curl_setopt($ch, CURLOPT_TIMEOUT, $second);  
529 -  
530 - //如果有配置代理这里就设置代理  
531 - if(WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"  
532 - && WxPayConfig::CURL_PROXY_PORT != 0){  
533 - curl_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST);  
534 - curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT);  
535 - }  
536 - curl_setopt($ch,CURLOPT_URL, $url);  
537 - curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);  
538 - curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验  
539 - //设置header  
540 - curl_setopt($ch, CURLOPT_HEADER, FALSE);  
541 - //要求结果为字符串且输出到屏幕上  
542 - curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);  
543 -  
544 - if($useCert == true){  
545 - //设置证书  
546 - //使用证书:cert 与 key 分别属于两个.pem文件  
547 - curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');  
548 - curl_setopt($ch,CURLOPT_SSLCERT, WxPayConfig::SSLCERT_PATH);  
549 - curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');  
550 - curl_setopt($ch,CURLOPT_SSLKEY, WxPayConfig::SSLKEY_PATH);  
551 - }  
552 - //post提交方式  
553 - curl_setopt($ch, CURLOPT_POST, TRUE);  
554 - curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);  
555 - //运行curl  
556 - $data = curl_exec($ch);  
557 - //返回结果  
558 - if($data){  
559 - curl_close($ch);  
560 - return $data;  
561 - } else {  
562 - $error = curl_errno($ch);  
563 - curl_close($ch);  
564 - throw new WxPayException("curl出错,错误码:$error");  
565 - }  
566 - }  
567 -  
568 - /**  
569 - * 获取毫秒级别的时间戳  
570 - */  
571 - private static function getMillisecond()  
572 - {  
573 - //获取毫秒的时间戳  
574 - $time = explode ( " ", microtime () );  
575 - $time = $time[1] . ($time[0] * 1000);  
576 - $time2 = explode( ".", $time );  
577 - $time = $time2[0];  
578 - return $time;  
579 - }  
580 -}  
581 -  
1 -<?php  
2 -/**  
3 -* 配置账号信息  
4 -*/  
5 -  
6 -class WxPayConfig  
7 -{  
8 - //=======【基本信息设置】=====================================  
9 - //  
10 - /**  
11 - * TODO: 修改这里配置为您自己申请的商户信息  
12 - * 微信公众号信息配置  
13 - *  
14 - * APPID:绑定支付的APPID(必须配置,开户邮件中可查看)  
15 - *  
16 - * MCHID:商户号(必须配置,开户邮件中可查看)  
17 - *  
18 - * KEY:商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置)  
19 - * 设置地址:https://pay.weixin.qq.com/index.php/account/api_cert  
20 - *  
21 - * APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置, 登录公众平台,进入开发者中心可设置),  
22 - * 获取地址:https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN  
23 - * @var string  
24 - */  
25 - const APPID = '';  
26 - const MCHID = '';  
27 - const KEY = '';  
28 - const APPSECRET = '';  
29 -  
30 - //=======【证书路径设置】=====================================  
31 - /**  
32 - * TODO:设置商户证书路径  
33 - * 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要,可登录商户平台下载,  
34 - * API证书下载地址:https://pay.weixin.qq.com/index.php/account/api_cert,下载之前需要安装商户操作证书)  
35 - * @var path  
36 - */  
37 - const SSLCERT_PATH = EXTEND_PATH . 'WxpayAPI/cert/apiclient_cert.pem';  
38 - const SSLKEY_PATH = EXTEND_PATH . 'WxpayAPI/cert/apiclient_key.pem';  
39 -  
40 - //=======【curl代理设置】===================================  
41 - /**  
42 - * TODO:这里设置代理机器,只有需要代理的时候才设置,不需要代理,请设置为0.0.0.0和0  
43 - * 本例程通过curl使用HTTP POST方法,此处可修改代理服务器,  
44 - * 默认CURL_PROXY_HOST=0.0.0.0和CURL_PROXY_PORT=0,此时不开启代理(如有需要才设置)  
45 - * @var unknown_type  
46 - */  
47 - const CURL_PROXY_HOST = "0.0.0.0";//"10.152.18.220";  
48 - const CURL_PROXY_PORT = 0;//8080;  
49 -  
50 - //=======【上报信息配置】===================================  
51 - /**  
52 - * TODO:接口调用上报等级,默认紧错误上报(注意:上报超时间为【1s】,上报无论成败【永不抛出异常】,  
53 - * 不会影响接口调用流程),开启上报之后,方便微信监控请求调用的质量,建议至少  
54 - * 开启错误上报。  
55 - * 上报等级,0.关闭上报; 1.仅错误出错上报; 2.全量上报  
56 - * @var int  
57 - */  
58 - const REPORT_LEVENL = 1;  
59 -}