Dokumentasi API Kirimo
API Kirimo memungkinkan Anda mengintegrasikan payment gateway ke website atau aplikasi dengan mudah. Semua request menggunakan JSON dan diautentikasi dengan API key. Kirimo menggunakan Duitku sebagai payment processor — mendukung Virtual Account, QRIS, dan berbagai metode pembayaran Indonesia.
Autentikasi
Semua request ke API harus menyertakan API key di header X-API-KEY. Dapatkan API key di halaman API Keys.
// Header yang diperlukan di setiap request
X-API-KEY: KRM-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Content-Type: application/json
Buat Pembayaran
Endpoint untuk membuat transaksi dan mendapatkan link pembayaran Duitku yang bisa diredirect ke pelanggan.
Parameter Body (JSON)
| Field | Tipe | Keterangan |
|---|---|---|
| customer_name wajib | string | Nama lengkap pelanggan |
| customer_email wajib | string | Email pelanggan yang valid |
| amount wajib | integer | Jumlah pembayaran dalam Rupiah. Minimal Rp 10.000. |
| order_id | string | ID unik order Anda. Auto-generate jika kosong. Harus unik per merchant. |
| customer_phone | string | Nomor HP pelanggan (opsional) |
| return_url | string | URL redirect setelah pelanggan selesai bayar |
| notify_url | string | URL webhook notifikasi pembayaran (server-side). Pastikan bisa diakses publik. |
Response Sukses
{
"status": "success",
"message": "Transaksi berhasil dibuat.",
"data": {
"order_id": "ORD-20240115-A1B2C3D4",
"amount": 150000,
"fee": 3000,
"net_amount": 147000,
"payment_url": "https://sandbox.duitku.com/topup/topupdirect/...",
"reference": "D123456789",
"status": "pending"
}
}
Cek Status Transaksi
Cek status transaksi secara real-time. Jika status di database masih pending, sistem akan otomatis cek ke Duitku untuk mendapatkan status terbaru.
Parameter Query
| Parameter | Keterangan |
|---|---|
| order_id wajib | ID order yang ingin dicek statusnya |
Response
{
"status": "success",
"data": {
"order_id": "ORD-20240115-A1B2C3D4",
"amount": 150000,
"fee": 3000,
"net_amount": 147000,
"status": "paid",
"payment_url": "https://sandbox.duitku.com/topup/...",
"customer_name": "Budi Santoso",
"created_at": "2024-01-15 10:30:00",
"paid_at": "2024-01-15 10:35:42"
}
}
Nilai status yang mungkin:
| Status | Keterangan |
|---|---|
pending | Menunggu pembayaran dari pelanggan |
paid | Pembayaran berhasil, saldo merchant sudah bertambah |
failed | Pembayaran gagal atau dibatalkan |
expired | Transaksi kadaluarsa (lebih dari 60 menit) |
Cek Saldo
{
"status": "success",
"data": {
"balance": 2450000,
"package": "basic",
"limit_used": 3500000
}
}
Riwayat Transaksi
{
"status": "success",
"data": {
"transactions": [
{
"order_id": "ORD-20240115-A1B2C3D4",
"amount": 150000,
"fee": 3000,
"net_amount": 147000,
"status": "paid",
"customer_name": "Budi Santoso",
"created_at": "2024-01-15 10:30:00",
"paid_at": "2024-01-15 10:35:42"
}
],
"page": 1,
"per_page": 20,
"total": 143,
"total_pages": 8
}
}
Webhook Notifikasi
Duitku mengirim notifikasi POST ke notify_url yang kamu set saat membuat transaksi, setiap kali status pembayaran berubah.
Payload Webhook dari Duitku (ke notify_url Anda)
{
"merchantCode": "DXXXXXX",
"amount": "150000",
"merchantOrderId": "ORD-20240115-A1B2C3D4",
"productDetail": "Pembayaran via Toko Saya",
"additionalParam": "",
"resultCode": "00",
"merchantUserId": "",
"reference": "D123456789",
"signature": "md5hash..."
}
Nilai resultCode
| resultCode | Arti |
|---|---|
00 | ✅ Pembayaran berhasil |
01 | ❌ Pembayaran gagal |
Cara Verifikasi Webhook di Server Anda
<?php
// Verifikasi signature dari Duitku
$merchantCode = $_POST['merchantCode'];
$amount = $_POST['amount'];
$merchantOrderId= $_POST['merchantOrderId'];
$resultCode = $_POST['resultCode'];
$signature = $_POST['signature'];
$merchantKey = 'API_KEY_DUITKU_ANDA'; // bukan API key Kirimo
$expectedSig = md5($merchantCode . $amount . $merchantOrderId . $merchantKey);
if ($signature !== $expectedSig) {
http_response_code(400);
echo 'Invalid signature';
exit;
}
if ($resultCode === '00') {
// Pembayaran berhasil — update order di database Anda
// Kirim email konfirmasi ke pelanggan
}
http_response_code(200);
echo '{"statusCode":"00"}';
/webhook.php dan update saldo merchant. Endpoint di atas adalah untuk notify_url server Anda sendiri jika ingin notifikasi langsung ke sistem Anda.
Contoh Integrasi PHP
<?php
$API_KEY = 'KRM-API_KEY_KAMU';
$BASE = 'https://kirimo.biz.id';
// ============================================================
// 1. BUAT PEMBAYARAN
// ============================================================
$ch = curl_init($BASE . '/api.php?action=payment');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode([
'order_id' => 'INV-' . time(),
'amount' => 150000,
'customer_name' => 'Budi Santoso',
'customer_email' => 'budi@example.com',
'customer_phone' => '081234567890',
'return_url' => 'https://tokomu.com/success',
'notify_url' => 'https://tokomu.com/webhook.php',
]),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-API-KEY: ' . $API_KEY,
],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($response['status'] === 'success') {
// Redirect ke halaman pembayaran Duitku
header('Location: ' . $response['data']['payment_url']);
exit;
}
// ============================================================
// 2. CEK STATUS TRANSAKSI
// ============================================================
$ch = curl_init($BASE . '/api.php?action=status&order_id=INV-123');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-KEY: ' . $API_KEY],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
echo $result['data']['status']; // paid, pending, failed
// ============================================================
// 3. HANDLER WEBHOOK (notify_url server Anda)
// ============================================================
$data = $_POST;
$resultCode = $data['resultCode'] ?? '';
$orderId = $data['merchantOrderId'] ?? '';
$amount = $data['amount'] ?? 0;
$signature = $data['signature'] ?? '';
// Verifikasi signature
$merchantKey = 'API_KEY_DUITKU_ANDA';
$expected = md5($data['merchantCode'] . $amount . $orderId . $merchantKey);
if ($signature !== $expected) {
http_response_code(400);
exit('Invalid signature');
}
if ($resultCode === '00') {
// Update status order di database Anda
// Kirim email konfirmasi ke pelanggan
}
http_response_code(200);
echo '{"statusCode":"00"}';
Contoh Integrasi Node.js
const axios = require('axios');
const API_KEY = 'KRM-API_KEY_KAMU';
const BASE = 'https://kirimo.biz.id';
// ============================================================
// 1. BUAT PEMBAYARAN
// ============================================================
async function createPayment() {
const { data } = await axios.post(
`${BASE}/api.php?action=payment`,
{
order_id: 'INV-' + Date.now(),
amount: 150000, // minimal 10000
customer_name: 'Budi Santoso',
customer_email: 'budi@example.com',
customer_phone: '081234567890',
return_url: 'https://tokomu.com/success',
notify_url: 'https://tokomu.com/webhook',
},
{ headers: { 'X-API-KEY': API_KEY, 'Content-Type': 'application/json' } }
);
// Redirect ke payment_url
console.log(data.data.payment_url);
return data.data.payment_url;
}
// ============================================================
// 2. CEK STATUS
// ============================================================
async function checkStatus(orderId) {
const { data } = await axios.get(
`${BASE}/api.php?action=status&order_id=${orderId}`,
{ headers: { 'X-API-KEY': API_KEY } }
);
return data.data.status; // 'paid' | 'pending' | 'failed'
}
// ============================================================
// 3. WEBHOOK HANDLER (Express.js)
// ============================================================
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.urlencoded({ extended: true }));
app.post('/webhook', (req, res) => {
const { merchantCode, amount, merchantOrderId, resultCode, signature } = req.body;
const merchantKey = 'API_KEY_DUITKU_ANDA';
// Verifikasi signature
const expected = crypto
.createHash('md5')
.update(merchantCode + amount + merchantOrderId + merchantKey)
.digest('hex');
if (signature !== expected) {
return res.status(400).send('Invalid signature');
}
if (resultCode === '00') {
// Update order di database Anda
console.log('Paid:', merchantOrderId);
}
res.status(200).json({ statusCode: '00' });
});
Contoh cURL
# Buat Pembayaran
curl -X POST "https://kirimo.biz.id/api.php?action=payment" \
-H "X-API-KEY: KRM-API_KEY_KAMU" \
-H "Content-Type: application/json" \
-d '{
"order_id": "INV-001",
"amount": 150000,
"customer_name": "Budi Santoso",
"customer_email": "budi@example.com",
"customer_phone": "081234567890",
"return_url": "https://tokomu.com/success",
"notify_url": "https://tokomu.com/webhook"
}'
# Cek Status Transaksi
curl "https://kirimo.biz.id/api.php?action=status&order_id=INV-001" \
-H "X-API-KEY: KRM-API_KEY_KAMU"
# Cek Saldo
curl "https://kirimo.biz.id/api.php?action=balance" \
-H "X-API-KEY: KRM-API_KEY_KAMU"
# Riwayat Transaksi (halaman 1)
curl "https://kirimo.biz.id/api.php?action=transactions&page=1" \
-H "X-API-KEY: KRM-API_KEY_KAMU"
Error Codes
| HTTP Code | Status | Keterangan |
|---|---|---|
| 200 | success | Request berhasil |
| 400 | error | Parameter tidak valid atau kurang |
| 401 | error | API key tidak valid atau tidak ada |
| 403 | error | IP tidak ada di whitelist / limit habis |
| 404 | error | Transaksi tidak ditemukan |
| 500 | error | Internal server error |
Semua response error mengikuti format:
{
"status": "error",
"message": "Deskripsi error di sini"
}