Issues (9)

src/Alipay.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace Nilnice\Payment;
4
5
use Illuminate\Config\Repository;
6
use Illuminate\Support\Collection;
7
use Illuminate\Support\Str;
8
use Monolog\Formatter\LineFormatter;
9
use Monolog\Handler\StreamHandler;
10
use Monolog\Logger;
11
use Nilnice\Payment\Alipay\Traits\RequestTrait;
12
use Nilnice\Payment\Alipay\Traits\SecurityTrait;
13
use Nilnice\Payment\Exception\GatewayException;
14
15
/**
16
 * @method Alipay\AppPayment app(array $array)
17
 * @method Alipay\BarPayment bar(array $array)
18
 * @method Alipay\ScanPayment scan(array $array)
19
 * @method Alipay\TransferPayment transfer(array $array)
20
 * @method Alipay\WapPayment wap(array $array)
21
 * @method Alipay\WebPayment web(array $array)
22
 */
23
class Alipay implements GatewayInterface
24
{
25
    use LogTrait;
26
    use RequestTrait;
27
    use SecurityTrait;
28
29
    /**
30
     * @var \Illuminate\Contracts\Config\Repository
31
     */
32
    protected $config;
33
34
    /**
35
     * @var array
36
     */
37
    protected $payload;
38
39
    /**
40
     * @var string
41
     */
42
    protected $gateway;
43
44
    /**
45
     * Alipay constructor.
46
     *
47
     * @param array $config
48
     *
49
     * @throws \Exception
50
     */
51 9
    public function __construct(array $config)
52
    {
53 9
        $this->config = new Repository($config);
54 9
        $env = $this->config->get('env', 'pro');
55 9
        $this->gateway = self::getGatewayUrl($env);
56 9
        $this->payload = [
57
            // 支付宝分配给开发者的应用 ID
58 9
            'app_id'      => $this->config->get('app_id'),
59
60
            // 接口名称
61 9
            'method'      => '',
62
63
            // 数据格式,仅支持 JSON
64 9
            'format'      => 'JSON',
65
66
            // 同步返回地址,HTTP/HTTPS 开头字符串
67 9
            'return_url'  => $this->config->get('return_url'),
68
69
            // 请求使用的编码格式,如:UTF-8, GBK, GB2312 等
70 9
            'charset'     => 'UTF-8',
71
72
            // 商户生成签名字符串所使用的签名算法类型,目前支持 RSA2 和 RSA,推荐使用 RSA2
73 9
            'sign_type'   => 'RSA2',
74
75
            // 商户请求参数的签名串,详见签名
76 9
            'sign'        => '',
77
78
            // 发送请求的时间,格式"yyyy-MM-dd HH:mm:ss"
79 9
            'timestamp'   => date('Y-m-d H:i:s'),
80
81
            // 调用的接口版本,固定为:1.0
82 9
            'version'     => '1.0',
83
84
            // 支付宝服务器主动通知商户服务器里指定的页面 http/https 路径
85 9
            'notify_url'  => $this->config->get('notify_url'),
86
87
            // 业务请求参数的集合,最大长度不限,除公共参数外所有请求参数都必须放在这个参数中传递,具体参照各产品快速接入文档
88 9
            'biz_content' => '',
89
        ];
90
91 9
        if ($this->config->has('log.file')) {
92
            $this->registerLogger($this->config, 'Alipay');
93
        }
94 9
    }
95
96
    /**
97
     * @param string $method
98
     * @param array  $arguments
99
     *
100
     * @return mixed
101
     *
102
     * @throws \Nilnice\Payment\Exception\GatewayException
103
     */
104 6
    public function __call(string $method, array $arguments)
105
    {
106 6
        return $this->dispatcher($method, ...$arguments);
0 ignored issues
show
$arguments is expanded, but the parameter $array of Nilnice\Payment\Alipay::dispatcher() does not expect variable arguments. ( Ignorable by Annotation )

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

106
        return $this->dispatcher($method, /** @scrutinizer ignore-type */ ...$arguments);
Loading history...
107
    }
108
109
    /**
110
     * Query an order information.
111
     *
112
     * @param array|string $order
113
     *
114
     * @return \Illuminate\Support\Collection
115
     *
116
     * @throws \Nilnice\Payment\Exception\GatewayException
117
     * @throws \Nilnice\Payment\Exception\InvalidKeyException
118
     * @throws \Nilnice\Payment\Exception\InvalidSignException
119
     * @throws \RuntimeException
120
     */
121
    public function query($order) : Collection
122
    {
123
        return $this->getOrderResult($order);
124
    }
125
126
    /**
127
     * Close an order.
128
     *
129
     * @param array|string $order
130
     *
131
     * @return \Illuminate\Support\Collection
132
     *
133
     * @throws \Nilnice\Payment\Exception\GatewayException
134
     * @throws \Nilnice\Payment\Exception\InvalidKeyException
135
     * @throws \Nilnice\Payment\Exception\InvalidSignException
136
     * @throws \RuntimeException
137
     */
138
    public function close($order) : Collection
139
    {
140
        return $this->getOrderResult($order, __FUNCTION__);
141
    }
142
143
    /**
144
     * Cancel an order.
145
     *
146
     * @param array|string $order
147
     *
148
     * @return \Illuminate\Support\Collection
149
     *
150
     * @throws \Nilnice\Payment\Exception\GatewayException
151
     * @throws \Nilnice\Payment\Exception\InvalidKeyException
152
     * @throws \Nilnice\Payment\Exception\InvalidSignException
153
     * @throws \RuntimeException
154
     */
155
    public function cancel($order) : Collection
156
    {
157
        return $this->getOrderResult($order, __FUNCTION__);
158
    }
159
160
    /**
161
     * Refund an order.
162
     *
163
     * @param array|string $order
164
     *
165
     * @return \Illuminate\Support\Collection
166
     *
167
     * @throws \Nilnice\Payment\Exception\GatewayException
168
     * @throws \Nilnice\Payment\Exception\InvalidKeyException
169
     * @throws \Nilnice\Payment\Exception\InvalidSignException
170
     * @throws \RuntimeException
171
     */
172
    public function refund($order) : Collection
173
    {
174
        return $this->getOrderResult($order, __FUNCTION__);
175
    }
176
177
    /**
178
     * To pay.
179
     *
180
     * @param string $gateway
181
     *
182
     * @return mixed
183
     *
184
     * @throws \Nilnice\Payment\Exception\GatewayException
185
     */
186 3
    protected function toPay(string $gateway)
187
    {
188 3
        $class = new $gateway($this->config); // Instantiate different gateways.
189
190 3
        if ($class instanceof PaymentInterface) {
191 3
            return $class->toPay($this->gateway, $this->payload);
192
        }
193
194
        throw new GatewayException(
195
            "Pay gateway [{$gateway}] must be an instance of the GatewayInterface.",
196
            2
197
        );
198
    }
199
200
    /**
201
     * Pay dispatcher.
202
     *
203
     * @param string $gateway
204
     * @param array  $array
205
     *
206
     * @return mixed
207
     *
208
     * @throws \Nilnice\Payment\Exception\GatewayException
209
     */
210 6
    private function dispatcher(string $gateway, array $array = [])
211
    {
212 6
        $this->payload['biz_content'] = $array;
213 6
        $class = \get_class($this) . '\\' . Str::studly($gateway) . 'Payment';
214
215 6
        if (class_exists($class)) {
216 3
            return $this->toPay($class);
217
        }
218
219 3
        throw new GatewayException("Pay gateway [{$gateway}] not exists.", 1);
220
    }
221
222
    /**
223
     * Get order result.
224
     *
225
     * @param array|string $order
226
     * @param string       $type
227
     *
228
     * @return \Illuminate\Support\Collection
229
     *
230
     * @throws \Nilnice\Payment\Exception\GatewayException
231
     * @throws \Nilnice\Payment\Exception\InvalidKeyException
232
     * @throws \Nilnice\Payment\Exception\InvalidSignException
233
     * @throws \RuntimeException
234
     */
235
    private function getOrderResult($order, $type = 'query') : Collection
236
    {
237
        $order = \is_array($order) ? $order : ['out_trade_no' => $order];
238
        switch (trim($type)) {
239
            case 'close':
240
                $method = Constant::ALI_PAY_CLOSE;
241
                break;
242
            case 'cancel':
243
                $method = Constant::ALI_PAY_CANCEL;
244
                break;
245
            case 'refund':
246
                $method = Constant::ALI_PAY_REFUND;
247
                break;
248
            default:
249
                $method = Constant::ALI_PAY_QUERY;
250
                break;
251
        }
252
        $this->payload['method'] = $method;
253
        $this->payload['biz_content'] = json_encode($order);
254
        $this->payload['sign'] = self::generateSign(
255
            $this->payload,
256
            $this->config->get('private_key')
257
        );
258
        Log::debug(ucfirst($type) . ' an order:', [
259
            $this->gateway,
260
            $this->payload,
261
        ]);
262
263
        return $this->send($this->payload, $this->config->get('public_key'));
264
    }
265
266
    /**
267
     * Get gateway url.
268
     *
269
     * @param string $env
270
     *
271
     * @return string
272
     */
273 9
    private static function getGatewayUrl($env = '') : string
274
    {
275 9
        $uri = '';
276 9
        if ($env === 'pro') {
277 6
            $uri = Constant::ALI_PAY_PRO_URI;
278 3
        } elseif ($env === 'dev') {
279 3
            $uri = Constant::ALI_PAY_DEV_URI;
280
        }
281
282 9
        return $uri;
283
    }
284
}
285