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 = []) |
|
|
|
|
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; |
|
|
|
|
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 |
|
|
|
|
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 |
|
|
|
|
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 |
|
|
|
|
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) |
|
|
|
|
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
|
|
|
|
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.