├── .gitignore
├── LICENSE
├── README.md
├── composer.json
├── phpunit.xml
├── src
├── Core
│ └── SnapApiCore.php
├── Exception
│ ├── AuthenticateException.php
│ ├── HttpException.php
│ ├── SignatureException.php
│ └── SnapBiException.php
├── Interfaces
│ ├── ConfigInterface.php
│ ├── HttpResponseInterface.php
│ └── SnapApiInterface.php
├── Services
│ ├── BCA
│ │ ├── BcaConfig.php
│ │ ├── BcaSnapApi.php
│ │ └── Traits
│ │ │ ├── HasAccessToken.php
│ │ │ ├── HasTransaction.php
│ │ │ └── HasVirtualAccount.php
│ ├── BRI
│ │ ├── BriConfig.php
│ │ ├── BriSnapApi.php
│ │ └── Traits
│ │ │ ├── HasAccessToken.php
│ │ │ └── HasTransaction.php
│ ├── Config.php
│ ├── DANA
│ │ ├── DanaConfig.php
│ │ ├── DanaSnapApi.php
│ │ └── Traits
│ │ │ ├── HasAccessToken.php
│ │ │ └── HasTransaction.php
│ ├── Mandiri
│ │ ├── MandiriConfig.php
│ │ ├── MandiriSnapApi.php
│ │ └── Traits
│ │ │ ├── HasAccessToken.php
│ │ │ └── HasTransaction.php
│ └── SnapBi.php
├── Support
│ ├── Http.php
│ ├── HttpResponse.php
│ └── Signature.php
├── Traits
│ ├── HasConfig.php
│ └── HasSelfCall.php
└── helper.php
└── tests
├── Fixtures
└── Fixture.example.php
└── Unit
├── ConfigTest.php
├── SignatureTest.php
└── SupportHttpTest.php
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
2 |
3 | composer.lock
4 | composer.phar
5 | vendor/
6 | .phpunit.*
7 | .code-coverage
8 | tests/Fixtures/Fixture.php
9 |
10 | index.php
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Otnansirk
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PHP SNAP BI
2 | This is a PHP library that serves as a wrapper for the SNAP API BI. It is fully compatible with Composer.
3 |
4 | ### Documentation
5 | https://php-snap-bi.gitbook.io/docs
6 |
7 | ## Installation
8 | ```bash
9 | composer require otnansirk/php-snap-bi
10 | ```
11 | or
12 | ```json
13 | {
14 | "require": {
15 | "otnansirk/php-snap-bi": "1.*"
16 | }
17 | }
18 | ```
19 | **Next :**
20 | visit [php-snap-bi Documentation](https://php-snap-bi.gitbook.io/docs/getting-started/configuration) for more detail.
21 |
22 | ## Contributing
23 | Thank you for considering contributing to the `php-snap-bi` package. The contribution guide can be found in the `php-snap-bi` [php-snap-bi documentation](https://php-snap-bi.gitbook.io/contribution-guide).
24 |
25 | ## Code of Conduct
26 | In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://php-snap-bi.gitbook.io/docs/contribution-guide/code-of-conduct).
27 |
28 | ## License
29 | The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/license/mit).
30 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "otnansirk/php-snap-bi",
3 | "description": "This is a standard national open API Payments wrapper for PHP",
4 | "keywords": [
5 | "snap-bi",
6 | "php-snap-bi",
7 | "sdk-snap-bca",
8 | "sdk-snap-mandiri",
9 | "sdk-snap-dana",
10 | "sdk-snap-bri",
11 | "php-snap-bca",
12 | "php-snap-mandiri",
13 | "php-snap-dana",
14 | "php-snap-bri",
15 | "php"
16 | ],
17 | "type": "library",
18 | "license": "MIT",
19 | "authors": [
20 | {
21 | "name": "Otnansirk",
22 | "email": "iam.otnansirk@gmail.com"
23 | }
24 | ],
25 | "support": {
26 | "forum": "https://github.com/otnansirk/php-snap-bi/discussions",
27 | "issues": "https://github.com/otnansirk/php-snap-bi/issues",
28 | "source": "https://github.com/otnansirk/php-snap-bi",
29 | "docs": "https://php-snap-bi.gitbook.io/docs"
30 | },
31 | "scripts": {
32 | "test": "XDEBUG_MODE=coverage phpunit"
33 | },
34 | "require": {
35 | "php": ">=7.4",
36 | "ext-curl": "*",
37 | "ramsey/uuid": "^4.7",
38 | "nesbot/carbon": "^2.71"
39 | },
40 | "require-dev": {
41 | "psy/psysh": "^0.11.20",
42 | "phpunit/phpunit": "^10.3"
43 | },
44 | "autoload": {
45 | "psr-4": {
46 | "Otnansirk\\SnapBI\\": "src/"
47 | },
48 | "files": [
49 | "src/helper.php"
50 | ]
51 | },
52 | "autoload-dev": {
53 | "psr-4": {
54 | "Otnansirk\\SnapBI\\": [
55 | "tests/",
56 | "tests/Integration",
57 | "tests/Unit",
58 | "tests/Fixtures"
59 | ]
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 | tests/Unit
9 |
10 |
11 | tests/Integration
12 |
13 |
14 |
15 |
16 | src
17 |
18 |
19 | src/Support/HttpResponse.php
20 | src/Support/Http.php
21 | src/Exception
22 | src/Interfaces
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/Core/SnapApiCore.php:
--------------------------------------------------------------------------------
1 | BcaConfig::get('channel_id'),
25 | 'X-PARTNER-ID' => BcaConfig::get('partner_id'),
26 | 'X-EXTERNAL-ID' => int_rand(16),
27 | ];
28 | }
29 |
30 | /**
31 | * Default body
32 | *
33 | * @return array
34 | */
35 | public static function defaultBody(): array
36 | {
37 | return [
38 | "partnerReferenceNo" => Uuid::uuid4(),
39 | "accountNo" => BcaConfig::get('account_id'),
40 | "bankCardToken" => BcaConfig::get('bank_card_token')
41 | ];
42 | }
43 | }
--------------------------------------------------------------------------------
/src/Services/BCA/BcaSnapApi.php:
--------------------------------------------------------------------------------
1 | object()->accessToken;
30 | }
31 |
32 | return new self;
33 | }
34 |
35 | /**
36 | * Throw error if not authenticated
37 | *
38 | * @return void
39 | */
40 | public static function authenticated()
41 | {
42 | if (!self::$token) {
43 | throw new AuthenticateException("Unauthorized: Please provide an access token", 400);
44 | }
45 | }
46 |
47 | /**
48 | * Get access token
49 | *
50 | * @return HttpResponse
51 | */
52 | public static function accessTokenB2b(): HttpResponseInterface
53 | {
54 | $path = BcaConfig::get('base_url') . "/openapi/v1.0/access-token/b2b";
55 | $headers = [
56 | 'X-TIMESTAMP' => currentTimestamp()->toIso8601String(),
57 | 'X-CLIENT-KEY' => BcaConfig::get('client_id'),
58 | 'X-SIGNATURE' => Signature::asymmetric(BcaConfig::class),
59 | ];
60 |
61 | $body = ['grantType' => 'client_credentials'];
62 | return Http::withHeaders($headers)->post($path, $body);
63 | }
64 | }
--------------------------------------------------------------------------------
/src/Services/BCA/Traits/HasTransaction.php:
--------------------------------------------------------------------------------
1 | toIso8601String();
28 | $accessToken = self::$token;
29 |
30 | $body = array_merge([
31 | "partnerReferenceNo" => Uuid::uuid4(),
32 | "accountNo" => BcaConfig::get('account_id'),
33 | "fromDateTime" => $startDate,
34 | "toDateTime" => $endDate,
35 | "bankCardToken" => BcaConfig::get('bank_card_token')
36 | ], self::$body);
37 |
38 | $headers = array_merge([
39 | 'X-TIMESTAMP' => $timestamp,
40 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
41 | 'CHANNEL-ID' => BcaConfig::get('channel_id'),
42 | 'X-PARTNER-ID' => BcaConfig::get('partner_id'),
43 | 'X-EXTERNAL-ID' => int_rand(16),
44 | ], self::$headers);
45 |
46 | $url = BcaConfig::get('base_url') . $path;
47 | return Http::withToken($accessToken)
48 | ->withHeaders($headers)
49 | ->post($url, $body);
50 | }
51 |
52 | /**
53 | * This service is used to pre-processing OneKlik Registration by Generating OneKlik Registration Web Token.
54 | *
55 | * @return HttpResponseInterface
56 | */
57 | public static function directDebitPayment(): HttpResponseInterface
58 | {
59 | // Required access token
60 | self::authenticated();
61 | $path = "/openapi/oneklik/v1.0/debit/payment-host-to-host";
62 |
63 | $timestamp = currentTimestamp()->toIso8601String();
64 | $accessToken = self::$token;
65 |
66 | $body = array_merge([
67 | "partnerReferenceNo" => Uuid::uuid4(),
68 | "accountNo" => BcaConfig::get('account_id'),
69 | "merchantId" => BcaConfig::get('partner_id'),
70 | "bankCardToken" => BcaConfig::get('bank_card_token')
71 | ], self::$body);
72 |
73 | $headers = array_merge([
74 | 'X-TIMESTAMP' => $timestamp,
75 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
76 | 'CHANNEL-ID' => BcaConfig::get('channel_id'),
77 | 'X-PARTNER-ID' => BcaConfig::get('partner_id'),
78 | 'X-EXTERNAL-ID' => int_rand(16),
79 | ], self::$headers);
80 |
81 | $url = BcaConfig::get('base_url') . $path;
82 | return Http::withToken($accessToken)
83 | ->withHeaders($headers)
84 | ->post($url, $body);
85 | }
86 |
87 | /**
88 | * This service is used to inquiry OneKlik transaction status.
89 | *
90 | * @return HttpResponseInterface
91 | */
92 | public static function directDebitPaymentStatus(): HttpResponseInterface
93 | {
94 | // Required access token
95 | self::authenticated();
96 | $path = "/openapi/oneklik/v1.0/debit/status";
97 |
98 | $timestamp = currentTimestamp()->toIso8601String();
99 | $accessToken = self::$token;
100 |
101 | $body = array_merge([
102 | "partnerReferenceNo" => Uuid::uuid4(),
103 | "serviceCode" => '54',
104 | ], self::$body);
105 |
106 | $headers = array_merge([
107 | 'X-TIMESTAMP' => $timestamp,
108 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
109 | 'CHANNEL-ID' => BcaConfig::get('channel_id'),
110 | 'X-PARTNER-ID' => BcaConfig::get('partner_id'),
111 | 'X-EXTERNAL-ID' => int_rand(16),
112 | ], self::$headers);
113 |
114 | $url = BcaConfig::get('base_url') . $path;
115 | return Http::withToken($accessToken)
116 | ->withHeaders($headers)
117 | ->post($url, $body);
118 | }
119 |
120 | /**
121 | * this is function transfer rtgs
122 | * @return HttpResponseInterface
123 | * @throws \Otnansirk\SnapBI\Exception\AuthenticateException
124 | * @throws \Otnansirk\SnapBI\Exception\HttpException
125 | */
126 | public static function transferRTGS(): HttpResponseInterface
127 | {
128 | // Required access token
129 | self::authenticated();
130 | $path = "/openapi/v1.0/transfer-rtgs";
131 |
132 | $timestamp = currentTimestamp()->toIso8601String();
133 | $accessToken = self::$token;
134 |
135 | $body = array_merge([
136 | "partnerReferenceNo" => Uuid::uuid4(),
137 | ], self::$body);
138 |
139 | $headers = array_merge([
140 | 'X-TIMESTAMP' => $timestamp,
141 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
142 | 'CHANNEL-ID' => BcaConfig::get('channel_id'),
143 | 'X-PARTNER-ID' => BcaConfig::get('partner_id'),
144 | 'X-EXTERNAL-ID' => int_rand(16),
145 | ], self::$headers);
146 |
147 | $url = BcaConfig::get('base_url') . $path;
148 | return Http::withToken($accessToken)
149 | ->withHeaders($headers)
150 | ->post($url, $body);
151 | }
152 |
153 | /**
154 | * This service is used to transfer SKNBI.
155 | * @return HttpResponseInterface
156 | * @throws \Otnansirk\SnapBI\Exception\AuthenticateException
157 | * @throws \Otnansirk\SnapBI\Exception\HttpException
158 | */
159 | public static function transferSKNBI(): HttpResponseInterface
160 | {
161 | // Required access token
162 | self::authenticated();
163 | $path = "/openapi/v1.0/transfer-skn";
164 |
165 | $timestamp = currentTimestamp()->toIso8601String();
166 | $accessToken = self::$token;
167 |
168 | $body = array_merge([
169 | "partnerReferenceNo" => Uuid::uuid4(),
170 | "sourceAccountNo" => BcaConfig::get('source_account_no')
171 | ], self::$body);
172 |
173 | $headers = array_merge([
174 | 'X-TIMESTAMP' => $timestamp,
175 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
176 | 'CHANNEL-ID' => BcaConfig::get('channel_id'),
177 | 'X-PARTNER-ID' => BcaConfig::get('partner_id'),
178 | 'X-EXTERNAL-ID' => int_rand(16),
179 | ], self::$headers);
180 |
181 | $url = BcaConfig::get('base_url') . $path;
182 | return Http::withToken($accessToken)
183 | ->withHeaders($headers)
184 | ->post($url, $body);
185 | }
186 |
187 | /**
188 | * This service is used to transfer intrabank.
189 | * means that the transfer is made within the same bank network
190 | * @return HttpResponseInterface
191 | * @throws \Otnansirk\SnapBI\Exception\AuthenticateException
192 | * @throws \Otnansirk\SnapBI\Exception\HttpException
193 | */
194 | public static function transferIntraBank(): HttpResponseInterface
195 | {
196 | // Required access token
197 | self::authenticated();
198 | $path = "/openapi/v1.0/transfer-intrabank";
199 |
200 | $timestamp = currentTimestamp()->toIso8601String();
201 | $accessToken = self::$token;
202 |
203 | $body = array_merge([
204 | "partnerReferenceNo" => Uuid::uuid4(),
205 | "sourceAccountNo" => BcaConfig::get('source_account_no'),
206 | ], self::$body);
207 |
208 | $headers = array_merge([
209 | 'X-TIMESTAMP' => $timestamp,
210 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
211 | 'CHANNEL-ID' => BcaConfig::get('channel_id'),
212 | 'X-PARTNER-ID' => BcaConfig::get('partner_id'),
213 | 'X-EXTERNAL-ID' => int_rand(16),
214 | ], self::$headers);
215 |
216 | $url = BcaConfig::get('base_url') . $path;
217 | return Http::withToken($accessToken)
218 | ->withHeaders($headers)
219 | ->post($url, $body);
220 | }
221 |
222 |
223 | /**
224 | * This service is used to transfer interbank online.
225 | * meaning that the sender uses a different Bank network to transfer to the receiver
226 | * @return HttpResponseInterface
227 | * @throws \Otnansirk\SnapBI\Exception\AuthenticateException
228 | * @throws \Otnansirk\SnapBI\Exception\HttpException
229 | */
230 | public static function transferInterBankONL(): HttpResponseInterface
231 | {
232 | // Required access token
233 | self::authenticated();
234 | $path = "/openapi/v2.0/transfer-interbank";
235 |
236 | $timestamp = currentTimestamp()->toIso8601String();
237 | $accessToken = self::$token;
238 |
239 | $body = array_merge([
240 | "partnerReferenceNo" => Uuid::uuid4(),
241 | "sourceAccountNo" => BcaConfig::get("source_account_no"),
242 | ], self::$body);
243 |
244 | $headers = array_merge([
245 | 'X-TIMESTAMP' => $timestamp,
246 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
247 | 'CHANNEL-ID' => BcaConfig::get('channel_id'),
248 | 'X-PARTNER-ID' => BcaConfig::get('partner_id'),
249 | 'X-EXTERNAL-ID' => int_rand(16),
250 | ], self::$headers);
251 |
252 | $url = BcaConfig::get('base_url') . $path;
253 | return Http::withToken($accessToken)
254 | ->withHeaders($headers)
255 | ->post($url, $body);
256 | }
257 |
258 | /**
259 | * This service is used to internal account inquiry.
260 | * @return HttpResponseInterface
261 | * @throws \Otnansirk\SnapBI\Exception\AuthenticateException
262 | * @throws \Otnansirk\SnapBI\Exception\HttpException
263 | */
264 | public static function internalAccountInquiry(): HttpResponseInterface
265 | {
266 | // Required access token
267 | self::authenticated();
268 | $path = "/openapi/v1.0/account-inquiry-internal";
269 |
270 | $timestamp = currentTimestamp()->toIso8601String();
271 | $accessToken = self::$token;
272 |
273 | $body = array_merge([
274 | "partnerReferenceNo" => Uuid::uuid4(),
275 | ], self::$body);
276 |
277 | $headers = array_merge([
278 | 'X-TIMESTAMP' => $timestamp,
279 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
280 | 'CHANNEL-ID' => BcaConfig::get('channel_id'),
281 | 'X-PARTNER-ID' => BcaConfig::get('partner_id'),
282 | 'X-EXTERNAL-ID' => int_rand(16),
283 | ], self::$headers);
284 |
285 | $url = BcaConfig::get('base_url') . $path;
286 | return Http::withToken($accessToken)
287 | ->withHeaders($headers)
288 | ->post($url, $body);
289 | }
290 |
291 | /**
292 | * This service is used to internal account inquiry.
293 | * @return HttpResponseInterface
294 | * @throws \Otnansirk\SnapBI\Exception\AuthenticateException
295 | * @throws \Otnansirk\SnapBI\Exception\HttpException
296 | */
297 | public static function accountInquiryExternal(): HttpResponseInterface
298 | {
299 | // Required access token
300 | self::authenticated();
301 | $path = "/openapi/v1.0/account-inquiry-external";
302 |
303 | $timestamp = currentTimestamp()->toIso8601String();
304 | $accessToken = self::$token;
305 |
306 | $body = array_merge([
307 | "partnerReferenceNo" => Uuid::uuid4()
308 | ], self::$body);
309 |
310 | $headers = array_merge([
311 | 'X-TIMESTAMP' => $timestamp,
312 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
313 | 'CHANNEL-ID' => BcaConfig::get('channel_id'),
314 | 'X-PARTNER-ID' => BcaConfig::get('partner_id'),
315 | 'X-EXTERNAL-ID' => int_rand(16),
316 | ], self::$headers);
317 |
318 | $url = BcaConfig::get('base_url') . $path;
319 | return Http::withToken($accessToken)
320 | ->withHeaders($headers)
321 | ->post($url, $body);
322 | }
323 |
324 | /**
325 | * This service is used to inquiry status transaction.
326 | * @return HttpResponseInterface
327 | * @throws \Otnansirk\SnapBI\Exception\AuthenticateException
328 | * @throws \Otnansirk\SnapBI\Exception\HttpException
329 | */
330 | public static function inquiryStatusTransaction(): HttpResponseInterface
331 | {
332 | // Required access token
333 | self::authenticated();
334 | $path = "/openapi/v1.0/balance-inquiry";
335 |
336 | $timestamp = currentTimestamp()->toIso8601String();
337 | $accessToken = self::$token;
338 |
339 | $body = array_merge([
340 | "originalPartnerReferenceNo" => Uuid::uuid4()
341 | ], self::$body);
342 |
343 | $headers = array_merge([
344 | 'X-TIMESTAMP' => $timestamp,
345 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
346 | 'CHANNEL-ID' => BcaConfig::get('channel_id'),
347 | 'X-PARTNER-ID' => BcaConfig::get('partner_id'),
348 | 'X-EXTERNAL-ID' => int_rand(16),
349 | ], self::$headers);
350 |
351 | $url = BcaConfig::get('base_url') . $path;
352 | return Http::withToken($accessToken)
353 | ->withHeaders($headers)
354 | ->post($url, $body);
355 | }
356 |
357 | /**
358 | * This service is used to balance inquiry.
359 | * @return HttpResponseInterface
360 | * @throws \Otnansirk\SnapBI\Exception\AuthenticateException
361 | * @throws \Otnansirk\SnapBI\Exception\HttpException
362 | */
363 | public static function balanceInquiry(): HttpResponseInterface
364 | {
365 | // Required access token
366 | self::authenticated();
367 | $path = "/openapi/v1.0/balance-inquiry";
368 |
369 | $timestamp = currentTimestamp()->toIso8601String();
370 | $accessToken = self::$token;
371 |
372 | $body = array_merge([
373 | "partnerReferenceNo" => Uuid::uuid4(),
374 | "accountNo" => BcaConfig::get('account_id'),
375 | "bankCardToken" => BcaConfig::get('bank_card_token'),
376 | ],
377 | self::$body);
378 |
379 | $headers = array_merge([
380 | 'X-TIMESTAMP' => $timestamp,
381 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
382 | 'CHANNEL-ID' => BcaConfig::get('channel_id'),
383 | 'X-PARTNER-ID' => BcaConfig::get('partner_id'),
384 | 'X-EXTERNAL-ID' => int_rand(16),
385 | ], self::$headers);
386 |
387 | $url = BcaConfig::get('base_url') . $path;
388 | return Http::withToken($accessToken)
389 | ->withHeaders($headers)
390 | ->post($url, $body);
391 | }
392 |
393 | /**
394 | * This service is used to transfer Bi fast.
395 | * @return HttpResponseInterface
396 | * @throws \Otnansirk\SnapBI\Exception\AuthenticateException
397 | * @throws \Otnansirk\SnapBI\Exception\HttpException
398 | */
399 | public static function transferBIFAST(): HttpResponseInterface
400 | {
401 | // Required access token
402 | self::authenticated();
403 | $path = "/openapi/v2.0/transfer-interbank";
404 |
405 | $timestamp = currentTimestamp()->toIso8601String();
406 | $accessToken = self::$token;
407 |
408 | $body = array_merge([
409 | "partnerReferenceNo" => Uuid::uuid4(),
410 | "sourceAccountNo" => BcaConfig::get('source_account_no'),
411 | ],
412 | self::$body);
413 |
414 | $headers = array_merge([
415 | 'X-TIMESTAMP' => $timestamp,
416 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
417 | 'CHANNEL-ID' => BcaConfig::get('channel_id'),
418 | 'X-PARTNER-ID' => BcaConfig::get('partner_id'),
419 | 'X-EXTERNAL-ID' => int_rand(16),
420 | ], self::$headers);
421 |
422 | $url = BcaConfig::get('base_url') . $path;
423 | return Http::withToken($accessToken)
424 | ->withHeaders($headers)
425 | ->post($url, $body);
426 | }
427 | }
--------------------------------------------------------------------------------
/src/Services/BCA/Traits/HasVirtualAccount.php:
--------------------------------------------------------------------------------
1 | toIso8601String();
26 | $accessToken = self::$token;
27 |
28 | $body = array_merge(BcaConfig::defaultBody(), self::$body);
29 |
30 | $headers = array_merge(
31 | BcaConfig::defaultHeaders(),
32 | [
33 | 'X-TIMESTAMP' => $timestamp,
34 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
35 | ],
36 | self::$headers
37 | );
38 |
39 | $url = BcaConfig::get('base_url') . $path;
40 | return Http::withToken($accessToken)
41 | ->withHeaders($headers)
42 | ->post($url, $body);
43 | }
44 |
45 | /**
46 | * This service is used to VA Payment Status.
47 | *
48 | * @return HttpResponseInterface
49 | */
50 | public static function vaInquiryStatus(): HttpResponseInterface
51 | {
52 | // Required access token
53 | self::authenticated();
54 | $path = "/openapi/v1.0/transfer-va/status";
55 |
56 | $timestamp = currentTimestamp()->toIso8601String();
57 | $accessToken = self::$token;
58 |
59 | $body = array_merge(BcaConfig::defaultBody(), self::$body);
60 |
61 | $headers = array_merge(
62 | BcaConfig::defaultHeaders(),
63 | [
64 | 'X-TIMESTAMP' => $timestamp,
65 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
66 | ],
67 | self::$headers
68 | );
69 |
70 | $url = BcaConfig::get('base_url') . $path;
71 | return Http::withToken($accessToken)
72 | ->withHeaders($headers)
73 | ->post($url, $body);
74 | }
75 |
76 | /**
77 | * This service is used to VA Payment Flag.
78 | *
79 | * @return HttpResponseInterface
80 | */
81 | public static function vaPayment(): HttpResponseInterface
82 | {
83 | // Required access token
84 | self::authenticated();
85 | $path = "/openapi/v1.0/transfer-va/payment";
86 |
87 | $timestamp = currentTimestamp()->toIso8601String();
88 | $accessToken = self::$token;
89 |
90 | $body = array_merge(BcaConfig::defaultBody(), self::$body);
91 |
92 | $headers = array_merge(
93 | BcaConfig::defaultHeaders(),
94 | [
95 | 'X-TIMESTAMP' => $timestamp,
96 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
97 | ],
98 | self::$headers
99 | );
100 |
101 | $url = BcaConfig::get('base_url') . $path;
102 | return Http::withToken($accessToken)
103 | ->withHeaders($headers)
104 | ->post($url, $body);
105 | }
106 |
107 | /**
108 | * This service is used to VA transfer BillPresentment.
109 | *
110 | * @return HttpResponseInterface
111 | */
112 | public static function vaInquiryIntrabank(): HttpResponseInterface
113 | {
114 | // Required access token
115 | self::authenticated();
116 | $path = "/openapi/v1.0/transfer-va/inquiry-intrabank";
117 |
118 | $timestamp = currentTimestamp()->toIso8601String();
119 | $accessToken = self::$token;
120 |
121 | $body = array_merge(BcaConfig::defaultBody(), self::$body);
122 |
123 | $headers = array_merge(
124 | BcaConfig::defaultHeaders(),
125 | [
126 | 'X-TIMESTAMP' => $timestamp,
127 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
128 | ],
129 | self::$headers
130 | );
131 |
132 | $url = BcaConfig::get('base_url') . $path;
133 | return Http::withToken($accessToken)
134 | ->withHeaders($headers)
135 | ->post($url, $body);
136 | }
137 |
138 | /**
139 | * SNAP Virtual Account Payment to VA from Intrabank
140 | * This service is used to VA transfer.
141 | *
142 | * @return HttpResponseInterface
143 | */
144 | public static function vaPayIntrabank(): HttpResponseInterface
145 | {
146 | // Required access token
147 | self::authenticated();
148 | $path = "/openapi/v1.0/transfer-va/payment-intrabank";
149 |
150 | $timestamp = currentTimestamp()->toIso8601String();
151 | $accessToken = self::$token;
152 |
153 | $body = array_merge(BcaConfig::defaultBody(), self::$body);
154 |
155 | $headers = array_merge(
156 | BcaConfig::defaultHeaders(),
157 | [
158 | 'X-TIMESTAMP' => $timestamp,
159 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
160 | ],
161 | self::$headers
162 | );
163 |
164 | $url = BcaConfig::get('base_url') . $path;
165 | return Http::withToken($accessToken)
166 | ->withHeaders($headers)
167 | ->post($url, $body);
168 | }
169 |
170 | /**
171 | * This service is used to Notification VA transfer.
172 | *
173 | * @return HttpResponseInterface
174 | */
175 | public static function vaNotifyPayIntrabank(): HttpResponseInterface
176 | {
177 | // Required access token
178 | self::authenticated();
179 | $path = "/openapi/v1.0/transfer-va/notify-payment-intrabank";
180 |
181 | $timestamp = currentTimestamp()->toIso8601String();
182 | $accessToken = self::$token;
183 |
184 | $body = array_merge(BcaConfig::defaultBody(), self::$body);
185 |
186 | $headers = array_merge(
187 | BcaConfig::defaultHeaders(),
188 | [
189 | 'X-TIMESTAMP' => $timestamp,
190 | 'X-SIGNATURE' => Signature::symmetric(BcaConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
191 | ],
192 | self::$headers
193 | );
194 |
195 | $url = BcaConfig::get('base_url') . $path;
196 | return Http::withToken($accessToken)
197 | ->withHeaders($headers)
198 | ->post($url, $body);
199 | }
200 |
201 | }
--------------------------------------------------------------------------------
/src/Services/BRI/BriConfig.php:
--------------------------------------------------------------------------------
1 | object()->accessToken;
31 | }
32 |
33 | return new self;
34 | }
35 |
36 | /**
37 | * Throw error if not authenticated
38 | *
39 | * @return void
40 | */
41 | public static function authenticated()
42 | {
43 | if (!self::$token) {
44 | throw new AuthenticateException("Unauthorized: Please provide an access token", 400);
45 | }
46 | }
47 |
48 | /**
49 | * Get access token
50 | *
51 | * @return HttpResponse
52 | */
53 | public static function accessTokenB2b(): HttpResponseInterface
54 | {
55 | $carbon = Carbon::now('Asia/Jakarta');
56 | $timestamp = $carbon->format('Y-m-d\TH:i:s.000P'); // outputs: 2021-11-02T13:14:15.000+07:00
57 | $path = BriConfig::get('base_url') . "/snap/v1.0/access-token/b2b";
58 | $headers = [
59 | 'X-TIMESTAMP' => $timestamp,
60 | 'X-CLIENT-KEY' => BriConfig::get('client_id'),
61 | 'X-SIGNATURE' => Signature::asymmetricBri(BriConfig::class,$timestamp),
62 | ];
63 |
64 | $body = ['grantType' => 'client_credentials'];
65 | return Http::withHeaders($headers)->post($path, $body);
66 | }
67 | }
--------------------------------------------------------------------------------
/src/Services/BRI/Traits/HasTransaction.php:
--------------------------------------------------------------------------------
1 | toIso8601String();
28 | $accessToken = self::$token;
29 |
30 | $body = array_merge([
31 | "partnerReferenceNo" => Uuid::uuid4(),
32 | "accountNo" => BriConfig::get('account_id'),
33 | "fromDateTime" => $startDate,
34 | "toDateTime" => $endDate,
35 | "bankCardToken" => BriConfig::get('bank_card_token')
36 | ], self::$body);
37 |
38 | $headers = array_merge([
39 | 'X-TIMESTAMP' => $timestamp,
40 | 'X-SIGNATURE' => Signature::symmetric(BriConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
41 | 'CHANNEL-ID' => BriConfig::get('channel_id'),
42 | 'X-PARTNER-ID' => BriConfig::get('partner_id'),
43 | 'X-EXTERNAL-ID' => int_rand(16),
44 | ], self::$headers);
45 |
46 | $url = BriConfig::get('base_url') . $path;
47 | return Http::withToken($accessToken)
48 | ->withHeaders($headers)
49 | ->post($url, $body);
50 | }
51 | }
--------------------------------------------------------------------------------
/src/Services/Config.php:
--------------------------------------------------------------------------------
1 | BcaConfig::class,
22 | 'mandiri' => MandiriConfig::class,
23 | 'dana' => DanaConfig::class,
24 | // Register new config
25 | ];
26 | }
27 |
28 | /**
29 | * Getting config by name
30 | * Currently support for
31 | * bca, mandiri, bri
32 | *
33 | * @param string $name
34 | * @return ConfigInterface
35 | */
36 | static function for (string $name): ConfigInterface
37 | {
38 | if (isset(self::registeredConfig()[$name])) {
39 | return self::registeredConfig()[$name]::call();
40 | }
41 |
42 | throw new SnapBiException("SNAP config for $name is not registered");
43 | }
44 |
45 | /**
46 | * If call an inaccessible static method of a class
47 | * will automatically invoke the __callStatic()
48 | * and return Config by method name
49 | *
50 | * @param string $method
51 | * @param array|null $args
52 | * @return ConfigInterface
53 | */
54 | static function __callStatic(string $method, array $args = null): ConfigInterface
55 | {
56 | if ($args) {
57 | self::for($method)->register($args[0]);
58 | }
59 | return self::for($method);
60 | }
61 |
62 | }
--------------------------------------------------------------------------------
/src/Services/DANA/DanaConfig.php:
--------------------------------------------------------------------------------
1 | object()->accessToken;
31 | }
32 |
33 | return new self;
34 | }
35 |
36 | /**
37 | * Throw error if not authenticated
38 | *
39 | * @return void
40 | */
41 | public static function authenticated()
42 | {
43 | if (!self::$token) {
44 | throw new AuthenticateException("Unauthorized: Please provide an access token", 400);
45 | }
46 | }
47 |
48 | /**
49 | * Get access token
50 | *
51 | * @return HttpResponse
52 | */
53 | public static function accessTokenB2b(): HttpResponseInterface
54 | {
55 | $path = DanaConfig::get('base_url') . "/v1.0/access-token/b2b.htm";
56 | $headers = [
57 | 'X-TIMESTAMP' => currentTimestamp()->toIso8601String(),
58 | 'X-CLIENT-KEY' => DanaConfig::get('client_id'),
59 | 'X-SIGNATURE' => Signature::asymmetric(DanaConfig::class),
60 | ];
61 |
62 | $body = ['grantType' => 'client_credentials'];
63 | return Http::withHeaders($headers)->post($path, $body);
64 | }
65 |
66 | /**
67 | * Get oAuth url
68 | *
69 | * @param array $params
70 | * @param array $data
71 | * @param bool $sign
72 | *
73 | * @inheritDoc https://dashboard.dana.id/api-docs/read/125
74 | */
75 | public static function oAuthUrl(array $params = [], array $data = [], bool $sign = false)
76 | {
77 | $seamlessData = count($data)
78 | ? ['seamlessData' => json_encode($data)]
79 | : [];
80 |
81 | $seamlessSign = $sign
82 | ? ['seamlessSign' => Signature::signSHA256withRSA(DanaConfig::class, $data)]
83 | : [];
84 |
85 | $queryParams = [
86 | 'timestamp' => currentTimestamp()->toIso8601String(),
87 | 'partnerId' => DanaConfig::get('partner_id'),
88 | 'externalId' => Uuid::uuid4()->toString(),
89 | 'channelId' => DanaConfig::get('channel_id'),
90 | 'state' => int_rand(32),
91 | 'scopes' => 'QUERY_BALANCE,PUBLIC_ID',
92 | 'redirectUrl' => DanaConfig::get('redirect_url'),
93 | ...$params,
94 | ...$seamlessData,
95 | ...$seamlessSign
96 | ];
97 | return DanaConfig::get('web_url') . "/v1.0/get-auth-code?" . http_build_query($queryParams);
98 | }
99 | }
--------------------------------------------------------------------------------
/src/Services/DANA/Traits/HasTransaction.php:
--------------------------------------------------------------------------------
1 | toIso8601String();
29 | $accessToken = self::$token;
30 |
31 | $body = array_merge([
32 | "partnerReferenceNo" => Uuid::uuid4(),
33 | "merchantId" => DanaConfig::get('account_id'),
34 | ], self::$body);
35 |
36 | $headers = array_merge([
37 | 'X-TIMESTAMP' => $timestamp,
38 | 'X-SIGNATURE' => Signature::danaAsymetricTransaction(DanaConfig::class, 'POST', $path, $body, $timestamp),
39 | 'CHANNEL-ID' => DanaConfig::get('channel_id'),
40 | 'X-PARTNER-ID' => DanaConfig::get('partner_id'),
41 | 'X-EXTERNAL-ID' => int_rand(16),
42 | ], self::$headers);
43 |
44 | $url = DanaConfig::get('base_url') . $path;
45 | return Http::withToken($accessToken)
46 | ->withHeaders($headers)
47 | ->post($url, $body);
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Services/Mandiri/MandiriConfig.php:
--------------------------------------------------------------------------------
1 | object()->accessToken;
30 | }
31 |
32 | return new self;
33 | }
34 |
35 | /**
36 | * Throw error if not authenticated
37 | *
38 | * @return void
39 | */
40 | public static function authenticated()
41 | {
42 | if (!self::$token) {
43 | throw new AuthenticateException("Unauthorized: Please provide an access token", 400);
44 | }
45 | }
46 |
47 | /**
48 | * Get access token
49 | *
50 | * @return HttpResponse
51 | */
52 | public static function accessTokenB2b(): HttpResponseInterface
53 | {
54 | $path = MandiriConfig::get('base_url') . "/openapi/auth/v2.0/access-token/b2b";
55 | $headers = [
56 | 'X-TIMESTAMP' => currentTimestamp()->toIso8601String(),
57 | 'X-CLIENT-KEY' => MandiriConfig::get('client_id'),
58 | 'X-SIGNATURE' => Signature::asymmetric(MandiriConfig::class),
59 | ];
60 |
61 | $body = ['grantType' => 'client_credentials'];
62 | return Http::withHeaders($headers)->post($path, $body);
63 | }
64 | }
--------------------------------------------------------------------------------
/src/Services/Mandiri/Traits/HasTransaction.php:
--------------------------------------------------------------------------------
1 | toIso8601String();
28 | $accessToken = self::$token;
29 |
30 | $body = array_merge([
31 | "partnerReferenceNo" => Uuid::uuid4(),
32 | "accountNo" => MandiriConfig::get('account_id'),
33 | "fromDateTime" => $startDate,
34 | "toDateTime" => $endDate,
35 | "bankCardToken" => MandiriConfig::get('bank_card_token')
36 | ], self::$body);
37 |
38 | $headers = array_merge([
39 | 'X-TIMESTAMP' => $timestamp,
40 | 'X-SIGNATURE' => Signature::symmetric(MandiriConfig::class, 'POST', $path, $body, $timestamp, $accessToken),
41 | 'CHANNEL-ID' => MandiriConfig::get('channel_id'),
42 | 'X-PARTNER-ID' => MandiriConfig::get('partner_id'),
43 | 'X-EXTERNAL-ID' => int_rand(16),
44 | ], self::$headers);
45 |
46 | $url = MandiriConfig::get('base_url') . $path;
47 | return Http::withToken($accessToken)
48 | ->withHeaders($headers)
49 | ->post($url, $body);
50 | }
51 | }
--------------------------------------------------------------------------------
/src/Services/SnapBi.php:
--------------------------------------------------------------------------------
1 | BcaSnapApi::class,
22 | 'mandiri' => MandiriSnapApi::class,
23 | 'dana' => DanaSnapApi::class,
24 | // Register new SnapApi
25 | ];
26 | }
27 |
28 | /**
29 | * Getting config by name
30 | * Currently support for
31 | * bca, mandiri, bri
32 | *
33 | * @param string $name
34 | * @return SnapApiInterface
35 | */
36 | static function for (string $name): SnapApiInterface
37 | {
38 | if (isset(self::registeredSnapApi()[$name])) {
39 | return self::registeredSnapApi()[$name]::call();
40 | }
41 |
42 | throw new SnapBiException("SNAP BI for $name is not registered");
43 | }
44 | /**
45 | * If call an inaccessible static method of a class
46 | * will automatically invoke the __callStatic()
47 | * and return SnapApi by method name
48 | *
49 | * @param string $method
50 | * @param array|null $args
51 | * @return SnapApiInterface
52 | */
53 | static function __callStatic(string $method, array $args = null): SnapApiInterface
54 | {
55 | return self::for($method);
56 | }
57 |
58 | }
--------------------------------------------------------------------------------
/src/Support/Http.php:
--------------------------------------------------------------------------------
1 | $url,
105 | CURLOPT_HTTPHEADER => $curlHeaders,
106 | CURLOPT_RETURNTRANSFER => true,
107 | CURLOPT_HEADER => true,
108 | CURLOPT_CUSTOMREQUEST => strtoupper($method),
109 | CURLOPT_POSTFIELDS => json_encode($body)
110 | );
111 | curl_setopt_array($ch, $curlOptions);
112 |
113 | $response = curl_exec($ch);
114 | curl_close($ch);
115 |
116 | // Get http status code info
117 | $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
118 |
119 | return new HttpResponse($response, $httpCode);
120 |
121 | } catch (\Throwable $th) {
122 | throw new HttpException("Error when request API");
123 | }
124 | }
125 |
126 | /**
127 | * Format array header to cUrl header
128 | *
129 | * @param array $headers
130 | * @return array
131 | */
132 | public static function headerFormated(array $headers): array
133 | {
134 |
135 | $result = array();
136 | foreach ($headers as $key => $value) {
137 | $result[] = $key . ':' . $value;
138 | }
139 | return $result;
140 | }
141 | }
--------------------------------------------------------------------------------
/src/Support/HttpResponse.php:
--------------------------------------------------------------------------------
1 | body = $body;
20 | $this->status = $statusCode;
21 | $this->headers = $headers;
22 | }
23 |
24 | /**
25 | * Get body as is
26 | *
27 | * @return string
28 | */
29 | function body(): string
30 | {
31 | return $this->body;
32 | }
33 |
34 | /**
35 | * Get status code
36 | *
37 | * @return integer
38 | */
39 | function status(): int
40 | {
41 | return $this->status;
42 | }
43 |
44 | /**
45 | * Get body as object
46 | *
47 | * @return object
48 | */
49 | function object(): object
50 | {
51 | return json_decode($this->body);
52 | }
53 |
54 | /**
55 | * Get body as array
56 | *
57 | * @return array
58 | */
59 | function array(): array
60 | {
61 | return json_decode($this->body, true);
62 | }
63 |
64 | /**
65 | * Get headers response
66 | *
67 | * @return array
68 | */
69 | function headers(): array
70 | {
71 | $headers = explode("\r\n", $this->headers);
72 |
73 | $headerArr = array();
74 | foreach ($headers as $headerLine) {
75 | list($key, $value) = explode(': ', $headerLine, 2);
76 | $headerArr[$key] = $value;
77 | }
78 | return $headerArr;
79 | }
80 |
81 | /**
82 | * Check is status code not in range 200 - 299
83 | *
84 | * @return boolean
85 | */
86 | function failed(): bool
87 | {
88 | return !(($this->status >= 200) && ($this->status < 300));
89 | }
90 | }
--------------------------------------------------------------------------------
/src/Support/Signature.php:
--------------------------------------------------------------------------------
1 | toIso8601String();
19 |
20 | $signature = "";
21 | if (!openssl_sign($stringToSign, $signature, $privateKey, OPENSSL_ALGO_SHA256)) {
22 | throw new SignatureException("Failed to generate signature");
23 | }
24 |
25 | // X-SIGNATURE
26 | return base64_encode($signature);
27 | }
28 |
29 | final public static function asymmetricBri(string $config,$timestamp) : String {
30 | $privateKey = $config::get('ssh_private_key');
31 | $stringToSign = $config::get('client_id').'|'.$timestamp;
32 | $signature = "";
33 | if (!openssl_sign($stringToSign, $signature, $privateKey, OPENSSL_ALGO_SHA256)) {
34 | throw new SignatureException("Failed to generate signature");
35 | }
36 |
37 | // X-SIGNATURE
38 | return base64_encode($signature);
39 | }
40 |
41 | /**
42 | * Generate signature symmetric
43 | *
44 | * @param string $config
45 | * @param string $method
46 | * @param string $path
47 | * @param array $body
48 | * @param string $timestamp
49 | * @param string $accessToken
50 | * @return string
51 | */
52 | final public static function symmetric(
53 | string $config,
54 | string $method,
55 | string $path,
56 | array $body,
57 | string $timestamp,
58 | string $accessToken
59 | ): string {
60 | // Body minify
61 | $hashBody = json_encode($body);
62 |
63 | // Calculate Hash with sha256
64 | $hashBody = hash('sha256', $hashBody);
65 |
66 | // Convert to lowercase
67 | $signedBody = strtolower($hashBody);
68 |
69 | $stringToSign = implode(':', [
70 | $method,
71 | $path,
72 | $accessToken,
73 | $signedBody,
74 | $timestamp
75 | ]);
76 |
77 | $signature = hash_hmac('sha512', $stringToSign, $config::get('client_secret'), true);
78 |
79 | // X-SIGNATURE
80 | return base64_encode($signature);
81 | }
82 |
83 | /**
84 | * Generate dana signature for transaction
85 | *
86 | * @param string $config
87 | * @param string $method
88 | * @param string $path
89 | * @param array $body
90 | * @param string $timestamp
91 | * @return string
92 | */
93 | final public static function danaAsymetricTransaction(
94 | string $config,
95 | string $method,
96 | string $path,
97 | array $body,
98 | string $timestamp
99 | ): string {
100 | $privateKey = $config::get('ssh_private_key');
101 |
102 | // Body minify
103 | $hashBody = json_encode($body);
104 |
105 | // Calculate Hash with sha256
106 | $hashBody = hash('sha256', $hashBody);
107 |
108 | // Convert to lowercase
109 | $signedBody = strtolower($hashBody);
110 |
111 | $stringToSign = implode(':', [
112 | $method,
113 | $path,
114 | $signedBody,
115 | $timestamp
116 | ]);
117 |
118 | $signature = "";
119 | if (!openssl_sign($stringToSign, $signature, $privateKey, OPENSSL_ALGO_SHA256)) {
120 | throw new SignatureException("Failed to generate signature");
121 | }
122 |
123 | // X-SIGNATURE
124 | return base64_encode($signature);
125 | }
126 |
127 | /**
128 | * Sign the seamlessData with generated privateKey and algorithm SHA256withRSA
129 | *
130 | * @param string $config
131 | * @param array $body
132 | * @return string
133 | */
134 | final public static function signSHA256withRSA(string $config, array $body): string
135 | {
136 |
137 | $privateKey = $config::get('ssh_private_key');
138 | $signature = "";
139 | if (!openssl_sign(json_encode($body), $signature, $privateKey, OPENSSL_ALGO_SHA256)) {
140 | throw new SignatureException("Failed to generate signature");
141 | }
142 | return base64_encode($signature);
143 | }
144 | }
--------------------------------------------------------------------------------
/src/Traits/HasConfig.php:
--------------------------------------------------------------------------------
1 | timezone($timezone);
18 | }
19 | }
20 |
21 | if (!function_exists('int_rand')) {
22 | /**
23 | * Random integer only
24 | *
25 | * @param int $length
26 | * @return string
27 | */
28 | function int_rand(int $length): string
29 | {
30 | $result = '';
31 | for ($i = 0; $i < $length; $i++) {
32 | $result .= mt_rand(0, 9);
33 | }
34 | return $result;
35 | }
36 | }
--------------------------------------------------------------------------------
/tests/Fixtures/Fixture.example.php:
--------------------------------------------------------------------------------
1 | "a82ed8bf-493a-4133-ba01-08129e3w8432",
20 | "client_secret" => "a82ed8bf-493a-4133-ba01-08129e3w8432",
21 | "ssh_private_key" => << << "UAYCORQ011",
63 | "account_id" => "0643002227",
64 | "bank_card_token" => "1234567890",
65 | "channel_id" => "92221",
66 | "base_url" => "https://api.api.com",
67 | ];
68 | }
69 | }
--------------------------------------------------------------------------------
/tests/Unit/ConfigTest.php:
--------------------------------------------------------------------------------
1 | expectException(\Otnansirk\SnapBI\Exception\SnapBiException::class);
11 | Config::bank(Fixture::configFixture());
12 | }
13 | function testThrowInvalidArgumentException()
14 | {
15 | $this->expectException(\InvalidArgumentException::class);
16 | Config::bca([]);
17 | }
18 |
19 | function testRegister()
20 | {
21 | Config::bca(Fixture::configFixture());
22 | $this->assertArrayHasKey("client_id", Config::bca()->all());
23 | $this->assertArrayHasKey("client_id", Config::for('bca')->all());
24 | }
25 |
26 | function testGet()
27 | {
28 | $this->assertArrayHasKey("client_id", Config::bca()->all());
29 | $this->assertArrayHasKey("client_id", Config::for('bca')->all());
30 | }
31 | function testAll()
32 | {
33 | $this->assertNotEmpty(Config::bca()->all());
34 | $this->assertNotEmpty(Config::for('bca')->all());
35 | }
36 | }
--------------------------------------------------------------------------------
/tests/Unit/SignatureTest.php:
--------------------------------------------------------------------------------
1 | assertIsString($res);
15 | $this->assertNotEmpty($res);
16 | }
17 |
18 | function testSymmetric()
19 | {
20 | Config::bca(Fixture::configFixture());
21 | $res = Signature::symmetric(
22 | Config::bca()::class,
23 | 'POST',
24 | '/api/path',
25 | ['name' => 'otnansirk'],
26 | currentTimestamp(),
27 | 'accessToken'
28 | );
29 |
30 | $this->assertIsString($res);
31 | $this->assertNotEmpty($res);
32 | }
33 | }
--------------------------------------------------------------------------------
/tests/Unit/SupportHttpTest.php:
--------------------------------------------------------------------------------
1 | ["Authorization " => "Bearer Shdjdxsw"],
11 | "response" => "Authorization :Bearer Shdjdxsw"
12 | ];
13 |
14 | $res = Http::headerFormated($cases['request']);
15 |
16 | $this->assertEquals($cases['response'], $res[0]);
17 | $this->assertIsArray($res);
18 | }
19 |
20 | function testWithToken()
21 | {
22 | $res = Http::withToken('qwerty');
23 | $this->assertInstanceOf(Http::class, $res);
24 | }
25 | }
--------------------------------------------------------------------------------