PHPackages                             pakailink/pakailink-sdk - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Payment Processing](/categories/payments)
4. /
5. pakailink/pakailink-sdk

ActiveLibrary[Payment Processing](/categories/payments)

pakailink/pakailink-sdk
=======================

PakaiLink Payment Gateway SDK for Laravel - SNAP compliant payment integration

v1.0.0(5mo ago)00MITPHPPHP ^8.3

Since Dec 9Pushed 5mo agoCompare

[ Source](https://github.com/pakailink/pakailink-sdk)[ Packagist](https://packagist.org/packages/pakailink/pakailink-sdk)[ RSS](/packages/pakailink-pakailink-sdk/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (6)Versions (2)Used By (0)

PakaiLink SDK for Laravel
=========================

[](#pakailink-sdk-for-laravel)

A comprehensive Laravel package for integrating with PakaiLink Payment Gateway. This SDK provides SNAP-compliant payment processing for Indonesian payment methods including Virtual Accounts, QRIS, E-Wallets, and Bank Transfers.

Features
--------

[](#features)

- ✅ **Easy Installation** - Install via Composer with automatic service provider discovery
- ✅ **SNAP Compliant** - Follows Standard National API Payment specification
- ✅ **Multiple Payment Methods** - VA, QRIS, E-Wallet, Retail, Bank Transfer
- ✅ **Dual Signature** - RSA-SHA256 (asymmetric) and HMAC-SHA512 (symmetric)
- ✅ **Token Management** - Automatic B2B token generation with caching
- ✅ **Retry Logic** - Automatic retry for network failures
- ✅ **Comprehensive Logging** - Detailed logging for debugging
- ✅ **Type Safe** - Full PHP 8.4 type hints and enums
- ✅ **Exception Handling** - Custom exceptions for different error types
- ✅ **Flexible Configuration** - Support for both camelCase and snake\_case keys

Requirements
------------

[](#requirements)

- PHP 8.4+
- Laravel 12.0+
- ext-openssl (for RSA signatures)
- ext-json

Installation
------------

[](#installation)

### Step 1: Install Package

[](#step-1-install-package)

Install the package via Composer:

```
composer require pakailink/pakailink-sdk
```

The service provider will be automatically discovered and registered by Laravel.

> **Note:** For local development, you may need to add the local repository to your `composer.json`:
>
> ```
> {
>     "repositories": [
>         {
>             "type": "path",
>             "url": "packages/pakailink/pakailink-sdk",
>             "options": {
>                 "symlink": true
>             }
>         }
>     ]
> }
> ```

### Step 2: Publish Configuration

[](#step-2-publish-configuration)

Publish the configuration file to your application:

```
php artisan vendor:publish --tag=pakailink
```

This will create `config/pakailink.php` in your application.

### Step 3: Configure Environment

[](#step-3-configure-environment)

Add to your `.env` file:

```
PAKAILINK_ENV=sandbox
PAKAILINK_BASE_URL=https://rising-dev.pakailink.id
PAKAILINK_CLIENT_ID=your_client_id
PAKAILINK_CLIENT_SECRET=your_client_secret
PAKAILINK_PARTNER_ID=your_partner_id
PAKAILINK_MERCHANT_ID=your_merchant_id
PAKAILINK_CHANNEL_ID=your_channel_id
PAKAILINK_PRIVATE_KEY_PATH=storage/keys/pakailink_private.pem
PAKAILINK_PUBLIC_KEY_PATH=storage/keys/pakailink_public.pem
```

### Step 4: Generate RSA Keys

[](#step-4-generate-rsa-keys)

```
# Generate private key
openssl genrsa -out storage/keys/pakailink_private.pem 2048

# Generate public key
openssl rsa -in storage/keys/pakailink_private.pem -pubout -out storage/keys/pakailink_public.pem

# Set permissions
chmod 400 storage/keys/pakailink_private.pem
chmod 444 storage/keys/pakailink_public.pem
```

Quick Start
-----------

[](#quick-start)

After installation and configuration, you can immediately start using the SDK:

```
use PakaiLink\Services\PakaiLinkService;

// Get account balance
$service = app(PakaiLinkService::class);
$balance = $service->getBalance();

echo "Current Balance: " . $balance['accountInfos'][0]['balanceAmount']['value'];
```

For specific payment methods, see the detailed usage examples below.

Usage
-----

[](#usage)

### Basic Service Access

[](#basic-service-access)

```
use PakaiLink\Services\PakaiLinkService;

// Get balance
$service = app(PakaiLinkService::class);
$balance = $service->getBalance();

// Get balance history
$history = $service->getBalanceHistory(
    startDate: '2025-01-01',
    endDate: '2025-01-31',
    page: 1,
    limit: 100
);
```

### Virtual Account Service

[](#virtual-account-service)

```
use PakaiLink\Services\PakaiLinkVirtualAccountService;
use PakaiLink\Data\CreateVirtualAccountData;

$service = app(PakaiLinkVirtualAccountService::class);

// Create Virtual Account
$data = CreateVirtualAccountData::from([
    'amount' => 100000,
    'customer_name' => 'John Doe',
    'bank_code' => '002', // BRI
]);

$response = $service->create($data);
// Returns: ['virtualAccountData' => ['virtualAccountNo' => '8808...', ...]]

// Inquiry VA Status
$status = $service->inquiryStatus($vaNumber, $inquiryRequestId);

// Update VA
$service->update($vaNumber, $trxId, 'U', 150000);

// Delete VA
$service->delete($vaNumber, $trxId);
```

### QRIS Service

[](#qris-service)

```
use PakaiLink\Services\PakaiLinkQrisService;
use PakaiLink\Data\GenerateQrisData;

$service = app(PakaiLinkQrisService::class);

// Generate QRIS QR Code
$data = GenerateQrisData::from([
    'merchant_id' => config('pakailink.credentials.merchant_id'),
    'amount' => 50000,
    'terminal_id' => 'TERM001', // Optional
    'validity_period' => '30', // Optional: minutes or Carbon instance
]);

$response = $service->generateQris($data);
// Returns: ['qrContent' => '...', 'originalPartnerReferenceNo' => '...', ...]

// Inquiry QRIS Status
$status = $service->inquiryStatus($partnerReferenceNo);

// Refund QRIS Transaction
$refund = $service->refund($partnerReferenceNo, 50000, 'Customer request');
```

### Bank Transfer Service

[](#bank-transfer-service)

```
use PakaiLink\Services\PakaiLinkTransferService;
use PakaiLink\Data\TransferToBankData;

$service = app(PakaiLinkTransferService::class);

// Inquiry bank account (verify before transfer)
$data = TransferToBankData::from([
    'beneficiary_bank_code' => '008', // Mandiri
    'beneficiary_account_no' => '1234567890',
    'beneficiary_account_name' => 'Jane Smith',
    'amount' => 100000,
]);

$inquiry = $service->inquiryTransfer($data);

// Execute transfer
$transfer = $service->transferToBank($data);

// Check transfer status
$status = $service->inquiryStatus($partnerReferenceNo);

// Transfer to VA
$vaTransfer = $service->transferToVA(
    beneficiaryVirtualAccountNo: '8808123456789012',
    beneficiaryBankCode: '002',
    amount: 100000
);
```

### E-money/E-wallet Service

[](#e-moneye-wallet-service)

```
use PakaiLink\Services\PakaiLinkEmoneyService;
use PakaiLink\Data\CreateEmoneyPaymentData;

$service = app(PakaiLinkEmoneyService::class);

// Create E-wallet Payment
$data = CreateEmoneyPaymentData::from([
    'channel_id' => 'PAYGOPAY', // GoPay
    'amount' => 75000,
    'customer_name' => 'Bob Wilson',
    'customer_phone' => '081234567890',
]);

$response = $service->createPayment($data);
// Returns: ['webRedirectUrl' => '...', 'referenceNo' => '...']

// Inquiry E-money Status
$status = $service->inquiryStatus($partnerReferenceNo);

// Refund E-money Transaction
$refund = $service->refund($partnerReferenceNo, 75000);
```

### HTTP Client

[](#http-client)

```
use PakaiLink\Services\PakaiLinkHttpClient;

$client = app(PakaiLinkHttpClient::class);

// Make authenticated POST request
$response = $client->post('/api/v1.0/endpoint', [
    'key' => 'value',
]);

// Make GET request
$response = $client->get('/api/v1.0/endpoint', [
    'param' => 'value',
]);
```

### Signature Service

[](#signature-service)

```
use PakaiLink\Services\PakaiLinkSignatureService;

$service = app(PakaiLinkSignatureService::class);

// Generate asymmetric signature (for B2B token)
$signature = $service->generateAsymmetricSignature(
    clientId: 'your_client_id',
    timestamp: now()->toIso8601String()
);

// Generate symmetric signature (for API requests)
$signature = $service->generateSymmetricSignature(
    httpMethod: 'POST',
    endpointUrl: '/api/v1.0/endpoint',
    accessToken: 'your_token',
    requestBody: '{"key":"value"}',
    timestamp: now()->toIso8601String()
);

// Validate callback signature
$isValid = $service->validateCallbackSignature(
    receivedSignature: $request->header('X-SIGNATURE'),
    requestBody: $request->getContent(),
    timestamp: $request->header('X-TIMESTAMP')
);
```

### Authentication Service

[](#authentication-service)

```
use PakaiLink\Services\PakaiLinkAuthService;

$service = app(PakaiLinkAuthService::class);

// Get B2B access token (cached)
$token = $service->getB2BAccessToken();

// Refresh token
$newToken = $service->refreshToken();

// Check if token is expired
if ($service->isTokenExpired()) {
    // Token needs refresh
}

// Clear cached token
$service->clearToken();
```

Payment Methods Supported
-------------------------

[](#payment-methods-supported)

MethodCodeDescriptionVirtual Account`002`, `008`, `009`, etc.13 banks supportedQRIS`QRIS`Dynamic &amp; Static QR paymentsE-Wallet`PAYGOPAY`, `PAYOVO`, etc.5 providers (GoPay, OVO, DANA, ShopeePay, LinkAja)Bank Transfer`002`-`950`117 banks supportedRetail Payment`ALFAMART`, `INDOMARET`2 storesEnums
-----

[](#enums)

### Transaction Types

[](#transaction-types)

```
use PakaiLink\Enums\PakaiLinkTransactionType;

PakaiLinkTransactionType::VIRTUAL_ACCOUNT
PakaiLinkTransactionType::QRIS
PakaiLinkTransactionType::EWALLET
PakaiLinkTransactionType::RETAIL
PakaiLinkTransactionType::TRANSFER_BANK
PakaiLinkTransactionType::TRANSFER_VA
PakaiLinkTransactionType::TOP_UP
PakaiLinkTransactionType::BALANCE_INQUIRY
```

### Transaction Status

[](#transaction-status)

```
use PakaiLink\Enums\PakaiLinkTransactionStatus;

PakaiLinkTransactionStatus::PENDING
PakaiLinkTransactionStatus::PROCESSING
PakaiLinkTransactionStatus::SUCCESS
PakaiLinkTransactionStatus::FAILED
PakaiLinkTransactionStatus::EXPIRED
PakaiLinkTransactionStatus::CANCELLED
```

### Bank Codes

[](#bank-codes)

```
use PakaiLink\Enums\PakaiLinkBankCode;

PakaiLinkBankCode::BRI->value         // '002'
PakaiLinkBankCode::MANDIRI->value     // '008'
PakaiLinkBankCode::BNI->value         // '009'
PakaiLinkBankCode::BCA->value         // '014'

// Get label
PakaiLinkBankCode::BRI->getLabel()    // 'Bank BRI'

// Check type
PakaiLinkBankCode::BSI->isSyariah()   // true
PakaiLinkBankCode::JAGO->isDigital()  // true
```

Exceptions
----------

[](#exceptions)

All exceptions extend `PakaiLink\Exceptions\PakaiLinkException`:

```
use PakaiLink\Exceptions\PakaiLinkException;
use PakaiLink\Exceptions\PakaiLinkAuthenticationException;
use PakaiLink\Exceptions\PakaiLinkSignatureException;
use PakaiLink\Exceptions\PakaiLinkValidationException;
use PakaiLink\Exceptions\PakaiLinkTransactionException;

try {
    $service->getBalance();
} catch (PakaiLinkAuthenticationException $e) {
    // Handle auth errors
} catch (PakaiLinkException $e) {
    // Handle other PakaiLink errors
    $context = $e->getContext();
}
```

Configuration
-------------

[](#configuration)

The package uses `config/pakailink.php` for configuration. Key settings:

```
return [
    'env' => env('PAKAILINK_ENV', 'sandbox'),
    'base_url' => env('PAKAILINK_BASE_URL'),

    'credentials' => [
        'client_id' => env('PAKAILINK_CLIENT_ID'),
        'client_secret' => env('PAKAILINK_CLIENT_SECRET'),
        'partner_id' => env('PAKAILINK_PARTNER_ID'),
        'merchant_id' => env('PAKAILINK_MERCHANT_ID'),
        'channel_id' => env('PAKAILINK_CHANNEL_ID'),
    ],

    'keys' => [
        'private_key_path' => base_path(env('PAKAILINK_PRIVATE_KEY_PATH')),
        'public_key_path' => base_path(env('PAKAILINK_PUBLIC_KEY_PATH')),
    ],

    'timeout' => env('PAKAILINK_TIMEOUT', 30),
    'retry_times' => env('PAKAILINK_RETRY_TIMES', 3),
    'retry_delay' => env('PAKAILINK_RETRY_DELAY', 1000),

    'cache' => [
        'token_ttl' => 840, // 14 minutes
        'token_key' => 'pakailink:access_token',
    ],
];
```

Logging
-------

[](#logging)

The package logs all activities to the `pakailink` channel:

```
// config/logging.php
'pakailink' => [
    'driver' => 'daily',
    'path' => storage_path('logs/payments/pakailink.log'),
    'level' => env('LOG_LEVEL', 'debug'),
    'days' => 90,
],
```

Architecture
------------

[](#architecture)

```
PakaiLink\Services\PakaiLinkService (Main)
├── PakaiLinkHttpClient (Authenticated requests)
│   ├── PakaiLinkAuthService (Token management)
│   │   └── PakaiLinkSignatureService (Asymmetric RSA)
│   └── PakaiLinkSignatureService (Symmetric HMAC)
└── Balance Operations

```

Security
--------

[](#security)

### RSA Keys

[](#rsa-keys)

- Private key used for B2B token request signatures (RSA-SHA256)
- Public key uploaded to PakaiLink dashboard
- Keys stored in `storage/keys/` with restrictive permissions
- Keys excluded from version control

### Signatures

[](#signatures)

- **Asymmetric (RSA-SHA256):** For B2B access token requests
- **Symmetric (HMAC-SHA512):** For all other API requests
- **Callback Validation:** HMAC-SHA512 with timing-safe comparison

### Token Caching

[](#token-caching)

- Access tokens cached for 14 minutes (expire in 15 minutes)
- Automatic refresh on expiry
- Cache key: `pakailink:access_token`

Testing
-------

[](#testing)

```
# Test service resolution
php artisan tinker
>>> $service = app(\PakaiLink\Services\PakaiLinkService::class);
>>> $balance = $service->getBalance();

# Test signature generation
>>> $sig = app(\PakaiLink\Services\PakaiLinkSignatureService::class);
>>> $signature = $sig->generateSymmetricSignature(...);
```

Error Handling
--------------

[](#error-handling)

```
use PakaiLink\Exceptions\PakaiLinkException;
use Illuminate\Support\Facades\Log;

try {
    $result = $client->post('/api/v1.0/endpoint', $data);
} catch (PakaiLinkException $e) {
    Log::error('PakaiLink error', [
        'message' => $e->getMessage(),
        'code' => $e->getCode(),
        'context' => $e->getContext(),
    ]);

    // Handle error
}
```

Package Structure
-----------------

[](#package-structure)

```
packages/pakailink/pakailink-sdk/
├── src/
│   ├── Services/
│   │   ├── PakaiLinkSignatureService.php
│   │   ├── PakaiLinkAuthService.php
│   │   ├── PakaiLinkHttpClient.php
│   │   └── PakaiLinkService.php
│   ├── Exceptions/
│   │   ├── PakaiLinkException.php
│   │   ├── PakaiLinkAuthenticationException.php
│   │   ├── PakaiLinkSignatureException.php
│   │   ├── PakaiLinkValidationException.php
│   │   └── PakaiLinkTransactionException.php
│   ├── Enums/
│   │   ├── PakaiLinkTransactionType.php
│   │   ├── PakaiLinkTransactionStatus.php
│   │   └── PakaiLinkBankCode.php
│   ├── Contracts/
│   ├── Facades/
│   └── PakaiLinkServiceProvider.php
├── config/
│   └── pakailink.php
├── composer.json
└── README.md

```

Extending the Package
---------------------

[](#extending-the-package)

### Add Payment Method Service

[](#add-payment-method-service)

Create a new service in your application:

```
namespace App\Services\PakaiLink;

use PakaiLink\Services\PakaiLinkHttpClient;

class CustomPaymentService
{
    public function __construct(
        protected PakaiLinkHttpClient $client
    ) {}

    public function processPayment(array $data): array
    {
        return $this->client->post('/api/v1.0/custom-endpoint', $data);
    }
}
```

### Register Custom Service

[](#register-custom-service)

In your application's service provider:

```
$this->app->singleton(CustomPaymentService::class, function ($app) {
    return new CustomPaymentService(
        client: $app->make(\PakaiLink\Services\PakaiLinkHttpClient::class)
    );
});
```

Support
-------

[](#support)

- **PakaiLink Documentation:**
- **Issues:** Report issues in your project repository
- **Questions:** Contact your development team

License
-------

[](#license)

MIT License

Credits
-------

[](#credits)

Developed by BigPG Team for Laravel applications integrating with PakaiLink Payment Gateway.

---

**Version:** 1.0.0

**Status:** Production Ready

**Last Updated:** 2025-11-18

###  Health Score

35

—

LowBetter than 79% of packages

Maintenance78

Regular maintenance activity

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

151d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/c387ba49c0a039173b01e8dd682d780e1f3170d6b9a678fac0d42be67bb8b259?d=identicon)[netwillbig](/maintainers/netwillbig)

---

Top Contributors

[![gwillyoo](https://avatars.githubusercontent.com/u/38490181?v=4)](https://github.com/gwillyoo "gwillyoo (3 commits)")

---

Tags

laravelpaymentgatewayindonesiasnapvirtual-accounte-walletqrispakailink

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/pakailink-pakailink-sdk/health.svg)

```
[![Health](https://phpackages.com/badges/pakailink-pakailink-sdk/health.svg)](https://phpackages.com/packages/pakailink-pakailink-sdk)
```

###  Alternatives

[omalizadeh/laravel-multi-payment

A driver-based laravel package for online payments via multiple gateways

491.1k](/packages/omalizadeh-laravel-multi-payment)[dena-a/iran-payment

a Laravel package to handle Internet Payment Gateways for Iran Banking System

312.4k1](/packages/dena-a-iran-payment)[parsisolution/gateway

A Laravel package for connecting to all Iraninan payment gateways

231.7k](/packages/parsisolution-gateway)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
