Completed
Push — master ( 017caa...491a31 )
by
unknown
16s queued 10s
created

Bankly::getAccount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
namespace WeDevBr\Bankly;
4
5
use Illuminate\Http\Client\RequestException;
6
use Illuminate\Support\Facades\Http;
7
use Ramsey\Uuid\Uuid;
8
9
/**
10
 * Class Bankly
11
 * @author Adeildo Amorim <[email protected]>
12
 * @package WeDevBr\Bankly
13
 */
14
class Bankly
15
{
16
    public $api_url;
17
    public $login_url;
18
    private $client_id;
19
    private $client_secret;
20
    private $token_expiry = 0;
21
    private $token = null;
22
    private $api_version = '1.0';
23
24
    /**
25
     * Bankly constructor.
26
     * @param null|string $client_secret provided by Bankly Staff
27
     * @param null|string $client_id provided by Bankly Staff
28
     */
29
    public function __construct($client_secret = null, $client_id = null)
30
    {
31
        $this->api_url = config('bankly')['api_url'];
32
        $this->login_url = config('bankly')['login_url'];
33
        $this->setClientCredentials(['client_secret' => $client_secret, 'client_id' => $client_id]);
34
    }
35
36
    /**
37
     * @param array|null $credentials
38
     * @return $this
39
     */
40
    public function setClientCredentials(array $credentials = null)
41
    {
42
        $this->client_secret = $credentials['client_secret'] ?? config('bankly')['client_secret'];
43
        $this->client_id = $credentials['client_id'] ?? config('bankly')['client_id'];
44
        return $this;
45
    }
46
47
    /**
48
     * @return array|mixed
49
     * @throws RequestException
50
     */
51
    final public function getBankList()
52
    {
53
        return $this->get('/banklist');
54
    }
55
56
    /**
57
     * @param string $account
58
     * @return array|mixed
59
     * @throws RequestException
60
     */
61
    final public function getBalance(string $account)
62
    {
63
        $account = $this->getAccount($account);
64
        return $account['balance'];
65
    }
66
67
    /**
68
     * @param string $account
69
     * @param string $includeBalance
70
     * @return array|mixed
71
     * @throws RequestException
72
     */
73
    final public function getAccount(string $account, string $includeBalance = 'true')
74
    {
75
        return $this->get('/accounts/' . $account, [
76
            'includeBalance' => $includeBalance,
77
        ]);
78
    }
79
80
    /**
81
     * @param $branch
82
     * @param $account
83
     * @param int $offset
84
     * @param int $limit
85
     * @param string $details
86
     * @param string $detailsLevelBasic
87
     * @return array|mixed
88
     * @throws RequestException
89
     */
90
    final public function getStatement(
91
        $branch,
92
        $account,
93
        $offset = 1,
94
        $limit = 20,
95
        $details = 'true',
96
        $detailsLevelBasic = 'true'
97
    ) {
98
        return $this->get('/account/statement', array(
99
            'branch' => $branch,
100
            'account' => $account,
101
            'offset' => $offset,
102
            'limit' => $limit,
103
            'details' => (string) $details,
104
            'detailsLevelBasic' => (string) $detailsLevelBasic
105
        ));
106
    }
107
108
    /**
109
     * @param string $branch
110
     * @param string $account
111
     * @param int $page
112
     * @param int $pagesize
113
     * @param string $include_details
114
     * @return array|mixed
115
     * @throws RequestException
116
     */
117
    public function getEvents(
118
        string $branch,
119
        string $account,
120
        int $page = 1,
121
        int $pagesize = 20,
122
        $include_details = 'true'
123
    ) {
124
        return $this->get(
125
            '/events',
126
            [
127
                'Branch' => $branch,
128
                'Account' => $account,
129
                'Page' => $page,
130
                'Pagesize' => $pagesize,
131
                'IncludeDetails' => (string) $include_details
132
            ]
133
        );
134
    }
135
136
    /**
137
     * @param int $amount
138
     * @param string $description
139
     * @param array $sender
140
     * @param array $recipient
141
     * @param string|null $correlation_id
142
     * @return array|mixed
143
     * @throws RequestException
144
     */
145
    public function transfer(
146
        int $amount,
147
        string $description,
148
        array $sender,
149
        array $recipient,
150
        string $correlation_id = null
151
    ) {
152
        if ($sender['bankCode']) {
153
            unset($sender['bankCode']);
154
        }
155
156
        return $this->post(
157
            '/fund-transfers',
158
            [
159
                'amount' => $amount,
160
                'description' => $description,
161
                'sender' => $sender,
162
                'recipient' => $recipient
163
            ],
164
            $correlation_id,
165
            true
166
        );
167
    }
168
169
    /**
170
     * Get transfer funds from an account
171
     * @param string $branch
172
     * @param string $account
173
     * @param int $pageSize
174
     * @param string|null $nextPage
175
     * @return array|mixed
176
     * @throws RequestException
177
     */
178
    public function getTransferFunds(string $branch, string $account, int $pageSize = 10, string $nextPage = null)
179
    {
180
        $queryParams = [
181
            'branch' => $branch,
182
            'account' => $account,
183
            'pageSize' => $pageSize
184
        ];
185
        if ($nextPage) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $nextPage of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
186
            $queryParams['nextPage'] = $nextPage;
187
        }
188
        return $this->get('/fund-transfers', $queryParams);
189
    }
190
191
    /**
192
     * Get Transfer Funds By Authentication Code
193
     * @param string $branch
194
     * @param string $account
195
     * @param string $authenticationCode
196
     * @return array|mixed
197
     * @throws RequestException
198
     */
199
    public function findTransferFundByAuthCode(string $branch, string $account, string $authenticationCode)
200
    {
201
        $queryParams = [
202
            'branch' => $branch,
203
            'account' => $account
204
        ];
205
        return $this->get('/fund-transfers/' . $authenticationCode, $queryParams);
206
    }
207
208
    /**
209
     * @param string $branch
210
     * @param string $account
211
     * @param string $authentication_id
212
     * @return array|mixed
213
     * @throws RequestException
214
     */
215
    public function getTransferStatus(string $branch, string $account, string $authentication_id)
216
    {
217
        return $this->get('/fund-transfers/' . $authentication_id . '/status', [
218
            'branch' => $branch,
219
            'account' => $account
220
        ]);
221
    }
222
223
    /**
224
     * @param string $endpoint
225
     * @param array|null $query
226
     * @param null $correlation_id
227
     * @return array|mixed
228
     * @throws RequestException
229
     */
230
    private function get(string $endpoint, array $query = null, $correlation_id = null)
231
    {
232
        if (now()->unix() > $this->token_expiry || !$this->token) {
233
            $this->auth();
234
        }
235
236
        if (is_null($correlation_id) && $this->requireCorrelationId($endpoint)) {
237
            $correlation_id = Uuid::uuid4()->toString();
238
        }
239
240
        return Http::withToken($this->token)
241
            ->withHeaders($this->getHeaders(['x-correlation-id' => $correlation_id]))
242
            ->get($this->getFinalUrl($endpoint), $query)
243
            ->throw()
244
            ->json();
245
    }
246
247
    /**
248
     * @param string $endpoint
249
     * @param array|null $body
250
     * @param string|null $correlation_id
251
     * @param bool $asJson
252
     * @return array|mixed
253
     * @throws RequestException
254
     */
255
    private function post(string $endpoint, array $body = null, string $correlation_id = null, bool $asJson = false)
256
    {
257
        if (now()->unix() > $this->token_expiry || !$this->token) {
258
            $this->auth();
259
        }
260
261
        if (is_null($correlation_id) && $this->requireCorrelationId($endpoint)) {
262
            $correlation_id = Uuid::uuid4()->toString();
263
        }
264
265
        $body_format = $asJson ? 'json' : 'form_params';
266
267
        return Http
268
            ::withToken($this->token)
269
            ->withHeaders($this->getHeaders(['x-correlation-id' => $correlation_id]))
270
            ->bodyFormat($body_format)
271
            ->post($this->getFinalUrl($endpoint), $body)
0 ignored issues
show
Bug introduced by
It seems like $body defined by parameter $body on line 255 can also be of type null; however, Illuminate\Http\Client\PendingRequest::post() does only seem to accept array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
272
            ->throw()
273
            ->json();
274
    }
275
276
    /**
277
     * @param string $version API version
278
     * @return $this
279
     */
280
    private function setApiVersion($version = '1.0')
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
281
    {
282
        $this->api_version = $version;
283
        return $this;
284
    }
285
286
    /**
287
     * @param array $headers
288
     * @return array|string[]
289
     */
290
    final private function getHeaders($headers = [])
291
    {
292
        $default_headers = [
293
            'API-Version' => $this->api_version
294
        ];
295
296
        if (count($headers) > 0) {
297
            $default_headers = array_merge($headers, $default_headers);
298
        }
299
300
        return $default_headers;
301
    }
302
303
    /**
304
     * @param string $endpoint
305
     * @return bool
306
     */
307
    final private function requireCorrelationId(string $endpoint)
308
    {
309
        $not_required_endpoints = [
310
            '/banklist',
311
            '/connect/token'
312
        ];
313
314
        return !in_array($endpoint, $not_required_endpoints);
315
    }
316
317
    /**
318
     * @param string $endpoint
319
     * @return string
320
     */
321
    final private function getFinalUrl(string $endpoint)
322
    {
323
        return $this->api_url . $endpoint;
324
    }
325
326
    /**
327
     * Do authentication
328
     * @param string $grant_type Default sets to 'client_credentials'
329
     * @throws RequestException
330
     */
331
    private function auth($grant_type = 'client_credentials'): void
332
    {
333
        //TODO: Add auth for username and password
334
        $body = [
335
            'grant_type' => $grant_type,
336
            'client_secret' => $this->client_secret,
337
            'client_id' => $this->client_id
338
        ];
339
340
        $response = Http::asForm()->post($this->login_url, $body)->throw()->json();
341
        $this->token = $response['access_token'];
342
        $this->token_expiry = now()->addSeconds($response['expires_in'])->unix();
343
    }
344
}
345