Passed
Push — master ( 016f2b...d8e01b )
by odenktools
03:51
created

BcaHttp::getBalanceInfo()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 41
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 29
dl 0
loc 41
c 0
b 0
f 0
rs 9.456
cc 2
nc 1
nop 2
1
<?php
2
3
namespace Bca;
4
5
/**
6
 * BCA REST API Library.
7
 *
8
 * @author     Pribumi Technology
9
 * @license    MIT
10
 * @copyright  (c) 2017, Pribumi Technology
11
 */
12
class BcaHttp
13
{
14
    public static $VERSION = '2.2.0';
15
16
    private static $timezone = 'Asia/Jakarta';
17
18
    private static $port = 443;
19
20
    private static $hostName = 'sandbox.bca.co.id';
21
22
    protected $settings = array(
23
        'corp_id'       => '',
24
        'client_id'     => '',
25
        'client_secret' => '',
26
        'api_key'       => '',
27
        'secret_key'    => '',
28
        'scheme'        => 'https',
29
        'port'          => 443,
30
        'timezone'      => 'Asia/Jakarta',
31
        'timeout'       => null,
32
        'development'   => true,
33
    );
34
35
    /**
36
     * Default Constructor.
37
     *
38
     * @param string $corp_id nilai corp id
39
     * @param string $client_id nilai client key
40
     * @param string $client_secret nilai client secret
41
     * @param string $api_key niali oauth key
42
     * @param string $secret_key nilai oauth secret
43
     * @param array $options opsi ke server bca
44
     */
45
    public function __construct($corp_id, $client_id, $client_secret, $api_key, $secret_key, $options = array())
46
    {
47
        if (!isset($options['port'])) {
48
            $options['port'] = self::getPort();
49
        }
50
51
        if (!isset($options['timezone'])) {
52
            $options['timezone'] = self::getTimeZone();
53
        }
54
55
        foreach ($options as $key => $value) {
56
            if (isset($this->settings[$key])) {
57
                $this->settings[$key] = $value;
58
            }
59
        }
60
61
        if (!array_key_exists('host', $this->settings)) {
62
            if (array_key_exists('host', $options)) {
63
                $this->settings['host'] = $options['host'];
64
            } else {
65
                $this->settings['host'] = self::getHostName();
66
            }
67
        }
68
69
        $this->settings['corp_id']       = $corp_id;
70
        $this->settings['client_id']     = $client_id;
71
        $this->settings['client_secret'] = $client_secret;
72
        $this->settings['api_key']       = $api_key;
73
        $this->settings['secret_key']    = $secret_key;
74
        
75
        $this->settings['host'] =
76
            preg_replace('/http[s]?\:\/\//', '', $this->settings['host'], 1);
77
    }
78
79
    /**
80
     * Ambil Nilai settings.
81
     *
82
     * @return array
83
     */
84
    public function getSettings()
85
    {
86
        return $this->settings;
87
    }
88
89
    /**
90
     * Build the ddn domain.
91
     * output = 'https://sandbox.bca.co.id:443'
92
     * scheme = http(s)
93
     * host = sandbox.bca.co.id
94
     * port = 80 ? 443
95
     *
96
     * @return string
97
     */
98
    private function ddnDomain()
99
    {
100
        return $this->settings['scheme'] . '://' . $this->settings['host'] . ':' . $this->settings['port'] . '/';
101
    }
102
103
    /**
104
     * Generate authentifikasi ke server berupa OAUTH.
105
     *
106
     * @return \Unirest\Response
107
     */
108
    public function httpAuth()
109
    {
110
        $client_id     = $this->settings['client_id'];
111
        $client_secret = $this->settings['client_secret'];
112
        
113
        $headerToken = base64_encode("$client_id:$client_secret");
114
115
        $headers = array('Accept' => 'application/json', 'Authorization' => "Basic $headerToken");
116
117
        $request_path = "api/oauth/token";
118
        $domain       = $this->ddnDomain();
119
        $full_url     = $domain . $request_path;
120
        
121
        \Unirest\Request::curlOpts(array(
122
            CURLOPT_SSL_VERIFYHOST => 0,
123
            CURLOPT_SSLVERSION => 6,
124
            CURLOPT_SSL_VERIFYPEER => false,
125
            CURLOPT_TIMEOUT => $this->settings['timeout'] !== 30 ? $this->settings['timeout'] : 30
126
        ));
127
128
        $data = array('grant_type' => 'client_credentials');
129
        $body = \Unirest\Request\Body::form($data);
130
        $response = \Unirest\Request::post($full_url, $headers, $body);
131
132
        return $response;
133
    }
134
135
    /**
136
     * Ambil informasi saldo berdasarkan nomor akun BCA.
137
     *
138
     * @param string $oauth_token nilai token yang telah didapatkan setelah login
139
     * @param array $sourceAccountId nomor akun yang akan dicek
140
     *
141
     * @return \Unirest\Response
142
     */
143
    public function getBalanceInfo($oauth_token, $sourceAccountId = [])
144
    {
145
        $corp_id = $this->settings['corp_id'];
146
        $apikey  = $this->settings['api_key'];
147
        $secret  = $this->settings['secret_key'];
148
        
149
        $this->validateArray($sourceAccountId);
150
151
        ksort($sourceAccountId);
152
        $arraySplit = implode(",", $sourceAccountId);
153
        $arraySplit = urlencode($arraySplit);
154
155
        $uriSign       = "GET:/banking/v3/corporates/$corp_id/accounts/$arraySplit";
156
        $isoTime       = self::generateIsoTime();
157
        $authSignature = self::generateSign($uriSign, $oauth_token, $secret, $isoTime, null);
158
159
        $headers                    = array();
160
        $headers['Accept']          = 'application/json';
161
        $headers['Content-Type']    = 'application/json';
162
        $headers['Authorization']   = "Bearer $oauth_token";
163
        $headers['X-BCA-Key']       = $apikey;
164
        $headers['X-BCA-Timestamp'] = $isoTime;
165
        $headers['X-BCA-Signature'] = $authSignature;
166
167
        $request_path = "banking/v3/corporates/$corp_id/accounts/$arraySplit";
168
        $domain       = $this->ddnDomain();
169
        $full_url     = $domain . $request_path;
170
        
171
        $data = array('grant_type' => 'client_credentials');
172
173
        \Unirest\Request::curlOpts(array(
174
            CURLOPT_SSL_VERIFYHOST => 0,
175
            CURLOPT_SSLVERSION => 6,
176
            CURLOPT_SSL_VERIFYPEER => false,
177
            CURLOPT_TIMEOUT => $this->settings['timeout'] !== 30 ? $this->settings['timeout'] : 30
178
        ));
179
180
        $body     = \Unirest\Request\Body::form($data);
181
        $response = \Unirest\Request::get($full_url, $headers, $body);
182
183
        return $response;
184
    }
185
186
    /**
187
     * Ambil Daftar transaksi pertanggal.
188
     *
189
     * @param string $oauth_token nilai token yang telah didapatkan setelah login
190
     * @param array $sourceAccount nomor akun yang akan dicek
191
     * @param string $startDate tanggal awal
192
     * @param string $endDate tanggal akhir
193
     * @param string $corp_id nilai CorporateID yang telah diberikan oleh pihak BCA
194
     *
195
     * @return \Unirest\Response
196
     */
197
    public function getAccountStatement($oauth_token, $sourceAccount, $startDate, $endDate)
198
    {
199
        $corp_id = $this->settings['corp_id'];
200
        
201
        $apikey = $this->settings['api_key'];
202
203
        $secret = $this->settings['secret_key'];
204
205
        $uriSign       = "GET:/banking/v3/corporates/$corp_id/accounts/$sourceAccount/statements?EndDate=$endDate&StartDate=$startDate";
206
        $isoTime       = self::generateIsoTime();
207
        $authSignature = self::generateSign($uriSign, $oauth_token, $secret, $isoTime, null);
208
209
        $headers                    = array();
210
        $headers['Accept']          = 'application/json';
211
        $headers['Content-Type']    = 'application/json';
212
        $headers['Authorization']   = "Bearer $oauth_token";
213
        $headers['X-BCA-Key']       = $apikey;
214
        $headers['X-BCA-Timestamp'] = $isoTime;
215
        $headers['X-BCA-Signature'] = $authSignature;
216
217
        $request_path = "banking/v3/corporates/$corp_id/accounts/$sourceAccount/statements?EndDate=$endDate&StartDate=$startDate";
218
        $domain       = $this->ddnDomain();
219
        $full_url     = $domain . $request_path;
220
221
        \Unirest\Request::curlOpts(array(
222
            CURLOPT_SSL_VERIFYHOST => 0,
223
            CURLOPT_SSLVERSION => 6,
224
            CURLOPT_SSL_VERIFYPEER => false,
225
            CURLOPT_TIMEOUT => $this->settings['timeout'] !== 30 ? $this->settings['timeout'] : 30
226
        ));
227
        
228
        $data = array('grant_type' => 'client_credentials');
229
        $body     = \Unirest\Request\Body::form($data);
230
        $response = \Unirest\Request::get($full_url, $headers, $body);
231
232
        return $response;
233
    }
234
235
    /**
236
     * Ambil informasi ATM berdasarkan lokasi GEO.
237
     *
238
     * @param string $oauth_token nilai token yang telah didapatkan setelah login
239
     * @param string $latitude Langitude GPS
240
     * @param string $longitude Longitude GPS
241
     * @param string $count Jumlah ATM BCA yang akan ditampilkan
242
     * @param string $radius Nilai radius dari lokasi GEO
243
     *
244
     * @return \Unirest\Response
245
     */
246
    public function getAtmLocation(
247
        $oauth_token,
248
        $latitude,
249
        $longitude,
250
        $count = '10',
251
        $radius = '20'
252
    ) {
253
        $apikey = $this->settings['api_key'];
254
        
255
        $secret = $this->settings['secret_key'];
256
257
        $params              = array();
258
        $params['SearchBy']  = 'Distance';
259
        $params['Latitude']  = $latitude;
260
        $params['Longitude'] = $longitude;
261
        $params['Count']     = $count;
262
        $params['Radius']    = $radius;
263
        ksort($params);
264
265
        $auth_query_string = self::arrayImplode('=', '&', $params);
266
267
        $uriSign       = "GET:/general/info-bca/atm?$auth_query_string";
268
        $isoTime       = self::generateIsoTime();
269
        $authSignature = self::generateSign($uriSign, $oauth_token, $secret, $isoTime, null);
270
271
        $headers                    = array();
272
        $headers['Accept']          = 'application/json';
273
        $headers['Content-Type']    = 'application/json';
274
        $headers['Authorization']   = "Bearer $oauth_token";
275
        $headers['X-BCA-Key']       = $apikey;
276
        $headers['X-BCA-Timestamp'] = $isoTime;
277
        $headers['X-BCA-Signature'] = $authSignature;
278
279
        $request_path = "general/info-bca/atm?SearchBy=Distance&Latitude=$latitude&Longitude=$longitude&Count=$count&Radius=$radius";
280
        $domain       = $this->ddnDomain();
281
        $full_url     = $domain . $request_path;
282
283
        \Unirest\Request::curlOpts(array(
284
            CURLOPT_SSL_VERIFYHOST => 0,
285
            CURLOPT_SSLVERSION => 6,
286
            CURLOPT_SSL_VERIFYPEER => false,
287
            CURLOPT_TIMEOUT => $this->settings['timeout'] !== 30 ? $this->settings['timeout'] : 30
288
        ));
289
        
290
        $data = array('grant_type' => 'client_credentials');
291
        $body     = \Unirest\Request\Body::form($data);
292
        $response = \Unirest\Request::get($full_url, $headers, $body);
293
294
        return $response;
295
    }
296
297
    /**
298
     * Ambil KURS mata uang.
299
     *
300
     * @param string $oauth_token nilai token yang telah didapatkan setelah login
301
     * @param string $rateType type rate
302
     * @param string $currency Mata uang
303
     *
304
     * @return \Unirest\Response
305
     */
306
    public function getForexRate(
307
        $oauth_token,
308
        $rateType = 'e-rate',
309
        $currency = 'USD'
310
    ) {
311
        $apikey = $this->settings['api_key'];
312
        
313
        $secret = $this->settings['secret_key'];
314
315
        $params             = array();
316
        $params['RateType'] = strtolower($rateType);
317
        $params['Currency'] = strtoupper($currency);
318
        ksort($params);
319
320
        $auth_query_string = self::arrayImplode('=', '&', $params);
321
322
        $uriSign       = "GET:/general/rate/forex?$auth_query_string";
323
        $isoTime       = self::generateIsoTime();
324
        $authSignature = self::generateSign($uriSign, $oauth_token, $secret, $isoTime, null);
325
326
        $headers                    = array();
327
        $headers['Accept']          = 'application/json';
328
        $headers['Content-Type']    = 'application/json';
329
        $headers['Authorization']   = "Bearer $oauth_token";
330
        $headers['X-BCA-Key']       = $apikey;
331
        $headers['X-BCA-Timestamp'] = $isoTime;
332
        $headers['X-BCA-Signature'] = $authSignature;
333
334
        $request_path = "general/rate/forex?$auth_query_string";
335
        $domain       = $this->ddnDomain();
336
        $full_url     = $domain . $request_path;
337
338
        \Unirest\Request::curlOpts(array(
339
            CURLOPT_SSL_VERIFYHOST => 0,
340
            CURLOPT_SSLVERSION => 6,
341
            CURLOPT_SSL_VERIFYPEER => false,
342
            CURLOPT_TIMEOUT => $this->settings['timeout'] !== 30 ? $this->settings['timeout'] : 30
343
        ));
344
        
345
        $data = array('grant_type' => 'client_credentials');
346
        $body     = \Unirest\Request\Body::form($data);
347
        $response = \Unirest\Request::get($full_url, $headers, $body);
348
349
        return $response;
350
    }
351
352
    /**
353
     * Transfer dana kepada akun lain dengan jumlah nominal tertentu.
354
     *
355
     * @param string $oauth_token nilai token yang telah didapatkan setelah login
356
     * @param int $amount nilai dana dalam RUPIAH yang akan ditransfer, Format: 13.2
357
     * @param string $beneficiaryAccountNumber  BCA Account number to be credited (Destination)
358
     * @param string $referenceID Sender's transaction reference ID
359
     * @param string $remark1 Transfer remark for receiver
360
     * @param string $remark2 ransfer remark for receiver
361
     * @param string $sourceAccountNumber Source of Fund Account Number
362
     * @param string $transactionID Transcation ID unique per day (using UTC+07 Time Zone). Format: Number
363
     * @param string $corp_id nilai CorporateID yang telah diberikan oleh pihak BCA [Optional]
364
     *
365
     * @return \Unirest\Response
366
     */
367
    public function fundTransfers(
368
        $oauth_token,
369
        $amount,
370
        $sourceAccountNumber,
371
        $beneficiaryAccountNumber,
372
        $referenceID,
373
        $remark1,
374
        $remark2,
375
        $transactionID
376
    ) {
377
        $corp_id = $this->settings['corp_id'];
378
        $apikey = $this->settings['api_key'];
379
        $secret = $this->settings['secret_key'];
380
381
        $uriSign = "POST:/banking/corporates/transfers";
382
        
383
        $isoTime = self::generateIsoTime();
384
385
        $headers                    = array();
386
        $headers['Accept']          = 'application/json';
387
        $headers['Content-Type']    = 'application/json';
388
        $headers['Authorization']   = "Bearer $oauth_token";
389
        $headers['X-BCA-Key']       = $apikey;
390
        $headers['X-BCA-Timestamp'] = $isoTime;
391
392
        $request_path = "banking/corporates/transfers";
393
        $domain       = $this->ddnDomain();
394
        $full_url     = $domain . $request_path;
395
396
        $bodyData                             = array();
397
        $bodyData['Amount']                   = $amount;
398
        $bodyData['BeneficiaryAccountNumber'] = $beneficiaryAccountNumber;
399
        $bodyData['CorporateID']              = $corp_id;
400
        $bodyData['CurrencyCode']             = 'IDR';
401
        $bodyData['ReferenceID']              = $referenceID;
402
        $bodyData['Remark1']                  = strtolower(str_replace(' ', '', $remark1));
403
        $bodyData['Remark2']                  = strtolower(str_replace(' ', '', $remark2));
404
        $bodyData['SourceAccountNumber']      = $sourceAccountNumber;
405
        $bodyData['TransactionDate']          = $isoTime;
406
        $bodyData['TransactionID']            = $transactionID;
407
408
        // Harus disort agar mudah kalkulasi HMAC
409
        ksort($bodyData);
410
411
        // Supaya jgn strip "ReferenceID" "/" jadi "/\" karena HMAC akan menjadi tidak cocok
412
        $encoderData = json_encode($bodyData, JSON_UNESCAPED_SLASHES);
413
414
        $authSignature = self::generateSign($uriSign, $oauth_token, $secret, $isoTime, $bodyData);
415
416
        $headers['X-BCA-Signature'] = $authSignature;
417
418
        \Unirest\Request::curlOpts(array(
419
            CURLOPT_SSL_VERIFYHOST => 0,
420
            CURLOPT_SSLVERSION => 6,
421
            CURLOPT_SSL_VERIFYPEER => false,
422
            CURLOPT_TIMEOUT => $this->settings['timeout'] !== 30 ? $this->settings['timeout'] : 30
423
        ));
424
        $body     = \Unirest\Request\Body::form($encoderData);
425
        $response = \Unirest\Request::post($full_url, $headers, $body);
426
427
        return $response;
428
    }
429
    
430
    /**
431
     * Realtime deposit untuk produk BCA.
432
     *
433
     * @param string $oauth_token nilai token yang telah didapatkan setelah login
434
     *
435
     * @return \Unirest\Response
436
     */
437
    public function getDepositRate($oauth_token)
438
    {
439
        $corp_id = $this->settings['corp_id'];
0 ignored issues
show
Unused Code introduced by
The assignment to $corp_id is dead and can be removed.
Loading history...
440
        $apikey  = $this->settings['api_key'];
441
        $secret  = $this->settings['secret_key'];
442
443
        $uriSign       = "GET:/general/rate/deposit";
444
        $isoTime       = self::generateIsoTime();
445
        $authSignature = self::generateSign($uriSign, $oauth_token, $secret, $isoTime, null);
446
447
        $headers                    = array();
448
        $headers['Accept']          = 'application/json';
449
        $headers['Content-Type']    = 'application/json';
450
        $headers['Authorization']   = "Bearer $oauth_token";
451
        $headers['X-BCA-Key']       = $apikey;
452
        $headers['X-BCA-Timestamp'] = $isoTime;
453
        $headers['X-BCA-Signature'] = $authSignature;
454
455
        $request_path = "general/rate/deposit";
456
        $domain       = $this->ddnDomain();
457
        $full_url     = $domain . $request_path;
458
459
        $data = array('grant_type' => 'client_credentials');
460
        
461
        \Unirest\Request::curlOpts(array(
462
            CURLOPT_SSL_VERIFYHOST => 0,
463
            CURLOPT_SSLVERSION => 6,
464
            CURLOPT_SSL_VERIFYPEER => false,
465
            CURLOPT_TIMEOUT => $this->settings['timeout'] !== 30 ? $this->settings['timeout'] : 30
466
        ));
467
        
468
        $body     = \Unirest\Request\Body::form($data);
469
        $response = \Unirest\Request::get($full_url, $headers, $body);
470
471
        return $response;
472
    }
473
    
474
    /**
475
     * Generate Signature.
476
     *
477
     * @param string $url Url yang akan disign
478
     * @param string $auth_token string nilai token dari login
479
     * @param string $secret_key string secretkey yang telah diberikan oleh BCA
480
     * @param string $isoTime string Waktu ISO8601
481
     * @param array $bodyToHash array Body yang akan dikirimkan ke Server BCA
482
     *
483
     * @return string
484
     */
485
    public static function generateSign($url, $auth_token, $secret_key, $isoTime, $bodyToHash)
486
    {
487
        $hash = null;
488
        if (is_array($bodyToHash)) {
0 ignored issues
show
introduced by
The condition is_array($bodyToHash) is always true.
Loading history...
489
            ksort($bodyToHash);
490
            $encoderData = json_encode($bodyToHash, JSON_UNESCAPED_SLASHES);
491
            $hash        = hash("sha256", $encoderData);
492
        } else {
493
            $hash = hash("sha256", "");
494
        }
495
        $stringToSign   = $url . ":" . $auth_token . ":" . $hash . ":" . $isoTime;
496
        $auth_signature = hash_hmac('sha256', $stringToSign, $secret_key, false);
497
498
        return $auth_signature;
499
    }
500
501
    /**
502
     * Set TimeZone.
503
     *
504
     * @param string $timeZone Time yang akan dipergunakan.
505
     *
506
     * @return string
507
     */
508
    public static function setTimeZone($timeZone)
509
    {
510
        self::$timezone = $timeZone;
511
    }
512
513
    /**
514
     * Get TimeZone.
515
     *
516
     * @return string
517
     */
518
    public static function getTimeZone()
519
    {
520
        return self::$timezone;
521
    }
522
523
    /**
524
     * Set nama domain BCA yang akan dipergunakan.
525
     *
526
     * @param string $hostName nama domain BCA yang akan dipergunakan.
527
     *
528
     * @return string
529
     */
530
    public static function setHostName($hostName)
531
    {
532
        self::$hostName = $hostName;
533
    }
534
535
    /**
536
     * Ambil nama domain BCA yang akan dipergunakan.
537
     *
538
     * @return string
539
     */
540
    public static function getHostName()
541
    {
542
        return self::$hostName;
543
    }
544
545
    /**
546
     * Set BCA port
547
     *
548
     * @param int $port Port yang akan dipergunakan
549
     *
550
     * @return int
551
     */
552
    public static function setPort($port)
553
    {
554
        self::$port = $port;
555
    }
556
557
    /**
558
     * Get BCA port
559
     *
560
     * @return int
561
     */
562
    public static function getPort()
563
    {
564
        return self::$port;
565
    }
566
567
    /**
568
     * Generate ISO8601 Time.
569
     *
570
     * @param string $timeZone Time yang akan dipergunakan
571
     *
572
     * @return string
573
     */
574
    public static function generateIsoTime()
575
    {
576
        $date = \Carbon\Carbon::now(self::getTimeZone());
577
        date_default_timezone_set(self::getTimeZone());
578
        $fmt     = $date->format('Y-m-d\TH:i:s');
579
        $ISO8601 = sprintf("$fmt.%s%s", substr(microtime(), 2, 3), date('P'));
580
581
        return $ISO8601;
582
    }
583
584
    /**
585
     * Validasi jika clientsecret telah di-definsikan.
586
     *
587
     * @param array $sourceAccountId
588
     *
589
     * @return bool
590
     */
591
    private function validateArray($sourceAccountId = [])
592
    {
593
        if (empty($sourceAccountId)) {
594
            throw new BcaHttpException('AccountNumber tidak boleh kosong.');
595
        } else {
596
            if (count($sourceAccountId) > 20) {
597
                throw new BcaHttpException('Maksimal Account Number ' . 20);
598
            }
599
        }
600
601
        return true;
602
    }
603
    
604
    /**
605
     * Implode an array with the key and value pair giving
606
     * a glue, a separator between pairs and the array
607
     * to implode.
608
     *
609
     * @param string $glue      The glue between key and value
610
     * @param string $separator Separator between pairs
611
     * @param array  $array     The array to implode
612
     *
613
     * @return string The imploded array
614
     */
615
    public static function arrayImplode($glue, $separator, $array)
616
    {
617
        if (!is_array($array)) {
0 ignored issues
show
introduced by
The condition is_array($array) is always true.
Loading history...
618
            throw new BcaHttpException('Data harus array.');
619
        }
620
        $string = array();
621
        foreach ($array as $key => $val) {
622
            if (is_array($val)) {
623
                $val = implode(',', $val);
624
            }
625
            $string[] = "{$key}{$glue}{$val}";
626
        }
627
628
        return implode($separator, $string);
629
    }
630
}
631