Wechat::pay()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yansongda\Pay\Provider;
6
7
use GuzzleHttp\Psr7\Response;
8
use GuzzleHttp\Psr7\ServerRequest;
9
use Psr\Http\Message\MessageInterface;
10
use Psr\Http\Message\ResponseInterface;
11
use Psr\Http\Message\ServerRequestInterface;
12
use Yansongda\Artful\Artful;
13
use Yansongda\Artful\Event;
14
use Yansongda\Artful\Exception\ContainerException;
15
use Yansongda\Artful\Exception\InvalidParamsException;
16
use Yansongda\Artful\Exception\ServiceNotFoundException;
17
use Yansongda\Artful\Plugin\AddPayloadBodyPlugin;
18
use Yansongda\Artful\Plugin\ParserPlugin;
19
use Yansongda\Artful\Rocket;
20
use Yansongda\Pay\Contract\ProviderInterface;
21
use Yansongda\Pay\Event\CallbackReceived;
22
use Yansongda\Pay\Event\MethodCalled;
23
use Yansongda\Pay\Exception\Exception;
24
use Yansongda\Pay\Pay;
25
use Yansongda\Pay\Plugin\Wechat\AddRadarPlugin;
26
use Yansongda\Pay\Plugin\Wechat\ResponsePlugin;
27
use Yansongda\Pay\Plugin\Wechat\StartPlugin;
28
use Yansongda\Pay\Plugin\Wechat\V3\AddPayloadSignaturePlugin;
29
use Yansongda\Pay\Plugin\Wechat\V3\CallbackPlugin;
30
use Yansongda\Pay\Plugin\Wechat\V3\VerifySignaturePlugin;
31
use Yansongda\Supports\Collection;
32
use Yansongda\Supports\Str;
33
34
/**
35
 * @method Collection|Rocket app(array $order)      APP 支付
36
 * @method Collection|Rocket mini(array $order)     小程序支付
37
 * @method Collection|Rocket mp(array $order)       公众号支付
38
 * @method Collection|Rocket scan(array $order)     扫码支付(摄像头,主动扫)
39
 * @method Collection|Rocket h5(array $order)       H5 支付
40
 * @method Collection|Rocket transfer(array $order) 帐户转账
41
 */
42
class Wechat implements ProviderInterface
43
{
44
    public const AUTH_TAG_LENGTH_BYTE = 16;
45
46
    public const MCH_SECRET_KEY_LENGTH_BYTE = 32;
47
48
    public const URL = [
49
        Pay::MODE_NORMAL => 'https://api.mch.weixin.qq.com/',
50
        Pay::MODE_SANDBOX => 'https://api.mch.weixin.qq.com/sandboxnew/',
51
        Pay::MODE_SERVICE => 'https://api.mch.weixin.qq.com/',
52
    ];
53
54
    /**
55
     * @throws ContainerException
56
     * @throws InvalidParamsException
57
     * @throws ServiceNotFoundException
58
     */
59
    public function __call(string $shortcut, array $params): null|Collection|MessageInterface
60
    {
61
        $plugin = '\\Yansongda\\Pay\\Shortcut\\Wechat\\'.Str::studly($shortcut).'Shortcut';
62
63
        return Artful::shortcut($plugin, ...$params);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Yansongda\Artful\...rtcut($plugin, $params) could return the type Yansongda\Artful\Rocket which is incompatible with the type-hinted return Psr\Http\Message\Message...upports\Collection|null. Consider adding an additional type-check to rule them out.
Loading history...
Bug introduced by
$params is expanded, but the parameter $params of Yansongda\Artful\Artful::shortcut() 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

63
        return Artful::shortcut($plugin, /** @scrutinizer ignore-type */ ...$params);
Loading history...
64
    }
65
66
    /**
67
     * @throws ContainerException
68
     * @throws InvalidParamsException
69
     */
70
    public function pay(array $plugins, array $params): null|Collection|MessageInterface|Rocket
71
    {
72
        return Artful::artful($plugins, $params);
73
    }
74
75
    /**
76
     * @throws ContainerException
77
     * @throws InvalidParamsException
78
     * @throws ServiceNotFoundException
79
     */
80
    public function query(array $order): Collection|Rocket
81
    {
82
        Event::dispatch(new MethodCalled('wechat', __METHOD__, $order, null));
83
84
        return $this->__call('query', [$order]);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->__call('query', array($order)) could return the type Psr\Http\Message\MessageInterface which is incompatible with the type-hinted return Yansongda\Artful\Rocket|...gda\Supports\Collection. Consider adding an additional type-check to rule them out.
Loading history...
85
    }
86
87
    /**
88
     * @throws InvalidParamsException
89
     */
90
    public function cancel(array $order): Collection|Rocket
91
    {
92
        throw new InvalidParamsException(Exception::PARAMS_METHOD_NOT_SUPPORTED, '参数异常: 微信不支持 cancel API');
93
    }
94
95
    /**
96
     * @throws ContainerException
97
     * @throws InvalidParamsException
98
     * @throws ServiceNotFoundException
99
     */
100
    public function close(array $order): Collection|Rocket
101
    {
102
        Event::dispatch(new MethodCalled('wechat', __METHOD__, $order, null));
103
104
        $this->__call('close', [$order]);
105
106
        return new Collection();
107
    }
108
109
    /**
110
     * @throws ContainerException
111
     * @throws InvalidParamsException
112
     * @throws ServiceNotFoundException
113
     */
114
    public function refund(array $order): Collection|Rocket
115
    {
116
        Event::dispatch(new MethodCalled('wechat', __METHOD__, $order, null));
117
118
        return $this->__call('refund', [$order]);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->__call('refund', array($order)) could return the type Psr\Http\Message\MessageInterface which is incompatible with the type-hinted return Yansongda\Artful\Rocket|...gda\Supports\Collection. Consider adding an additional type-check to rule them out.
Loading history...
119
    }
120
121
    /**
122
     * @throws ContainerException
123
     * @throws InvalidParamsException
124
     */
125
    public function callback(null|array|ServerRequestInterface $contents = null, ?array $params = null): Collection|Rocket
126
    {
127
        $request = $this->getCallbackParams($contents);
128
129
        Event::dispatch(new CallbackReceived('wechat', clone $request, $params, null));
130
131
        return $this->pay(
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->pay(array(... '_params' => $params)) could return the type Psr\Http\Message\MessageInterface|null which is incompatible with the type-hinted return Yansongda\Artful\Rocket|...gda\Supports\Collection. Consider adding an additional type-check to rule them out.
Loading history...
132
            [CallbackPlugin::class],
133
            ['_request' => $request, '_params' => $params]
134
        );
135
    }
136
137
    public function success(): ResponseInterface
138
    {
139
        return new Response(
140
            200,
141
            ['Content-Type' => 'application/json'],
142
            json_encode(['code' => 'SUCCESS', 'message' => '成功']),
143
        );
144
    }
145
146
    public function mergeCommonPlugins(array $plugins): array
147
    {
148
        return array_merge(
149
            [StartPlugin::class],
150
            $plugins,
151
            [AddPayloadBodyPlugin::class, AddPayloadSignaturePlugin::class, AddRadarPlugin::class, VerifySignaturePlugin::class, ResponsePlugin::class, ParserPlugin::class],
152
        );
153
    }
154
155
    protected function getCallbackParams(null|array|ServerRequestInterface $contents = null): ServerRequestInterface
156
    {
157
        if (is_array($contents) && isset($contents['body'], $contents['headers'])) {
158
            return new ServerRequest('POST', 'http://localhost', $contents['headers'], $contents['body']);
159
        }
160
161
        if (is_array($contents)) {
162
            return new ServerRequest('POST', 'http://localhost', [], json_encode($contents));
163
        }
164
165
        if ($contents instanceof ServerRequestInterface) {
166
            return $contents;
167
        }
168
169
        return ServerRequest::fromGlobals();
170
    }
171
}
172