Completed
Push — master ( d444bc...935144 )
by Wei
07:33
created

WechatPay::downloadFundFlow()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
c 0
b 0
f 0
nc 1
nop 3
dl 0
loc 8
rs 9.4285
1
<?php
2
/**
3
 * @license MIT
4
 * @author zhangv
5
 */
6
namespace zhangv\wechat;
7
8
use \Exception;
9
10
class WechatPay {
11
	const TRADETYPE_JSAPI = 'JSAPI',TRADETYPE_NATIVE = 'NATIVE',TRADETYPE_APP = 'APP',TRADETYPE_MWEB = 'MWEB';
12
	const SIGNTYPE_MD5 = 'MD5', SIGNTYPE_HMACSHA256 = 'HMAC-SHA256';
13
	const CHECKNAME_FORCECHECK = 'FORCE_CHECK',CHECKNAME_NOCHECK = 'NO_CHECK';
14
	const ACCOUNTTYPE_BASIC = 'Basic',ACCOUNTTYPE_OPERATION = 'Operation',ACCOUNTTYPE_FEES = 'Fees';
15
	/** 支付 */
16
	const URL_UNIFIEDORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder";
17
	const URL_ORDERQUERY = "https://api.mch.weixin.qq.com/pay/orderquery";
18
	const URL_CLOSEORDER = 'https://api.mch.weixin.qq.com/pay/closeorder';
19
	const URL_REFUND = 'https://api.mch.weixin.qq.com/secapi/pay/refund';
20
	const URL_REFUNDQUERY = 'https://api.mch.weixin.qq.com/pay/refundquery';
21
	const URL_DOWNLOADBILL = 'https://api.mch.weixin.qq.com/pay/downloadbill';
22
	const URL_DOWNLOAD_FUND_FLOW = 'https://api.mch.weixin.qq.com/pay/downloadfundflow';
23
	const URL_REPORT = 'https://api.mch.weixin.qq.com/payitil/report';
24
	const URL_SHORTURL = 'https://api.mch.weixin.qq.com/tools/shorturl';
25
	const URL_MICROPAY = 'https://api.mch.weixin.qq.com/pay/micropay';
26
	const URL_GETHBINFO = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo';
27
	const URL_BATCHQUERYCOMMENT = 'https://api.mch.weixin.qq.com/billcommentsp/batchquerycomment';
28
	const URL_REVERSE = 'https://api.mch.weixin.qq.com/secapi/pay/reverse';
29
	const URL_AUTHCODETOOPENID = 'https://api.mch.weixin.qq.com/tools/authcodetoopenid';
30
	/** 红包 */
31
	const URL_SENDREDPACK = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack';
32
	const URL_SENDGROUPREDPACK = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendgroupredpack';
33
	/** 企业付款 */
34
	const URL_TRANSFER_WALLET = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';
35
	const URL_QUERY_TRANSFER_WALLET = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo';
36
	const URL_TRANSFER_BANKCARD = 'https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank';
37
	const URL_QUERY_TRANSFER_BANKCARD = 'https://api.mch.weixin.qq.com/mmpaysptrans/query_bank';
38
	/** 代金券 */
39
	const URL_SEND_COUPON = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/send_coupon';
40
	const URL_QUERY_COUPON_STOCK = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/query_coupon_stock';
41
	const URL_QUERY_COUPON_INFO = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/querycouponsinfo';
42
	/** Sandbox获取测试公钥 */
43
	const URL_GETPUBLICKEY = 'https://fraud.mch.weixin.qq.com/risk/getpublickey';
44
	public static $BANKCODE = ['工商银行' => '1002', '农业银行' => '1005', '中国银行' => '1026', '建设银行' => '1003', '招商银行' => '1001',
45
		'邮储银行' => '1066', '交通银行' => '1020', '浦发银行' => '1004', '民生银行' => '1006', '兴业银行' => '1009', '平安银行' => '1010',
46
		'中信银行' => '1021', '华夏银行' => '1025', '广发银行' => '1027', '光大银行' => '1022', '北京银行' => '1032', '宁波银行' => '1056',];
47
48
	public $getSignKeyUrl = "https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey";
49
	public $sandbox = false;
50
51
	/** @var string */
52
	public $returnCode;
53
	/** @var string */
54
	public $returnMsg;
55
	/** @var string */
56
	public $resultCode;
57
	/** @var string */
58
	public $errCode;
59
	/** @var string */
60
	public $errCodeDes;
61
	/** @var string */
62
	public $requestXML = null;
63
	/** @var string */
64
	public $responseXML = null;
65
	/** @var array */
66
	public $requestArray = null;
67
	/** @var array */
68
	public $responseArray = null;
69
	/** @var array */
70
	private $config;
71
	/** @var HttpClient */
72
	private $httpClient = null;
73
	/** @var WechatOAuth */
74
	private $wechatOAuth = null;
75
76
	/**
77
	 * @param $config array 配置
78
	 */
79
	public function __construct(array $config) {
80
		$this->config = $config;
81
		$this->httpClient = new HttpClient(5);
82
	}
83
84
	public function getWechatOAuth(){
85
		if(!$this->wechatOAuth){
86
			$this->wechatOAuth = new WechatOAuth($this->config['app_id'],$this->config['app_secret']);
87
		}
88
		return $this->wechatOAuth;
89
	}
90
91
	public function setConfig($config){
92
		$this->config = $config;
93
	}
94
95
	public function setHttpClient($httpClient){
96
		$this->httpClient = $httpClient;
97
	}
98
99
	/**
100
	 * 获取JSAPI(公众号/小程序)的预支付单信息(prepay_id)
101
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
102
	 * @param $body string 内容
103
	 * @param $out_trade_no string 商户订单号
104
	 * @param $total_fee int 总金额
105
	 * @param $openid string openid
106
	 * @param $spbill_create_ip
107
	 * @param $ext array
108
	 * @return string
109
	 * @throws \Exception
110
	 */
111
	public function getPrepayId($body,$out_trade_no,$total_fee,$openid,$spbill_create_ip = null,$ext = null) {
112
		$data = ($ext && is_array($ext))?$ext:array();
113
		$data["body"]         = $body;
114
		$data["out_trade_no"] = $out_trade_no;
115
		$data["total_fee"]    = $total_fee;
116
		$data["spbill_create_ip"] = $spbill_create_ip?:$_SERVER["REMOTE_ADDR"];
117
		$data["notify_url"]   = $this->config["notify_url"];
118
		$data["trade_type"]   = WechatPay::TRADETYPE_JSAPI;
119
		if(!$openid) throw new Exception('openid is required when trade_type is JSAPI');
120
		$data["openid"]   = $openid;
121
		$result = $this->unifiedOrder($data);
122
		return $result["prepay_id"];
123
	}
124
125
	/**
126
	 * 获取APP的的预支付单信息(prepay_id)(注意这里的appid是从开放平台申请的)
127
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1
128
	 * @param $body string 内容
129
	 * @param $out_trade_no string 商户订单号
130
	 * @param $total_fee int 总金额
131
	 * @param $spbill_create_ip string 终端ID
132
	 * @param $ext array
133
	 * @return string
134
	 */
135
	public function getPrepayIdAPP($body,$out_trade_no,$total_fee,$spbill_create_ip,$ext = null) {
136
		$data = ($ext && is_array($ext))?$ext:array();
137
		$data["body"]         = $body;
138
		$data["out_trade_no"] = $out_trade_no;
139
		$data["total_fee"]    = $total_fee;
140
		$data["spbill_create_ip"] = $spbill_create_ip;
141
		$data["notify_url"]   = $this->config["notify_url"];
142
		$data["trade_type"]   = WechatPay::TRADETYPE_APP;
143
		$result = $this->unifiedOrder($data);
144
		return $result["prepay_id"];
145
	}
146
147
	/**
148
	 * 扫码支付(模式二)获取支付二维码
149
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1
150
	 * @param $body
151
	 * @param $out_trade_no
152
	 * @param $total_fee
153
	 * @param $product_id
154
	 * @param $spbill_create_ip string 本地IP
155
	 * @param $ext array
156
	 * @return string
157
	 * @throws Exception
158
	 */
159
	public function getCodeUrl($body,$out_trade_no,$total_fee,$product_id,$spbill_create_ip = null,$ext = null){
160
		$data = ($ext && is_array($ext))?$ext:array();
161
		$data["body"]         = $body;
162
		$data["out_trade_no"] = $out_trade_no;
163
		$data["total_fee"]    = $total_fee;
164
		$data["spbill_create_ip"] = $spbill_create_ip?:$_SERVER["SERVER_ADDR"];
165
		$data["notify_url"]   = $this->config["notify_url"];
166
		$data["trade_type"]   = self::TRADETYPE_NATIVE;
167
		if(!$product_id) throw new Exception('product_id is required when trade_type is NATIVE');
168
		$data["product_id"]   = $product_id;
169
		$result = $this->unifiedOrder($data);
170
		return $result["code_url"];
171
	}
172
173
	/**
174
	 * H5支付获取支付跳转链接
175
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_20&index=1
176
	 * @param $body string 商品描述
177
	 * @param $out_trade_no string 商户订单号
178
	 * @param $total_fee int 总金额(分)
179
	 * @param $ext array
180
	 * @return string
181
	 * @throws Exception
182
	 */
183
	public function getMwebUrl($body,$out_trade_no,$total_fee,$ext = null){
184
		$data = ($ext && is_array($ext))?$ext:array();
185
		$data["body"]         = $body;
186
		$data["out_trade_no"] = $out_trade_no;
187
		$data["total_fee"]    = $total_fee;
188
		$data["spbill_create_ip"] = isset($_SERVER["REMOTE_ADDR"])?$_SERVER["REMOTE_ADDR"]:'';
189
		$data["notify_url"]   = $this->config["notify_url"];
190
		$data["trade_type"]   = self::TRADETYPE_MWEB;
191
		if(!isset($this->config['h5_scene_info'])) throw new Exception('h5_scene_info should be configured');
192
		$data["scene_info"]   = json_encode($this->config['h5_scene_info']);
193
		$result = $this->unifiedOrder($data);
194
		return $result["mweb_url"];
195
	}
196
197
	/**
198
	 * 统一下单接口
199
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
200
	 * @param array $params
201
	 * @throws Exception
202
	 * @return string JSON
203
	 */
204
	public function unifiedOrder($params) {
205
		$data = array();
206
		$data["appid"] = $this->config["app_id"];
207
		$data["device_info"] = (isset($params['device_info'])&&trim($params['device_info'])!='')?$params['device_info']:null;
208
		$data["body"] = $params['body'];
209
		$data["detail"] = isset($params['detail'])?$params['detail']:null;//optional
210
		$data["attach"] = isset($params['attach'])?$params['attach']:null;//optional
211
		$data["out_trade_no"] = isset($params['out_trade_no'])?$params['out_trade_no']:null;
212
		$data["fee_type"] = isset($params['fee_type'])?$params['fee_type']:'CNY';
213
		$data["total_fee"]    = $params['total_fee'];
214
		$data["spbill_create_ip"] = $params['spbill_create_ip'];
215
		$data["time_start"] = isset($params['time_start'])?$params['time_start']:null;//optional
216
		$data["time_expire"] = isset($params['time_expire'])?$params['time_expire']:null;//optional
217
		$data["goods_tag"] = isset($params['goods_tag'])?$params['goods_tag']:null;
218
		$data["notify_url"] = $this->config["notify_url"];
219
		$data["trade_type"] = $params['trade_type'];
220
		if($params['trade_type'] == WechatPay::TRADETYPE_NATIVE){
221
			if(!isset($params['product_id'])) throw new Exception('product_id is required when trade_type is NATIVE');
222
			$data["product_id"] = $params['product_id'];
223
		}
224
		if($params['trade_type'] == WechatPay::TRADETYPE_JSAPI){
225
			if(!isset($params['openid'])) throw new Exception('openid is required when trade_type is JSAPI');
226
			$data["openid"] = $params['openid'];
227
		}
228
		$result = $this->post(self::URL_UNIFIEDORDER, $data);
229
		return $result;
230
	}
231
232
	/**
233
	 * 查询订单(根据微信订单号)
234
	 * @ref  https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_2
235
	 * @param $transaction_id string 微信订单号
236
	 * @return array
237
	 */
238
	public function queryOrderByTransactionId($transaction_id){
239
		$data = array();
240
		$data["appid"] = $this->config["app_id"];
241
		$data["transaction_id"] = $transaction_id;
242
		$result = $this->post(self::URL_ORDERQUERY, $data);
243
		return $result;
244
	}
245
246
	/**
247
	 * 查询订单(根据商户订单号)
248
	 * @ref  https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_2
249
	 * @param $out_trade_no string 商户订单号
250
	 * @return array
251
	 */
252
	public function queryOrderByOutTradeNo($out_trade_no){
253
		$data = array();
254
		$data["appid"] = $this->config["app_id"];
255
		$data["out_trade_no"] = $out_trade_no;
256
		$result = $this->post(self::URL_ORDERQUERY, $data);
257
		return $result;
258
	}
259
260
	/**
261
	 * 查询退款(根据微信订单号)
262
	 * @ref  https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_5
263
	 * @param $transaction_id string 微信交易号
264
	 * @param $offset int 偏移
265
	 * @return array
266
	 */
267
	public function queryRefundByTransactionId($transaction_id,$offset = 0){
268
		$data = array();
269
		$data["appid"] = $this->config["app_id"];
270
		$data["transaction_id"] = $transaction_id;
271
		$data["offset"] = $offset;
272
		$result = $this->post(self::URL_REFUNDQUERY, $data);
273
		return $result;
274
	}
275
276
	/**
277
	 * 查询退款(根据商户订单号)
278
	 * @ref  https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_5
279
	 * @param $out_trade_no string 商户交易号
280
	 * @param $offset int 偏移
281
	 * @return array
282
	 */
283
	public function queryRefundByOutTradeNo($out_trade_no,$offset = 0){
284
		$data = array();
285
		$data["appid"] = $this->config["app_id"];
286
		$data["out_trade_no"] = $out_trade_no;
287
		$data["offset"] = $offset;
288
		$result = $this->post(self::URL_REFUNDQUERY, $data);
289
		return $result;
290
	}
291
292
	/**
293
	 * 查询退款(根据微信退款单号)
294
	 * @ref  https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_5
295
	 * @param $refund_id string 微信退款单号
296
	 * @param $offset int 偏移
297
	 * @return array
298
	 */
299
	public function queryRefundByRefundId($refund_id,$offset = 0){
300
		$data = array();
301
		$data["appid"] = $this->config["app_id"];
302
		$data["refund_id"] = $refund_id;
303
		$data["offset"] = $offset;
304
		$result = $this->post(self::URL_REFUNDQUERY, $data);
305
		return $result;
306
	}
307
308
	/**
309
	 * 查询退款(根据商户退款单号)
310
	 * @ref  https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_5
311
	 * @param $out_refund_no string 商户退款单号
312
	 * @param $offset int 偏移
313
	 * @return array
314
	 */
315
	public function queryRefundByOutRefundNo($out_refund_no,$offset = 0){
316
		$data = array();
317
		$data["appid"] = $this->config["app_id"];
318
		$data["out_refund_no"] = $out_refund_no;
319
		$data["offset"] = $offset;
320
		$result = $this->post(self::URL_REFUNDQUERY, $data);
321
		return $result;
322
	}
323
324
	/**
325
	 * 关闭订单
326
	 * @ref  https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3
327
	 * @param $out_trade_no string 商户订单号
328
	 * @return array
329
	 */
330
	public function closeOrder($out_trade_no){
331
		$data = array();
332
		$data["appid"] = $this->config["app_id"];
333
		$data["out_trade_no"] = $out_trade_no;
334
		$result = $this->post(self::URL_CLOSEORDER, $data,false);
335
		return $result;
336
	}
337
338
	/**
339
	 * 申请退款 - 使用商户订单号
340
	 * @ref  https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_4
341
	 * @ref  https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
342
	 * @param $out_trade_no string 商户订单号
343
	 * @param $out_refund_no string 商户退款单号
344
	 * @param $total_fee int 总金额(单位:分)
345
	 * @param $refund_fee int 退款金额(单位:分)
346
	 * @param $ext array 扩展数组
347
	 * @return array
348
	 */
349
	public function refundByOutTradeNo($out_trade_no,$out_refund_no,$total_fee,$refund_fee,$ext = array()){
350
		$data = ($ext && is_array($ext))?$ext:array();
351
		$data["appid"] = $this->config["app_id"];
352
		$data["out_trade_no"] = $out_trade_no;
353
		$data["out_refund_no"] = $out_refund_no;
354
		$data["total_fee"] = $total_fee;
355
		$data["refund_fee"] = $refund_fee;
356
		$result = $this->post(self::URL_REFUND, $data,true);
357
		return $result;
358
	}
359
360
	/**
361
	 * 申请退款 - 使用微信订单号
362
	 * @ref  https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_4
363
	 * @ref  https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
364
	 * @param $transaction_id string 微信订单号
365
	 * @param $out_refund_no string 商户退款单号
366
	 * @param $total_fee int 总金额(单位:分)
367
	 * @param $refund_fee int 退款金额(单位:分)
368
	 * @param $ext array 扩展数组
369
	 * @return array
370
	 */
371
	public function refundByTransactionId($transaction_id,$out_refund_no,$total_fee,$refund_fee,$ext = array()){
372
		$data = ($ext && is_array($ext))?$ext:array();
373
		$data["appid"] = $this->config["app_id"];
374
		$data["transaction_id"] = $transaction_id;
375
		$data["out_refund_no"] = $out_refund_no;
376
		$data["total_fee"] = $total_fee;
377
		$data["refund_fee"] = $refund_fee;
378
		$result = $this->post(self::URL_REFUND, $data,true);
379
		return $result;
380
	}
381
382
	/**
383
	 * 撤销订单 - 使用商户订单号
384
	 * @ref  https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_11&index=3
385
	 * @param $out_trade_no string 商户订单号
386
	 * @return array
387
	 */
388
	public function reverseByOutTradeNo($out_trade_no){
389
		$data = array();
390
		$data["appid"] = $this->config["app_id"];
391
		$data["out_trade_no"] = $out_trade_no;
392
		$result = $this->post(self::URL_REVERSE, $data,true);
393
		return $result;
394
	}
395
396
	/**
397
	 * 撤销订单 - 使用微信订单号
398
	 * @ref  https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_11&index=3
399
	 * @param $transaction_id string 微信订单号
400
	 * @return array
401
	 */
402
	public function reverseByTransactionId($transaction_id){
403
		$data = array();
404
		$data["appid"] = $this->config["app_id"];
405
		$data["transaction_id"] = $transaction_id;
406
		$result = $this->post(self::URL_REVERSE, $data,true);
407
		return $result;
408
	}
409
410
	/**
411
	 * 下载对账单
412
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_6
413
	 * @param $bill_date string 下载对账单的日期,格式:20140603
414
	 * @param $bill_type string 类型 ALL|SUCCESS
415
	 * @return array
416
	 */
417
	public function downloadBill($bill_date,$bill_type = 'ALL'){
418
		$data = array();
419
		$data["appid"] = $this->config["app_id"];
420
		$data["bill_date"] = $bill_date;
421
		$data["bill_type"] = $bill_type;
422
		$result = $this->post(self::URL_DOWNLOADBILL, $data);
423
		return $result;
424
	}
425
426
	/**
427
	 * 下载资金账单
428
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_18&index=7
429
	 * @param $bill_date string 资金账单日期,格式:20140603
430
	 * @param $account_type string 资金账户类型 Basic|Operation|Fees
431
	 * @param $tar_type string 压缩账单
432
	 * @return array
433
	 */
434
	public function downloadFundFlow($bill_date,$account_type = self::ACCOUNTTYPE_BASIC,$tar_type = 'GZIP'){
435
		$data = array();
436
		$data["appid"] = $this->config["app_id"];
437
		$data["bill_date"] = $bill_date;
438
		$data["account_type"] = $account_type;
439
		$data["tar_type"] = $tar_type;
440
		$result = $this->post(self::URL_DOWNLOAD_FUND_FLOW, $data);
441
		return $result;
442
	}
443
444
	/**
445
	 * 发放普通红包
446
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3
447
	 * @param $mch_billno string 商户订单号
448
	 * @param $send_name string 商户名称
449
	 * @param $re_openid string 用户openid
450
	 * @param $total_amount int 付款金额 单位分
451
	 * @param $total_num int 红包发放总人数
452
	 * @param $wishing string 红包祝福语
453
	 * @param $act_name string 活动名称
454
	 * @param $remark string 备注
455
	 * @param $scene_id string 场景id,发放红包使用场景,红包金额大于200时必传 PRODUCT_1:商品促销 PRODUCT_2:抽奖 PRODUCT_3:虚拟物品兑奖 PRODUCT_4:企业内部福利 PRODUCT_5:渠道分润 PRODUCT_6:保险回馈 PRODUCT_7:彩票派奖 PRODUCT_8:税务刮奖
456
	 * @param $riskinfo string 活动信息
457
	 * @param $consume_mch_id string 资金授权商户号
458
	 * @return array
459
	 * @throws Exception
460
	 */
461
	public function sendRedPack($mch_billno,$send_name,$re_openid,$total_amount,$total_num,$wishing,$act_name,$remark,$scene_id = '',$riskinfo = '',$consume_mch_id = ''){
462
		$data = array();
463
		$data["wxappid"] = $this->config["app_id"];
464
		$data["mch_billno"] = $mch_billno;
465
		$data["send_name"] = $send_name;
466
		$data["re_openid"] = $re_openid;
467
		$data["total_amount"] = $total_amount;
468
		if($total_amount > 20000 && trim($scene_id)=='') throw new Exception("scene_id is required when total_amount beyond 20000");
469
		$data["total_num"] = $total_num;
470
		$data["wishing"] = $wishing;
471
		$data["act_name"] = $act_name;
472
		$data["remark"] = $remark;
473
		$data["scene_id"] = $scene_id;
474
		$data["riskinfo"] = $riskinfo;
475
		$data["consume_mch_id"] = $consume_mch_id;
476
		$result = $this->post(self::URL_SENDREDPACK, $data, true); //cert is required
477
		return $result;
478
	}
479
480
	/**
481
	 * 发放裂变红包
482
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_5&index=4
483
	 * @param $mch_billno string 商户订单号
484
	 * @param $send_name string 商户名称
485
	 * @param $re_openid string 用户openid
486
	 * @param $total_amount int 付款金额 单位分
487
	 * @param $total_num int 红包发放总人数
488
	 * @param $wishing string 红包祝福语
489
	 * @param $act_name string 活动名称
490
	 * @param $remark string 备注
491
	 * @param $scene_id string 场景id,发放红包使用场景,红包金额大于200时必传 PRODUCT_1:商品促销 PRODUCT_2:抽奖 PRODUCT_3:虚拟物品兑奖 PRODUCT_4:企业内部福利 PRODUCT_5:渠道分润 PRODUCT_6:保险回馈 PRODUCT_7:彩票派奖 PRODUCT_8:税务刮奖
492
	 * @param $riskinfo string 活动信息
493
	 * @param $consume_mch_id string 资金授权商户号
494
	 * @return array
495
	 * @throws Exception
496
	 */
497
	public function sendGroupRedPack($mch_billno,$send_name,$re_openid,$total_amount,$total_num,$wishing,$act_name,$remark,$scene_id = '',$riskinfo = '',$consume_mch_id = ''){
498
		$data = array();
499
		$data["wxappid"] = $this->config["app_id"];//NOTE: WXappid
500
		$data["mch_billno"] = $mch_billno;
501
		$data["send_name"] = $send_name;
502
		$data["re_openid"] = $re_openid;
503
		$data["total_amount"] = $total_amount;
504
		if($total_amount > 20000 && trim($scene_id)=='') throw new Exception("scene_id is required when total_amount beyond 20000(200rmb)");
505
		$data["total_num"] = $total_num;
506
		$data["amt_type"] = 'ALL_RAND'; //红包金额设置方式 ALL_RAND—全部随机
507
		$data["wishing"] = $wishing;
508
		$data["act_name"] = $act_name;
509
		$data["remark"] = $remark;
510
		$data["scene_id"] = $scene_id;
511
		$data["riskinfo"] = $riskinfo;
512
		$data["consume_mch_id"] = $consume_mch_id;
513
		$result = $this->post(self::URL_SENDGROUPREDPACK, $data, true); //cert is required
514
		return $result;
515
	}
516
517
	/**
518
	 * 查询红包记录
519
	 * @param $mch_billno string 商户订单号
520
	 * @return array
521
	 * @throws Exception
522
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_6&index=5
523
	 */
524
	public function getHbInfo($mch_billno){
525
		$data = array();
526
		$data["mch_billno"] = $mch_billno;
527
		$data["appid"] = $this->config["app_id"];
528
		$data["bill_type"] = 'MCHT'; //MCHT:通过商户订单号获取红包信息。
529
		$result = $this->post(self::URL_GETHBINFO, $data, true); //cert is required
530
		return $result;
531
	}
532
533
	/**
534
	 * 拉取订单评价数据
535
	 * @param string $begin_time 开始时间,格式为yyyyMMddHHmmss
536
	 * @param string $end_time 结束时间,格式为yyyyMMddHHmmss
537
	 * @param int $offset 偏移
538
	 * @param int $limit 条数
539
	 * @return array
540
	 */
541
	public function batchQueryComment($begin_time,$end_time,$offset = 0,$limit = 200){
542
		$data = array();
543
		$data["appid"] = $this->config["app_id"];
544
		$data["begin_time"] = $begin_time;
545
		$data["end_time"] = $end_time;
546
		$data["offset"] = $offset;
547
		$data["limit"] = $limit;
548
		$data["sign"] = $this->sign($data,WechatPay::SIGNTYPE_HMACSHA256);
549
		$result = $this->post(self::URL_BATCHQUERYCOMMENT, $data, true); //cert is required
550
		return $result;
551
	}
552
553
	/**
554
	 * 获取支付参数(JSAPI - 公众号/小程序支付 , APP - APP支付)
555
	 * @param $prepay_id string 预支付ID
556
	 * @param $trade_type string 支付类型
557
	 * @return array
558
	 */
559
	public function getPackage($prepay_id, $trade_type = WechatPay::TRADETYPE_JSAPI) {
560
		$data = array();
561
		if ($trade_type == WechatPay::TRADETYPE_JSAPI){
562
			$data["package"]   = "prepay_id=$prepay_id";
563
			$data["timeStamp"] = time();
564
			$data["nonceStr"]  = $this->getNonceStr();
565
			$data["appId"] = $this->config["app_id"];
566
			$data["signType"]  = "MD5";
567
			$data["paySign"]   = $this->sign($data);
568
		} else if ($trade_type == WechatPay::TRADETYPE_APP){
569
			$data["package"]   = "Sign=WXPay";
570
			$data['prepayid'] = $prepay_id;
571
			$data['partnerid'] = $this->config["mch_id"];
572
			$data["timestamp"] = time();
573
			$data["noncestr"]  = $this->getNonceStr();
574
			$data["appid"] = $this->config["app_id"];
575
			$data["sign"]   = $this->sign($data);
576
		}
577
		return $data;
578
	}
579
580
	/**
581
	 * 提交刷卡支付
582
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1
583
	 * @param $body
584
	 * @param $out_trade_no
585
	 * @param $total_fee
586
	 * @param $spbill_create_ip
587
	 * @param $auth_code
588
	 * @param array $ext
589
	 * @return array
590
	 */
591
	public function microPay($body,$out_trade_no,$total_fee,$spbill_create_ip,$auth_code,$ext = array()){
592
		$data = (!empty($ext) && is_array($ext))?$ext:array();
593
		$data["appid"] = $this->config["app_id"];
594
		$data["body"]         = $body;
595
		$data["out_trade_no"] = $out_trade_no;
596
		$data["total_fee"]    = $total_fee;
597
		$data["spbill_create_ip"] = $spbill_create_ip;
598
		$data["auth_code"] = $auth_code;
599
		$result = $this->post(self::URL_MICROPAY,$data,false);
600
		return $result;
601
	}
602
603
	/**
604
	 * 支付结果通知处理
605
	 * @param $notify_data array|string 通知数据
606
	 * @param $callback callable 回调
607
	 * @return null
608
	 * @throws Exception
609
	 */
610
	public function onPaidNotify($notify_data,callable $callback = null){
611
		if(!is_array($notify_data)){
612
			$notify_data = $this->xml2array($notify_data);
613
		}
614
		if($this->validateSign($notify_data)){
615
			if($callback && is_callable($callback)){
616
				return call_user_func_array( $callback , [$notify_data] );
617
			}else{
618
				$this->responseNotify();
619
			}
620
		}else{
621
			throw new Exception('Invalid paid notify data');
622
		}
623
	}
624
625
	/**
626
	 * 退款结果通知处理
627
	 * @param string|array $notify_data 通知数据(XML/array)
628
	 * @param callable $callback 回调
629
	 * @return mixed
630
	 * @throws Exception
631
	 */
632
	public function onRefundedNotify($notify_data,callable $callback = null){
633
		if(!is_array($notify_data)){
634
			$notify_data = $this->xml2array($notify_data);
635
		}
636
		if($this->validateSign($notify_data)){
637
			if($callback && is_callable($callback)){
638
				return call_user_func_array( $callback , $notify_data );
639
			}else{
640
				$this->responseNotify();
641
			}
642
		}else{
643
			throw new Exception('Invalid refunded notify data');
644
		}
645
	}
646
647
	/**
648
	 * 验证数据签名
649
	 * @param $data array 数据数组
650
	 * @return boolean 数据校验结果
651
	 */
652
	public function validateSign($data) {
653
		if (!isset($data["sign"])) {
654
			return false;
655
		}
656
		$sign = $data["sign"];
657
		unset($data["sign"]);
658
		return $this->sign($data) == $sign;
659
	}
660
661
	/**
662
	 * 响应微信支付后台通知
663
	 * @param $return_code string 返回状态码 SUCCESS/FAIL
664
	 * @param $return_msg string 返回信息
665
	 */
666
	public function responseNotify($return_code="SUCCESS", $return_msg= 'OK') {
667
		$data = array();
668
		$data["return_code"] = $return_code;
669
		if ($return_msg) {
670
			$data["return_msg"] = $return_msg;
671
		}
672
		$xml = $this->array2xml($data);
673
		print $xml;
674
	}
675
676
	/**
677
	 * 交易保障
678
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_8&index=8
679
	 * @param string $interface_url
680
	 * @param string $execution_time
681
	 * @param string $return_code
682
	 * @param string $result_code
683
	 * @param string $user_ip
684
	 * @param string $out_trade_no
685
	 * @param string $time
686
	 * @param string $device_info
687
	 * @param string $return_msg
688
	 * @param string $err_code
689
	 * @param string $err_code_des
690
	 * @return array
691
	 */
692
	public function report($interface_url,$execution_time,$return_code,$result_code,$user_ip,$out_trade_no = null,$time = null,$device_info = null,
693
	                       $return_msg = null,$err_code = null,$err_code_des = null){
694
		$data = array();
695
		$data["appid"] = $this->config["app_id"];
696
		$data["interface_url"] = $interface_url;
697
		$data["execution_time"] = $execution_time;
698
		$data["return_code"] = $return_code;
699
		$data["result_code"] = $result_code;
700
		$data["user_ip"] = $user_ip;
701
		if($out_trade_no) $data["out_trade_no"] = $out_trade_no;
702
		if($time) $data["time"] = $time;
703
		if($device_info) $data["device_info"] = $device_info;
704
		if($return_msg) $data["return_msg"] = $return_msg;
705
		if($err_code) $data["err_code"] = $err_code;
706
		if($err_code_des) $data["err_code_des"] = $err_code_des;
707
		$result = $this->post(self::URL_REPORT, $data, false);
708
		return $result;
709
	}
710
711
	/**
712
	 * 转换短链接
713
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_9&index=8
714
	 * @param $longurl
715
	 * @return string
716
	 */
717
	public function shortUrl($longurl){
718
		$data = array();
719
		$data["appid"] = $this->config["app_id"];
720
		$data["long_url"] = $longurl;
721
		$result = $this->post(self::URL_SHORTURL,$data,false);
722
		return $result['short_url'];
723
	}
724
725
	/**
726
	 * 授权码查询openid
727
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_13&index=10
728
	 * @param $auth_code
729
	 * @return mixed
730
	 */
731
	public function authCodeToOpenId($auth_code){
732
		$data = array();
733
		$data["appid"] = $this->config["app_id"];
734
		$data["auth_code"] = $auth_code;
735
		$result = $this->post(self::URL_AUTHCODETOOPENID,$data,false);
736
		return $result['openid'];
737
	}
738
739
	/**
740
	 * 企业付款到零钱
741
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
742
	 * @param $partner_trade_no
743
	 * @param $openid
744
	 * @param $amount
745
	 * @param $desc
746
	 * @param $spbill_create_ip
747
	 * @param $check_name
748
	 * @param $re_user_name
749
	 * @return array
750
	 * @throws Exception
751
	 */
752
	public function transferWallet($partner_trade_no,$openid,$amount,$desc,$spbill_create_ip = null,$re_user_name = null,$check_name = WechatPay::CHECKNAME_FORCECHECK){
753
		$data = array();
754
		if($check_name == WechatPay::CHECKNAME_FORCECHECK && !$re_user_name) throw new Exception('Real name is required');
755
		$data["mch_appid"] = $this->config["app_id"];
756
		$data["mchid"] = $this->config["mch_id"];
757
		$data["partner_trade_no"] = $partner_trade_no;
758
		$data["openid"] = $openid;
759
		$data["amount"] = $amount;
760
		$data["desc"] = $desc;
761
		$data['spbill_create_ip'] = $spbill_create_ip?:$_SERVER['SERVER_ADDR'];
762
		$data["check_name"] = $check_name;
763
		$data["re_user_name"] = $re_user_name;
764
		$result = $this->post(self::URL_TRANSFER_WALLET,$data,true);
765
		return $result;
766
	}
767
768
	/**
769
	 * 查询企业付款
770
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3
771
	 * @param $partner_trade_no
772
	 * @return array
773
	 */
774
	public function queryTransferWallet($partner_trade_no){
775
		$data = array();
776
		$data["appid"] = $this->config["app_id"];
777
		$data["mch_id"] = $this->config["mch_id"];
778
		$data["partner_trade_no"] = $partner_trade_no;
779
		$result = $this->post(self::URL_QUERY_TRANSFER_WALLET,$data,true);
780
		return $result;
781
	}
782
783
	/**
784
	 * 企业付款到银行卡
785
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_2
786
	 * @param $partner_trade_no
787
	 * @param $bank_no
788
	 * @param $true_name
789
	 * @param $bank_code
790
	 * @param $amount
791
	 * @param $desc
792
	 * @return array
793
	 * @throws Exception
794
	 */
795
	public function transferBankCard($partner_trade_no,$bank_no,$true_name,$bank_code,$amount,$desc){
796
		if(!in_array($bank_code,array_values(self::$BANKCODE))) throw new Exception("Unsupported bank code: $bank_code");
797
		$data = array();
798
		$data["partner_trade_no"] = $partner_trade_no;
799
		$enc_bank_no = $this->rsaEncrypt($bank_no);
800
		$data["enc_bank_no"] = $enc_bank_no;
801
		$enc_true_name = $this->rsaEncrypt($true_name);
802
		$data["enc_true_name"] = $enc_true_name;
803
		$data["bank_code"] = $bank_code;
804
		$data["desc"] = $desc;
805
		$data["amount"] = $amount;
806
		$result = $this->post(self::URL_TRANSFER_BANKCARD,$data,true);
807
		return $result;
808
	}
809
810
	/**
811
	 * 查询企业付款银行卡
812
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_3
813
	 * @param $partner_trade_no
814
	 * @return array
815
	 */
816
	public function queryTransferBankCard($partner_trade_no){
817
		$data = array();
818
		$data["appid"] = $this->config["app_id"];
819
		$data["mch_id"] = $this->config["mch_id"];
820
		$data["partner_trade_no"] = $partner_trade_no;
821
		$result = $this->post(self::URL_QUERY_TRANSFER_WALLET,$data,true);
822
		return $result;
823
	}
824
825
	/**
826
	 * 发放代金券
827
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_3&index=4
828
	 * @param $coupon_stock_id
829
	 * @param $open_id
830
	 * @param $partner_trade_no
831
	 * @param string $op_user_id
832
	 * @param array $ext
833
	 * @return array
834
	 */
835
	public function sendCoupon($coupon_stock_id,$open_id,$partner_trade_no,$op_user_id = '',$ext = array()){
836
		$data = (!empty($ext) && is_array($ext))?$ext:array();
837
		$data["partner_trade_no"] = $partner_trade_no;
838
		$data["coupon_stock_id"] = $coupon_stock_id;
839
		$data["openid_count"] = 1;
840
		$data["open_id"] = $open_id;
841
		$data["op_user_id"] = $op_user_id;
842
		$result = $this->post(self::URL_SEND_COUPON,$data,true);
843
		return $result;
844
	}
845
846
	/**
847
	 * 查询代金券批次
848
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_4&index=5
849
	 * @param $coupon_stock_id
850
	 * @param string $op_user_id
851
	 * @return array
852
	 */
853
	public function queryCouponStock($coupon_stock_id,$op_user_id = ''){
854
		$data = array();
855
		$data["coupon_stock_id"] = $coupon_stock_id;
856
		$data["op_user_id"] = $op_user_id;
857
		$result = $this->post(self::URL_QUERY_COUPON_STOCK,$data,false);
858
		return $result;
859
	}
860
861
	/**
862
	 * 查询代金券信息
863
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_5&index=6
864
	 * @param $coupon_id
865
	 * @param $open_id
866
	 * @param $stock_id
867
	 * @param string $op_user_id
868
	 * @param array $ext
869
	 * @return array
870
	 */
871
	public function queryCouponsInfo($coupon_id,$open_id,$stock_id,$op_user_id = '',$ext = array()){
872
		$data = (!empty($ext) && is_array($ext))?$ext:array();
873
		$data["coupon_id"] = $coupon_id;
874
		$data["stock_id"] = $stock_id;
875
		$data["open_id"] = $open_id;
876
		$data["op_user_id"] = $op_user_id;
877
		$result = $this->post(self::URL_QUERY_COUPON_INFO,$data,false);
878
		return $result;
879
	}
880
881
	/**
882
	 * 获取RSA加密公钥
883
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_7&index=4
884
	 * @param bool $refresh
885
	 * @return string
886
	 * @throws Exception
887
	 */
888
	public function getPublicKey($refresh = false){
889
		if (!$refresh && file_exists($this->config["rsa_pubkey_path"])) {
890
			$pubkey = file_get_contents($this->config["rsa_pubkey_path"]);
891
			return $pubkey;
892
		}
893
		$data = array();
894
		$data["mch_id"] = $this->config["mch_id"];
895
		$data["sign_type"] = $this->config["sign_type"];
896
		$result = $this->post(self::URL_GETPUBLICKEY,$data,true);
897
		$pubkey = $result['pub_key'];
898
		$pubkey = $this->convertPKCS1toPKCS8($pubkey);
899
		$fp = fopen($this->config["rsa_pubkey_path"], "w");
900
		if ($fp) {
0 ignored issues
show
introduced by
$fp is of type resource|false, thus it always evaluated to false.
Loading history...
901
			fwrite($fp, $pubkey);
902
			fclose($fp);
903
			return $pubkey;
904
		}else {
905
			throw new Exception("RSA public key not found");
906
		}
907
	}
908
909
	private function convertPKCS1toPKCS8($pkcs1){
910
		$start_key = $pkcs1;
911
		$start_key = str_replace('-----BEGIN RSA PUBLIC KEY-----', '', $start_key);
912
		$start_key = trim(str_replace('-----END RSA PUBLIC KEY-----', '', $start_key));
913
		$key = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A' . str_replace("\n", '', $start_key);
914
		$key = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($key, 64, "\n", true) . "\n-----END PUBLIC KEY-----";
915
		return $key;
916
	}
917
918
	private function rsaEncrypt($data){
919
		$pubkey = $this->getPublicKey();
920
		$encrypted = null;
921
		$pubkey = openssl_get_publickey($pubkey);
922
		if (openssl_public_encrypt($data, $encrypted, $pubkey,OPENSSL_PKCS1_OAEP_PADDING))
923
			$data = base64_encode($encrypted);
924
		else
925
			throw new Exception('Unable to encrypt data');
926
		return $data;
927
	}
928
929
	/**
930
	 * sandbox环境获取验签秘钥
931
	 * @ref https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=23_1
932
	 * @return array
933
	 */
934
	public function getSignKey(){
935
		$data = array();
936
		$data["mch_id"] = $this->config["mch_id"];
937
		$result = $this->post($this->getSignKeyUrl,$data,false);
938
		return $result['sandbox_signkey'];
939
	}
940
941
	/**
942
	 * 获取JSAPI所需要的页面参数
943
	 * @return array
944
	 */
945
	public function getSignPackage($url){
946
		$jsapiTicket = $this->getJSAPITicket();
947
		$timestamp = time();
948
		$nonceStr = $this->getNonceStr();
949
		$rawString = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
950
		$signature = sha1($rawString);
951
952
		$signPackage = array(
953
			"appId" => $this->config['app_id'],
954
			"nonceStr" => $nonceStr,
955
			"timestamp" => $timestamp,
956
			"url" => $url,
957
			"signature" => $signature,
958
			"rawString" => $rawString
959
		);
960
		return $signPackage;
961
	}
962
963
	/**
964
	 * 获取JSAPI Ticket
965
	 * @return string
966
	 */
967
	public function getJSAPITicket(){
968
		if(isset($this->config['jsapi_ticket']) && file_exists($this->config['jsapi_ticket'])){
969
			$data = json_decode(file_get_contents($this->config['jsapi_ticket']));
970
			if (!$data || $data->expire_time < time()) {
971
				$data = $this->getWechatOAuth()->getTicket();
972
				$fp = fopen($this->config["jsapi_ticket"], "w");
973
				fwrite($fp, $data);
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fwrite() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

973
				fwrite(/** @scrutinizer ignore-type */ $fp, $data);
Loading history...
974
				if ($fp) fclose($fp);
0 ignored issues
show
introduced by
$fp is of type resource|false, thus it always evaluated to false.
Loading history...
975
				$data = json_decode($data);
976
			}
977
			return $data->jsapi_ticket;
978
		}
979
	}
980
981
	private function post($url, $data,$cert = true) {
982
		if(!isset($data['mch_id']) && !isset($data['mchid'])) $data["mch_id"] = $this->config["mch_id"];
983
		if(!isset($data['nonce_str'])) $data["nonce_str"] = $this->getNonceStr();
984
		if(!isset($data['sign'])) $data['sign'] = $this->sign($data);
985
		$this->requestXML = $this->responseXML = null;
986
		$this->requestArray = $this->responseArray = null;
987
988
		$this->requestArray = $data;
989
		$this->requestXML = $this->array2xml($data);
990
		$opts = [
991
			CURLOPT_SSL_VERIFYPEER => false,
992
			CURLOPT_SSL_VERIFYHOST => false,
993
			CURLOPT_RETURNTRANSFER => true,
994
			CURLOPT_TIMEOUT => 10
995
		];
996
		if($cert == true){
997
			$opts[CURLOPT_SSLCERTTYPE] = 'PEM';
998
			$opts[CURLOPT_SSLCERT] = $this->config['ssl_cert_path'];
999
			$opts[CURLOPT_SSLKEYTYPE] = 'PEM';
1000
			$opts[CURLOPT_SSLKEY] = $this->config['ssl_key_path'];
1001
		}
1002
		$processResponse = true;
1003
		if(in_array($url,[self::URL_DOWNLOADBILL,self::URL_DOWNLOAD_FUND_FLOW])){
1004
			$processResponse = false;
1005
		}
1006
		if($this->sandbox === true){
1007
			$host = "https://api.mch.weixin.qq.com";
1008
			$url = str_replace($host,'',$url);
1009
			$url = "{$host}/sandboxnew{$url}";
1010
		}
1011
		$content = $this->httpClient->post($url,$this->requestXML,[],$opts);
1012
		if(!$content) throw new Exception("Empty response with {$this->requestXML}");
1013
1014
		$this->responseXML = $content;
1015
		if($processResponse)
1016
			return $this->processResponseXML($this->responseXML);
1017
		else return $this->responseXML;
1018
1019
	}
1020
1021
	private function processResponseXML($responseXML){
1022
		$result = $this->xml2array($responseXML);
1023
		$this->responseArray = $result;
1024
		if(empty($result['return_code'])){
1025
			throw new Exception("No return code presents in {$this->responseXML}");
1026
		}
1027
		$this->returnCode = $result["return_code"];
1028
		$this->returnMsg = isset($result['return_msg'])?$result['return_msg']:'';
1029
1030
		if ($this->returnCode == "SUCCESS") {
1031
			if(isset($result['result_code']) && $result['result_code'] == "FAIL"){
1032
				$this->resultCode = $result['result_code'];
1033
				$this->errCode = $result['err_code'];
1034
				$this->errCodeDes = $result['err_code_des'];
1035
				throw new Exception("[$this->errCode]$this->errCodeDes");
1036
			}else{
1037
				return $result;
1038
			}
1039
		} else {
1040
			if($result["return_code"] == "FAIL"){
1041
				throw new Exception($this->returnMsg);
1042
			}else{
1043
				$this->resultCode = $result['result_code'];
1044
				$this->errCode = $result['err_code'];
1045
				$this->errCodeDes = $result['err_code_des'];
1046
				throw new Exception("[$this->errCode]$this->errCodeDes");
1047
			}
1048
		}
1049
	}
1050
1051
	public function sign($data,$sign_type = WechatPay::SIGNTYPE_MD5) {
1052
		ksort($data);
1053
		$string1 = "";
1054
		foreach ($data as $k => $v) {
1055
			if ($v && trim($v)!='') {
1056
				$string1 .= "$k=$v&";
1057
			}
1058
		}
1059
		$stringSignTemp = $string1 . "key=" . $this->config["api_key"];
1060
		if($sign_type == WechatPay::SIGNTYPE_MD5){
1061
			$sign = strtoupper(md5($stringSignTemp));
1062
		}elseif($sign_type == WechatPay::SIGNTYPE_HMACSHA256){
1063
			$sign = strtoupper(hash_hmac('sha256',$stringSignTemp,$this->config["api_key"]));
1064
		}else throw new Exception("Not supported sign type - $sign_type");
1065
		return $sign;
1066
	}
1067
1068
	private function array2xml($array) {
1069
		$xml = "<xml>" . PHP_EOL;
1070
		foreach ($array as $k => $v) {
1071
			if($v && trim($v)!='')
1072
				$xml .= "<$k><![CDATA[$v]]></$k>" . PHP_EOL;
1073
		}
1074
		$xml .= "</xml>";
1075
		return $xml;
1076
	}
1077
1078
	private function xml2array($xml) {
1079
		$array = array();
1080
		$tmp = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $tmp is dead and can be removed.
Loading history...
1081
		try{
1082
			$tmp = (array) simplexml_load_string($xml);
1083
		}catch(Exception $e){
1084
			throw $e;
1085
		}
1086
		foreach ( $tmp as $k => $v) {
1087
			$array[$k] = (string) $v;
1088
		}
1089
		return $array;
1090
	}
1091
1092
	private function getNonceStr() {
1093
		return substr(str_shuffle("abcdefghijklmnopqrstuvwxyz0123456789"),0,32);
1094
	}
1095
1096
}