Midtrans Client - Node JS
Midtrans ❤️ Node JS!
This is the Official Node JS API client/library for Midtrans Payment API. Visit https://midtrans.com. More information about the product and see documentation at http://docs.midtrans.com for more technical details.
1. Installation
1.a Using NPM
npm install --save midtrans-client
1.b Manual Installation
If you are not using NPM, you can clone or download this repository.
Then require from index.js
file.
let midtransClient = require('./midtrans-client-nodejs/index.js');
2. Usage
2.1 Choose Product/Method
We have 2 different products of payment that you can use:
- Snap - Customizable payment popup will appear on your web/app (no redirection). doc ref
- Snap Redirect - Customer need to be redirected to payment url hosted by midtrans. doc ref
- Core API (VT-Direct) - Basic backend implementation, you can customize the frontend embedded on your web/app as you like (no redirection). doc ref
Choose one that you think best for your unique needs.
2.2 Client Initialization and Configuration
Get your client key and server key from Midtrans Dashboard
Create API client object
const midtransClient = require('midtrans-client');
let coreApi = new midtransClient.CoreApi({
isProduction : false,
serverKey : 'YOUR_SERVER_KEY',
clientKey : 'YOUR_CLIENT_KEY'
});
const midtransClient = require('midtrans-client');
let snap = new midtransClient.Snap({
isProduction : false,
serverKey : 'YOUR_SERVER_KEY',
clientKey : 'YOUR_CLIENT_KEY'
});
You can also re-set config using Snap.apiConfig.set( ... )
example:
const midtransClient = require('midtrans-client');
let snap = new midtransClient.Snap();
snap.apiConfig.set({
isProduction : false,
serverKey : 'YOUR_SERVER_KEY',
clientKey : 'YOUR_CLIENT_KEY'
});
snap.apiConfig.set({serverKey : 'YOUR_SERVER_KEY'});
You can also set config directly from attribute
const midtransClient = require('midtrans-client');
let snap = new midtransClient.Snap();
snap.apiConfig.isProduction = false;
snap.apiConfig.serverKey = 'YOUR_SERVER_KEY';
snap.apiConfig.clientKey = 'YOUR_CLIENT_KEY';
2.2.A Snap
You can see Snap example here.
Available methods for Snap
class
createTransaction(parameter)
createTransactionToken(parameter)
createTransactionRedirectUrl(parameter)
parameter
is Object or String of JSON of SNAP Parameter
Get Snap Token
const midtransClient = require('midtrans-client');
let snap = new midtransClient.Snap({
isProduction : false,
serverKey : 'YOUR_SERVER_KEY',
clientKey : 'YOUR_CLIENT_KEY'
});
let parameter = {
"transaction_details": {
"order_id": "test-transaction-123",
"gross_amount": 200000
}, "credit_card":{
"secure" : true
}
};
snap.createTransaction(parameter)
.then((transaction)=>{
let transactionToken = transaction.token;
console.log('transactionToken:',transactionToken);
})
Initialize Snap JS when customer click pay button
On frontend / html:
Replace PUT_TRANSACTION_TOKEN_HERE
with transactionToken
acquired above
<html>
<body>
<button id="pay-button">Pay!</button>
<pre><div id="result-json">JSON result will appear here after payment:<br></div></pre>
<script src="https://app.sandbox.midtrans.com/snap/snap.js" data-client-key="<Set your ClientKey here>"></script>
<script type="text/javascript">
document.getElementById('pay-button').onclick = function(){
snap.pay('PUT_TRANSACTION_TOKEN_HERE', {
onSuccess: function(result){
document.getElementById('result-json').innerHTML += JSON.stringify(result, null, 2);
},
onPending: function(result){
document.getElementById('result-json').innerHTML += JSON.stringify(result, null, 2);
},
onError: function(result){
document.getElementById('result-json').innerHTML += JSON.stringify(result, null, 2);
}
});
};
</script>
</body>
</html>
Implement Notification Handler
Refer to this section
2.2.B Snap Redirect
Also available as examples here.
Get Redirection URL of a Payment Page
const midtransClient = require('midtrans-client');
let snap = new midtransClient.Snap({
isProduction : false,
serverKey : 'YOUR_SERVER_KEY',
clientKey : 'YOUR_CLIENT_KEY'
});
let parameter = {
"transaction_details": {
"order_id": "test-transaction-123",
"gross_amount": 200000
}, "credit_card":{
"secure" : true
}
};
snap.createTransaction(parameter)
.then((transaction)=>{
let redirectUrl = transaction.redirect_url;
console.log('redirectUrl:',redirectUrl);
})
Implement Notification Handler
Refer to this section
2.2.C Core API (VT-Direct)
You can see some Core API examples here.
Available methods for CoreApi
class
charge(parameter={})
capture(parameter={})
cardRegister(parameter={})
cardToken(parameter={})
cardPointInquiry(tokenId)
parameter
is Object or String of JSON of Core API Parameter
Credit Card Get Token
Get token should be handled on Frontend please refer to API docs
Credit Card Charge
const midtransClient = require('midtrans-client');
let core = new midtransClient.CoreApi({
isProduction : false,
serverKey : 'YOUR_SERVER_KEY',
clientKey : 'YOUR_CLIENT_KEY'
});
let parameter = {
"payment_type": "credit_card",
"transaction_details": {
"gross_amount": 12145,
"order_id": "test-transaction-54321",
},
"credit_card":{
"token_id": 'CREDIT_CARD_TOKEN',
"authentication": true
}
};
core.charge(parameter)
.then((chargeResponse)=>{
console.log('chargeResponse:');
console.log(chargeResponse);
});
Credit Card 3DS Authentication
The credit card charge result may contains redirect_url
for 3DS authentication. 3DS Authentication should be handled on Frontend please refer to API docs
For full example on Credit Card 3DS transaction refer to:
2.2.D Subscription API
You can see some Subscription API examples here, Subscription API Docs
Subscription API for Credit Card
To use subscription API for credit card, you should first obtain the 1-click saved token, refer to this docs.
You will receive saved_token_id
as part of the response when the initial card payment is accepted (will also available in the HTTP notification's JSON), refer to this docs.
const midtransClient = require('midtrans-client');
let core = new midtransClient.CoreAPi({
isProduction : false,
serverKey : 'YOUR_SERVER_KEY',
clientKey : 'YOUR_CLIENT_KEY'
});
let parameter = {
"name": "MONTHLY_2021",
"amount": "14000",
"currency": "IDR",
"payment_type": "credit_card",
"token": "521111gmWqMegyejqCQmmopnCFRs1117",
"schedule": {
"interval": 1,
"interval_unit": "month",
"max_interval": 12,
"start_time": "2021-11-25 07:25:01 +0700"
},
"metadata": {
"description": "Recurring payment for A"
},
"customer_details": {
"first_name": "John",
"last_name": "Doe",
"email": "johndoe@email.com",
"phone": "+62812345678"
}
};
core.createSubscription(parameter)
.then((response)=>{
});
core.getSubscription(subscriptionId)
.then((response)=>{
});
core.enableSubscription(subscriptionId)
.then((response)=>{
});
let updateSubscriptionParam = {
"name": "MONTHLY_2021",
"amount": "300000",
"currency": "IDR",
"token": savedTokenId,
"schedule": {
"interval": 1
}
}
core.updateSubscription(subscriptionId, updateSubscriptionParam)
.then((response)=>{
});
Subscription API for Gopay
To use subscription API for gopay, you should first link your customer gopay account with gopay tokenization API, refer to this section
You will receive gopay payment token using getPaymentAccount
API call
You can see some Subscription API examples here
2.2.E Tokenization API
You can see some Tokenization API examples here, Tokenization API Docs
const midtransClient = require('midtrans-client');
let core = new midtransClient.CoreApi({
isProduction : false,
serverKey : 'YOUR_SERVER_KEY',
clientKey : 'YOUR_CLIENT_KEY'
});
let parameter = {
"payment_type": "gopay",
"gopay_partner": {
"phone_number": "81212345678",
"country_code": "62",
"redirect_url": "https://www.gojek.com"
}
};
core.linkPaymentAccount(parameter)
.then((response)=>{
});
core.getPaymentAccount(activeAccountId)
.then((response)=>{
});
core.unlinkPaymentAccount(activeAccountId)
.then((response)=>{
});
2.3 Handle HTTP Notification
IMPORTANT NOTE: To update transaction status on your backend/database, DO NOT solely rely on frontend callbacks! For security reason to make sure the status is authentically coming from Midtrans, only update transaction status based on HTTP Notification or API Get Status.
Create separated web endpoint (notification url) to receive HTTP POST notification callback/webhook.
HTTP notification will be sent whenever transaction status is changed.
Example also available here
const midtransClient = require('midtrans-client');
let apiClient = new midtransClient.Snap({
isProduction : false,
serverKey : 'YOUR_SERVER_KEY',
clientKey : 'YOUR_CLIENT_KEY'
});
apiClient.transaction.notification(notificationJson)
.then((statusResponse)=>{
let orderId = statusResponse.order_id;
let transactionStatus = statusResponse.transaction_status;
let fraudStatus = statusResponse.fraud_status;
console.log(`Transaction notification received. Order ID: ${orderId}. Transaction status: ${transactionStatus}. Fraud status: ${fraudStatus}`);
if (transactionStatus == 'capture'){
if (fraudStatus == 'challenge'){
} else if (fraudStatus == 'accept'){
}
} else if (transactionStatus == 'settlement'){
} else if (transactionStatus == 'deny'){
} else if (transactionStatus == 'cancel' ||
transactionStatus == 'expire'){
} else if (transactionStatus == 'pending'){
}
});
2.4 Transaction Action
Also available as examples here
Get Status
apiClient.transaction.status('YOUR_ORDER_ID OR TRANSACTION_ID')
.then((response)=>{
});
Get Status B2B
apiClient.transaction.statusb2b('YOUR_ORDER_ID OR TRANSACTION_ID')
.then((response)=>{
});
Approve Transaction
apiClient.transaction.approve('YOUR_ORDER_ID OR TRANSACTION_ID')
.then((response)=>{
});
Deny Transaction
apiClient.transaction.deny('YOUR_ORDER_ID OR TRANSACTION_ID')
.then((response)=>{
});
Cancel Transaction
apiClient.transaction.cancel('YOUR_ORDER_ID OR TRANSACTION_ID')
.then((response)=>{
});
Expire Transaction
apiClient.transaction.expire('YOUR_ORDER_ID OR TRANSACTION_ID')
.then((response)=>{
});
Refund Transaction
let parameter = {
"refund_key": "order1-ref1",
"amount": 5000,
"reason": "Item out of stock"
}
apiClient.transaction.refund('YOUR_ORDER_ID OR TRANSACTION_ID',parameter)
.then((response)=>{
});
Refund Transaction with Direct Refund
let parameter = {
"refund_key": "order1-ref1",
"amount": 5000,
"reason": "Item out of stock"
}
apiClient.transaction.refundDirect('YOUR_ORDER_ID OR TRANSACTION_ID',parameter)
.then((response)=>{
});
3. Handling Error / Exception
When using function that result in Midtrans API call e.g: core.charge(...)
or snap.createTransaction(...)
there's a chance it may throw error (MidtransError
object), the error object will contains below properties that can be used as information to your error handling logic:
snap.createTransaction(parameter)
.then((res)=>{
})
.catch((e)=>{
e.message
e.httpStatusCode
e.ApiResponse
e.rawHttpClientData
})
4. Advanced Usage
Custom Http Client Config
Under the hood this API wrapper is using Axios as http client. You can override the default config.
You can set via the value of this <api-client-instance>.httpClient.http_client.defaults
object, like described in Axios guide. e.g:
let snap = new midtransClient.Snap({
isProduction : false,
serverKey : 'YOUR_SERVER_KEY',
clientKey : 'YOUR_CLIENT_KEY'
});
snap.httpClient.http_client.defaults.timeout = 2500;
snap.httpClient.http_client.defaults.headers.common['My-Header'] = 'my-custom-value';
Custom Http Client Interceptor
As Axios also support interceptor, you can also apply it here. e.g:
snap.httpClient.http_client.interceptors.request.use(function (config) {
return config;
}, function (error) {
return Promise.reject(error);
});
It can be used for example to customize/manipulate http request's body, header, etc. before it got sent to the destination API url.
Override Http Notification Url
As described in API docs, merchant can opt to change or add custom notification urls on every transaction. It can be achieved by adding additional HTTP headers into charge request.
This can be achived by:
let snap = new midtransClient.Snap({
isProduction : false,
serverKey : 'YOUR_SERVER_KEY',
clientKey : 'YOUR_CLIENT_KEY'
});
snap.httpClient.http_client.defaults.headers.common['X-Override-Notification'] = 'https://mysite.com/midtrans-notification-handler';
or append notification:
snap.httpClient.http_client.defaults.headers.common['X-Append-Notification'] = 'https://mysite.com/midtrans-notification-handler';
5. Iris Disbursement API
Iris is Midtrans’ cash management solution that allows you to disburse payments to any bank accounts in Indonesia securely and easily. Iris connects to the banks’ hosts to enable seamless transfer using integrated APIs.
For more details please visit: https://iris-docs.midtrans.com
5.1 Client Initialization
Get your API key from Midtrans Iris Dashboard
Create API client object. Note: the serverKey means your API key.
const midtransClient = require('midtrans-client');
let iris = new midtransClient.Iris({
isProduction : false,
serverKey : 'YOUR_API_KEY'
});
Then perform one of the available functions, using the payload described on Iris docs, e.g:
let iris = new midtransClient.Iris({
isProduction : false,
serverKey : 'YOUR_API_KEY'
});
iris.createBeneficiaries({
"name": "Budi Susantoo",
"account": "0611101146",
"bank": "bca",
"alias_name": "budisusantoo",
"email": "budi.susantoo@example.com"
})
.then((res)=>{
})
.catch((err)=>{
})
5.2 Available methods of Iris API
ping()
createBeneficiaries(parameter={})
updateBeneficiaries(aliasName,parameter={})
getBeneficiaries()
createPayouts(parameter={})
approvePayouts(parameter={})
rejectPayouts(parameter={})
getPayoutDetails(referenceNo)
getTransactionHistory(parameter={})
getTopupChannels()
getBalance()
getFacilitatorBankAccounts()
getFacilitatorBalance(bankAccountId)
getBeneficiaryBanks()
validateBankAccount(parameter={})
You can also refer to Iris test cases for sample usage for now. Dedicated sample usage might be written later in the future.
Examples
Examples are available on /examples folder.
There are:
Notes
Not Designed for Frontend Usage
This library/package is mainly NOT FOR FRONTEND (Browser's javascript) usage, but for backend (Node JS server) usage:
- This is mainly for backend usage, to do secure server-to-server/backend-to-backend API call.
- You may/will encounter CORS issue if you are using this to do API request from frontend.
- Your API ServerKey may also be exposed to public if you are using this on frontend.
- If what you need is to display Snap payment page on your frontend, please follow this official documentation
Get help