Socket
Book a DemoInstallSign in
Socket

doku-nodejs-library

Package Overview
Dependencies
Maintainers
2
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

doku-nodejs-library

doku nodejs library

1.0.52
latest
Source
npmnpm
Version published
Weekly downloads
30
-30.23%
Maintainers
2
Weekly downloads
 
Created
Source

DOKU NODE JS SDK Documentation

Introduction

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

Table of Contents

1. Getting Started

Requirements

  • NODE JS version 18 or higher

Installation

To install the Doku Snap SDK, use Composer:

npm i doku-nodejs-library

Configuration

Before using the Doku Snap SDK, you need to initialize it with your credentials:

  • Client ID, Secret Key and DOKU Public 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.
ParameterDescriptionRequired
privateKeyThe private key for the partner service.
publicKeyThe public key for the partner service.
dokuPublicKeyKey that merchants use to verify DOKU request
clientIdThe client ID associated with the service.
secretKeyThe secret key for the partner service.
isProductionSet to true for production environment
issuerOptional issuer for advanced configurations.
authCodeOptional 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
});

2. Usage

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
});

Virtual Account

I. Virtual Account (DGPC & MGPC)

DGPC
  • Description: A pre-generated virtual account provided by DOKU.
  • Use Case: Recommended for one-time transactions.
MGPC
  • Description: Merchant generated virtual account.
  • Use Case: Recommended for top up business model.

Parameters for createVA and updateVA

ParameterDescriptionData TypeRequired
partnerServiceIdThe unique identifier for the partner service.String(20)
customerNoThe customer's identification number.String(20)
virtualAccountNoThe virtual account number associated with the customer.String(20)
virtualAccountNameThe name of the virtual account associated with the customer.String(255)
virtualAccountEmailThe email address associated with the virtual account.String(255)
virtualAccountPhoneThe phone number associated with the virtual account.String(9-30)
trxIdInvoice number in Merchants system.String(64)
totalAmountvalue: Transaction Amount (ISO 4217)
Example: "11500.00"
String(16.2)
Currency: Currency
Example: "IDR"
String(3)
additionalInfochannel: Channel that will be applied for this VA
Example: VIRTUAL_ACCOUNT_BANK_CIMB
String(20)
virtualAccountConfigreusableStatus: 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)
virtualAccountTrxTypeTransaction type for this transaction. C (Closed Amount), O (Open Amount)String(1)
expiredDateExpiration date for Virtual Account. ISO-8601
Example: "2023-01-01T10:55:00+07:00"
String
freeTextEnglish: Free text for additional description.
Example: "Free text"
String(64)
Indonesia: Free text for additional description.
Example: "Tulisan Bebas"
String(64)
  • 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
            })
          }
        
      })
    })
    
  • 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
            })
          }
        })
    })
    
  • Delete Virtual Account

    ParameterDescriptionData TypeRequired
    partnerServiceIdThe unique identifier for the partner service.String(8)
    customerNoThe customer's identification number.String(20)
    virtualAccountNoThe virtual account number associated with the customer.String(20)
    trxIdInvoice number in Merchant's system.String(64)
    additionalInfochannel: Channel applied for this VA.
    Example: VIRTUAL_ACCOUNT_BANK_CIMB
    String(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
          })
        }
      })
    })
    

II. Virtual Account (DIPC)

  • 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);
        }})
    

III. Check Virtual Account Status

ParameterDescriptionData TypeRequired
partnerServiceIdThe unique identifier for the partner service.String(8)
customerNoThe customer's identification number.String(20)
virtualAccountNoThe virtual account number associated with the customer.String(20)
inquiryRequestIdThe customer's identification number.String(128)
paymentRequestIdThe virtual account number associated with the customer.String(128)
additionalInfoThe 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
          })
      }
     })
    })
    

B. Binding / Registration Operations

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.

ServicesBinding TypeDetails
Direct DebitAccount BindingSupports Allo Bank and CIMB
Direct DebitCard RegistrationSupports BRI
E-WalletAccount BindingSupports OVO

I. Account Binding

  • Binding
ParameterDescriptionData TypeRequired
phoneNoPhone Number Customer.
Format: 628238748728423
String(9-16)
additionalInfochannel: Payment Channel
String
custIdMerchant: Customer id from merchantString(64)
customerName: Customer name from merchantString(70)
email: Customer email from merchant String(64)
idCard: Customer id card from merchantString(20)
country: Customer country String
address: Customer AddressString(255)
dateOfBirth String(YYYYMMDD)
successRegistrationUrl: Redirect URL when binding is success String
failedRegistrationUrl: Redirect URL when binding is success failString
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});
        }
      })
    })
    

II. Card Registration

  • 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});
        }
       
      })
    })
    
  • 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});
        }
       
      })
    })
    

C. Direct Debit and E-Wallet

I. Request Payment

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.

AcquirerChannel Name
Allo BankDIRECT_DEBIT_ALLO_SNAP
BRIDIRECT_DEBIT_BRI_SNAP
CIMBDIRECT_DEBIT_CIMB_SNAP
OVOEMONEY_OVO_SNAP
Common parameter
ParameterDescriptionData TypeRequired
partnerReferenceNo Reference No From Partner
Format: 628238748728423
String(9-16)
amountvalue: Transaction Amount (ISO 4217)
Example: "11500.00"
String(16.2)
Currency: Currency
Example: "IDR"
String(3)
additionalInfo channel: payment channelString
remarks:Remarks from PartnerString(40)
successPaymentUrl: Redirect Url if payment successString
failedPaymentUrl: Redirect Url if payment fail String
Allo Bank Specific Parameters
ParameterDescriptionRequired
additionalInfo.remarksRemarks from the partner
additionalInfo.lineItems.nameItem name (String)
additionalInfo.lineItems.priceItem price (ISO 4217)
additionalInfo.lineItems.quantityItem quantity (Integer)
payOptionDetails.payMethodBalance type (options: BALANCE/POINT/PAYLATER)
payOptionDetails.transAmount.valueTransaction amount
payOptionDetails.transAmount.currencyCurrency (ISO 4217, e.g., "IDR")
CIMB Specific Parameters
ParameterDescriptionRequired
additionalInfo.remarksRemarks from the partner
OVO Specific Parameters
ParameterDescriptionRequired
feeTypeFee type from partner (values: OUR, BEN, SHA)
payOptionDetails.payMethodPayment method format: CASH, POINTS
payOptionDetails.transAmount.valueTransaction amount (ISO 4217)
payOptionDetails.transAmount.currencyCurrency (ISO 4217, e.g., "IDR")
payOptionDetails.feeAmount.valueFee amount (if applicable)
payOptionDetails.feeAmount.currencyCurrency for the fee
additionalInfo.paymentTypeTransaction 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});
            }
           
          })
        })
    

II. Request Payment Jump APP

AcquirerChannel Name
DANAEMONEY_DANA_SNAP
ShopeePayEMONEY_SHOPEE_PAY_SNAP

The following fields are common across DANA and ShopeePay requests:

ParameterDescriptionData TypeRequired
partnerReferenceNo Reference No From Partner
Examplae : INV-0001
String(9-16)
validUptoExpired time payment url String
pointOfInitiationPoint of initiation from partner,
value: app/pc/mweb
String
urlParamurl: URL after payment sucess String
type: Pay Return
always PAY_RETURN
String
isDeepLink: Is Merchant use deep link or not
Example: "Y/N"
String(1)
amountvalue: Transaction Amount (ISO 4217)
Example: "11500.00"
String(16.2)
Currency: Currency
Example: "IDR"
String(3)
additionalInfo channel: payment channelString
DANA

DANA spesific parameters

ParameterDescriptionData TypeRequired
additionalInfoorderTitle: Order title from merchantString
supportDeepLinkCheckoutUrl : Value 'true' for Jumpapp behaviour, 'false' for webview, false by defaultString
For Shopeepay and Dana you can use the `doPaymentJumpApp` function for for Jumpapp behaviour
  • 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});
        }
       
      })
    })

3. Other Operation

A. Check Transaction Status

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
        })
      }
    })
})

B. Refund

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});
      }
     
    })
})

C. Balance Inquiry

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});
      }
     
    })
})

4. Error Handling and Troubleshooting

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 CodeDescriptionSolution
4010000UnauthorizedCheck if Client ID and Secret Key are valid.
4012400Virtual Account Not FoundVerify the virtual account number provided.
2002400SuccessfulTransaction completed successfully.

Keywords

doku

FAQs

Package last updated on 17 Jul 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.