Completed
Branch master (3a051a)
by Songda
01:40
created

Alipay::verify()   B

Complexity

Conditions 5
Paths 16

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 9
nc 16
nop 0
1
<?php
2
3
namespace Yansongda\Pay\Gateways;
4
5
use Symfony\Component\HttpFoundation\Request;
6
use Symfony\Component\HttpFoundation\Response;
7
use Yansongda\Pay\Contracts\GatewayApplicationInterface;
8
use Yansongda\Pay\Contracts\GatewayInterface;
9
use Yansongda\Pay\Exceptions\GatewayException;
10
use Yansongda\Pay\Exceptions\InvalidSignException;
11
use Yansongda\Pay\Gateways\Alipay\Support;
12
use Yansongda\Pay\Log;
13
use Yansongda\Supports\Arr;
14
use Yansongda\Supports\Collection;
15
use Yansongda\Supports\Config;
16
use Yansongda\Supports\Str;
17
18
class Alipay implements GatewayApplicationInterface
19
{
20
    /**
21
     * Config.
22
     *
23
     * @var Config
24
     */
25
    protected $config;
26
27
    /**
28
     * Alipay payload.
29
     *
30
     * @var array
31
     */
32
    protected $payload;
33
34
    /**
35
     * Alipay gateway.
36
     *
37
     * @var string
38
     */
39
    protected $gateway;
40
41
    /**
42
     * Bootstrap.
43
     *
44
     * @author yansongda <[email protected]>
45
     *
46
     * @param Config $config
47
     */
48
    public function __construct(Config $config)
49
    {
50
        $this->config = $config;
51
        $this->gateway = Support::baseUri($this->config->get('mode', 'normal'));
52
        $this->payload = [
53
            'app_id'      => $this->config->get('app_id'),
54
            'method'      => '',
55
            'format'      => 'JSON',
56
            'charset'     => 'utf-8',
57
            'sign_type'   => 'RSA2',
58
            'version'     => '1.0',
59
            'return_url'  => $this->config->get('return_url'),
60
            'notify_url'  => $this->config->get('notify_url'),
61
            'timestamp'   => date('Y-m-d H:i:s'),
62
            'sign'        => '',
63
            'biz_content' => '',
64
        ];
65
    }
66
67
    /**
68
     * Pay an order.
69
     *
70
     * @author yansongda <[email protected]>
71
     *
72
     * @param string $gateway
73
     * @param array  $params
74
     *
75
     * @return Response|Collection
76
     */
77 View Code Duplication
    public function pay($gateway, $params = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
78
    {
79
        $this->payload['biz_content'] = json_encode($params);
80
81
        $gateway = get_class($this).'\\'.Str::studly($gateway).'Gateway';
82
83
        if (class_exists($gateway)) {
84
            return $this->makePay($gateway);
85
        }
86
87
        throw new GatewayException("Pay Gateway [{$gateway}] not exists", 1);
88
    }
89
90
    /**
91
     * Verfiy sign.
92
     *
93
     * @author yansongda <[email protected]>
94
     *
95
     * @return Collection
96
     */
97
    public function verify(): Collection
98
    {
99
        $request = Request::createFromGlobals();
100
101
        $data = $request->request->count() > 0 ? $request->request->all() : $request->query->all();
102
103
        $data = (!isset($data['charset']) || $data['charset'] != 'utf-8') ? Arr::encoding($data, 'utf-8', 'gb2312') : $data;
0 ignored issues
show
Bug introduced by
The method encoding() does not seem to exist on object<Yansongda\Supports\Arr>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
104
105
        Log::debug('Receive Alipay Request:', $data);
106
107
        if (Support::verifySign($data, $this->config->get('ali_public_key'))) {
108
            return new Collection($data);
109
        }
110
111
        Log::warning('Alipay Sign Verify FAILED', $data);
112
113
        throw new InvalidSignException('Alipay Sign Verify FAILED', 3, $data);
114
    }
115
116
    /**
117
     * Query an order.
118
     *
119
     * @author yansongda <[email protected]>
120
     *
121
     * @param string|array $order
122
     *
123
     * @return Collection
124
     */
125 View Code Duplication
    public function find($order): Collection
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
126
    {
127
        $this->payload['method'] = 'alipay.trade.query';
128
        $this->payload['biz_content'] = json_encode(is_array($order) ? $order : ['out_trade_no' => $order]);
129
        $this->payload['sign'] = Support::generateSign($this->payload, $this->config->get('private_key'));
130
131
        Log::debug('Find An Order:', [$this->gateway, $this->payload]);
132
133
        return Support::requestApi($this->payload, $this->config->get('ali_public_key'));
134
    }
135
136
    /**
137
     * Refund an order.
138
     *
139
     * @author yansongda <[email protected]>
140
     *
141
     * @param array $order
142
     *
143
     * @return Collection
144
     */
145
    public function refund($order): Collection
146
    {
147
        $this->payload['method'] = 'alipay.trade.refund';
148
        $this->payload['biz_content'] = json_encode($order);
149
        $this->payload['sign'] = Support::generateSign($this->payload, $this->config->get('private_key'));
150
151
        Log::debug('Refund An Order:', [$this->gateway, $this->payload]);
152
153
        return Support::requestApi($this->payload, $this->config->get('ali_public_key'));
154
    }
155
156
    /**
157
     * Cancel an order.
158
     *
159
     * @author yansongda <[email protected]>
160
     *
161
     * @param string|array $order
162
     *
163
     * @return Collection
164
     */
165 View Code Duplication
    public function cancel($order): Collection
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
166
    {
167
        $this->payload['method'] = 'alipay.trade.cancel';
168
        $this->payload['biz_content'] = json_encode(is_array($order) ? $order : ['out_trade_no' => $order]);
169
        $this->payload['sign'] = Support::generateSign($this->payload, $this->config->get('private_key'));
170
171
        Log::debug('Cancel An Order:', [$this->gateway, $this->payload]);
172
173
        return Support::requestApi($this->payload, $this->config->get('ali_public_key'));
174
    }
175
176
    /**
177
     * Close an order.
178
     *
179
     * @author yansongda <[email protected]>
180
     *
181
     * @param string|array $order
182
     *
183
     * @return Collection
184
     */
185 View Code Duplication
    public function close($order): Collection
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
186
    {
187
        $this->payload['method'] = 'alipay.trade.close';
188
        $this->payload['biz_content'] = json_encode(is_array($order) ? $order : ['out_trade_no' => $order]);
189
        $this->payload['sign'] = Support::generateSign($this->payload, $this->config->get('private_key'));
190
191
        Log::debug('Close An Order:', [$this->gateway, $this->payload]);
192
193
        return Support::requestApi($this->payload, $this->config->get('ali_public_key'));
194
    }
195
196
    /**
197
     * Reply success to alipay.
198
     *
199
     * @author yansongda <[email protected]>
200
     *
201
     * @return Response
202
     */
203
    public function success(): Response
204
    {
205
        return Response::create('success');
206
    }
207
208
    /**
209
     * Make pay gateway.
210
     *
211
     * @author yansongda <[email protected]>
212
     *
213
     * @param string $gateway
214
     *
215
     * @return Response|Collection
216
     */
217 View Code Duplication
    protected function makePay($gateway)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
218
    {
219
        $app = new $gateway($this->config);
220
221
        if ($app instanceof GatewayInterface) {
222
            return $app->pay($this->gateway, $this->payload);
223
        }
224
225
        throw new GatewayException("Pay Gateway [{$gateway}] Must Be An Instance Of GatewayInterface", 2);
226
    }
227
228
    /**
229
     * Magic pay.
230
     *
231
     * @author yansongda <[email protected]>
232
     *
233
     * @param string $method
234
     * @param array  $params
235
     *
236
     * @return Response|Collection
237
     */
238
    public function __call($method, $params)
239
    {
240
        return $this->pay($method, ...$params);
241
    }
242
}
243