Mulai
Mulai cepat
Dari pendaftaran sampai webhook pertama di sandbox, kira-kira dalam 15 menit.
Panduan ini memakai sandbox: tidak ada uang sungguhan, dan pembayaran bisa dibayar dengan simulasi. Anda butuh terminal dengan curl dan, untuk langkah webhook, server dengan endpoint HTTPS publik.
1. Daftar akun sandbox#
Buka halaman pendaftaran sandbox, isi nama usaha, nama kontak, email kerja, telepon, dan jenis usaha, lalu masukkan kode 6 digit yang dikirim ke email Anda. Pendaftaran sandbox berjalan otomatis, tanpa menunggu persetujuan: akun, project "Proyek utama", QRIS dan Virtual Account, simulasi bayar, dan satu API key langsung dibuat, dan Anda masuk sebagai Pemilik.
Halaman sukses menampilkan merchant_id, project_id, dan API key sandbox. API key hanya ditampilkan sekali: salin sekarang dan simpan di server. Selanjutnya masuk ke Dashboard Merchant sandbox (https://sandbox-merchant.algoritmakitadigital.id) memakai email dan kode 6 digit.
2. Ambil kredensial sandbox#
Anda memerlukan tiga nilai:
| Nilai | Contoh | Di mana |
|---|---|---|
| API key sandbox | akd_sk_… |
halaman sukses pendaftaran, ditampilkan sekali; dashboard selanjutnya hanya menampilkan prefiksnya. Hilang? Minta key baru ke tim AKD. |
project_id |
8f1c2d3e-… |
halaman sukses pendaftaran, atau Dashboard Merchant → Pengembang → Lingkungan dan ID |
merchant_id |
UUID | halaman sukses pendaftaran, atau Dashboard Merchant → Pengembang (untuk korespondensi dengan tim AKD) |
Simpan API key di secret manager atau variabel lingkungan server, jangan di aplikasi mobile, frontend, atau repositori kode. Untuk langkah berikutnya:
export AKD_BASE_URL="https://sandbox-api.algoritmakitadigital.id"
export AKD_API_KEY="akd_sk_..." # API key sandbox Anda
export AKD_PROJECT_ID="..." # project_id sandbox AndaCek bahwa key dan project benar. Jawaban 200 memuat metode pembayaran yang aktif untuk project Anda:
curl -sS "$AKD_BASE_URL/v1/integration-context?project_id=$AKD_PROJECT_ID" \
-H "Authorization: Bearer $AKD_API_KEY"3. Buat pembayaran QRIS#
Idempotency-Key wajib; pakai satu key unik per percobaan pembuatan pembayaran untuk satu pesanan.
cURL
curl -sS -X POST "$AKD_BASE_URL/v1/payments" \
-H "Authorization: Bearer $AKD_API_KEY" \
-H "Idempotency-Key: ORDER-1001-attempt-1" \
-H "Content-Type: application/json" \
--data @- <<JSON
{
"project_id": "$AKD_PROJECT_ID",
"external_order_id": "ORDER-1001",
"amount": 15000,
"currency": "IDR",
"payment_method": "QRIS"
}
JSONNode.js
// create-payment.mjs (Node.js 18+): node create-payment.mjs
const res = await fetch(`${process.env.AKD_BASE_URL}/v1/payments`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.AKD_API_KEY}`,
'Idempotency-Key': 'ORDER-1001-attempt-1',
'Content-Type': 'application/json',
},
body: JSON.stringify({
project_id: process.env.AKD_PROJECT_ID,
external_order_id: 'ORDER-1001',
amount: 15000,
currency: 'IDR',
payment_method: 'QRIS',
}),
});
const payment = await res.json();
if (!res.ok) throw new Error(`${res.status} ${payment.error}`);
console.log(payment.payment_id, payment.status, payment.checkout.qr_string);PHP
<?php
// create-payment.php: php create-payment.php
$body = json_encode([
'project_id' => getenv('AKD_PROJECT_ID'),
'external_order_id' => 'ORDER-1001',
'amount' => 15000,
'currency' => 'IDR',
'payment_method' => 'QRIS',
]);
$ch = curl_init(getenv('AKD_BASE_URL') . '/v1/payments');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('AKD_API_KEY'),
'Idempotency-Key: ORDER-1001-attempt-1',
'Content-Type: application/json',
],
]);
$raw = curl_exec($ch);
if ($raw === false) {
throw new RuntimeException(curl_error($ch));
}
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
$payment = json_decode($raw, true);
if ($status !== 200) {
throw new RuntimeException($status . ' ' . ($payment['error'] ?? $raw));
}
echo $payment['payment_id'], ' ', $payment['status'], ' ', $payment['checkout']['qr_string'], PHP_EOL;Go
// main.go: go run main.go
package main
import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"time"
)
func main() {
body, err := json.Marshal(map[string]any{
"project_id": os.Getenv("AKD_PROJECT_ID"),
"external_order_id": "ORDER-1001",
"amount": 15000,
"currency": "IDR",
"payment_method": "QRIS",
})
if err != nil {
log.Fatal(err)
}
req, err := http.NewRequest(http.MethodPost, os.Getenv("AKD_BASE_URL")+"/v1/payments", bytes.NewReader(body))
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("AKD_API_KEY"))
req.Header.Set("Idempotency-Key", "ORDER-1001-attempt-1")
req.Header.Set("Content-Type", "application/json")
res, err := (&http.Client{Timeout: 30 * time.Second}).Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
var payment struct {
PaymentID string `json:"payment_id"`
Status string `json:"status"`
Error string `json:"error"`
Checkout struct {
QRString string `json:"qr_string"`
} `json:"checkout"`
}
if err := json.NewDecoder(res.Body).Decode(&payment); err != nil {
log.Fatal(err)
}
if res.StatusCode != http.StatusOK {
log.Fatalf("%d %s", res.StatusCode, payment.Error)
}
fmt.Println(payment.PaymentID, payment.Status, payment.Checkout.QRString)
}Respons 200 berisi payment_id, status: "PENDING", expires_at (saat ini 30 menit), dan checkout.qr_string. Di aplikasi Anda, string ini dirender sebagai kode QR. Simpan payment_id:
export AKD_PAYMENT_ID="..." # payment_id dari responsDetail field dan error: Membuat pembayaran.
4. Simulasikan pembayaran#
Di sandbox, minta simulasi bayar untuk pembayaran PENDING (tanpa body):
curl -sS -X POST "$AKD_BASE_URL/v1/payments/$AKD_PAYMENT_ID/simulate" \
-H "Authorization: Bearer $AKD_API_KEY"Jawabannya 202 {"status":"simulation_requested"}. Beberapa detik kemudian pembayaran menjadi PAID:
curl -sS "$AKD_BASE_URL/v1/payments/$AKD_PAYMENT_ID" \
-H "Authorization: Bearer $AKD_API_KEY"5. Terima webhook payment.paid#
Saat pembayaran lunas, AKD mengirim POST JSON ke endpoint webhook HTTPS Anda dengan header X-AKD-Signature-V2 dan X-AKD-Event-ID.
- Minta pendaftaran endpoint webhook sandbox ke tim AKD (lihat permintaan perubahan). Signing secret (
whsec_…) hanya ditampilkan sekali; simpan di server. - Pasang verifikasi signature dari contoh Node.js, PHP, atau Go: baca raw body, tolak timestamp lebih dari 5 menit, bandingkan HMAC secara constant-time.
- Deduplikasi dengan
X-AKD-Event-ID, tandai pesanan lunas satu kali, dan jawab2xxdalam 10 detik. - Buat pembayaran baru dan simulasikan lagi; pastikan webhook diterima dan lolos verifikasi.
6. Cek di Dashboard Merchant#
Di Dashboard Merchant sandbox:
- Transaksi: pembayaran
ORDER-1001berstatus lunas, dengan linimasa statusnya. - Pengembang → Riwayat webhook: delivery
payment.paidberstatusDELIVERED, dengan kode respons server Anda. Delivery yang gagal dicoba ulang otomatis; yang berakhirDEADbisa dikirim ulang dari sini.
Langkah berikutnya#
- Lengkapi checklist uji: idempotensi, error,
payment.expired, Virtual Account. - Pelajari alur onboarding sampai go-live. Bila integrasi sudah siap, Pemilik mengajukan akun live dari menu Ajukan Live di Dashboard Merchant sandbox.
- Baca kode error dan batas laju sebelum produksi.