Dokumentasi Open API (Headless E-commerce)
Selamat datang di dokumentasi pengembang Akunfy. Open API Akunfy memungkinkan seller menjual produk instan mereka (Akun/Kredensial, Link, Lisensi) secara headless melalui platform pihak ketiga seperti Bot Telegram, Bot WhatsApp, Custom Website, atau Discord, dengan memanfaatkan sistem manajemen stok dan payment gateway Akunfy secara dinamis.
1. Otentikasi & Base URL
Seluruh request ke Open API wajib dikirim ke base URL berikut menggunakan protokol HTTPS:
https://akunfy.com/api
Gunakan API Key yang telah Anda generate di halaman Dashboard Seller sebagai Bearer Token pada header request Anda:
Authorization: Bearer YOUR_API_KEY Accept: application/json Content-Type: application/json
2. Referensi API Endpoints
/v1/seller/products
Menarik katalog produk seller berstatus active yang siap dijual (hanya mendukung tipe *Instant Delivery*, tipe Jasa diecualikan). Endpoint ini mengembalikan harga dinamis terhitung dan sisa stok riil saat ini.
Query Parameters
per_page(integer, optional) - Jumlah produk per halaman. Default: 15, Max: 100.page(integer, optional) - Halaman keberapa yang ingin ditarik.
Contoh Response
{
"success": true,
"data": [
{
"id": 43,
"name": "Netflix Premium 1 Bulan Resmi",
"slug": "netflix-premium-1-bulan-resmi-43",
"price": 15000,
"stock_count": 12,
"thumbnail": "https://akunfy.com/storage/products/example.webp",
"category": {
"id": 5,
"name": "Streaming",
"slug": "streaming"
},
"created_at": "2026-08-05T09:49:46.000000Z",
"updated_at": "2026-08-05T09:49:46.000000Z"
}
],
"meta": {
"current_page": 1,
"last_page": 3,
"per_page": 15,
"total": 42
}
}/v1/seller/checkout
Membuat tagihan transaksi pembelian baru. Sistem akan secara otomatis mengunci (*lockForUpdate*) stok unit termurah (*auto-pick*) dan memanggil API Payment Gateway (Paprika QRIS/lainnya) untuk menerbitkan URL QRIS/VA.
Request Body (JSON)
| Field | Tipe | Wajib | Deskripsi |
|---|---|---|---|
| product_id | Integer | Ya | ID produk yang ingin dibeli. |
| quantity | Integer | Ya | Jumlah unit pembelian (min 1). |
| payment_method | String | Ya | Metode pembayaran. Contoh: paprika, duitku, manual. |
| payment_code | String | Tidak | Kode sub-metode/channel pembayaran jika dibutuhkan. |
| guest_name | String | Ya | Nama pembeli pihak ketiga (guest). |
| guest_email | String | Ya | Email pembeli pihak ketiga. |
| guest_phone | String | Ya | Nomor HP pembeli pihak ketiga (format WA aktif). |
| buyer_note | String | Tidak | Catatan tambahan dari pembeli. |
Contoh Response
{
"success": true,
"message": "Checkout successfully created.",
"data": {
"merchant_ref": "INV-ZXYABC050826",
"reference_id": "PAP-992178229",
"amount": 15000,
"fee": 500,
"total_amount": 15500,
"payment_url": "00020101021226620016COM.CO.PAPRIKA...",
"payment_method": "paprika",
"payment_channel": "Paprika QRIS",
"status": "unpaid",
"expired_time": "2026-08-05T10:49:46.000000Z"
}
}/v1/seller/transactions/{merchant_ref}
Melakukan pengecekan status tagihan transaksi tertentu secara aktif (*polling*). Jika status transaksi telah terbayar (paid atau completed), response akan secara otomatis memuat array berisi kredensial atau link download unit produk digital yang dibeli.
Contoh Response (Setelah Lunas)
{
"success": true,
"data": {
"merchant_ref": "INV-ZXYABC050826",
"reference_id": "PAP-992178229",
"amount": 15000,
"fee": 500,
"total_amount": 15500,
"payment_url": "00020101021226620016COM.CO.PAPRIKA...",
"payment_method": "paprika",
"payment_channel": "Paprika QRIS",
"status": "paid",
"expired_time": "2026-08-05T10:49:46.000000Z",
"paid_at": "2026-08-05T09:55:12.000000Z",
"credentials": [
{
"data_type": "login",
"data_1": "[email protected]",
"data_2": "rahasiaseller123"
}
]
}
}3. Outbound Webhook & Keamanan HMAC Signature
Ketika status transaksi berubah menjadi paid (lunas) atau expired (kedaluwarsa), server Akunfy akan menembakkan request POST secara asinkron ke URL Webhook Anda.
Header Webhook
Setiap request webhook dari Akunfy memuat header tanda tangan keamanan berikut:
Content-Type: application/json X-Akunfy-Signature: <SHA256_HMAC_SIGNATURE>
Struktur Payload Webhook
{
"event": "transaction.paid",
"timestamp": 1785835772,
"data": {
"merchant_ref": "INV-ZXYABC050826",
"reference_id": "PAP-992178229",
"status": "paid",
"amount": 15000,
"fee": 500,
"total_amount": 15500,
"payment_method": "paprika",
"payment_channel": "Paprika QRIS",
"buyer_note": null,
"guest_name": "Budi Santoso",
"guest_email": "[email protected]",
"guest_phone": "6281234567890",
"paid_at": "2026-08-05T09:55:12.000000Z",
"expired_time": "2026-08-05T10:49:46.000000Z",
"credentials": [
{
"data_type": "login",
"data_1": "[email protected]",
"data_2": "rahasiaseller123"
}
]
}
}Verifikasi Signature
Untuk menjamin request benar-benar datang dari Akunfy, Anda harus memvalidasi header X-Akunfy-Signature dengan mere-generate signature menggunakan payload mentah (*raw body*) dan Webhook Secret Anda.
<?php
$rawPayload = file_get_contents('php://input');
$receivedSignature = $_SERVER['HTTP_X_AKUNFY_SIGNATURE'] ?? '';
$webhookSecret = 'YOUR_WEBHOOK_SECRET';
$calculatedSignature = hash_hmac('sha256', $rawPayload, $webhookSecret);
if (hash_equals($calculatedSignature, $receivedSignature)) {
// Tanda tangan valid! Proses data webhook.
$payload = json_decode($rawPayload, true);
// Kirim respons 200 OK
http_response_code(200);
echo json_encode(['status' => 'success']);
} else {
// Tanda tangan TIDAK valid! Tolak request.
http_response_code(401);
echo json_encode(['status' => 'unauthorized']);
}const crypto = require('crypto');
const express = require('express');
const app = express();
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-akunfy-signature'];
const webhookSecret = 'YOUR_WEBHOOK_SECRET';
const hmac = crypto.createHmac('sha256', webhookSecret);
const calculatedSignature = hmac.update(req.body).digest('hex');
if (calculatedSignature === signature) {
const payload = JSON.parse(req.body.toString());
console.log('Webhook valid:', payload.event);
res.status(200).json({ status: 'success' });
} else {
res.status(401).json({ status: 'unauthorized' });
}
});