Test Failed
Push — master ( 5cc9b2...b2198a )
by wannanbigpig
13:04 queued 01:33
created

Support::generateSign()   B

Complexity

Conditions 6
Paths 11

Size

Total Lines 37
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 25
nc 11
nop 1
dl 0
loc 37
rs 8.8977
c 0
b 0
f 0
1
<?php
2
/**
3
 * Support.php
4
 *
5
 * Created by PhpStorm.
6
 *
7
 * author: liuml  <[email protected]>
8
 * DateTime: 2019-04-04  15:42
9
 */
10
11
namespace WannanBigPig\Alipay\Kernel\Support;
12
13
use Symfony\Component\HttpFoundation\Request;
14
use Symfony\Component\HttpFoundation\Response;
15
use WannanBigPig\Alipay\Kernel\Events\ApiRequestEnd;
16
use WannanBigPig\Alipay\Kernel\Events\ApiRequestStart;
17
use WannanBigPig\Alipay\Kernel\Events\SignFailed;
18
use WannanBigPig\Alipay\Kernel\Exceptions\SignException;
19
use WannanBigPig\Supports\AccessData;
20
use WannanBigPig\Supports\Config;
21
use WannanBigPig\Supports\Curl\HttpRequest;
22
use WannanBigPig\Supports\Events;
23
use WannanBigPig\Supports\Exceptions;
24
use WannanBigPig\Supports\Str;
25
26
class Support
27
{
28
29
    use HttpRequest;
30
31
    /**
32
     * Instance.
33
     *
34
     * @var Support
35
     */
36
    private static $instance;
37
38
    /**
39
     * Config.
40
     *
41
     * @var Config
42
     */
43
    public static $config;
44
45
    /**
46
     * Charset
47
     *
48
     * @var string
49
     */
50
    public static $fileCharset = 'UTF-8';
51
52
    /**
53
     * @var string
54
     */
55
    public static $respCharset = 'UTF-8';
56
57
    /**
58
     * @var float
59
     */
60
    public $connectTimeout = 6.0;
61
62
    /**
63
     * @var string
64
     */
65
    public $baseUri = '';
66
67
    /**
68
     * @var float
69
     */
70
    public $timeout = 6.0;
71
72
    /**
73
     * @static   getInstance
74
     *
75
     * @return Support
76
     *
77
     * @author   liuml  <[email protected]>
78
     * @DateTime 2019-04-09  10:13
79
     */
80
    public static function getInstance()
81
    {
82
        if (php_sapi_name() === 'cli' || !(self::$instance instanceof self)) {
83
            self::$instance = new self();
84
            self::$instance->setHttpOptions();
85
        }
86
87
        return self::$instance;
88
    }
89
90
    /**
91
     * setHttpOptions
92
     */
93
    protected function setHttpOptions()
94
    {
95
        if (self::$config->has('http') && is_array(self::$config->get('http'))) {
96
            self::$config->offsetUnset('http.base_uri');
97
            $this->httpOptions = self::$config->get('http');
98
        }
99
    }
100
101
    /**
102
     * @static   createConfig
103
     *
104
     * @param $config
105
     *
106
     * @return Config
107
     *
108
     * @author   liuml  <[email protected]>
109
     * @DateTime 2019-04-08  17:17
110
     */
111
    public static function createConfig($config)
112
    {
113
        self::$config = new Config($config);
114
115
        return self::$config;
116
    }
117
118
    /**
119
     * @static   getConfig
120
     *
121
     * @param  string  $key
122
     * @param  string  $default
123
     *
124
     * @return mixed
125
     *
126
     * @author   liuml  <[email protected]>
127
     * @DateTime 2019-04-08  17:17
128
     */
129
    public static function getConfig($key = '', $default = '')
130
    {
131
        if ($key === '') {
132
            return self::$config->get();
133
        }
134
135
        if (self::$config->offsetExists($key)) {
136
            return self::$config[$key];
137
        }
138
139
        return $default;
140
    }
141
142
    /**
143
     * @static   generateSign
144
     *
145
     * @param  array  $params
146
     *
147
     * @return string
148
     *
149
     * @throws Exceptions\InvalidArgumentException
150
     *
151
     * @author   liuml  <[email protected]>
152
     * @DateTime 2019-04-09  17:24
153
     */
154
    public static function generateSign(array $params): string
155
    {
156
        $privateKey = self::getConfig('private_key');
157
        if (!is_string($privateKey)) {
158
            throw new Exceptions\InvalidArgumentException('请检查 [ private_key ] 配置项的私钥文件格式或路径是否正确,只接受字符串类型值');
159
        }
160
        $keyFromFile = Str::endsWith($privateKey, '.pem');
161
        if ($keyFromFile) {
162
            $res = openssl_pkey_get_private('file://' . $privateKey);
163
        } else {
164
            $res = "-----BEGIN RSA PRIVATE KEY-----\n" .
165
                wordwrap(
166
                    $privateKey,
167
                    64,
168
                    "\n",
169
                    true
170
                ) . "\n-----END RSA PRIVATE KEY-----";
171
        }
172
173
        if (!$res) {
174
            throw new Exceptions\InvalidArgumentException('支付宝RSA私钥错误。请检查 [ private_key ] 配置项的私钥文件格式或路径是否正确');
175
        }
176
177
        $data = self::getSignContent($params);
178
        if ("RSA2" == self::getConfig('sign_type', 'RSA2')) {
179
            openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256);
180
        } else {
181
            openssl_sign($data, $sign, $res);
182
        }
183
184
        $sign = base64_encode($sign);
185
        if ($keyFromFile) {
186
            // 释放资源
187
            openssl_free_key($res);
0 ignored issues
show
Bug introduced by
It seems like $res can also be of type string; however, parameter $key_identifier of openssl_free_key() 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

187
            openssl_free_key(/** @scrutinizer ignore-type */ $res);
Loading history...
188
        }
189
190
        return $sign;
191
    }
192
193
    /**
194
     * @static   getSignContent
195
     *
196
     * @param $params
197
     *
198
     * @return string
199
     *
200
     * @author   liuml  <[email protected]>
201
     * @DateTime 2019-04-08  21:03
202
     */
203
    public static function getSignContent($params)
204
    {
205
        ksort($params);
206
207
        $stringToBeSigned = "";
208
209
        foreach ($params as $k => $v) {
210
            if ($v !== '' && !is_null($v) && $k != 'sign' && '@' != substr($v, 0, 1)) {
211
                $v = self::characet($v, $params['charset'] ?? 'utf-8');
212
213
                $stringToBeSigned .= $k . '=' . $v . '&';
214
            }
215
        }
216
        unset($k, $v);
217
218
        return rtrim($stringToBeSigned, '&');
219
    }
220
221
    /**
222
     * @static   getSignContentUrlencode
223
     *
224
     * @param $params
225
     *
226
     * @return string
227
     *
228
     * @author   liuml  <[email protected]>
229
     * @DateTime 2019-04-11  11:56
230
     */
231
    public static function getSignContentUrlencode($params)
232
    {
233
        ksort($params);
234
235
        $stringToBeSigned = "";
236
237
        foreach ($params as $k => $v) {
238
            if ($v !== '' && !is_null($v) && $k != 'sign' && '@' != substr($v, 0, 1)) {
239
                $v = self::characet($v, $params['charset'] ?? 'utf-8');
240
241
                $stringToBeSigned .= $k . '=' . urlencode($v) . '&';
242
            }
243
        }
244
245
        unset($k, $v);
246
247
        return rtrim($stringToBeSigned, '&');
248
    }
249
250
    /**
251
     * @static  verifySign
252
     *
253
     * @param  string       $data
254
     * @param  string       $sign
255
     * @param  null|string  $sign_type
256
     *
257
     * @return bool
258
     *
259
     * @throws \WannanBigPig\Supports\Exceptions\InvalidArgumentException
260
     */
261
    public static function verifySign(string $data, string $sign, $sign_type = null): bool
262
    {
263
        $publicKey = self::getConfig('ali_public_key');
264
        if (!is_string($publicKey)) {
265
            throw new Exceptions\InvalidArgumentException('请检查 [ ali_public_key ] 配置项的公钥文件格式或路径是否正确,只支持字符串类型参数');
266
        }
267
        $keyFromFile = Str::endsWith($publicKey, '.pem');
268
        if ($keyFromFile) {
269
            $res = openssl_pkey_get_public("file://" . $publicKey);
270
        } else {
271
            if ($publicKey) {
272
                $res = "-----BEGIN PUBLIC KEY-----\n" .
273
                    wordwrap(
274
                        $publicKey,
275
                        64,
276
                        "\n",
277
                        true
278
                    ) . "\n-----END PUBLIC KEY-----";
279
            } else {
280
                $res = false;
281
            }
282
        }
283
284
        if (!$res) {
285
            Events::dispatch(
286
                SignFailed::NAME,
287
                new SignFailed(
288
                    self::$config->get('event.driver'),
1 ignored issue
show
Bug introduced by
It seems like self::config->get('event.driver') can also be of type array and null; however, parameter $driver of WannanBigPig\Alipay\Kern...gnFailed::__construct() does only seem to accept string, 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

288
                    /** @scrutinizer ignore-type */ self::$config->get('event.driver'),
Loading history...
289
                    self::$config->get('event.method'),
1 ignored issue
show
Bug introduced by
It seems like self::config->get('event.method') can also be of type array and null; however, parameter $method of WannanBigPig\Alipay\Kern...gnFailed::__construct() does only seem to accept string, 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

289
                    /** @scrutinizer ignore-type */ self::$config->get('event.method'),
Loading history...
290
                    [$data],
291
                    '支付宝RSA公钥错误。请检查 [ ali_public_key ] 配置项的公钥文件格式或路径是否正确'
292
                )
293
            );
294
            throw new Exceptions\InvalidArgumentException('支付宝RSA公钥错误。请检查 [ ali_public_key ] 配置项的公钥文件格式或路径是否正确');
295
        }
296
        $sign_type = $sign_type === null ? self::getConfig('sign_type', 'RSA2') : $sign_type;
297
        // 调用openssl内置方法验签,返回bool值
298
        if ("RSA2" == $sign_type) {
299
            $result = (openssl_verify(
300
                $data,
301
                base64_decode($sign),
302
                $res,
303
                OPENSSL_ALGO_SHA256
304
            ) === 1);
305
        } else {
306
            $result = (openssl_verify($data, base64_decode($sign), $res) === 1);
307
        }
308
309
        if ($keyFromFile) {
310
            // 释放资源
311
            openssl_free_key($res);
0 ignored issues
show
Bug introduced by
It seems like $res can also be of type string; however, parameter $key_identifier of openssl_free_key() 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

311
            openssl_free_key(/** @scrutinizer ignore-type */ $res);
Loading history...
312
        }
313
314
        return $result;
315
    }
316
317
    /**
318
     * @static   characet
319
     *
320
     * @param $data
321
     * @param $targetCharset
322
     *
323
     * @return false|string|string[]|null
324
     *
325
     * @author   liuml  <[email protected]>
326
     * @DateTime 2019-04-08  21:03
327
     */
328
    public static function characet($data, $targetCharset)
329
    {
330
        if (!empty($data)) {
331
            $data = mb_convert_encoding(
332
                $data,
333
                $targetCharset,
334
                self::$fileCharset
335
            );
336
        }
337
338
        return $data;
339
    }
340
341
342
    /**
343
     * @static   requestApi
344
     *
345
     * @param         $gatewayUrl
346
     * @param  array  $data
347
     *
348
     * @return AccessData
349
     *
350
     * @throws Exceptions\BusinessException
351
     * @throws Exceptions\InvalidArgumentException
352
     * @throws SignException
353
     *
354
     * @author   liuml  <[email protected]>
355
     * @DateTime 2019-04-11  10:38
356
     */
357
    public static function requestApi($gatewayUrl, array $data): AccessData
358
    {
359
        Events::dispatch(
360
            ApiRequestStart::NAME,
361
            new ApiRequestStart(
362
                self::$config->get('event.driver'),
1 ignored issue
show
Bug introduced by
It seems like self::config->get('event.driver') can also be of type array and null; however, parameter $driver of WannanBigPig\Alipay\Kern...estStart::__construct() does only seem to accept string, 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

362
                /** @scrutinizer ignore-type */ self::$config->get('event.driver'),
Loading history...
363
                self::$config->get('event.method'),
364
                $gatewayUrl,
365
                $data
366
            )
367
        );
368
        $data = array_filter($data, function ($value) {
369
            return ($value == '' || is_null($value)) ? false : true;
370
        });
371
        // 请求支付宝网关
372
        $resp = self::getInstance()->post($gatewayUrl, $data);
373
374
        self::$respCharset = mb_detect_encoding($resp, "UTF-8, GBK, GB2312");
375
376
        // 将返回结果转换本地文件编码
377
        $result = iconv(self::$respCharset, self::$fileCharset . "//IGNORE", $resp);
378
379
        Events::dispatch(
380
            ApiRequestEnd::NAME,
381
            new ApiRequestEnd(
382
                self::$config->get('event.driver'),
1 ignored issue
show
Bug introduced by
It seems like self::config->get('event.driver') can also be of type array and null; however, parameter $driver of WannanBigPig\Alipay\Kern...questEnd::__construct() does only seem to accept string, 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

382
                /** @scrutinizer ignore-type */ self::$config->get('event.driver'),
Loading history...
383
                self::$config->get('event.method'),
1 ignored issue
show
Bug introduced by
It seems like self::config->get('event.method') can also be of type array and null; however, parameter $method of WannanBigPig\Alipay\Kern...questEnd::__construct() does only seem to accept string, 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

383
                /** @scrutinizer ignore-type */ self::$config->get('event.method'),
Loading history...
384
                $gatewayUrl,
385
                $data,
386
                $result
387
            )
388
        );
389
390
        return self::processingApiResult($data, $result);
391
    }
392
393
    /**
394
     * @static   processingApiResult
395
     *
396
     * @param $data
397
     * @param $resp
398
     *
399
     * @return AccessData
400
     *
401
     * @throws Exceptions\BusinessException
402
     * @throws Exceptions\InvalidArgumentException
403
     * @throws SignException
404
     *
405
     * @author   liuml  <[email protected]>
406
     * @DateTime 2019-04-11  10:38
407
     */
408
    protected static function processingApiResult($data, $resp): AccessData
409
    {
410
        $format = self::getConfig('format', 'JSON');
411
        // 解析返回结果
412
        $respWellFormed = false;
413
        if ("XML" == $format) {
414
            $disableLibxmlEntityLoader = libxml_disable_entity_loader(true);
415
            $respObject                = @simplexml_load_string($resp);
416
            libxml_disable_entity_loader($disableLibxmlEntityLoader);
417
            if (false !== $respObject) {
418
                $respWellFormed = true;
419
            }
420
            $result = json_decode(json_encode($respObject), true);
421
        } else {
422
            $result = json_decode($resp, true);
423
            if (null !== $result) {
424
                $respWellFormed = true;
425
            }
426
        }
427
        //返回的HTTP文本不是标准JSON或者XML,记下错误日志
428
        if (false === $respWellFormed) {
429
            throw new Exceptions\InvalidArgumentException(
430
                '返回的HTTP文本不是标准JSON或者XML',
431
                $resp
432
            );
433
        }
434
435
        $method = str_replace('.', '_', $data['method']) . '_response';
436
437
        // 签名不存在抛出应用异常,该异常为支付宝网关错误,例如 app_id 配置错误,没有返回签名,建议检查配置项是否正确
438
        if (!isset($result['sign'])) {
439
            throw new SignException(
440
                '[' . $method . '] Get Alipay API Error: msg ['
441
                . $result[$method]['msg'] . ']',
442
                $result
443
            );
444
        }
445
446
        $result_method_content = json_encode($result[$method], JSON_UNESCAPED_UNICODE);
447
        $result_method_content = mb_convert_encoding($result_method_content, self::$respCharset, self::$fileCharset);
448
        // 验证支付返回的签名,验证失败抛出应用异常
449
        if (!self::verifySign($result_method_content, $result['sign'])) {
450
            Events::dispatch(
451
                SignFailed::NAME,
452
                new SignFailed(
453
                    self::$config->get('event.driver'),
1 ignored issue
show
Bug introduced by
It seems like self::config->get('event.driver') can also be of type array and null; however, parameter $driver of WannanBigPig\Alipay\Kern...gnFailed::__construct() does only seem to accept string, 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

453
                    /** @scrutinizer ignore-type */ self::$config->get('event.driver'),
Loading history...
454
                    self::$config->get('event.method'),
1 ignored issue
show
Bug introduced by
It seems like self::config->get('event.method') can also be of type array and null; however, parameter $method of WannanBigPig\Alipay\Kern...gnFailed::__construct() does only seem to accept string, 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

454
                    /** @scrutinizer ignore-type */ self::$config->get('event.method'),
Loading history...
455
                    $result,
456
                    'Signature verification error'
457
                )
458
            );
459
            throw new SignException(
460
                '[' . $method
461
                . '] Get Alipay API Error: Signature verification error',
462
                $result
463
            );
464
        }
465
466
        // 业务返回处理,返回码 10000 则正常返回成功数据,其他的则抛出业务异常
467
        // 捕获 BusinessException 异常 获取 raw 元素查看完整数据并做处理
468
        if ($result[$method]['code'] != '10000' && Support::getConfig('business_exception', false)) {
1 ignored issue
show
Bug introduced by
false of type false is incompatible with the type string expected by parameter $default of WannanBigPig\Alipay\Kern...rt\Support::getConfig(). ( Ignorable by Annotation )

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

468
        if ($result[$method]['code'] != '10000' && Support::getConfig('business_exception', /** @scrutinizer ignore-type */ false)) {
Loading history...
469
            throw new Exceptions\BusinessException(
470
                '[' . $method
471
                . '] Business Error: msg [' . $result[$method]['msg'] . ']'
472
                . (isset($result[$method]['sub_code']) ? ' - sub_code ['
473
                    . $result[$method]['sub_code'] . ']' : '')
474
                . (isset($result[$method]['sub_msg']) ? ' - sub_msg ['
475
                    . $result[$method]['sub_msg'] . ']' : ''),
476
                $result[$method]
477
            );
478
        }
479
480
        return new AccessData($result[$method]);
481
    }
482
483
    /**
484
     * @static   assemblyProgram
485
     *
486
     * @param          $gatewayUrl
487
     * @param  array   $data
488
     * @param  string  $httpmethod
489
     *
490
     * @return Response
491
     *
492
     * @author   liuml  <[email protected]>
493
     * @DateTime 2019-04-12  09:54
494
     */
495
    public static function assemblyProgram($gatewayUrl, array $data, $httpmethod = 'POST'): Response
496
    {
497
        if ("GET" == strtoupper($httpmethod)) {
498
            //value做urlencode
499
            $preString = self::getSignContentUrlencode($data);
500
501
            //拼接GET请求串
502
            $requestUrl = $gatewayUrl . "?" . $preString;
503
504
            return Response::create($requestUrl);
505
        }
506
507
        //拼接表单字符串
508
        return Response::create(self::buildRequestForm($gatewayUrl, $data));
509
    }
510
511
    /**
512
     * @static   buildRequestForm
513
     *
514
     * @param $gatewayUrl
515
     * @param $para_temp
516
     *
517
     * @return string
518
     *
519
     * @author   liuml  <[email protected]>
520
     * @DateTime 2019-04-10  15:13
521
     */
522
    protected static function buildRequestForm($gatewayUrl, $para_temp)
523
    {
524
        $sHtml = "<form id='alipaysubmit' name='alipaysubmit' action='"
525
            . $gatewayUrl . "' method='POST'>";
526
527
        foreach ($para_temp as $key => $val) {
528
            if (!is_null($val)) {
529
                //$val = $this->characet($val, $this->postCharset);
530
                $val = str_replace("'", "&apos;", $val);
531
                //$val = str_replace("\"","&quot;",$val);
532
                $sHtml .= "<input type='hidden' name='" . $key . "' value='"
533
                    . $val . "'/>";
534
            }
535
        }
536
537
        //submit按钮控件请不要含有name属性
538
        $sHtml = $sHtml
539
            . "<input type='submit' value='ok' style='display:none;'></form>";
540
541
        $sHtml = $sHtml
542
            . "<script>document.forms['alipaysubmit'].submit();</script>";
543
544
        return $sHtml;
545
    }
546
547
    /**
548
     * @static   executeApi
549
     *
550
     * @param $params
551
     * @param $method
552
     *
553
     * @return AccessData
554
     *
555
     * @throws Exceptions\BusinessException
556
     * @throws Exceptions\InvalidArgumentException
557
     * @throws SignException
558
     *
559
     * @author   liuml  <[email protected]>
560
     * @DateTime 2019-04-12  10:06
561
     */
562
    public static function executeApi($params, $method)
563
    {
564
        // 获取公共参数
565
        $payload = self::$config->get('payload');
566
        // 设置方法
567
        $payload['method'] = $method;
568
        // 设置业务参数
569
        $payload['biz_content'] = json_encode($params);
570
        // 过滤空值
571
        $payload = array_filter($payload, function ($value) {
1 ignored issue
show
Bug introduced by
It seems like $payload can also be of type null; however, parameter $input of array_filter() does only seem to accept array, 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

571
        $payload = array_filter(/** @scrutinizer ignore-type */ $payload, function ($value) {
Loading history...
572
            return $value !== '' && !is_null($value);
573
        });
574
        // 设置签名
575
        $payload['sign'] = self::generateSign($payload);
576
        // 获取支付宝网关地址
577
        $base_uri = self::getConfig('base_uri');
578
579
        // 请求支付宝网关
580
        return self::requestApi($base_uri, $payload);
581
    }
582
583
    /**
584
     * 页面提交执行方法
585
     *
586
     * @param  array   $params  跳转类接口的request; $httpmethod 提交方式。两个值可选:post、get
587
     * @param  string  $method  构建好的、签名后的最终跳转URL(GET)或String形式的form(POST)
588
     *
589
     * @return Response
590
     *
591
     * @throws Exceptions\InvalidArgumentException
592
     *
593
     * @author   liuml  <[email protected]>
594
     * @DateTime 2019-04-12  09:59
595
     */
596
    public static function executePage($params, $method)
597
    {
598
        // 请求跳转类接口,返回字符串组装格式get url或post表单形式,默认POST形式
599
        $http_method = 'POST';
600
        if (isset($params['http_method'])) {
601
            $http_method = isset($params['http_method'])
602
                ? $params['http_method'] : 'POST';
603
            unset($params['http_method']);
604
        }
605
        // 获取公共参数
606
        $payload = self::$config->get('payload');
607
        // 设置方法
608
        $payload['method'] = $method;
609
        // 设置业务参数
610
        $payload['biz_content'] = json_encode($params);
611
        // 过滤空值
612
        $payload = array_filter($payload, function ($value) {
1 ignored issue
show
Bug introduced by
It seems like $payload can also be of type null; however, parameter $input of array_filter() does only seem to accept array, 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

612
        $payload = array_filter(/** @scrutinizer ignore-type */ $payload, function ($value) {
Loading history...
613
            return $value !== '' && !is_null($value);
614
        });
615
        // 设置签名
616
        $payload['sign'] = self::generateSign($payload);
617
        // 获取支付宝网关地址
618
        $base_uri = self::getConfig('base_uri');
619
620
        // 生成客户端需要的表单或者url字符串
621
        return self::assemblyProgram($base_uri, $payload, $http_method);
622
    }
623
624
    /**
625
     * 生成用于调用收银台SDK的字符串
626
     *
627
     * @param  array  $params  SDK接口的请求参数对象
628
     * @param         $method
629
     *
630
     * @return Response
631
     *
632
     * @throws \WannanBigPig\Supports\Exceptions\InvalidArgumentException
633
     */
634
    public static function executeSdk($params, $method): Response
635
    {
636
        // 获取公共参数
637
        $payload = self::$config->get('payload');
638
        // 设置方法
639
        $payload['method'] = $method;
640
        // 设置业务参数
641
        $payload['biz_content'] = json_encode($params);
642
        // 过滤空值
643
        $payload = array_filter($payload, function ($value) {
1 ignored issue
show
Bug introduced by
It seems like $payload can also be of type null; however, parameter $input of array_filter() does only seem to accept array, 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

643
        $payload = array_filter(/** @scrutinizer ignore-type */ $payload, function ($value) {
Loading history...
644
            return $value !== '' && !is_null($value);
645
        });
646
        ksort($payload);
647
        // 设置签名
648
        $payload['sign'] = self::generateSign($payload);
649
650
        foreach ($payload as &$value) {
651
            $value = self::characet($value, $payload['charset']);
652
        }
653
654
        return Response::create(http_build_query($payload));
655
    }
656
657
    /**
658
     * @static  notifyVerify
659
     *
660
     * @param  mixed  $data
661
     *
662
     * @return bool
663
     *
664
     * @throws Exceptions\InvalidArgumentException
665
     */
666
    public static function notifyVerify($data = null)
667
    {
668
        $data      = ($data === null) ? self::getRequest() : $data;
669
        $sign_type = null;
670
        if (isset($data['sign_type'])) {
671
            $sign_type         = $data['sign_type'];
672
            $data['sign_type'] = null;
673
        }
674
675
        return self::verifySign(
676
            Support::getSignContent($data),
677
            $data['sign'],
678
            $sign_type
679
        );
680
    }
681
682
    /**
683
     * @static  getRequest
684
     *
685
     * @return array
686
     */
687
    public static function getRequest()
688
    {
689
        $request = Request::createFromGlobals();
690
691
        return $request->request->count() > 0 ? $request->request->all() : $request->query->all();
692
    }
693
}
694