Welcome to the DOKU NODE JS SDK! This SDK simplifies access to the DOKU API for your server-side NODE JS applications, enabling seamless integration with payment and virtual account services.
If your looking for another language PHP, Go, Python, Java
- DOKU NODE JS SDK Documentation
- NODE JS version 18 or higher
To install the Doku Snap SDK, use Composer:
npm install doku
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. | ❌ |
const doku = require('doku-nodejs-library');
let privateKey = `-----BEGIN PRIVATE KEY-----
your privatekey
-----END PRIVATE KEY-----`;
let issuer = "your issuer";
let clientID = "your client id";
let publicKey = `-----BEGIN PUBLIC KEY-----
your public key
-----END PUBLIC KEY-----`;
let dokuPublicKey = `-----BEGIN PUBLIC KEY-----
doku public key
-----END PUBLIC KEY-----`;
let secretKey = 'SK-VknOxwR4xZSEPnG7fpJo';
let snap = new doku.Snap({
isProduction : false,
privateKey : privateKey,
clientID : clientID,
publicKey :publicKey,
dokuPublicKey:dokuPublicKey,
issuer:issuer,
secretKey:secretKey
});
Initialization Always start by initializing the Snap object.
let snap = new doku.Snap({
isProduction : false,
privateKey : privateKey,
clientID : clientID,
publicKey :publicKey,
dokuPublicKey:dokuPublicKey,
issuer:issuer,
secretKey:secretKey
});
- 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
const CreateVARequestDto = require('doku-nodejs-library/_models/createVaRequestDto'); const VirtualAccountConfig = require('doku-nodejs-library/_models/virtualAccountConfig'); const TotalAmount = require('doku-nodejs-library/_models/totalAmount'); const AdditionalInfo = require('doku-nodejs-library/_models/additionalInfo'); app.post('/create-va', async (req,res) => { let createVaRequestDto = new CreateVARequestDto(); createVaRequestDto.partnerServiceId = req.body.partnerServiceId; createVaRequestDto.customerNo =req.body.customerNo; createVaRequestDto.virtualAccountNo = req.body.partnerServiceId+req.body.customerNo; createVaRequestDto.virtualAccountName = req.body.virtualAccountName; createVaRequestDto.virtualAccountEmail = req.body.virtualAccountEmail; createVaRequestDto.virtualAccountPhone = req.body.virtualAccountPhone; createVaRequestDto.trxId = req.body.trxId; let totalAmount = new TotalAmount(); totalAmount.value = req.body.totalAmount.value; totalAmount.currency = req.body.totalAmount.currency; createVaRequestDto.totalAmount = totalAmount; let virtualAccountConfig = new VirtualAccountConfig(); virtualAccountConfig.reusableStatus = req.body.additionalInfo.virtualAccountConfig.reusableStatus; let additionalInfo = new AdditionalInfo("VIRTUAL_ACCOUNT_BANK_CIMB", virtualAccountConfig); additionalInfo.channel = req.body.additionalInfo.channel; additionalInfo.virtualAccountConfig = virtualAccountConfig; createVaRequestDto.additionalInfo = additionalInfo; createVaRequestDto.virtualAccountTrxType =req.body.virtualAccountTrxType; createVaRequestDto.expiredDate = req.body.expiredDate; await snap.createVa(createVaRequestDto).then(va=>{ res.status(200).send(va); }).catch(err=>{ if(err.response){ res.status(400).send(err.response.data) }else{ res.status(400).send({ responseCode:"400", responseMessage:err.message }) } }) })
- Function:
-
Update Virtual Account
- Function:
updateVa
const UpdateVaVirtualAccountConfigDto = require('doku-nodejs-library/_models/updateVaVirtualAccountConfigDTO'); const VirtualAccountConfig = require('doku-nodejs-library/_models/virtualAccountConfig'); const TotalAmount = require('doku-nodejs-library/_models/totalAmount'); const UpdateVaAdditionalInfoDto = require('doku-nodejs-library/_models/updateVaAdditionalInfoDTO'); app.post('/update-va', async (req,res) => { let updateVaRequestDto = new UpdateVaDto() updateVaRequestDto.partnerServiceId = req.body.partnerServiceId; updateVaRequestDto.customerNo = req.body.customerNo; updateVaRequestDto.virtualAccountNo = updateVaRequestDto.partnerServiceId+updateVaRequestDto.customerNo; updateVaRequestDto.virtualAccountName = req.body.virtualAccountName; updateVaRequestDto.virtualAccountEmail = req.body.virtualAccountEmail; updateVaRequestDto.trxId = req.body.trxId let totalAmount = new TotalAmount(); totalAmount.value = req.body.totalAmount.value; totalAmount.currency = req.body.totalAmount.currency; updateVaRequestDto.totalAmount = totalAmount; let virtualAccountConfig = new UpdateVaVirtualAccountConfigDto(); virtualAccountConfig.status = "INACTIVE"; let additionalInfo = new UpdateVaAdditionalInfoDto(req.body.additionalInfo.channel, virtualAccountConfig); additionalInfo.channel = req.body.additionalInfo.channel; additionalInfo.virtualAccountConfig = virtualAccountConfig; updateVaRequestDto.additionalInfo = additionalInfo; updateVaRequestDto.virtualAccountTrxType = "C"; updateVaRequestDto.expiredDate = req.body.expiredDate; console.log(updateVaRequestDto) await snap.updateVa(updateVaRequestDto).then(va=>{ res.status(200).send(va); }).catch((err)=>{ if(err.response){ res.status(400).send(err.response.data) }else{ res.status(400).send({ responseCode:"400", responseMessage:err.message }) } }) })
- 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
const DeleteVaRequestDto = require('doku-nodejs-library/_models/deleteVaRequestDTO'); const DeleteVaRequestAdditionalInfo = require('doku-nodejs-library/_models/deleteVaRequestAdditionalInfoDTO'); app.post('/delete-va', async (req,res) => { let deleteVaRequestDto = new DeleteVaRequestDto() deleteVaRequestDto.partnerServiceId = req.body.partnerServiceId; deleteVaRequestDto.customerNo = req.body.customerNo; deleteVaRequestDto.virtualAccountNo = req.body.virtualAccountNo deleteVaRequestDto.trxId = req.body.trxId let additionalInfo = new DeleteVaRequestAdditionalInfo(req.body.additionalInfo.channel); deleteVaRequestDto.additionalInfo = additionalInfo; await snap.deletePaymentCode(deleteVaRequestDto).then(response=>{ res.status(200).send(response); }).catch((err)=>{ if(err.response){ res.status(400).send(err.response.data) }else{ res.status(400).send({ responseCode:"400", responseMessage:err.message }) } }) })
-
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
const InquiryResponseVirtualAccountDataDTO = require('doku-nodejs-library/_models/InquiryResponseVirtualAccountDataDTO'); const InquiryResponseBodyDTO = require('doku-nodejs-library/_models/inquiryResponseBodyDTO'); const TotalAmount = require('doku-nodejs-library/_models/totalAmount'); const InquiryResponseAdditionalInfoDTO = require('doku-nodejs-library/_models/inquiryResponseAdditionalInfoDTO'); const VirtualAccountConfig = require('doku-nodejs-library/_models/virtualAccountConfig'); const InquiryReasonDto = require('doku-nodejs-library/_models/inquiryReasonDTO'); app.post("/v1.1/transfer-va/inquiry",(req,res)=>{ let data = new InquiryRequestDTO(); data.partnerServiceId = req.body.partnerServiceId; data.customerNo = req.body.customerNo; data.virtualAccountNo = req.body.virtualAccountNo; data.trxDateInit = req.body.trxDateInit; data.inquiryRequestId = req.body.inquiryRequestId; data.additionalInfo = req.body.additionalInfo; let isvalid = snap.validateTokenB2B(req.headers['authorization']); if(isvalid){ <!--validate yout virtualAccountNo in your database--> let bodyData = new InquiryResponseBodyDTO() bodyData.responseCode = "2002400"; bodyData.responseMessage = "Successful" let vaData = new InquiryResponseVirtualAccountDataDTO() vaData.partnerServiceId = req.body.partnerServiceId; vaData.customerNo = req.body.customerNo; vaData.virtualAccountNo = req.body.virtualAccountNo; vaData.virtualAccountName = "Nama "+Date.now(); vaData.virtualAccountEmail ="email."+Date.now()+"@gmail.com"; vaData.virtualAccountPhone = `${Date.now()}`; let totalAmount = new TotalAmount() totalAmount.currency = "IDR"; totalAmount.value = "25000.00" vaData.totalAmount = totalAmount; vaData.virtualAccountTrxType = "C" let additionalInfo = new InquiryResponseAdditionalInfoDTO() additionalInfo.channel = req.body.additionalInfo.channel; additionalInfo.trxId = "INV_MERCHANT_"+Date.now(); let virtualAccountConfig = new VirtualAccountConfig() virtualAccountConfig.reusableStatus = true; virtualAccountConfig.maxAmount = "100000.00"; virtualAccountConfig.minAmount = "10000.00" additionalInfo.virtualAccountConfig = virtualAccountConfig; vaData.additionalInfo = additionalInfo; vaData.inquiryStatus ="00"; let inquiryReason = new InquiryReasonDto() inquiryReason.english = "Success"; inquiryReason.indonesia = "Sukses"; vaData.inquiryReason = inquiryReason; vaData.inquiryRequestId = req.body.inquiryRequestId; vaData.freeText = [ { "english": "Free text", "indonesia": "Tulisan Bebas" } ] bodyData.virtualAccountData = vaData; }else{ let body ={ "responseCode": "4010000", "responseMessage": "Unauthorized", } res.status(401).send(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
const CheckStatusVARequestDto = require('doku-nodejs-library/_models/checkStatusVARequestDTO'); app.post('/check-status', async (req,res) => { let checkVaRequestDto = new CheckStatusVARequestDto() checkVaRequestDto.partnerServiceId = req.body.partnerServiceId; checkVaRequestDto.customerNo = req.body.customerNo; checkVaRequestDto.virtualAccountNo = checkVaRequestDto.partnerServiceId+checkVaRequestDto.customerNo; await snap.checkStatusVa(checkVaRequestDto).then(response=>{ res.status(200).send(response); }).catch((err)=>{ if(err.response){ res.status(400).send(err.response.data) }else{ res.status(400).send({ responseCode:"400", responseMessage:err.message }) } }) })
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
const AccountBindingRequestDto = require('doku-nodejs-library/_models/accountBindingRequestDTO'); app.post("/account-binding", async (req,res)=>{ let request = new AccountBindingRequestDto() request.phoneNo = req.body.phoneNo request.additionalInfo = req.body.additionalInfo; let ipAddress = req.headers['x-ip-address']; let deviceId = req.headers['x-device-id']; await snap.doAccountBinding(request,ipAddress,deviceId).then((response)=>{ res.status(200).send(response); }).catch((err)=>{ if(err.response?.data){ res.status(parseInt(err.response.data.responseCode.substring(0, 3))).send(err.response.data); }else{ res.status(500).send({"message":err.message}); } }) })
- Unbinding
- Function:
getTokenB2B2C
app.post('/token-b2b2c', async (req,res) => { <!--YOUR_AUTH_CODE_FROM_ACCOUNT_BINDING--> let authCode = req.body['authCode']; await snap.getTokenB2B2c(authCode).then((response)=>{ res.status(200).send(response); }).catch((err)=>{ if(err.response?.data){ res.status(err.response.status).send(err.response.data); }else{ res.status(500).send({"message":err.message}); } }) })
- Function:
doAccountUnbinding
const {AccountUnbindingRequestDto,AccountUnbindingAdditionalInfo} = require('doku-nodejs-library/_models/accountUnbindingRequestDTO'); app.post("/account-unbinding", async (req,res)=>{ let request = new AccountUnbindingRequestDto() let additionalInfo = new AccountUnbindingAdditionalInfo(req.body.additionalInfo.channel) request.tokenId = req.body.tokenId; request.additionalInfo = additionalInfo; let ipAddress = req.headers['x-ip-address']; await snap.doAccountUnbinding(request,ipAddress).then((response)=>{ res.status(200).send(response); }).catch((err)=>{ if(err.response?.data){ res.status(err.response.status).send(err.response.data); }else{ res.status(500).send({"message":err.message}); } }) })
- Function:
-
Registration
- Function:
doCardRegistration
const CardRegistrationRequestDTO = require('doku-nodejs-library/_models/cardRegistrationRequestDTO'); app.post("/card-registration", async (req,res)=>{ let request = new CardRegistrationRequestDTO() request.cardData = req.body.cardData; request.custIdMerchant = req.body.custIdMerchant; request.phoneNo = req.body.phoneNo; request.additionalInfo = req.body.additionalInfo; console.log(request) await snap.doRegistrationCardBind(request).then((response)=>{ res.status(200).send(response.data); }).catch((err)=>{ if(err.response?.data){ res.status(err.response.status).send(err.response.data); }else{ console.log(err) res.status(500).send({"message":err.message}); } }) })
- Function:
-
UnRegistration
- Function:
getTokenB2B2C
app.post('/token-b2b2c', async (req,res) => { <!--YOUR_AUTH_CODE_FROM_ACCOUNT_BINDING--> let authCode = req.body['authCode']; await snap.getTokenB2B2c(authCode).then((response)=>{ res.status(200).send(response); }).catch((err)=>{ if(err.response?.data){ res.status(err.response.status).send(err.response.data); }else{ res.status(500).send({"message":err.message}); } }) })
- Function:
doCardUnbinding
const CardUnRegistUnbindRequestDTO= require('doku-nodejs-library/_models/cardUnregistUnbindRequestDTO'); app.post("/card-unbinding", async (req,res)=>{ let request = new CardUnRegistUnbindRequestDTO(req.body.tokenId, req.body.additionalInfo ) await snap.doUnRegistCardUnBind(request).then((response)=>{ res.status(200).send(response); }).catch((err)=>{ if(err.response?.data){ res.status(err.response.status).send(err.response.data); }else{ console.log(err) res.status(500).send({"message":err.message}); } }) })
- 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
const { PaymentRequestDto } = require('doku-nodejs-library/_models/paymentRequestDirectDebitDTO'); app.post("/debit-payment", async (req,res)=>{ let request = new PaymentRequestDto() request.payOptionDetails = req.body.payOptionDetails; request.partnerReferenceNo = req.body.partnerReferenceNo; request.amount = req.body.amount; request.additionalInfo = req.body.additionalInfo; let ipAddress = req.headers['x-ip-address']; let authCode = req.body['authCode']; await snap.doPayment(request,authCode,ipAddress).then((response)=>{ res.status(200).send(response); }).catch((err)=>{ if(err.response?.data){ res.status(err.response.status).send(err.response.data); }else{ res.status(500).send({"message":err.message}); } }) })
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
const PaymentJumpAppRequestDto = require('doku-nodejs-library/_models/paymentJumpAppRequestDTO');
app.post("/payment-jump-app", async (req,res)=>{
let request = new PaymentJumpAppRequestDto()
request.partnerReferenceNo = req.body.partnerReferenceNo;
request.pointOfInitiation = req.body.pointOfInitiation;
request.urlParam = req.body.urlParam;
request.amount = req.body.amount;
request.additionalInfo = req.body.additionalInfo;
request.validUpto = req.body.validUpto;
let ipAddress = req.headers['x-ip-address'];
let deviceId = req.headers['x-device-id'];
await snap.doPaymentJumpApp(request,ipAddress,deviceId).then((response)=>{
res.status(200).send(response);
}).catch((err)=>{
if(err.response?.data){
res.status(err.response.status).send(err.response.data);
}else{
res.status(500).send({"message":err.message});
}
})
})
const CheckStatusDirectDebitDTO = require('doku-nodejs-library/_models/checkStatusDirectDebitRequestDTO');
app.post('/debit-status', async (req,res) => {
let request = new CheckStatusDirectDebitDTO()
request.originalExternalId = req.body.originalExternalId
request.originalPartnerReferenceNo= req.body.originalPartnerReferenceNo
request.originalReferenceNo = req.body.originalReferenceNo
request.serviceCode = req.body.serviceCode
request.transactionDate= req.body.transactionDate
request.amount = req.body.amount
request.merchantId = req.body.merchantId
request.subMerchantId = req.body.subMerchantId
request.externalStoreId= req.body.externalStoreId
request.additionalInfo= req.body.additionalInfo
await snap.doCheckStatus(request).then(response=>{
res.status(200).send(response);
}).catch((err)=>{
if(err.response){
res.status(400).send(err.response.data)
}else{
res.status(400).send({
responseCode:"400",
responseMessage:err.message
})
}
})
})
const RefundRequestDto = require('doku-nodejs-library/_models/refundRequestDTO');
app.post("/refund", async (req,res)=>{
let request = new RefundRequestDto();
request.originalPartnerReferenceNo = req.body.originalPartnerReferenceNo;
request.refundAmount = req.body.refundAmount;
request.partnerRefundNo = req.body.partnerRefundNo;
request.originalExternalId = req.body.originalExternalId;
request.reason = req.body.reason;
request.additionalInfo = req.body.additionalInfo;
let ipAddress = req.headers['x-ip-address'];
let authCode = req.body['authCode'];
let deviceId = req.headers['deviceId'];
await snap.doRefund(request,authCode,ipAddress,deviceId).then((response)=>{
res.status(200).send(response);
}).catch((err)=>{
if(err.response?.data){
res.status(err.response.status).send(err.response.data);
}else{
res.status(500).send({"message":err.message});
}
})
})
const BalanceInquiryRequestDto = require('doku-nodejs-library/_models/balanceInquiryRequestDTO');
app.post("/balance-inquiry", async (req,res)=>{
let request = new BalanceInquiryRequestDto();
request.additionalInfo = req.body.additionalInfo
let ipAddress = req.headers['x-ip-address'];
let authCode = req.body['authCode'];
await snap.doBalanceInquiry(request,authCode,ipAddress).then((response)=>{
res.status(200).send(response);
}).catch((err)=>{
if(err.response?.data){
res.status(err.response.status).send(err.response.data);
}else{
res.status(500).send({"message":err.message});
}
})
})
The SDK throws exceptions for various error conditions. Always wrap your API calls in try-catch blocks:
await snap.createVa(createVaRequestDto).then(va=>{
res.status(200).send(va);
}).catch(err=>{
if(err.response){
res.status(400).send(err.response.data)
}else{
res.status(400).send({
responseCode:"400",
responseMessage:err.message
})
}
})
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. |