REST API Mutasi Bank: Dokumentasi Lengkap dengan Contoh Code
Panduan step-by-step untuk developer: authentication, 25+ endpoints, webhook integration, dan best practices untuk production

Banking automation & API integration tutorials for Indonesian developers
📌 TL;DR (Quick Summary)
Butuh otomasi monitoring transaksi bank untuk sistem Anda? API Mutasibank menyediakan:
✅ 25+ REST API endpoints untuk complete automation
✅ 34 bank didukung (BCA, BRI, Mandiri, BNI, BSI, dll)
✅ Webhook callbacks dengan HMAC-SHA256 signature security
✅ Code examples siap pakai: PHP, Node.js, Python
✅ Gratis 7 hari trial untuk testing tanpa biaya
Reading time: 15 menit • Level: Intermediate
Daftar Isi
Apa itu API Mutasi Bank?
Pernahkah Anda menghabiskan berjam-jam untuk manual checking transfer bank setiap hari? Atau kehilangan customer karena verifikasi pembayaran terlalu lama?
REST API Mutasi Bank adalah solusi untuk mengotomasi 100% proses monitoring transaksi bank. Dengan API ini, sistem Anda bisa:
🎯 Use Cases Umum:
E-Commerce & Marketplace:
Auto-confirm order saat customer transfer
Match nominal dengan order ID
Kirim konfirmasi instant ke customer
Gaming & Top-Up:
Deteksi pembayaran otomatis (5-10 menit)
Auto-process top-up saldo
Hemat waktu operasional hingga 80%
Fintech & Payment Gateway:
Build payment verification system
Multi-bank support dalam 1 API
Real-time balance monitoring
UMKM & Retail:
Monitor transaksi multi-cabang
Deteksi anomali transaksi
Laporan keuangan otomatis
🏦 Supported Banks (34 Total):
BCA (5 variants): KlikBCA, BCA API, BCA SNAP, BCA Giro, BCA Syariah
BRI (6 variants): BRI IB, BRI Giro, BRI CMS, IBBIZ, Qlola
Mandiri (6 variants): Livin', Mandiri IB, Mandiri Giro, MCM Corporate
BNI (4 variants): BNI IB, BNI Mobile, BNI Giro, BNI Direct NG
BSI (4 variants): BSI IB, BSI CMS, BSI Remittance, BSI CUZ
Others (9 banks): Muamalat, CIMB, Sinarmas, Permata, Jago, dll
👉 Lihat daftar lengkap bank yang didukung
Getting Started
Prerequisites
Sebelum mulai, pastikan Anda punya:
✅ PHP 7.4+ / Node.js 14+ / Python 3.8+
✅ Account Mutasibank (daftar gratis 7 hari)
✅ API Token (dari dashboard Mutasibank)
✅ Basic knowledge: HTTP, JSON, REST API
Step 1: Get Your API Token
Login ke mutasibank.co.id
Go to Dashboard → API Key
Copy your API token
Simpan di environment variable (jangan hardcode!)
# .env
MUTASIBANK_API_TOKEN=your_api_token_here
Step 2: Quick Test
Test API dengan cURL untuk memastikan token valid:
curl -X GET "https://mutasibank.co.id/api/v1/user" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Expected response:
{
"error": false,
"data": {
"name": "John Doe",
"email": "john@example.com",
"saldo": 100000,
"jenis_akun": "advance"
}
}
✅ Jika dapat response seperti ini, token Anda valid!
Authentication
Bearer Token Authentication
Semua API request memerlukan Bearer token di header:
Authorization: Bearer YOUR_API_TOKEN
Security Best Practices
❌ Bad Practice (DON'T DO THIS):
<?php
// Hardcoded token - DANGEROUS!
$token = "abc123def456ghi789";
✅ Good Practice (DO THIS):
<?php
// Store in environment variable
$token = getenv('MUTASIBANK_API_TOKEN');
// Or with Laravel
$token = env('MUTASIBANK_API_TOKEN');
// Node.js with dotenv
require('dotenv').config();
const token = process.env.MUTASIBANK_API_TOKEN;
# Python with python-dotenv
import os
from dotenv import load_dotenv
load_dotenv()
token = os.getenv('MUTASIBANK_API_TOKEN')
Error Responses
401 Unauthorized:
{
"error": true,
"message": "User not found"
}
Solusi: Check token Anda di dashboard, pastikan masih valid.
Core Endpoints
API Mutasibank menyediakan 25+ endpoints untuk complete automation. Berikut endpoint-endpoint utama:
1. User Management
GET /api/v1/user
Get informasi user yang sedang login (balance, package, dll).
Request:
curl -X GET "https://mutasibank.co.id/api/v1/user" \
-H "Authorization: Bearer YOUR_TOKEN"
Response:
{
"error": false,
"data": {
"name": "John Doe",
"email": "john@example.com",
"saldo": 100000,
"jenis_akun": "advance"
}
}
2. Bank Accounts
GET /api/v1/accounts
Get semua bank account yang terdaftar.
Request:
curl -X GET "https://mutasibank.co.id/api/v1/accounts" \
-H "Authorization: Bearer YOUR_TOKEN"
Response:
{
"error": false,
"data": [
{
"id": 1,
"unique_id": "abc123def",
"bank_name": "Bank BCA Personal",
"account_name": "PT Example Indonesia",
"account_number": "1234567890",
"is_active": true,
"last_check": "2025-10-02 10:30:00",
"last_balance": 5000000,
"status": "online"
}
]
}
POST /api/v1/account/create
Daftarkan bank account baru untuk di-monitor.
Request:
curl -X POST "https://mutasibank.co.id/api/v1/account/create" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"bank_id": 1,
"account_name": "PT Example",
"account_no": "1234567890",
"user_banking": "your_username",
"password_banking": "your_password",
"schedule_minutes": 10
}'
Response:
{
"error": false,
"message": "Account created successfully",
"data": {
"id": 123,
"unique_id": "xyz789",
"bank_name": "Bank BCA Personal"
}
}
Other Account Endpoints:
GET /api/v1/account/{id}- Get single accountPUT /api/v1/account/{id}- Update accountDELETE /api/v1/account/{id}- Delete accountPOST /api/v1/account/{id}/toggle- Enable/disable monitoringPOST /api/v1/account/{id}/input_token- Input BCA token (untuk BCA)POST /api/v1/account/{id}/rerun- Manually trigger checkGET /api/v1/account/{id}/log_bot- Get bot activity logs
3. Transactions (Bank Statements)
GET /api/v1/account/{id}/statements
Get transaction history dari bank account.
Parameters:
start_date(required): FormatY-m-d(e.g.,2025-01-01)end_date(required): FormatY-m-d
Request:
curl -X GET "https://mutasibank.co.id/api/v1/account/1/statements?start_date=2025-10-01&end_date=2025-10-02" \
-H "Authorization: Bearer YOUR_TOKEN"
Response:
{
"error": false,
"data": [
{
"id": "uuid-transaction-id",
"unique_id": "TRX20251002001",
"transaction_date": "2025-10-02",
"description": "TRANSFER FROM JOHN DOE ORDER-12345",
"type": "CR",
"amount": 150000,
"balance": 5150000
}
]
}
Field explanation:
type:CR= Credit (uang masuk),DB= Debit (uang keluar)amount: Nominal transaksibalance: Saldo setelah transaksidescription: Keterangan dari bank
POST /api/v1/account/{id}/match
Find transaction by amount (single result).
Request:
curl -X POST "https://mutasibank.co.id/api/v1/account/1/match" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"amount": 150000}'
Use case: Match pembayaran customer dengan order amount.
POST /api/v1/account/{id}/match_multiple
Find ALL transactions yang match dengan amount (multiple results).
Use case: Untuk amount yang mungkin muncul berkali-kali (e.g., harga produk yang sama).
POST /api/v1/transaction/{id}/validate
Validate specific transaction by ID.
curl -X POST "https://mutasibank.co.id/api/v1/transaction/uuid-123/validate" \
-H "Authorization: Bearer YOUR_TOKEN"
4. Webhooks
GET /api/v1/webhooks
List all registered webhooks.
POST /api/v1/webhook/create
Create webhook untuk receive real-time notifications.
Request:
{
"url": "https://yoursite.com/webhook/mutasibank",
"bank_account_id": 1,
"description": "Production webhook"
}
Response includes:
Webhook ID
Webhook Secret (64 chars) - SIMPAN INI untuk signature verification!
Other Webhook Endpoints:
PUT /api/v1/webhook/{id}- Update webhookDELETE /api/v1/webhook/{id}- Delete webhookGET /api/v1/webhook/{id}- Get webhook details
5. Other Endpoints
Categories:
GET /api/v1/categories- Transaction categoriesPOST /api/v1/category- Create categoryPUT /api/v1/category/{id}- Update categoryDELETE /api/v1/category/{id}- Delete category
Billing:
POST /api/v1/topup- Create top-up request
📖 Lihat semua 25+ endpoints di Swagger UI
Code Examples
PHP Implementation
Install helper class:
git clone https://github.com/daffigusti/mutasi_api_sample
cd mutasi_api_sample
Basic usage:
<?php
require_once 'Helper.php';
// Initialize
$api = new MutasibankAPI('your-api-token');
// Get user info
$user = $api->getUser();
echo "Balance: Rp " . number_format($user['data']['saldo']) . "\n";
// Get all accounts
$accounts = $api->getAccounts();
foreach ($accounts['data'] as $account) {
echo "{$account['bank_name']}: {$account['account_number']}\n";
echo "Balance: Rp " . number_format($account['last_balance']) . "\n";
}
// Get transactions (last 7 days)
$accountId = 1;
$transactions = $api->getStatements(
$accountId,
date('Y-m-d', strtotime('-7 days')),
date('Y-m-d')
);
foreach ($transactions['data'] as $tx) {
$type = $tx['type'] == 'CR' ? 'MASUK' : 'KELUAR';
echo "[{$type}] {$tx['description']}: Rp " . number_format($tx['amount']) . "\n";
}
// Match transaction by amount
$amount = 150000;
$match = $api->matchTransaction($accountId, $amount);
if (!$match['error']) {
echo "Found transaction:\n";
echo "Description: {$match['data']['description']}\n";
echo "Date: {$match['data']['transaction_date']}\n";
} else {
echo "Transaction not found\n";
}
// Create new account
$newAccount = $api->createAccount([
'bank_id' => 1, // BCA
'account_name' => 'PT Example',
'account_no' => '1234567890',
'user_banking' => 'username_klikbca',
'password_banking' => 'password_klikbca',
'schedule_minutes' => 10,
'url_callback' => 'https://yoursite.com/webhook'
]);
print_r($newAccount);
📥 Download complete Helper.php
Node.js Implementation
const axios = require('axios');
class MutasibankAPI {
constructor(apiToken) {
this.baseURL = 'https://mutasibank.co.id/api/v1';
this.token = apiToken;
this.headers = {
'Authorization': `Bearer ${apiToken}`,
'Content-Type': 'application/json'
};
}
// Get user info
async getUser() {
const response = await axios.get(`${this.baseURL}/user`, {
headers: this.headers
});
return response.data;
}
// Get all accounts
async getAccounts() {
const response = await axios.get(`${this.baseURL}/accounts`, {
headers: this.headers
});
return response.data;
}
// Get transactions
async getStatements(accountId, startDate, endDate) {
const response = await axios.get(
`${this.baseURL}/account/${accountId}/statements`,
{
headers: this.headers,
params: {
start_date: startDate,
end_date: endDate
}
}
);
return response.data;
}
// Match transaction
async matchTransaction(accountId, amount) {
const response = await axios.post(
`${this.baseURL}/account/${accountId}/match`,
{ amount },
{ headers: this.headers }
);
return response.data;
}
}
// Usage
const api = new MutasibankAPI(process.env.MUTASIBANK_TOKEN);
(async () => {
// Get accounts
const accounts = await api.getAccounts();
console.log('Accounts:', accounts.data);
// Get today's transactions
const today = new Date().toISOString().split('T')[0];
const transactions = await api.getStatements(1, today, today);
console.log('Transactions:', transactions.data);
// Match transaction
const match = await api.matchTransaction(1, 150000);
if (!match.error) {
console.log('Found:', match.data);
}
})();
Python Implementation
import requests
from datetime import date, timedelta
import os
class MutasibankAPI:
def __init__(self, api_token):
self.base_url = 'https://mutasibank.co.id/api/v1'
self.token = api_token
self.headers = {
'Authorization': f'Bearer {api_token}',
'Content-Type': 'application/json'
}
def get_user(self):
response = requests.get(
f'{self.base_url}/user',
headers=self.headers
)
return response.json()
def get_accounts(self):
response = requests.get(
f'{self.base_url}/accounts',
headers=self.headers
)
return response.json()
def get_statements(self, account_id, start_date, end_date):
response = requests.get(
f'{self.base_url}/account/{account_id}/statements',
headers=self.headers,
params={
'start_date': start_date,
'end_date': end_date
}
)
return response.json()
def match_transaction(self, account_id, amount):
response = requests.post(
f'{self.base_url}/account/{account_id}/match',
headers=self.headers,
json={'amount': amount}
)
return response.json()
# Usage
api = MutasibankAPI(os.getenv('MUTASIBANK_TOKEN'))
# Get user
user = api.get_user()
print(f"Balance: Rp {user['data']['saldo']:,}")
# Get accounts
accounts = api.get_accounts()
for account in accounts['data']:
print(f"{account['bank_name']}: {account['account_number']}")
# Get last 7 days transactions
today = date.today()
last_week = today - timedelta(days=7)
transactions = api.get_statements(
account_id=1,
start_date=last_week.strftime('%Y-%m-%d'),
end_date=today.strftime('%Y-%m-%d')
)
for tx in transactions['data']:
tx_type = 'MASUK' if tx['type'] == 'CR' else 'KELUAR'
print(f"[{tx_type}] {tx['description']}: Rp {tx['amount']:,}")
Webhook Integration
Webhook adalah cara paling efisien untuk menerima notifikasi transaksi tanpa perlu polling.
How Webhooks Work
Bank Transaction Occurs
↓
Mutasibank detects (5-10 min)
↓
Mutasibank sends POST to your URL
↓
Your server processes instantly
Create Webhook
$webhook = $api->createWebhook([
'url' => 'https://yoursite.com/webhook/mutasibank',
'bank_account_id' => 1,
'description' => 'Production webhook for account BCA'
]);
// IMPORTANT: Save webhook secret!
$secret = $webhook['data']['secret']; // 64 characters
// Store this in environment variable
Webhook Payload
Setiap kali ada transaksi baru, Mutasibank akan POST ke URL Anda:
{
"api_key": "your_api_token",
"account_id": 123,
"module": "bca",
"account_name": "PT Example",
"account_number": "1234567890",
"balance": 5150000,
"data_mutasi": [
{
"id": "uuid-tx-id",
"transaction_date": "2025-10-02 14:30:00",
"description": "TRANSFER FROM CUSTOMER ORDER-12345",
"type": "CR",
"amount": 150000,
"balance": 5150000
}
]
}
Webhook Security (CRITICAL!)
🔒 Selalu verifikasi signature untuk prevent fraud!
Headers yang dikirim:
X-Mutasibank-Signature: abc123... (HMAC-SHA256 hash)
X-Mutasibank-Timestamp: 1696234567 (Unix timestamp)
X-Mutasibank-Webhook-Id: uuid-webhook-id
PHP Verification:
<?php
// Get headers
$signature = $_SERVER['HTTP_X_MUTASIBANK_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_MUTASIBANK_TIMESTAMP'] ?? '';
// Get raw payload
$payload = file_get_contents('php://input');
// Get webhook secret (from dashboard when creating webhook)
$secret = getenv('WEBHOOK_SECRET'); // 64 chars
// Verify timestamp (prevent replay attacks)
if (abs(time() - $timestamp) > 300) { // 5 minutes tolerance
http_response_code(401);
die(json_encode(['error' => 'Request expired']));
}
// Calculate expected signature
$expectedSignature = hash_hmac('sha256', $payload, $secret);
// Verify signature (use constant-time comparison!)
if (!hash_equals($expectedSignature, $signature)) {
http_response_code(401);
die(json_encode(['error' => 'Invalid signature']));
}
// ✅ Signature valid - process webhook
$data = json_decode($payload, true);
foreach ($data['data_mutasi'] as $transaction) {
// Your business logic here
if ($transaction['type'] == 'CR') { // Credit (uang masuk)
// Auto-confirm order
$orderId = extractOrderId($transaction['description']);
confirmOrder($orderId, $transaction['amount']);
}
}
http_response_code(200);
echo json_encode(['success' => true]);
📥 Download complete webhook examples (PHP, Node.js, Python)
Best Practices
1. Security
✅ DO:
Always use HTTPS for webhook URLs
Verify HMAC signatures (use
hash_equals())Check timestamp to prevent replay attacks
Store secrets in environment variables
Enable SSL verification in cURL
Log webhook activity (without sensitive data)
❌ DON'T:
Use HTTP for webhooks (insecure!)
Skip signature verification (risk of fraud!)
Use
==for signature comparison (timing attack vulnerable)Hardcode API tokens in code
Log sensitive data (passwords, tokens)
2. Performance
✅ Optimize dengan:
Cache API responses (5-10 min untuk balance)
Use webhooks instead of constant polling
Batch operations when possible
Implement queue for webhook processing
Set reasonable timeouts (30 seconds)
3. Error Handling
<?php
function callAPIWithRetry($callback, $maxRetries = 3) {
$attempt = 0;
$delay = 1; // seconds
while ($attempt < $maxRetries) {
try {
return $callback();
} catch (Exception $e) {
$attempt++;
if ($attempt >= $maxRetries) {
// Log error
error_log("API Error after {$maxRetries} retries: " . $e->getMessage());
throw $e;
}
// Exponential backoff: 1s, 2s, 4s
sleep($delay);
$delay *= 2;
}
}
}
// Usage
$accounts = callAPIWithRetry(function() use ($api) {
return $api->getAccounts();
});
4. Production Checklist
Sebelum production, pastikan:
[ ] API token disimpan di environment variable
[ ] Webhook signature verification implemented
[ ] SSL certificate valid untuk webhook URL
[ ] Error logging & monitoring setup
[ ] Retry logic untuk API calls
[ ] Rate limiting awareness (60 req/min recommended)
[ ] Queue workers running (untuk webhook processing)
[ ] Alerting untuk critical errors
Real-World Use Case: E-Commerce Auto-Confirm
Contoh complete implementation untuk auto-confirm order:
<?php
// webhook_handler.php
// 1. Verify signature (lihat code di atas)
verifyWebhookSignature();
// 2. Parse payload
$data = json_decode(file_get_contents('php://input'), true);
// 3. Process each transaction
foreach ($data['data_mutasi'] as $transaction) {
if ($transaction['type'] == 'CR') { // Uang masuk
// Extract order ID from description
// Example: "TRANSFER FROM CUSTOMER ORDER-12345"
preg_match('/ORDER-(\d+)/', $transaction['description'], $matches);
if (isset($matches[1])) {
$orderId = $matches[1];
// Find order in database
$order = DB::table('orders')
->where('id', $orderId)
->where('total', $transaction['amount'])
->where('status', 'pending')
->first();
if ($order) {
// Update order status
DB::table('orders')->where('id', $orderId)->update([
'status' => 'paid',
'payment_proof' => $transaction['id'],
'paid_at' => $transaction['transaction_date']
]);
// Send confirmation email
Mail::to($order->customer_email)->send(
new OrderConfirmedEmail($order)
);
// Send WhatsApp notification
WhatsApp::send(
$order->customer_phone,
"✅ Pembayaran order #{$orderId} telah dikonfirmasi! Terima kasih."
);
// Log success
Log::info('Order auto-confirmed', [
'order_id' => $orderId,
'amount' => $transaction['amount'],
'tx_id' => $transaction['id']
]);
}
}
}
}
http_response_code(200);
echo json_encode(['success' => true]);
Benefit:
⚡ Auto-confirm dalam 5-10 menit (sesuai schedule)
🤖 Zero manual work
📉 Reduce customer complaints
📈 Increase customer satisfaction
FAQ
Q: Berapa rate limit API?
A: Currently tidak ada hard limit, tapi kami recommend maksimal 60 requests/minute untuk optimal performance.
Q: Apakah ada sandbox/testing environment?
A: Ya! Gunakan free 7-day trial untuk testing dengan real bank accounts. Atau bisa create test account dengan minimal balance.
Q: Bagaimana billing calculation?
A: Harga per rekening per hari:
Standard: Rp 2.000/hari (untuk 10 bank tertentu)
Advanced: Rp 3.500/hari (untuk 24 bank)
Monitor 10 rekening = Rp 20.000-35.000/hari.
Q: Support bank apa saja?
A: Total 34 bank didukung, termasuk:
BCA (5 variants)
BRI (6 variants)
Mandiri (6 variants)
BNI (4 variants)
BSI, CIMB, Permata, Muamalat, dll
Q: Webhook retry policy?
A: Jika webhook gagal terkirim, sistem auto-retry 3 kali dengan exponential backoff:
Retry 1: 1 second
Retry 2: 5 seconds
Retry 3: 25 seconds
Jika tetap gagal, akan di-queue untuk manual retry.
Q: Maximum transaction history?
A: Unlimited. Semua data transaksi disimpan permanent untuk keperluan audit dan reporting.
Q: Apakah bisa real-time?
A: Tergantung bank dan paket:
Web scraping: 5-10 menit (sesuai schedule)
BCA API/SNAP: Near real-time (1-2 menit)
Webhook: Notifikasi instant setelah deteksi
Kesimpulan
REST API Mutasi Bank menyediakan solusi complete untuk otomasi monitoring transaksi bank:
✅ 25+ endpoints untuk semua kebutuhan
✅ 34 bank didukung dengan berbagai jenis rekening
✅ Webhook untuk real-time notifications
✅ Security dengan HMAC-SHA256 signatures
✅ Code examples ready-to-use untuk 3 bahasa
✅ Production-ready dengan retry logic & error handling
🚀 Ready to Automate Your Bank Monitoring?
Daftar sekarang dan dapatkan:
✓ 7 hari trial GRATIS tanpa biaya di awal
✓ Full API access dengan 25+ endpoints
✓ 34 banks supported (BCA, BRI, Mandiri, BNI, dll)
✓ Webhook integration dengan signature security
✓ Priority support via WhatsApp
📚 Resources
Documentation:
Support:
📧 Email: support@mutasibank.co.id
🌐 Website: mutasibank.co.id
Related Articles:
Coming soon: Webhook Signature Verification Tutorial
Coming soon: Best Practices Security untuk Banking API
Coming soon: Cara Integrasi dengan Laravel
Questions? Drop a comment below atau hubungi kami via WhatsApp! 👇
Found this helpful? Jangan lupa like dan share! 🙏
Tags: #api #rest #banking #indonesia #webhook #php #nodejs #python #tutorial #developer


