Mutasiku JavaScript SDK for interacting with the Mutasiku API to manage financial accounts and track transactions for Indonesian payment providers like DANA, OVO, GOPAY MERCHANT and etc.
npm install mutasiku-sdkimport MutasikuSDK from 'mutasiku-sdk';
const mutasiku = new MutasikuSDK({
apiKey: process.env.MUTASIKU_API_KEY
});// Get all providers
const providers = await mutasiku.getProviders();
// With filters
const filteredProviders = await mutasiku.getProviders({
type: 'EWALLET',
isActive: true,
search: 'dana'
});// Get all accounts
const accounts = await mutasiku.getAccounts();
// With pagination and filters
const filteredAccounts = await mutasiku.getAccounts({
limit: 10,
page: 1,
providerCode: 'OVO',
isActive: true,
search: 'my account'
});const account = await mutasiku.getAccountById('account-id-here');const result = await mutasiku.updateAccount('account-id-here', {
accountName: 'New Account Name',
intervalMinutes: 10,
isActive: true
});Trigger a manual refresh for an account to sync the latest transactions:
const result = await mutasiku.refreshAccount('account-id-here');const result = await mutasiku.removeAccount('account-id-here');const addOvoResult = await mutasiku.addAccount({
action: "ovo-send-otp",
phoneNumber: "+628123456789",
providerCode: "OVO",
accountName: "My OVO Account",
intervalMinutes: 5,
verificationMethod: "WhatsApp"
});
// If successful, verify with OTP
if (addOvoResult.status === 'success') {
const verifyResult = await mutasiku.verifyAccount({
action: "ovo-verify-otp",
sessionId: addOvoResult.data.sessionId,
otp: "123456", // OTP received via WhatsApp or SMS
pin: "123456" // OVO PIN
});
}const addDanaResult = await mutasiku.addAccount({
action: "dana-send-otp",
phoneNumber: "08123456789",
pin: "123456", // DANA PIN
providerCode: "DANA",
accountName: "My DANA Account",
intervalMinutes: 5,
verificationMethod: "SMS"
});
// If successful, verify with OTP
if (addDanaResult.status === 'success') {
const verifyResult = await mutasiku.verifyAccount({
action: "dana-verify-otp",
sessionId: addDanaResult.data.sessionId,
otp: "123456" // OTP received via SMS
});
}const addGopayResult = await mutasiku.addAccount({
action: "gopay-merchant-send-otp",
phoneNumber: "08123456789",
providerCode: "GOPAY-MERCHANT",
accountName: "My GOPAY Merchant",
intervalMinutes: 5,
verificationMethod: "SMS"
});
// First OTP verification
if (addGopayResult.status === 'success') {
const verifyResult = await mutasiku.verifyAccount({
action: "gopay-merchant-verify-otp",
sessionId: addGopayResult.data.sessionId,
otp: "123456"
});
// If second OTP is required
if (verifyResult.status === 'success' && verifyResult.data.requireSecondOtp) {
const secondOtpResult = await mutasiku.verifySecondOtp({
sessionId: verifyResult.data.sessionId,
otp: "654321"
});
}
}When an account session expires, you can relogin:
const reloginResult = await mutasiku.addAccount({
action: "dana-send-otp",
accountId: "existing-account-id",
verificationMethod: "SMS"
});
if (reloginResult.status === 'success') {
const verifyResult = await mutasiku.verifyAccount({
action: "dana-verify-otp",
sessionId: reloginResult.data.sessionId,
otp: "123456",
accountId: "existing-account-id"
});
}Create QRIS, Virtual Account, or Direct payments:
// QRIS Payment (Static)
const qrisPayment = await mutasiku.createPayment({
type: 'QRIS',
walletAccountId: 'your-wallet-account-id',
amount: 50000,
externalId: 'order-123',
description: 'Order #123',
customerName: 'John Doe',
customerEmail: 'john@example.com',
expiredAt: '2025-12-31T23:59:59Z',
callbackUrl: 'https://yoursite.com/success'
});
// QRIS Payment (Dynamic)
const qrisDynamicPayment = await mutasiku.createPayment({
type: 'QRIS-DYNAMIC',
walletAccountId: 'your-wallet-account-id',
amount: 75000,
externalId: 'order-124'
});
// Virtual Account Payment (BCA)
const vaPayment = await mutasiku.createPayment({
type: 'VA-BCA',
walletAccountId: 'your-wallet-account-id',
amount: 100000,
externalId: 'order-456',
customerName: 'Jane Doe'
});
// Virtual Account Payment (Mandiri)
const vaMandiriPayment = await mutasiku.createPayment({
type: 'VA-MANDIRI',
walletAccountId: 'your-wallet-account-id',
amount: 100000,
externalId: 'order-789'
});
// Virtual Account Payment (Permata)
const vaPermataPayment = await mutasiku.createPayment({
type: 'VA-PERMATA',
walletAccountId: 'your-wallet-account-id',
amount: 100000,
externalId: 'order-101'
});
// Direct Payment
const directPayment = await mutasiku.createPayment({
type: 'DIRECT',
walletAccountId: 'your-wallet-account-id',
amount: 25000
});const status = await mutasiku.getPaymentStatus('payment-id-here');
if (status.status === 'success') {
console.log('Payment status:', status.data.status); // PENDING, PAID, EXPIRED, FAILED
if (status.data.status === 'PAID') {
console.log('Paid at:', status.data.paidAt);
}
}// Get all transactions from the past 7 days
const recentTransactions = await mutasiku.getMutasi({
days: 7
});
// With custom date range and filters
const customTransactions = await mutasiku.getMutasi({
startDate: '2025-01-01',
endDate: '2025-01-31',
accountId: 'account-id-here',
accountType: 'EWALLET',
type: 'CREDIT', // or 'DEBIT'
minAmount: 10000,
maxAmount: 1000000,
search: 'coffee',
limit: 50,
page: 1
});const banks = await mutasiku.getDanaBanks('dana-account-id');
if (banks.status === 'success') {
console.log('Available banks:', banks.data);
// Returns list of supported banks with their details
}Upload a QR code image to make QRIS payments through DANA:
// For browser usage with file input
const fileInput = document.getElementById('qr-upload');
const file = fileInput.files[0];
const result = await mutasiku.transferDanaQris('dana-account-id', file, 25000);
if (result.status === 'success') {
console.log('QRIS payment successful');
} else {
console.error('QRIS payment failed:', result.message || result.error);
}Transfer money from DANA to bank accounts using a two-step process:
Step 1: Initialize Transfer (Check Account Name)
const initResult = await mutasiku.transferDanaBankInit('dana-account-id', {
accountNumber: '1234567890',
amount: 10000,
instId: 'BCAC1ID',
instLocalName: 'BCA',
payMethod: 'WITHDRAW_BANKCARD',
payOption: 'WITHDRAW_BANKCARD_BCA'
});
if (initResult.status === 'success') {
console.log('Account verified:', initResult.data.accountName);
console.log('Bank Account Index:', initResult.data.bankAccountIndexNo);
}Step 2: Confirm Transfer
if (initResult.status === 'success') {
const confirmResult = await mutasiku.transferDanaBankCreate('dana-account-id', {
amount: 10000,
bankAccountIndexNo: initResult.data.bankAccountIndexNo // From init response
});
if (confirmResult.status === 'success') {
console.log('Transfer completed successfully!');
} else {
console.error('Transfer failed:', confirmResult.message || confirmResult.error);
}
}| Option | Type | Required | Description |
|---|---|---|---|
| apiKey | string | Yes | Your Mutasiku API key |
| logger | object | No | Custom logger (defaults to console) |
getProviders(options)- Get available banks and e-wallets
getAccounts(options)- Get all accounts with optional filtersgetAccountById(accountId)- Get a specific account by IDupdateAccount(accountId, data)- Update account informationrefreshAccount(accountId)- Trigger manual refresh for an accountremoveAccount(accountId)- Remove an accountaddAccount(data)- Add a new account (OVO, DANA, GOPAY-MERCHANT, etc.)verifyAccount(data)- Verify account with OTPverifySecondOtp(data)- Verify GOPAY Merchant second OTP
getMutasi(options)- Get transaction history with filters
createPayment(data)- Create QRIS, QRIS-DYNAMIC, Virtual Account, or Direct paymentgetPaymentStatus(paymentId)- Check payment status
getDanaBanks(accountId)- Get available banks for DANA transfertransferDanaQris(accountId, qrImage, amount)- Make QRIS payment using QR code imagetransferDanaBankInit(accountId, transferData)- Initialize bank transfer and verify account nametransferDanaBankCreate(accountId, transferData)- Confirm and execute bank transfer
| Provider | QRIS | QRIS-DYNAMIC | VA-BCA | VA-MANDIRI | VA-PERMATA | DIRECT |
|---|---|---|---|---|---|---|
| DANA PERSONAL | - | - | Yes | Yes | Yes | Yes |
| DANA BISNIS | Yes | Yes | - | - | - | - |
| OVO | - | - | - | - | - | Yes |
| GOPAY-MERCHANT | Yes | Yes | - | - | - | - |
| Parameter | Type | Required | Description |
|---|---|---|---|
| accountId | string | Yes | DANA account ID |
| transferData.accountNumber | string | Yes | Destination bank account number |
| transferData.amount | number | Yes | Transfer amount (minimum Rp 10,000) |
| transferData.instId | string | Yes | Bank institution ID |
| transferData.instLocalName | string | Yes | Bank local name |
| transferData.payMethod | string | Yes | Payment method |
| transferData.payOption | string | Yes | Payment option |
| Parameter | Type | Required | Description |
|---|---|---|---|
| accountId | string | Yes | DANA account ID |
| transferData.amount | number | Yes | Transfer amount |
| transferData.bankAccountIndexNo | string | Yes | Bank account index from init response |
| Parameter | Type | Required | Description |
|---|---|---|---|
| accountId | string | Yes | DANA account ID |
| qrImage | File/Blob | Yes | QR code image file |
| amount | number | Yes | Payment amount |
All API methods return a response object with the following structure:
// Success response
{
status: 'success',
data: { /* response data */ },
pagination: { /* pagination info if applicable */ }
}
// Error response
{
status: 'error',
message: 'Human readable message',
error: { /* error details if any */ }
}Note: Check response.status === 'success' to verify if the request was successful.
async function performDanaTransfer() {
// 1. Get available banks
const banks = await mutasiku.getDanaBanks('your-dana-account-id');
// 2. Initialize transfer to verify account
const initResult = await mutasiku.transferDanaBankInit('your-dana-account-id', {
accountNumber: '1234567890',
amount: 10000,
instId: 'BCAC1ID',
instLocalName: 'BCA',
payMethod: 'WITHDRAW_BANKCARD',
payOption: 'WITHDRAW_BANKCARD_BCA'
});
if (initResult.status === 'success') {
console.log(`Transferring to: ${initResult.data.accountName}`);
// 3. Confirm transfer
const result = await mutasiku.transferDanaBankCreate('your-dana-account-id', {
amount: 10000,
bankAccountIndexNo: initResult.data.bankAccountIndexNo
});
if (result.status === 'success') {
console.log('Transfer successful!');
}
}
}async function createAndCheckPayment() {
// Create QRIS payment
const payment = await mutasiku.createPayment({
type: 'QRIS',
walletAccountId: 'your-wallet-account-id',
amount: 50000,
externalId: 'order-123'
});
if (payment.status === 'success') {
console.log('QR Code:', payment.data.qrCode);
// Check status periodically
const checkStatus = async () => {
const status = await mutasiku.getPaymentStatus(payment.data.id);
if (status.status === 'success' && status.data.status === 'PAID') {
console.log('Payment received!');
return true;
}
return false;
};
// Poll for status (in production, use webhooks instead)
const interval = setInterval(async () => {
if (await checkStatus()) {
clearInterval(interval);
}
}, 5000);
}
}MIT License
MIT License
Copyright (c) 2026 PT. Cobra Code Indonesia
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.