1 | <?php |
||||||
2 | |||||||
3 | /* |
||||||
4 | * This file is part of the overtrue/wechat. |
||||||
5 | * |
||||||
6 | * (c) overtrue <[email protected]> |
||||||
7 | * |
||||||
8 | * This source file is subject to the MIT license that is bundled |
||||||
9 | * with this source code in the file LICENSE. |
||||||
10 | */ |
||||||
11 | |||||||
12 | namespace EasyWeChat\MicroMerchant\Kernel; |
||||||
13 | |||||||
14 | use EasyWeChat\Kernel\Exceptions\InvalidArgumentException; |
||||||
15 | use EasyWeChat\Kernel\Support; |
||||||
16 | use EasyWeChat\MicroMerchant\Application; |
||||||
17 | use EasyWeChat\MicroMerchant\Kernel\Exceptions\EncryptException; |
||||||
18 | use EasyWeChat\Payment\Kernel\BaseClient as PaymentBaseClient; |
||||||
19 | |||||||
20 | /** |
||||||
21 | * Class BaseClient. |
||||||
22 | * |
||||||
23 | * @author liuml <[email protected]> |
||||||
24 | * @DateTime 2019-07-10 12:06 |
||||||
25 | */ |
||||||
26 | class BaseClient extends PaymentBaseClient |
||||||
27 | { |
||||||
28 | /** |
||||||
29 | * @var string |
||||||
30 | */ |
||||||
31 | protected $certificates; |
||||||
32 | |||||||
33 | /** |
||||||
34 | * BaseClient constructor. |
||||||
35 | * |
||||||
36 | * @param \EasyWeChat\MicroMerchant\Application $app |
||||||
37 | */ |
||||||
38 | 24 | public function __construct(Application $app) |
|||||
39 | { |
||||||
40 | 24 | $this->app = $app; |
|||||
0 ignored issues
–
show
|
|||||||
41 | |||||||
42 | 24 | $this->setHttpClient($this->app['http_client']); |
|||||
43 | 24 | } |
|||||
44 | |||||||
45 | /** |
||||||
46 | * Extra request params. |
||||||
47 | * |
||||||
48 | * @return array |
||||||
49 | */ |
||||||
50 | 4 | protected function prepends() |
|||||
51 | { |
||||||
52 | 4 | return []; |
|||||
53 | } |
||||||
54 | |||||||
55 | /** |
||||||
56 | * httpUpload. |
||||||
57 | * |
||||||
58 | * @param string $url |
||||||
59 | * @param array $files |
||||||
60 | * @param array $form |
||||||
61 | * @param array $query |
||||||
62 | * @param bool $returnResponse |
||||||
63 | * |
||||||
64 | * @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string |
||||||
65 | * |
||||||
66 | * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException |
||||||
67 | * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException |
||||||
68 | * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidSignException |
||||||
69 | * @throws \GuzzleHttp\Exception\GuzzleException |
||||||
70 | */ |
||||||
71 | public function httpUpload(string $url, array $files = [], array $form = [], array $query = [], $returnResponse = false) |
||||||
72 | { |
||||||
73 | $multipart = []; |
||||||
74 | |||||||
75 | foreach ($files as $name => $path) { |
||||||
76 | $multipart[] = [ |
||||||
77 | 'name' => $name, |
||||||
78 | 'contents' => fopen($path, 'r'), |
||||||
79 | ]; |
||||||
80 | } |
||||||
81 | |||||||
82 | $base = [ |
||||||
83 | 'mch_id' => $this->app['config']['mch_id'], |
||||||
84 | ]; |
||||||
85 | |||||||
86 | $form = array_merge($base, $form); |
||||||
87 | |||||||
88 | $form['sign'] = $this->getSign($form); |
||||||
89 | |||||||
90 | foreach ($form as $name => $contents) { |
||||||
91 | $multipart[] = compact('name', 'contents'); |
||||||
92 | } |
||||||
93 | |||||||
94 | $options = [ |
||||||
95 | 'query' => $query, |
||||||
96 | 'multipart' => $multipart, |
||||||
97 | 'connect_timeout' => 30, |
||||||
98 | 'timeout' => 30, |
||||||
99 | 'read_timeout' => 30, |
||||||
100 | 'cert' => $this->app['config']->get('cert_path'), |
||||||
101 | 'ssl_key' => $this->app['config']->get('key_path'), |
||||||
102 | ]; |
||||||
103 | |||||||
104 | $this->pushMiddleware($this->logMiddleware(), 'log'); |
||||||
105 | |||||||
106 | $response = $this->performRequest($url, 'POST', $options); |
||||||
107 | |||||||
108 | $result = $returnResponse ? $response : $this->castResponseToType($response, $this->app->config->get('response_type')); |
||||||
109 | // auto verify signature |
||||||
110 | if ($returnResponse || 'array' !== ($this->app->config->get('response_type') ?? 'array')) { |
||||||
111 | $this->app->verifySignature($this->castResponseToType($response, 'array')); |
||||||
0 ignored issues
–
show
The method
verifySignature() does not exist on EasyWeChat\Payment\Application . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
112 | } else { |
||||||
113 | $this->app->verifySignature($result); |
||||||
114 | } |
||||||
115 | |||||||
116 | return $result; |
||||||
117 | } |
||||||
118 | |||||||
119 | /** |
||||||
120 | * request. |
||||||
121 | * |
||||||
122 | * @param string $endpoint |
||||||
123 | * @param array $params |
||||||
124 | * @param string $method |
||||||
125 | * @param array $options |
||||||
126 | * @param bool $returnResponse |
||||||
127 | * |
||||||
128 | * @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string |
||||||
129 | * |
||||||
130 | * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException |
||||||
131 | * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException |
||||||
132 | * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidSignException |
||||||
133 | * @throws \GuzzleHttp\Exception\GuzzleException |
||||||
134 | */ |
||||||
135 | 4 | protected function request(string $endpoint, array $params = [], $method = 'post', array $options = [], $returnResponse = false) |
|||||
136 | { |
||||||
137 | $base = [ |
||||||
138 | 4 | 'mch_id' => $this->app['config']['mch_id'], |
|||||
139 | ]; |
||||||
140 | |||||||
141 | 4 | $params = array_merge($base, $this->prepends(), $params); |
|||||
142 | 4 | $params['sign'] = $this->getSign($params); |
|||||
143 | 4 | $options = array_merge([ |
|||||
144 | 4 | 'body' => Support\XML::build($params), |
|||||
145 | ], $options); |
||||||
146 | |||||||
147 | 4 | $this->pushMiddleware($this->logMiddleware(), 'log'); |
|||||
148 | 4 | $response = $this->performRequest($endpoint, $method, $options); |
|||||
149 | 4 | $result = $returnResponse ? $response : $this->castResponseToType($response, $this->app->config->get('response_type')); |
|||||
150 | // auto verify signature |
||||||
151 | 4 | if ($returnResponse || 'array' !== ($this->app->config->get('response_type') ?? 'array')) { |
|||||
152 | 4 | $this->app->verifySignature($this->castResponseToType($response, 'array')); |
|||||
153 | } else { |
||||||
154 | 1 | $this->app->verifySignature($result); |
|||||
155 | } |
||||||
156 | |||||||
157 | 4 | return $result; |
|||||
158 | } |
||||||
159 | |||||||
160 | /** |
||||||
161 | * processing parameters contain fields that require sensitive information encryption. |
||||||
162 | * |
||||||
163 | * @param array $params |
||||||
164 | * |
||||||
165 | * @return array |
||||||
166 | * |
||||||
167 | * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException |
||||||
168 | * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\EncryptException |
||||||
169 | */ |
||||||
170 | protected function processParams(array $params) |
||||||
171 | { |
||||||
172 | $serial_no = $this->app['config']->get('serial_no'); |
||||||
173 | if (null === $serial_no) { |
||||||
174 | throw new InvalidArgumentException('config serial_no connot be empty.'); |
||||||
175 | } |
||||||
176 | |||||||
177 | $params['cert_sn'] = $serial_no; |
||||||
178 | $sensitive_fields = $this->getSensitiveFieldsName(); |
||||||
179 | foreach ($params as $k => $v) { |
||||||
180 | if (in_array($k, $sensitive_fields, true)) { |
||||||
181 | $params[$k] = $this->encryptSensitiveInformation($v); |
||||||
182 | } |
||||||
183 | } |
||||||
184 | |||||||
185 | return $params; |
||||||
186 | } |
||||||
187 | |||||||
188 | /** |
||||||
189 | * To id card, mobile phone number and other fields sensitive information encryption. |
||||||
190 | * |
||||||
191 | * @param string $string |
||||||
192 | * |
||||||
193 | * @return string |
||||||
194 | * |
||||||
195 | * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException |
||||||
196 | * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\EncryptException |
||||||
197 | */ |
||||||
198 | protected function encryptSensitiveInformation(string $string) |
||||||
199 | { |
||||||
200 | $certificates = $this->app['config']->get('certificate'); |
||||||
201 | if (null === $certificates) { |
||||||
202 | throw new InvalidArgumentException('config certificate connot be empty.'); |
||||||
203 | } |
||||||
204 | |||||||
205 | $encrypted = ''; |
||||||
206 | $publicKeyResource = openssl_get_publickey($certificates); |
||||||
207 | $f = openssl_public_encrypt($string, $encrypted, $publicKeyResource); |
||||||
208 | openssl_free_key($publicKeyResource); |
||||||
209 | if ($f) { |
||||||
210 | return base64_encode($encrypted); |
||||||
211 | } |
||||||
212 | |||||||
213 | throw new EncryptException('Encryption of sensitive information failed'); |
||||||
214 | } |
||||||
215 | |||||||
216 | /** |
||||||
217 | * get sensitive fields name. |
||||||
218 | * |
||||||
219 | * @return array |
||||||
220 | */ |
||||||
221 | protected function getSensitiveFieldsName() |
||||||
222 | { |
||||||
223 | return [ |
||||||
224 | 'id_card_name', |
||||||
225 | 'id_card_number', |
||||||
226 | 'account_name', |
||||||
227 | 'account_number', |
||||||
228 | 'contact', |
||||||
229 | 'contact_phone', |
||||||
230 | 'contact_email', |
||||||
231 | 'legal_person', |
||||||
232 | 'mobile_phone', |
||||||
233 | 'email', |
||||||
234 | ]; |
||||||
235 | } |
||||||
236 | |||||||
237 | /** |
||||||
238 | * getSign. |
||||||
239 | * |
||||||
240 | * @param array $params |
||||||
241 | * |
||||||
242 | * @return string |
||||||
243 | * |
||||||
244 | * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException |
||||||
245 | */ |
||||||
246 | 5 | protected function getSign(array $params) |
|||||
247 | { |
||||||
248 | 5 | $params = array_filter($params); |
|||||
249 | |||||||
250 | 5 | $key = $this->app->getKey(); |
|||||
251 | |||||||
252 | 5 | $encryptMethod = Support\get_encrypt_method(Support\Arr::get($params, 'sign_type', 'MD5'), $key); |
|||||
0 ignored issues
–
show
The function
get_encrypt_method was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
253 | |||||||
254 | 5 | return Support\generate_sign($params, $key, $encryptMethod); |
|||||
0 ignored issues
–
show
The function
generate_sign was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
255 | } |
||||||
256 | } |
||||||
257 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..