Dokumentasi Reseller API v1
Integrasikan sistem penjualan Anda secara otomatis dengan Digitalku Murah menggunakan API berbasis JSON & keamanan enkripsi HMAC-SHA256.
1. Pendahuluan & Gambaran Umum
Reseller API **Digitalku Murah** dirancang khusus untuk kemitraan sistem-ke-sistem (B2B). Dengan API ini, mitra dapat melakukan integrasi programmatik penuh mulai dari sinkronisasi katalog produk ter-update, pengecekan saldo aktif, pembuatan pesanan (checkout) real-time dengan memotong saldo reseller, hingga memantau status pengiriman barang digital secara otomatis.
http://localhost:8080/api/reseller/v1Catatan: Ganti domain dengan domain production server https://api.digitalku-murah.com jika sudah live.
2. Autentikasi & Header Keamanan
Guna menjamin keamanan transaksi keuangan reseller, setiap permintaan HTTP ke endpoint API wajib menyertakan empat header keamanan berikut secara lengkap:
| Header | Tipe | Deskripsi | Contoh Nilai |
|---|---|---|---|
X-API-Key | String | API Key unik Anda yang didapatkan dari dashboard reseller. | DKM_KEY_6ae3bcfa23... |
X-Timestamp | Integer | Unix epoch timestamp saat request dibuat (dalam satuan detik). | 1717070104 |
X-Nonce | String | String acak unik sekali pakai untuk mencegah replay attack. | req_e30cf2a4db9 |
X-Signature | String | Tanda tangan digital hex-encoded hasil enkripsi HMAC-SHA256. | a492fe5dbd81c4e97a3c... |
- Toleransi Waktu (Skew): Nilai timestamp akan divalidasi ketat oleh server. Jika selisih waktu server dengan timestamp Anda melebihi 5 menit, request otomatis ditolak.
- Anti Replay (Nonce): Nonce yang sama tidak boleh dipakai berulang kali dalam kurun waktu 5 menit. Percobaan penggunaan nonce ganda akan menghasilkan error
409 Conflict.
3. Mekanisme Perhitungan Signature
Signature digital dihasilkan dengan mengamankan string dasar request menggunakan algoritma **HMAC-SHA256** dan kunci **API Secret** Anda.
Langkah 1: Susun String Dasar (Signing Base String)
Gabungkan parameter request di bawah ini menggunakan karakter baris baru (\n / newline) sebagai pemisah:
{X-Timestamp}\n{X-Nonce}\n{HTTP_METHOD}\n{REQUEST_PATH}\n{RAW_REQUEST_BODY} Catatan: Jika request tidak memiliki request body (misal: request GET), komponen RAW_REQUEST_BODY dibiarkan berupa string kosong "" (tetapi newline pemisah sebelumnya harus tetap ada).
Langkah 2: Enkripsi dengan API Secret
Gunakan algoritma HMAC-SHA256 untuk melakukan hashing pada string dasar tersebut. Berikut adalah kode implementasi praktis dalam berbagai bahasa pemrograman:
<?php
// Script Pembuatan Signature HMAC-SHA256 - PHP
$apiKey = "DKM_KEY_6ae3bcfa23";
$apiSecret = "DKM_SEC_f893de23b890";
$timestamp = time();
$nonce = bin2hex(random_bytes(8));
$method = "POST";
$path = "/api/reseller/v1/orders";
$body = json_encode([
"product_slug" => "netflix-premium",
"variant_id" => 121,
"qty" => 1,
"customer_name" => "Rian Wijaya",
"customer_email" => "rian@example.com"
]);
// Susun signing base string dipisah newline (\n)
$baseString = implode("\n", [
$timestamp,
$nonce,
$method,
$path,
$body
]);
// Hitung HMAC-SHA256
$signature = hash_hmac('sha256', $baseString, $apiSecret);
// Kirim request dengan header:
// X-API-Key: $apiKey
// X-Timestamp: $timestamp
// X-Nonce: $nonce
// X-Signature: $signature
?>4. Referensi Endpoint API v1
Berikut adalah spesifikasi lengkap endpoint API v1 beserta contoh request dan respon format JSON.
/products Ambil Semua Katalog ProdukMengambil seluruh data produk aktif yang siap dipesan beserta varian masing-masing. Harga otomatis yang tampil adalah harga khusus reseller.
page(Integer): Nomor halaman data (Default:1).per_page(Integer): Jumlah produk per halaman. Maks: 100 (Default:20).search(String): Filter cari berdasarkan nama/deskripsi.category(String): Filter slug kategori produk (misal:streaming).
{
"success": true,
"data": {
"items": [
{
"id": 12,
"slug": "netflix-premium",
"name": "Netflix Premium",
"category": "Streaming",
"price": 14000,
"lowest_price": 14000,
"variant_count": 1,
"has_variants": true,
"availability": "available",
"requires_email": true,
"variants": [
{
"id": 121,
"product_id": 12,
"variant_name": "Netflix 1 Bulan - Sharing 1 Device",
"price": 14000,
"stock_status": "available",
"available_stock": 42
}
]
}
],
"page": 1,
"per_page": 20,
"total": 1,
"total_pages": 1
}
}/products/:slug Ambil Detail ProdukMendapatkan detail satu produk aktif secara lengkap berdasarkan slug produk (contoh: netflix-premium).
:slug(String, Wajib): Nama slug dari produk digital.
{
"success": true,
"data": {
"id": 12,
"slug": "netflix-premium",
"name": "Netflix Premium",
"category": "Streaming",
"price": 14000,
"lowest_price": 14000,
"variants": [
{
"id": 121,
"product_id": 12,
"variant_name": "Netflix 1 Bulan - Sharing",
"price": 14000,
"stock_status": "available",
"available_stock": 42
}
]
}
}/balance Cek Saldo ResellerMengecek sisa saldo aktif reseller Anda yang siap digunakan untuk memproses pesanan digital secara instan.
{
"success": true,
"data": {
"balance": 258000
}
}/orders Buat Pemesanan Menggunakan SaldoMembuat pesanan produk digital baru. Sistem backend akan secara langsung memotong saldo aktif Anda, menandai pesanan sebagai lunas (status: "paid"), dan memicu pengiriman produk secara otomatis.
{
"product_slug": "netflix-premium",
"variant_id": 121,
"customer_name": "Rian Wijaya",
"customer_email": "rian@example.com",
"qty": 1,
"note": "Profil nomor 3 ya min!"
}{
"success": true,
"data": {
"invoice_no": "INV-20260530-0042",
"status": "paid",
"product_name": "Netflix Premium",
"qty": 1,
"unit_price": 14000,
"total": 14000,
"buyer_name": "Rian Wijaya",
"buyer_email": "rian@example.com",
"balance_before": 258000,
"balance_after": 244000,
"paid_at": "2026-05-30T13:52:10+07:00",
"fulfillment_status": "pending",
"is_fulfilled": false
}
}/orders/:invoice Cek Status Pemesanan DetailMengecek detail pesanan digital dan mengambil kredensial (akun/voucher/code) pada kolom delivered_items setelah proses pengiriman selesai.
:invoice(String, Wajib): Kode invoice pesanan (contoh:INV-20260530-0042).
{
"success": true,
"data": {
"invoice_no": "INV-20260530-0042",
"status": "paid",
"fulfillment_status": "fulfilled",
"is_fulfilled": true,
"product_name": "Netflix Premium",
"qty": 1,
"total": 14000,
"buyer_name": "Rian Wijaya",
"buyer_email": "rian@example.com",
"paid_at": "2026-05-30T13:52:10+07:00",
"fulfilled_at": "2026-05-30T13:52:15+07:00",
"delivered_items": "Email: netflix-rian@dkm.club | Password: securepass | Profile: Profile 3 (PIN: 4242)"
}
}/transactions Riwayat Mutasi SaldoMendapatkan riwayat mutasi masuk/keluar (debit/kredit) dari saldo reseller Anda untuk rekonsiliasi berkala.
{
"success": true,
"data": {
"items": [
{
"id": 18,
"type": "order_debit",
"direction": "debit",
"amount": 14000,
"balance_before": 258000,
"balance_after": 244000,
"invoice_no": "INV-20260530-0042",
"note": "saldo dipotong untuk order reseller",
"created_at": "2026-05-30T13:52:10+07:00"
}
],
"page": 1,
"limit": 20,
"total": 1,
"total_pages": 1
}
}5. Status Transaksi & Alur Refund
Setiap transaksi reseller memiliki siklus hidup yang terbagi menjadi dua status utama:
A. Status Pemesanan (status)
- paid: Saldo reseller berhasil didebit dan pesanan lunas. Backend langsung mengantrekan proses pengiriman produk digital.
- completed: Pesanan sukses diproses dan kredensial produk digital telah terkirim sepenuhnya.
- failed: Proses gagal. Saldo reseller Anda otomatis dikembalikan penuh oleh sistem (Auto-refund).
B. Status Pemenuhan (fulfillment_status)
- pending: Pesanan sedang masuk antrean fulfillment asinkronus server.
- processing: Pesanan sedang diproses ke API provider eksternal.
- fulfilled: Pesanan berhasil dipenuhi. Detail produk berada pada string parameter
delivered_items. - failed: Pengiriman gagal permanen (misal: stok provider kosong, atau akun tidak tersedia).
fulfillment_status: "failed"), backend secara instan mengkreditkan kembali saldo yang didebit dan mencatat mutasi refund tersebut.6. Penanganan Error & Troubleshooting
Bila terjadi kegagalan validasi atau error sistem, API akan mengembalikan respon berformat standard:
{
"error": "Pesan deskripsi kesalahan detail dari server."
} | HTTP Status | Deskripsi & Solusi |
|---|---|
400 Bad Request | Request tidak lengkap (misal email pembeli kosong) ATAU Saldo reseller tidak mencukupi untuk membuat order. |
401 Unauthorized | Autentikasi gagal. Periksa kecocokan API Key, API Secret, timestamp kedaluwarsa (> 5 menit), atau hitungan signature Anda. |
404 Not Found | Data tidak ditemukan. Produk slug tidak aktif/ditemukan atau kode invoice salah. |
409 Conflict | Replay attack dicegah. Nonce yang Anda kirimkan sudah terpakai. Silakan generate string nonce unik baru. |
500 Internal Error | Kegagalan sistem server. Hubungi admin toko jika kendala terjadi secara terus menerus. |