Client::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 0
c 1
b 0
f 0
nc 1
nop 6
dl 0
loc 8
ccs 1
cts 1
cp 1
crap 1
rs 10
1
<?php
2
3
namespace Sebdesign\VivaPayments;
4
5
use GuzzleHttp\Client as GuzzleClient;
6
use GuzzleHttp\Psr7\Uri;
7
use GuzzleHttp\RequestOptions;
8
use Psr\Http\Message\ResponseInterface;
9
use Psr\Http\Message\UriInterface;
10
use Sebdesign\VivaPayments\Enums\Environment;
11
12
class Client
13
{
14
    /**
15
     * Demo environment URL.
16
     */
17
    public const DEMO_URL = 'https://demo.vivapayments.com';
18
19
    /**
20
     * Production environment URL.
21
     */
22
    public const PRODUCTION_URL = 'https://www.vivapayments.com';
23
24
    /**
25
     * Demo environment accounts URL.
26
     */
27
    public const DEMO_ACCOUNTS_URL = 'https://demo-accounts.vivapayments.com';
28
29
    /**
30
     * Production environment accounts URL.
31
     */
32
    public const PRODUCTION_ACCOUNTS_URL = 'https://accounts.vivapayments.com';
33
34
    /**
35
     * Demo environment URL.
36
     */
37
    public const DEMO_API_URL = 'https://demo-api.vivapayments.com';
38
39
    /**
40
     * Production environment URL.
41
     */
42
    public const PRODUCTION_API_URL = 'https://api.vivapayments.com';
43
44
    protected string $token;
45
46 20
    public function __construct(
47
        public readonly GuzzleClient $client,
48
        protected Environment $environment,
49
        protected string $merchantId,
50
        protected string $apiKey,
51
        protected string $clientId,
52
        protected string $clientSecret,
53
    ) {
54
    }
55
56
    /**
57
     * Request OAuth access tokens.
58
     */
59 6
    public function oauth(): OAuth
60
    {
61 6
        return new OAuth($this, $this->clientId, $this->clientSecret);
62
    }
63
64
    /**
65
     * Create card tokens.
66
     */
67 3
    public function cards(): Card
68
    {
69 3
        return new Card($this);
70
    }
71
72
    /**
73
     * Create payment orders.
74
     */
75 3
    public function orders(): Order
0 ignored issues
show
Bug introduced by
The type Sebdesign\VivaPayments\Order was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
76
    {
77 3
        return new Order($this);
78
    }
79
80
    /**
81
     * Retrieve and create recurring transactions.
82
     */
83 3
    public function transactions(): Transaction
84
    {
85 3
        return new Transaction($this);
86
    }
87
88
    /**
89
     * Verity webhooks.
90
     */
91 3
    public function webhooks(): Webhook
92
    {
93 3
        return new Webhook($this);
94
    }
95
96
    /**
97
     * Make a GET request.
98
     *
99
     * @param  array<string,mixed>  $options
100
     * @return array<mixed>
101
     */
102 12
    public function get(string $url, array $options = []): array
103
    {
104 12
        $response = $this->client->get($url, $options);
105
106 12
        return $this->getBody($response);
107
    }
108
109
    /**
110
     * Make a POST request.
111
     *
112
     * @param  array<string,mixed>  $options
113
     * @return array<mixed>
114
     */
115 6
    public function post(string $url, array $options = []): array
116
    {
117 6
        $response = $this->client->post($url, $options);
118
119 6
        return $this->getBody($response);
120
    }
121
122
    /**
123
     * Get the response body.
124
     *
125
     * @return array<mixed>
126
     *
127
     * @throws \Sebdesign\VivaPayments\VivaException
128
     */
129 18
    protected function getBody(ResponseInterface $response): array
130
    {
131 18
        $body = (string) $response->getBody();
132
133 18
        $decoded = json_decode(
134
            json: $body,
135
            associative: true,
136
            depth: 512,
137 18
            flags: JSON_BIGINT_AS_STRING | JSON_THROW_ON_ERROR,
138
        );
139
140 18
        if (! is_array($decoded)) {
141 3
            throw new VivaException('Invalid response', 0);
142
        }
143
144 15
        if (isset($decoded['ErrorCode']) && $decoded['ErrorCode'] !== 0) {
145 3
            throw new VivaException($decoded['ErrorText'], $decoded['ErrorCode']);
146
        }
147
148 12
        return $decoded;
149
    }
150
151
    /**
152
     * Get the URL.
153
     */
154 6
    public function getUrl(): UriInterface
155
    {
156 6
        return new Uri(match ($this->environment) {
157 2
            Environment::Production => self::PRODUCTION_URL,
158 2
            Environment::Demo => self::DEMO_URL,
159
        });
160
    }
161
162
    /**
163
     * Get the accounts URL.
164
     */
165 9
    public function getAccountsUrl(): UriInterface
166
    {
167 9
        return new Uri(match ($this->environment) {
168 3
            Environment::Production => self::PRODUCTION_ACCOUNTS_URL,
169 3
            Environment::Demo => self::DEMO_ACCOUNTS_URL,
170
        });
171
    }
172
173
    /**
174
     * Get the API URL.
175
     */
176 6
    public function getApiUrl(): UriInterface
177
    {
178 6
        return new Uri(match ($this->environment) {
179 2
            Environment::Production => self::PRODUCTION_API_URL,
180 2
            Environment::Demo => self::DEMO_API_URL,
181
        });
182
    }
183
184
    /**
185
     * Authenticate using basic auth.
186
     *
187
     * @return array{auth:array{string,string}}
0 ignored issues
show
Documentation Bug introduced by
The doc comment array{auth:array{string,string}} at position 6 could not be parsed: Expected ':' at position 6, but found 'string'.
Loading history...
188
     */
189 6
    public function authenticateWithBasicAuth(): array
190
    {
191
        return [
192 6
            RequestOptions::AUTH => [$this->merchantId, $this->apiKey],
193
        ];
194
    }
195
196
    /**
197
     * Authenticate using the bearer token as an authorization header.
198
     *
199
     * @return array{headers:array{Authorization:string}};
200
     */
201 3
    public function authenticateWithBearerToken(): array
202
    {
203 3
        $token = $this->token ??= $this->oauth()->requestToken()->access_token;
204
205
        return [
206 1
            RequestOptions::HEADERS => [
207 3
                'Authorization' => "Bearer {$token}",
208
            ],
209
        ];
210
    }
211
212
    /**
213
     * Use the production or demo environment.
214
     */
215 18
    public function withEnvironment(Environment|string $environment): self
216
    {
217 18
        $this->environment = is_string($environment) ? Environment::from($environment) : $environment;
218
219 18
        return $this;
220
    }
221
222
    /**
223
     * Use the given Merchant ID and API key for basic authentication.
224
     *
225
     * @see https://developer.vivawallet.com/getting-started/find-your-account-credentials/merchant-id-and-api-key/
226
     */
227 3
    public function withBasicAuthCredentials(
228
        #[\SensitiveParameter] string $merchantId,
229
        #[\SensitiveParameter] string $apiKey,
230
    ): self {
231 3
        $this->merchantId = $merchantId;
232 3
        $this->apiKey = $apiKey;
233
234 3
        return $this;
235
    }
236
237
    /**
238
     * Use the given client credentials to authenticate with OAuth 2.0.
239
     *
240
     * @see https://developer.vivawallet.com/getting-started/find-your-account-credentials/client-smart-checkout-credentials/
241
     */
242 3
    public function withOAuthCredentials(
243
        #[\SensitiveParameter] string $clientId,
244
        #[\SensitiveParameter] string $clientSecret,
245
    ): self {
246 3
        $this->clientId = $clientId;
247 3
        $this->clientSecret = $clientSecret;
248
249 3
        return $this;
250
    }
251
252
    /**
253
     * Use the given access token to authenticate with OAuth 2.0.
254
     */
255 3
    public function withToken(#[\SensitiveParameter] string $token): self
256
    {
257 3
        $this->token = $token;
258
259 3
        return $this;
260
    }
261
}
262