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

WechatPay::sendRedPack()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 17
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 16
nc 2
nop 11
dl 0
loc 17
rs 9.4285
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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
}