Passed
Push — master ( a6a7ae...bf6fd0 )
by i
03:53
created

RequestTrait::send()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 24
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 15
nc 3
nop 2
dl 0
loc 24
ccs 0
cts 17
cp 0
crap 12
rs 8.9713
c 0
b 0
f 0
1
<?php
2
3
namespace Nilnice\Payment\Alipay\Traits;
4
5
use GuzzleHttp\Client;
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Collection;
8
use Nilnice\Payment\Constant;
9
use Nilnice\Payment\Exception\GatewayException;
10
use Nilnice\Payment\Exception\InvalidSignException;
11
use Psr\Http\Message\ResponseInterface;
12
13
trait RequestTrait
14
{
15
    /**
16
     * Send a Alipay interface request.
17
     *
18
     * @param array  $array
19
     * @param string $key
20
     *
21
     * @return \Illuminate\Support\Collection
22
     * @throws \Nilnice\Payment\Exception\GatewayException
23
     * @throws \Nilnice\Payment\Exception\InvalidKeyException
24
     * @throws \Nilnice\Payment\Exception\InvalidSignException
25
     * @throws \RuntimeException
26
     */
27
    public function send(array $array, string $key) : Collection
28
    {
29
        $method = Arr::get($array, 'method');
30
        $method = str_replace('.', '_', $method) . '_response';
31
        $result = $this->post('', $array);
32
        $result = mb_convert_encoding($result, 'UTF-8', 'GB2312');
33
        $result = json_decode($result, true);
34
35
        $data = Arr::get($result, $method);
36
        $sign = Arr::get($result, 'sign');
37
        if (! self::verifySign($data, $key, true, $sign)) {
38
            throw new InvalidSignException(
39
                'Invalid Alipay [signature] verify.',
40
                3
41
            );
42
        }
43
44
        if ('10000' === $code = Arr::get($result, "{$method}.code")) {
45
            return new Collection($data);
46
        }
47
48
        throw new GatewayException(
49
            "Gateway Alipay [{$data['msg']}] error.",
50
            $code
51
        );
52
    }
53
54
    /**
55
     * Send a post request.
56
     *
57
     * @param string $gateway
58
     * @param mixed  $parameter
59
     * @param array  ...$options
60
     *
61
     * @return mixed
62
     * @throws \RuntimeException
63
     */
64
    public function post(
65
        string $gateway,
66
        $parameter = null,
67
        ...$options
68
    ) {
69
        $options = $options[0] ?? [];
70
        if (\is_array($parameter)) {
71
            $options['form_params'] = $parameter;
72
        } else {
73
            $options['body'] = $parameter;
74
        }
75
76
        return $this->request('post', $gateway, $options);
77
    }
78
79
    /**
80
     * Send a request.
81
     *
82
     * @param string $method
83
     * @param string $gateway
84
     * @param array  $options
85
     *
86
     * @return mixed
87
     * @throws \RuntimeException
88
     */
89
    public function request(
90
        string $method,
91
        string $gateway,
92
        array $options = []
93
    ) {
94
        if (property_exists($this, 'config')) {
95
            $baseuri = $this->config->get('env') === 'dev'
96
                ? Constant::ALI_PAY_DEV_URI
97
                : Constant::ALI_PAY_PRO_URI;
98
        }
99
        $baseuri = $baseuri ?? '';
100
        $timeout = property_exists($this, 'timeout') ? $this->timeout : 5.0;
101
        $config = ['base_uri' => $baseuri, 'timeout' => $timeout];
102
103
        $client = new Client($config);
104
        $response = $client->{$method}($gateway, $options);
105
106
        return $this->jsonResponse($response);
107
    }
108
109
    /**
110
     * Decodes a json/javascript/xml response contents.
111
     *
112
     * @param \Psr\Http\Message\ResponseInterface $response
113
     *
114
     * @return mixed
115
     * @throws \RuntimeException
116
     */
117
    protected function jsonResponse(ResponseInterface $response)
118
    {
119
        $type = $response->getHeaderLine('Content-Type');
120
        $content = $response->getBody()->getContents();
121
122
        if (false !== self::contains($type, 'json')) {
0 ignored issues
show
introduced by
The condition false !== self::contains($type, 'json') can never be false.
Loading history...
123
            $content = json_decode($content, true);
124
        }
125
126
        return $content;
127
    }
128
129
    /**
130
     * Find the position of the first occurrence of a substring in a string.
131
     *
132
     * @param string $needle
133
     * @param string $haystack
134
     * @param bool   $isStrict
135
     *
136
     * @return bool|int
137
     */
138
    private static function contains(
139
        string $needle,
140
        string $haystack,
141
        bool $isStrict = false
142
    ) {
143
        return $isStrict
144
            ? strpos($haystack, $needle)
145
            : stripos($haystack, $needle);
146
    }
147
}
148