Skip to content

PTNUSASATUINTIARTHA-DOKU/doku-nodejs-library

Repository files navigation

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 install doku

Configuration

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

  1. Client ID and Secret Key: Retrieve these from the Integration menu in your Doku Dashboard
  2. Private Key and Public Key : Generate your Private Key and Public Key

How to generate Merchant privateKey and publicKey :

  1. generate private key RSA : openssl genrsa -out private.key 2048
  2. set passphrase your private key RSA : openssl pkcs8 -topk8 -inform PEM -outform PEM -in private.key -out pkcs8.key -v1 PBE-SHA1-3DES
  3. 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:

  1. Standard Asymmetric Encryption Signature: SHA256withRSA dengan Private Key ( Kpriv ) dan Public Key ( Kpub ) (256 bits)
  2. Standard Symmetric Encryption Signature HMAC_SHA512 (512 bits)
  3. 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
});

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

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
  1. 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
            })
          }
        
      })
    })
    
  2. 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
            })
          }
        })
    })
    
  3. 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_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

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

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.

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

I. Account Binding

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

  1. 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});
        }
       
      })
    })
    
  2. 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.

Acquirer Channel Name
Allo Bank DIRECT_DEBIT_ALLO_SNAP
BRI DIRECT_DEBIT_BRI_SNAP
CIMB DIRECT_DEBIT_CIMB_SNAP
OVO EMONEY_OVO_SNAP
Common parameter
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
Allo Bank Specific Parameters
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")
CIMB Specific Parameters
Parameter Description Required
additionalInfo.remarks Remarks from the partner
OVO Specific Parameters
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});
            }
           
          })
        })
    

II. Request Payment Jump APP

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 Return
always PAY_RETURN
String
isDeepLink: Is Merchant use deep link or not
Example: "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

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
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 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.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •