AKD Pay Docs
EnglishEN Dashboard
LIVE Dokumentasi ini sama untuk sandbox dan live.

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 Anda

Cek 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"
}
JSON

Node.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 respons

Detail 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.

  1. Minta pendaftaran endpoint webhook sandbox ke tim AKD (lihat permintaan perubahan). Signing secret (whsec_…) hanya ditampilkan sekali; simpan di server.
  2. Pasang verifikasi signature dari contoh Node.js, PHP, atau Go: baca raw body, tolak timestamp lebih dari 5 menit, bandingkan HMAC secara constant-time.
  3. Deduplikasi dengan X-AKD-Event-ID, tandai pesanan lunas satu kali, dan jawab 2xx dalam 10 detik.
  4. Buat pembayaran baru dan simulasikan lagi; pastikan webhook diterima dan lolos verifikasi.

6. Cek di Dashboard Merchant#

Di Dashboard Merchant sandbox:

  • Transaksi: pembayaran ORDER-1001 berstatus lunas, dengan linimasa statusnya.
  • Pengembang → Riwayat webhook: delivery payment.paid berstatus DELIVERED, dengan kode respons server Anda. Delivery yang gagal dicoba ulang otomatis; yang berakhir DEAD bisa 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.