Passed
Push — master ( 1dfbea...9713c0 )
by Songda
02:53 queued 51s
created

StartPlugin   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 95
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 12
eloc 40
c 1
b 0
f 0
dl 0
loc 95
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getCerts() 0 14 4
A getCertId() 0 18 3
A getReturnUrl() 0 7 2
A getNotifyUrl() 0 7 2
A assembly() 0 24 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yansongda\Pay\Plugin\Unipay;
6
7
use Closure;
8
use Yansongda\Pay\Contract\ConfigInterface;
9
use Yansongda\Pay\Contract\PluginInterface;
10
use Yansongda\Pay\Exception\ContainerException;
11
use Yansongda\Pay\Exception\Exception;
12
use Yansongda\Pay\Exception\InvalidConfigException;
13
use Yansongda\Pay\Exception\ServiceNotFoundException;
14
use Yansongda\Pay\Logger;
15
use Yansongda\Pay\Pay;
16
use Yansongda\Pay\Rocket;
17
18
use function Yansongda\Pay\get_tenant;
19
use function Yansongda\Pay\get_unipay_config;
20
21
class StartPlugin implements PluginInterface
22
{
23
    /**
24
     * @throws ContainerException
25
     * @throws ServiceNotFoundException
26
     * @throws InvalidConfigException
27
     */
28
    public function assembly(Rocket $rocket, Closure $next): Rocket
29
    {
30
        Logger::debug('[Unipay][StartPlugin] 插件开始装载', ['rocket' => $rocket]);
31
32
        $params = $rocket->getParams();
33
        $config = get_unipay_config($params);
34
        $tenant = get_tenant($params);
35
36
        $rocket->mergePayload(array_merge($params, [
37
            'version' => '5.1.0',
38
            'encoding' => 'utf-8',
39
            'backUrl' => $this->getNotifyUrl($params, $config),
40
            'currencyCode' => '156',
41
            'accessType' => '0',
42
            'signature' => '',
43
            'signMethod' => '01',
44
            'merId' => $config['mch_id'] ?? '',
45
            'frontUrl' => $this->getReturnUrl($params, $config),
46
            'certId' => $this->getCertId($tenant, $config),
47
        ]));
48
49
        Logger::info('[Unipay][StartPlugin] 插件装载完毕', ['rocket' => $rocket]);
50
51
        return $next($rocket);
52
    }
53
54
    /**
55
     * @throws ContainerException
56
     * @throws InvalidConfigException
57
     * @throws ServiceNotFoundException
58
     */
59
    public function getCertId(string $tenant, array $config): string
60
    {
61
        if (!empty($config['certs']['cert_id'])) {
62
            return $config['certs']['cert_id'];
63
        }
64
65
        $certs = $this->getCerts($config);
66
        $ssl = openssl_x509_parse($certs['cert'] ?? '');
67
68
        if (false === $ssl) {
69
            throw new InvalidConfigException(Exception::CONFIG_UNIPAY_INVALID, '配置异常: 解析银联 `mch_cert_path` 失败,请检查参数是否正确');
70
        }
71
72
        $certs['cert_id'] = $ssl['serialNumber'] ?? '';
73
74
        Pay::get(ConfigInterface::class)->set('unipay.'.$tenant.'.certs', $certs);
75
76
        return $certs['cert_id'];
77
    }
78
79
    protected function getReturnUrl(array $params, array $config): string
80
    {
81
        if (!empty($params['_return_url'])) {
82
            return $params['_return_url'];
83
        }
84
85
        return $config['return_url'] ?? '';
86
    }
87
88
    protected function getNotifyUrl(array $params, array $config): string
89
    {
90
        if (!empty($params['_notify_url'])) {
91
            return $params['_notify_url'];
92
        }
93
94
        return $config['notify_url'] ?? '';
95
    }
96
97
    /**
98
     * @return array ['cert' => 公钥, 'pkey' => 私钥, 'extracerts' => array]
99
     *
100
     * @throws InvalidConfigException
101
     */
102
    protected function getCerts(array $config): array
103
    {
104
        $path = $config['mch_cert_path'] ?? null;
105
        $password = $config['mch_cert_password'] ?? null;
106
107
        if (is_null($path) || is_null($password)) {
108
            throw new InvalidConfigException(Exception::CONFIG_UNIPAY_INVALID, '配置异常: 缺少银联配置 -- [mch_cert_path] or [mch_cert_password]');
109
        }
110
111
        if (false === openssl_pkcs12_read(file_get_contents($path), $certs, $password)) {
112
            throw new InvalidConfigException(Exception::CONFIG_UNIPAY_INVALID, '配置异常: 读取银联 `mch_cert_path` 失败,请确认参数是否正确');
113
        }
114
115
        return $certs;
116
    }
117
}
118