Passed
Pull Request — master (#461)
by Songda
02:16
created

SignPlugin::formatPayload()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
c 0
b 0
f 0
dl 0
loc 12
rs 10
cc 3
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yansongda\Pay\Plugin\Alipay;
6
7
use Closure;
8
use Yansongda\Pay\Contract\PluginInterface;
9
use Yansongda\Pay\Exception\InvalidConfigException;
10
use Yansongda\Pay\Logger;
11
use Yansongda\Pay\Rocket;
12
use Yansongda\Supports\Str;
13
14
class SignPlugin implements PluginInterface
15
{
16
    /**
17
     * @throws \Yansongda\Pay\Exception\ContainerDependencyException
18
     * @throws \Yansongda\Pay\Exception\ContainerException
19
     * @throws \Yansongda\Pay\Exception\InvalidConfigException
20
     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
21
     */
22
    public function assembly(Rocket $rocket, Closure $next): Rocket
23
    {
24
        Logger::info('[alipay][SignPlugin] 插件开始装载', ['rocket' => $rocket]);
25
26
        $this->formatPayload($rocket);
27
28
        $sign = $this->getSign($rocket);
29
30
        $rocket->mergePayload(['sign' => $sign]);
31
32
        Logger::info('[alipay][SignPlugin] 插件装载完毕', ['rocket' => $rocket]);
33
34
        return $next($rocket);
35
    }
36
37
    protected function formatPayload(Rocket $rocket): void
38
    {
39
        $payload = $rocket->getPayload()->filter(function ($v, $k) {
40
            return '' !== $v && !is_null($v) && 'sign' != $k;
41
        });
42
43
        $contents = array_filter($payload->get('biz_content', []), function ($v, $k) {
44
            return !Str::startsWith(strval($k), '_');
45
        }, ARRAY_FILTER_USE_BOTH);
46
47
        $rocket->setPayload(
48
            $payload->merge(['biz_content' => json_encode($contents)])
49
        );
50
    }
51
52
    /**
53
     * @throws \Yansongda\Pay\Exception\ContainerDependencyException
54
     * @throws \Yansongda\Pay\Exception\ContainerException
55
     * @throws \Yansongda\Pay\Exception\InvalidConfigException
56
     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
57
     */
58
    protected function getSign(Rocket $rocket): string
59
    {
60
        $privateKey = $this->getPrivateKey($rocket->getParams());
61
62
        $content = $rocket->getPayload()->sortKeys()->toString();
63
64
        openssl_sign($content, $sign, $privateKey, OPENSSL_ALGO_SHA256);
65
66
        $sign = base64_encode($sign);
67
68
        !is_resource($privateKey) ?: openssl_free_key($privateKey);
69
70
        return $sign;
71
    }
72
73
    /**
74
     * @throws \Yansongda\Pay\Exception\ContainerDependencyException
75
     * @throws \Yansongda\Pay\Exception\ContainerException
76
     * @throws \Yansongda\Pay\Exception\InvalidConfigException
77
     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
78
     *
79
     * @return resource|string
80
     */
81
    protected function getPrivateKey(array $params)
82
    {
83
        $privateKey = get_alipay_config($params)->get('app_secret_cert');
84
85
        if (is_null($privateKey)) {
86
            throw new InvalidConfigException(InvalidConfigException::ALIPAY_CONFIG_ERROR, 'Missing Alipay Config -- [app_secret_cert]');
87
        }
88
89
        return get_public_or_private_cert($privateKey);
90
    }
91
}
92