Welcome to the DOKU PHP SDK! This SDK simplifies access to the DOKU API for your server-side PHP applications, enabling seamless integration with payment and virtual account services.
If your looking for another language Node.js, Go, Python, Java
- DOKU PHP SDK Documentation
- PHP version 7.4 or higher
- Composer installed
To install the Doku Snap SDK, use Composer:
composer require doku/doku-php-library
Before using the Doku Snap SDK, you need to initialize it with your credentials:
- Client ID and Secret Key: Retrieve these from the Integration menu in your Doku Dashboard
- Private Key and Public Key : Generate your Private Key and Public Key
How to generate Merchant privateKey and publicKey :
- generate private key RSA : openssl genrsa -out private.key 2048
- set passphrase your private key RSA : openssl pkcs8 -topk8 -inform PEM -outform PEM -in private.key -out pkcs8.key -v1 PBE-SHA1-3DES
- generate public key RSA : openssl rsa -in private.key -outform PEM -pubout -out public.pem
The encryption model applied to messages involves both asymmetric and symmetric encryption, utilizing a combination of Private Key and Public Key, adhering to the following standards:
- Standard Asymmetric Encryption Signature: SHA256withRSA dengan Private Key ( Kpriv ) dan Public Key ( Kpub ) (256 bits)
- Standard Symmetric Encryption Signature HMAC_SHA512 (512 bits)
- Standard Symmetric Encryption AES-256 dengan client secret sebagai encryption key.
Parameter | Description | Required |
---|---|---|
privateKey |
The private key for the partner service. | ✅ |
publicKey |
The public key for the partner service. | ✅ |
clientId |
The client ID associated with the service. | ✅ |
secretKey |
The secret key for the partner service. | ✅ |
isProduction |
Set to true for production environment | ✅ |
issuer |
Optional issuer for advanced configurations. | ❌ |
authCode |
Optional authorization code for advanced use. | ❌ |
use Doku\Snap\Snap;
$privateKey = "YOUR_PRIVATE_KEY";
$publicKey = "YOUR_PUBLIC_KEY";
$clientId = "YOUR_CLIENT_ID";
$secretKey = "YOUR_SECRET_KEY";
$isProduction = false;
$issuer = "YOUR_ISSUER";
$authCode = "YOUR_AUTH_CODE";
$snap = new Snap($privateKey, $publicKey, $clientId, $issuer, $isProduction, $secretKey, $authCode);
Initialization Always start by initializing the Snap object.
$snap = new Snap($privateKey, $publicKey, $clientId, $issuer, $isProduction, $secretKey, $authCode);
- Description: A pre-generated virtual account provided by DOKU.
- Use Case: Recommended for one-time transactions.
- Description: Merchant generated virtual account.
- Use Case: Recommended for top up business model.
Parameters for createVA and updateVA
Parameter | Description | Data Type | Required | |
---|---|---|---|---|
partnerServiceId |
The unique identifier for the partner service. | String(20) | ✅ | |
customerNo |
The customer's identification number. | String(20) | ✅ | |
virtualAccountNo |
The virtual account number associated with the customer. | String(20) | ✅ | |
virtualAccountName |
The name of the virtual account associated with the customer. | String(255) | ✅ | |
virtualAccountEmail |
The email address associated with the virtual account. | String(255) | ❌ | |
virtualAccountPhone |
The phone number associated with the virtual account. | String(9-30) | ❌ | |
trxId |
Invoice number in Merchants system. | String(64) | ✅ | |
totalAmount |
value : Transaction Amount (ISO 4217) Example: "11500.00" |
String(16.2) | ✅ | |
Currency : Currency Example: "IDR" |
String(3) | ✅ | ||
additionalInfo |
channel : Channel that will be applied for this VA Example: VIRTUAL_ACCOUNT_BANK_CIMB |
String(20) | ✅ | |
virtualAccountConfig |
reusableStatus : Reusable Status For Virtual Account Transaction value TRUE or FALSE |
Boolean | ❌ | |
minAmount : Minimum Amount can be used only if virtualAccountTrxType is Open Amount (O). Example: "10000.00" |
String(16.2) | ❌ | ||
maxAmount : Maximum Amount can be used only if virtualAccountTrxType is Open Amount (O). Example: "5000000.00" |
String(16.2) | ❌ | ||
virtualAccountTrxType |
Transaction type for this transaction. C (Closed Amount), O (Open Amount) | String(1) | ✅ | |
expiredDate |
Expiration date for Virtual Account. ISO-8601 Example: "2023-01-01T10:55:00+07:00" |
String | ❌ |
-
Create Virtual Account
- Function:
createVa
use Doku\Snap\Models\VA\Request\CreateVaRequestDto; use Doku\Snap\Models\TotalAmount\TotalAmount; use Doku\Snap\Models\VA\AdditionalInfo\CreateVaRequestAdditionalInfo; use Doku\Snap\Models\VA\VirtualAccountConfig\CreateVaVirtualAccountConfig; $createVaRequestDto = new CreateVaRequestDto( "8129014", // partner "17223992157", // customerno "812901417223992157", // virtualAccountNo "T_" . time(), // virtualAccountName "test.example." . time() . "@test.com", // virtualAccountEmail "621722399214895", // virtualAccountPhone "INV_CIMB_" . time(), // trxId new TotalAmount("12500.00", "IDR"), // totalAmount new CreateVaRequestAdditionalInfo( "VIRTUAL_ACCOUNT_BANK_CIMB", new CreateVaVirtualAccountConfig(true) ), // additionalInfo 'C', // virtualAccountTrxType "2024-08-31T09:54:04+07:00" // expiredDate ); $result = $snap->createVa($createVaRequestDto); echo json_encode($result, JSON_PRETTY_PRINT);
- Function:
-
Update Virtual Account
- Function:
updateVa
use Doku\Snap\Models\VA\Request\UpdateVaRequestDto; use Doku\Snap\Models\VA\AdditionalInfo\UpdateVaRequestAdditionalInfo; use Doku\Snap\Models\VA\VirtualAccountConfig\UpdateVaVirtualAccountConfig; $updateVaRequestDto = new UpdateVaRequestDto( "8129014", // partnerServiceId "17223992155", // customerNo "812901417223992155", // virtualAccountNo "T_" . time(), // virtualAccountName "test.example." . time() . "@test.com", // virtualAccountEmail "00000062798", // virtualAccountPhone "INV_CIMB_" . time(), // trxId new TotalAmount("14000.00", "IDR"), // totalAmount new UpdateVaRequestAdditionalInfo("VIRTUAL_ACCOUNT_BANK_CIMB", new UpdateVaVirtualAccountConfig("ACTIVE", "10000.00", "15000.00")), // additionalInfo "O", // virtualAccountTrxType "2024-08-02T15:54:04+07:00" // expiredDate ); $result = $snap->updateVa($updateVaRequestDto); echo json_encode($result, JSON_PRETTY_PRINT);
- Function:
-
Delete Virtual Account
Parameter Description Data Type Required partnerServiceId
The unique identifier for the partner service. String(8) ✅ customerNo
The customer's identification number. String(20) ✅ virtualAccountNo
The virtual account number associated with the customer. String(20) ✅ trxId
Invoice number in Merchant's system. String(64) ✅ additionalInfo
channel
: Channel applied for this VA.
Example: VIRTUAL_ACCOUNT_BANK_CIMBString(30) ✅
-
Function:
deletePaymentCode
use Doku\Snap\Models\VA\Request\DeleteVaRequestDto; use Doku\Snap\Models\VA\Request\DeleteVaRequestDto; use Doku\Snap\Models\VA\AdditionalInfo\DeleteVaRequestAdditionalInfo; $deleteVaRequestDto = new DeleteVaRequestDto( "8129014", // partnerServiceId "17223992155", // customerNo "812901417223992155", // virtualAccountNo "INV_CIMB_" . time(), // trxId new DeleteVaRequestAdditionalInfo("VIRTUAL_ACCOUNT_BANK_CIMB") // additionalInfo ); $result = $snap->deletePaymentCode($deleteVaRequestDto); echo json_encode($result, JSON_PRETTY_PRINT);
-
Description: The VA number is registered on merchant side and DOKU will forward Acquirer inquiry request to merchant side when the customer make payment at the acquirer channel
-
Function:
directInquiryVa
use Doku\Snap\Models\DirectInquiry\InquiryResponseBodyDto; use Doku\Snap\Models\DirectInquiry\InquiryResponseVirtualAccountDataDto; use Doku\Snap\Models\DirectInquiry\InquiryReasonDto; use Doku\Snap\Models\DirectInquiry\InquiryResponseAdditionalInfoDto; use Doku\Snap\Models\VA\VirtualAccountConfig\CreateVaVirtualAccountConfig; use Doku\Snap\Models\TotalAmount\TotalAmount; directInquiry(){ $requestBody = $this->request->getJSON(true); $authorization = $this->request->getHeaderLine('Authorization'); $isValid = $this->snap->validateTokenB2B($authorization); if($isValid) { $responseCode =2002400; $responseMessage = 'Successful'; $inquiryRequestId = $requestBody['inquiryRequestId']; $partnerServiceId = $requestBody['partnerServiceId']; $customerNo = $requestBody['customerNo']; $virtualAccountNo = $requestBody['virtualAccountNo']; <!-- validate virtualAccountNo from your database before proccess it --> $virtualAccountName = "Nama ". time(); $trxId = "INV_MERCHANT_" . time(); $virtualAccountEmail = "email." . time() . "@gmail.com"; $virtualAccountPhone =time(); $totalAmount = new TotalAmount( "25000.00", "IDR" ); $inquiryStatus = "00"; $additionalInfo = new InquiryResponseAdditionalInfoDto( $requestBody['additionalInfo']['channel'], $trxId, new CreateVaVirtualAccountConfig( true, "100000.00", "10000.00" ) ); $inquiryReason = new InquiryReasonDto( "Success", "Sukses" ); $virtualAccountTrxType = "C"; $freeText = [ [ "english" => "Free text", "indonesia" => "Tulisan Bebas" ] ]; $vaData = new InquiryResponseVirtualAccountDataDto( $partnerServiceId, $customerNo, $virtualAccountNo, $virtualAccountName, $virtualAccountEmail, $virtualAccountPhone, $totalAmount, $virtualAccountTrxType, $additionalInfo, $inquiryStatus, $inquiryReason, $inquiryRequestId, $freeText ); $body = new InquiryResponseBodyDto( $responseCode, $responseMessage, $vaData ); return $this->respond($body); } }
Parameter | Description | Data Type | Required |
---|---|---|---|
partnerServiceId |
The unique identifier for the partner service. | String(8) | ✅ |
customerNo |
The customer's identification number. | String(20) | ✅ |
virtualAccountNo |
The virtual account number associated with the customer. | String(20) | ✅ |
inquiryRequestId |
The customer's identification number. | String(128) | ❌ |
paymentRequestId |
The virtual account number associated with the customer. | String(128) | ❌ |
additionalInfo |
The virtual account number associated with the customer. | String | ❌ |
- Function:
checkStatusVa
use Doku\Snap\Models\VA\Request\CheckStatusVaRequestDto; $checkStatusVaRequestDto = new CheckStatusVaRequestDto( "8129014", // partnerServiceId "17223992155", // customerNo "812901417223992155", // virtualAccountNo null, null, null ); $result = $snap-> ($checkStatusVaRequestDto); echo json_encode($result, JSON_PRETTY_PRINT);
The card registration/account binding process must be completed before payment can be processed. The merchant will send the card registration request from the customer to DOKU.
Each card/account can only registered/bind to one customer on one merchant. Customer needs to verify OTP and input PIN.
Services | Binding Type | Details |
---|---|---|
Direct Debit | Account Binding | Supports Allo Bank and CIMB |
Direct Debit | Card Registration | Supports BRI |
E-Wallet | Account Binding | Supports OVO |
- Binding
Parameter | Description | Data Type | Required | |
---|---|---|---|---|
phoneNo |
Phone Number Customer. Format: 628238748728423 |
String(9-16) | ✅ | |
additionalInfo |
channel : Payment Channel |
String | ✅ | |
custIdMerchant : Customer id from merchant |
String(64) | ✅ | ||
customerName : Customer name from merchant |
String(70) | ❌ | ||
email : Customer email from merchant |
String(64) | ❌ | ||
idCard : Customer id card from merchant |
String(20) | ❌ | ||
country : Customer country |
String | ❌ | ||
address : Customer Address |
String(255) | ❌ | ||
dateOfBirth |
String(YYYYMMDD) | ❌ | ||
successRegistrationUrl : Redirect URL when binding is success |
String | ✅ | ||
failedRegistrationUrl : Redirect URL when binding is success fail |
String | ✅ | ||
deviceModel : Device Model customer |
String | ✅ | ||
osType : Format: ios/android |
String | ✅ | ||
channelId : Format: app/web |
String | ✅ |
-
Function:
doAccountBinding
use Doku\Snap\Models\AccountBinding\AccountBindingRequestDto; use Doku\Snap\Models\AccountBinding\AccountBindingAdditionalInfoRequestDto; public function accountBinding() { $requestData = $this->request->getJSON(true); $partnerReferenceNo = $requestData['phoneNo'] ?? null; $additionalInfo = new AccountBindingAdditionalInfoRequestDto( $requestData['additionalInfo']['channel'], $requestData['additionalInfo']['custIdMerchant'], $requestData['additionalInfo']['customerName']?? null, $requestData['additionalInfo']['email'], $requestData['additionalInfo']['idCard'] ?? null, $requestData['additionalInfo']['country'] ?? null, $requestData['additionalInfo']['address'] ?? null, $requestData['additionalInfo']['dateOfBirth'] ?? null, $requestData['additionalInfo']['successRegistrationUrl'], $requestData['additionalInfo']['failedRegistrationUrl'], $requestData['additionalInfo']['deviceModel'] ?? null, $requestData['additionalInfo']['osType'] ?? null, $requestData['additionalInfo']['channelId'] ?? null ); $requestBody = new AccountBindingRequestDto( $partnerReferenceNo, $additionalInfo ); $ipAddress = $this->request->getHeaderLine('X-IP-ADDRESS'); $deviceId = $this->request->getHeaderLine('X-DEVICE-ID'); $response = $this->snap->doAccountBinding($requestBody, $ipAddress, $deviceId); if (is_array($response) || is_object($response)) { $responseObject = (array)$response; // Ubah objek ke array jika perlu } else { throw new \Exception('Unexpected response type'); } $responseCode = $responseObject['responseCode']; $statusCode = substr($responseCode, 0, 3); $this->response->setStatusCode((int)$statusCode); return $this->response->setJSON($responseObject); }
- Unbinding
- Function:
getTokenB2B2C
public function getTokenB2B2C() { $requestData = $this->request->getJSON(true); $authCode = $requestData['authCode']; $tokenData = $this->snap->getTokenB2B2C($authCode); return $this->response->setJSON($tokenData); }
- Function:
doAccountUnbinding
use Doku\Snap\Models\AccountUnbinding\AccountUnbindingRequestDto; use Doku\Snap\Models\AccountUnbinding\AccountUnbindingAdditionalInfoRequestDto; public function accountUnbinding() { $requestData = $this->request->getJSON(true); $tokenId = $requestData['tokenId'] ?? ''; $additionalInfo = new AccountUnbindingAdditionalInfoRequestDto( $requestData['additionalInfo']['channel'] ); $requestBody = new AccountUnbindingRequestDto( $tokenId, $additionalInfo ); $ipAddress = $this->request->getHeaderLine('X-IP-ADDRESS'); $response = $this->snap->doAccountUnbinding($requestBody, $ipAddress); if (is_array($response) || is_object($response)) { $responseObject = (array)$response; // Ubah objek ke array jika perlu } else { throw new \Exception('Unexpected response type'); } $responseCode = $responseObject['responseCode']; $statusCode = substr($responseCode, 0, 3); $this->response->setStatusCode((int)$statusCode); return $this->response->setJSON($responseObject); }
- Function:
-
Registration
- Function:
doCardRegistration
use Doku\Snap\Models\CardRegistration\CardRegistrationRequestDto; use Doku\Snap\Models\CardRegistration\CardRegistrationAdditionalInfoRequestDto; use Doku\Snap\Models\CardRegistration\CardRegistrationCardDataRequestDto; public function cardRegist() { $requestData = $this->request->getJSON(true); $cardData = new CardRegistrationCardDataRequestDto( $requestData['cardData']['bankCardNo'], $requestData['cardData']['bankCardType'], $requestData['cardData']['expiryDate'], $requestData['cardData']['identificationNo'], $requestData['cardData']['identificationType'], $requestData['cardData']['email'], ); $custIdMerchant = $requestData['custIdMerchant'] ?? null; $phoneNo = $requestData['phoneNo'] ?? null; $additionalInfo = new CardRegistrationAdditionalInfoRequestDto( $requestData['additionalInfo']['channel'], $requestData['additionalInfo']['customerName']?? null, $requestData['additionalInfo']['email'], $requestData['additionalInfo']['idCard'] ?? null, $requestData['additionalInfo']['country'] ?? null, $requestData['additionalInfo']['address'] ?? null, $requestData['additionalInfo']['dateOfBirth'] ?? null, $requestData['additionalInfo']['successRegistrationUrl']?? null, $requestData['additionalInfo']['failedRegistrationUrl']?? null ); $requestBody = new CardRegistrationRequestDto( $cardData, $custIdMerchant, $phoneNo, $additionalInfo ); $response = $this->snap->doCardRegistration($requestBody); if (is_array($response) || is_object($response)) { $responseObject = (array)$response; // Ubah objek ke array jika perlu } else { throw new \Exception('Unexpected response type'); } $responseCode = $responseObject['responseCode']; $statusCode = substr($responseCode, 0, 3); $this->response->setStatusCode((int)$statusCode); return $this->response->setJSON($responseObject); }
- Function:
-
UnRegistration
- Function:
getTokenB2B2C
public function getTokenB2B2C() { $requestData = $this->request->getJSON(true); $authCode = $requestData['authCode']; $tokenData = $this->snap->getTokenB2B2C($authCode); return $this->response->setJSON($tokenData); }
- Function:
doCardUnbinding
use Doku\Snap\Models\AccountUnbinding\AccountUnbindingRequestDto; use Doku\Snap\Models\AccountUnbinding\AccountUnbindingAdditionalInfoRequestDto; public function cardUnbinding() { $requestData = $this->request->getJSON(true); $tokenId = $requestData['tokenId'] ?? ''; $additionalInfo = new AccountUnbindingAdditionalInfoRequestDto( $requestData['additionalInfo']['channel'] ); $requestBody = new AccountUnbindingRequestDto( $tokenId, $additionalInfo ); $ipAddress = $this->request->getHeaderLine('X-IP-ADDRESS'); $response = $this->snap->doCardUnbinding($requestBody); if (is_array($response) || is_object($response)) { $responseObject = (array)$response; // Ubah objek ke array jika perlu } else { throw new \Exception('Unexpected response type'); } $responseCode = $responseObject['responseCode']; $statusCode = substr($responseCode, 0, 3); $this->response->setStatusCode((int)$statusCode); return $this->response->setJSON($responseObject); }
- Function:
Once a customer’s account or card is successfully register/bind, the merchant can send a payment request. This section describes how to send a unified request that works for both Direct Debit and E-Wallet channels.
Acquirer | Channel Name |
---|---|
Allo Bank | DIRECT_DEBIT_ALLO_SNAP |
BRI | DIRECT_DEBIT_BRI_SNAP |
CIMB | DIRECT_DEBIT_CIMB_SNAP |
OVO | EMONEY_OVO_SNAP |
Parameter | Description | Data Type | Required | |
---|---|---|---|---|
partnerReferenceNo |
Reference No From Partner Format: 628238748728423 |
String(9-16) | ✅ | |
amount |
value : Transaction Amount (ISO 4217) Example: "11500.00" |
String(16.2) | ✅ | |
Currency : Currency Example: "IDR" |
String(3) | ✅ | ||
additionalInfo |
channel : payment channel |
String | ✅ | |
remarks :Remarks from Partner |
String(40) | ✅ | ||
successPaymentUrl : Redirect Url if payment success |
String | ✅ | ||
failedPaymentUrl : Redirect Url if payment fail
|
String | ✅ |
Parameter | Description | Required |
---|---|---|
additionalInfo.remarks |
Remarks from the partner | ✅ |
additionalInfo.lineItems.name |
Item name (String) | ✅ |
additionalInfo.lineItems.price |
Item price (ISO 4217) | ✅ |
additionalInfo.lineItems.quantity |
Item quantity (Integer) | ✅ |
payOptionDetails.payMethod |
Balance type (options: BALANCE/POINT/PAYLATER) | ✅ |
payOptionDetails.transAmount.value |
Transaction amount | ✅ |
payOptionDetails.transAmount.currency |
Currency (ISO 4217, e.g., "IDR") | ✅ |
Parameter | Description | Required |
---|---|---|
additionalInfo.remarks |
Remarks from the partner | ✅ |
Parameter | Description | Required |
---|---|---|
feeType |
Fee type from partner (values: OUR, BEN, SHA) | ❌ |
payOptionDetails.payMethod |
Payment method format: CASH, POINTS | ✅ |
payOptionDetails.transAmount.value |
Transaction amount (ISO 4217) | ✅ |
payOptionDetails.transAmount.currency |
Currency (ISO 4217, e.g., "IDR") | ✅ |
payOptionDetails.feeAmount.value |
Fee amount (if applicable) | ✅ |
payOptionDetails.feeAmount.currency |
Currency for the fee | ✅ |
additionalInfo.paymentType |
Transaction type (values: SALE, RECURRING) | ✅ |
Here’s how you can use the doPayment
function for both payment types:
-
Function:
doPayment
use Doku\Snap\Models\TotalAmount\TotalAmount; use Doku\Snap\Models\Payment\PaymentRequestDto; use Doku\Snap\Models\Payment\PaymentAdditionalInfoRequestDto; public function payment(){ $requestData = $this->request->getJSON(true); $payOptionDetails =json_decode(json_encode($requestData['payOptionDetails'] ?? null)); $partnerReferenceNo = $requestData['partnerReferenceNo'] ?? null; $amount = new TotalAmount( $requestData['amount']['value'], $requestData['amount']['currency'] ); $additionalInfo = new PaymentAdditionalInfoRequestDto( $requestData['additionalInfo']['channel'], $requestData['additionalInfo']['remarks'], $requestData['additionalInfo']['successPaymentUrl'], $requestData['additionalInfo']['failedPaymentUrl'], $requestData['additionalInfo']['lineItems'], $requestData['additionalInfo']['paymentType'] ?? null ); $feeType = $requestData['feeType'] ?? ''; $chargeToken = $requestData['chargeToken'] ?? ''; $request = new PaymentRequestDto( $partnerReferenceNo, $amount, $payOptionDetails, $additionalInfo, $feeType, $chargeToken ); $ipAddress = $this->request->getHeaderLine('X-IP-ADDRESS'); $authCode = $requestData['authCode']; $response = $this->snap->doPayment($request, $authCode, $ipAddress); if (is_array($response) || is_object($response)) { $responseObject = (array)$response; // Ubah objek ke array jika perlu } else { throw new \Exception('Unexpected response type'); } // var_dump($responseObject); // Ambil responseCode $responseCode = $responseObject['responseCode']; // Atur status HTTP berdasarkan tiga angka pertama $statusCode = substr($responseCode, 0, 3); $this->response->setStatusCode((int)$statusCode); // Set status HTTP return $this->response->setJSON($responseObject); }
Acquirer | Channel Name |
---|---|
DANA | EMONEY_DANA_SNAP |
ShopeePay | EMONEY_SHOPEE_PAY_SNAP |
The following fields are common across DANA and ShopeePay requests:
Parameter | Description | Data Type | Required | |
---|---|---|---|---|
partnerReferenceNo |
Reference No From Partner Examplae : INV-0001 |
String(9-16) | ✅ | |
validUpto |
Expired time payment url | String | ❌ | |
pointOfInitiation |
Point of initiation from partner, value: app/pc/mweb |
String | ❌ | |
urlParam |
url : URL after payment sucess |
String | ✅ | |
type : Pay Returnalways PAY_RETURN |
String | ✅ | ||
isDeepLink : Is Merchant use deep link or notExample: "Y/N" |
String(1) | ✅ | ||
amount |
value : Transaction Amount (ISO 4217) Example: "11500.00" |
String(16.2) | ✅ | |
Currency : Currency Example: "IDR" |
String(3) | ✅ | ||
additionalInfo |
channel : payment channel |
String | ✅ |
DANA spesific parameters
Parameter | Description | Data Type | Required | |
---|---|---|---|---|
additionalInfo |
orderTitle : Order title from merchant |
String | ❌ | |
supportDeepLinkCheckoutUrl : Value 'true' for Jumpapp behaviour, 'false' for webview, false by default |
String | ❌ |
- Function:
doPaymentJumpApp
use Doku\Snap\Models\TotalAmount\TotalAmount;
use Doku\Snap\Models\PaymentJumpApp\PaymentJumpAppRequestDto;
use Doku\Snap\Models\PaymentJumpApp\PaymentJumpAppAdditionalInfoRequestDto;
use Doku\Snap\Models\PaymentJumpApp\UrlParamDto;
public function paymentJumpApp()
{
$requestData = $this->request->getJSON(true);
$partnerReferenceNo = $requestData['partnerReferenceNo'] ?? '';
$validUpTo = $requestData['validUpTo'] ?? '';
$pointOfInitiation = $requestData['pointOfInitiation'] ?? '';
$urlParam = new UrlParamDto(
$requestData['urlParam'][0]['url'],
$requestData['urlParam'][0]['type'],
$requestData['urlParam'][0]['isDeepLink']
);
$amount = new TotalAmount(
$requestData['amount']['value'],
$requestData['amount']['currency']
);
$metadata = isset($requestData['additionalInfo']['metadata']) ? $requestData['additionalInfo']['metadata'] : null;
$supportDeepLinkCheckoutUrl = isset($requestData['additionalInfo']['supportDeepLinkCheckoutUrl']) ? $requestData['additionalInfo']['supportDeepLinkCheckoutUrl'] : null;
$additionalInfo = new PaymentJumpAppAdditionalInfoRequestDto(
$requestData['additionalInfo']['channel'],
$requestData['additionalInfo']['orderTitle'],
$metadata,
$supportDeepLinkCheckoutUrl
);
$requestBody = new PaymentJumpAppRequestDto(
$partnerReferenceNo,
$validUpTo,
$pointOfInitiation,
$urlParam,
$amount,
$additionalInfo
);
$ipAddress = $this->request->getHeaderLine('X-IP-ADDRESS');
$deviceId = $this->request->getHeaderLine('X-DEVICE-ID');
$response = $this->snap->doPaymentJumpApp($requestBody,$deviceId,$ipAddress);
if (is_array($response) || is_object($response)) {
$responseObject = (array)$response; // Ubah objek ke array jika perlu
} else {
throw new \Exception('Unexpected response type');
}
$responseCode = $responseObject['responseCode'];
$statusCode = substr($responseCode, 0, 3);
$this->response->setStatusCode((int)$statusCode);
return $this->response->setJSON($responseObject);
}
public function debitStatus()
{
$requestData = $this->request->getJSON(true);
$originalPartnerReferenceNo = $requestData['originalPartnerReferenceNo'] ?? '';
$originalReferenceNo = $requestData['originalReferenceNo'] ?? '';
$originalExternalId = $requestData['originalExternalId'] ?? '';
$serviceCode = $requestData['serviceCode'] ?? '';
$transactionDate = $requestData['transactionDate'] ?? '';
$amountValue = $requestData['amount']['value'] ?? '';
$amountCurrency = $requestData['amount']['currency'] ?? '';
$amount = new TotalAmount($amountValue, $amountCurrency);
$merchantId = $requestData['merchantId'] ?? '';
$subMerchantId = $requestData['subMerchantId'] ?? '';
$externalStoreId = $requestData['externalStoreId'] ?? '';
$deviceId = $requestData['additionalInfo']['deviceId'] ?? '';
$channel = $requestData['additionalInfo']['channel'] ?? '';
$additionalInfo = new CheckStatusAdditionalInfoRequestDto($deviceId, $channel);
$requestBody = new DirectDebitCheckStatusRequestDto(
$originalPartnerReferenceNo,
$originalReferenceNo,
$originalExternalId,
$serviceCode,
$transactionDate,
$amount,
$merchantId,
$subMerchantId,
$externalStoreId,
$additionalInfo
);
$response = $this->snap->doCheckStatus($requestBody);
if (is_array($response) || is_object($response)) {
$responseObject = (array)$response; // Ubah objek ke array jika perlu
} else {
throw new \Exception('Unexpected response type');
}
$responseCode = $responseObject['responseCode'];
$statusCode = substr($responseCode, 0, 3);
$this->response->setStatusCode((int)$statusCode);
return $this->response->setJSON($responseObject);
}
public function refund()
{
$requestData = $this->request->getJSON(true);
$additionalInfo = new RefundAdditionalInfoRequestDto(
$requestData['additionalInfo']['channel']
);
$originalPartnerReferenceNo = $requestData['originalPartnerReferenceNo'] ?? '';
$originalExternalId = $requestData['originalExternalId'] ?? '';
$refundAmount = new TotalAmount(
$requestData['refundAmount']['value'],
$requestData['refundAmount']['currency']
);
$reason = $requestData['reason'] ?? '';
$partnerRefundNo = $requestData['partnerRefundNo'] ?? '';
$ipAddress = $this->request->getHeaderLine('X-IP-ADDRESS');
$authCode = $requestData['authCode'];
$deviceId = $this->request->getHeaderLine('deviceId');
$requestBody = new RefundRequestDto(
$additionalInfo,
$originalPartnerReferenceNo,
$originalExternalId,
$refundAmount,
$reason,
$partnerRefundNo
);
$response = $this->snap->doRefund($requestBody, $authCode, $ipAddress, $deviceId);
if (is_array($response) || is_object($response)) {
$responseObject = (array)$response; // Ubah objek ke array jika perlu
} else {
throw new \Exception('Unexpected response type');
}
$responseCode = $responseObject['responseCode'];
$statusCode = substr($responseCode, 0, 3);
$this->response->setStatusCode((int)$statusCode);
return $this->response->setJSON($responseObject);
}
public function checkBalance()
{
$requestData = $this->request->getJSON(true);
$additionalInfo = new BalanceInquiryAdditionalInfoRequestDto(
$requestData['additionalInfo']['channel']
);
$requestBody = new BalanceInquiryRequestDto(
$additionalInfo
);
$ipAddress = $this->request->getHeaderLine('X-IP-ADDRESS');
$authCode = $requestData['authCode'];
$response = $this->snap->doBalanceInquiry($requestBody, $authCode, $ipAddress);
if (is_array($response) || is_object($response)) {
$responseObject = (array)$response; // Ubah objek ke array jika perlu
} else {
throw new \Exception('Unexpected response type');
}
$responseCode = $responseObject['responseCode'];
$statusCode = substr($responseCode, 0, 3);
$this->response->setStatusCode((int)$statusCode);
return $this->response->setJSON($responseObject);
}
The SDK throws exceptions for various error conditions. Always wrap your API calls in try-catch blocks:
try {
$result = $snap->createVa($createVaRequestDto);
// Process successful result
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . PHP_EOL;
// Handle the error appropriately
}
This section provides common errors and solutions:
Error Code | Description | Solution |
---|---|---|
4010000 |
Unauthorized | Check if Client ID and Secret Key are valid. |
4012400 |
Virtual Account Not Found | Verify the virtual account number provided. |
2002400 |
Successful | Transaction completed successfully. |