Lewati ke konten utama
AF Stores
Cari produk

Ketik minimal 2 karakter.

Developers

API AF STORES

Gunakan API v2 HMAC untuk seluruh integrasi baru. API v1 legacy dinonaktifkan secara default dan hanya tersedia jika operator mengaktifkannya sementara untuk migrasi client lama.

Base URL

Mulai cepat

https://af-stores.com/api/v2

Semua endpoint memakai POST, Content-Type: application/json, dan HTTPS. Ambil UID serta API secret dari halaman profil account.

Keamanan produksiSimpan secret hanya di server. Jangan menaruhnya di aplikasi browser, URL, repository, atau log.
HMAC SHA-256

Autentikasi v2

HeaderIsi
X-AF-UIDUID API account
X-AF-TimestampUnix timestamp; toleransi server 5 menit
X-AF-NonceNilai acak unik per request
X-AF-Request-IDID unik per request; dapat menjadi idempotency fallback
X-AF-SignatureHex HMAC SHA-256 dari canonical string

Canonical string

UPPERCASE_METHOD + "\n" + PATH + "\n" + TIMESTAMP + "\n" + NONCE + "\n" + REQUEST_ID + "\n" + SHA256(RAW_BODY)

Contoh signing PHP

$body = json_encode($payload, JSON_UNESCAPED_SLASHES); $timestamp = (string) time(); $nonce = bin2hex(random_bytes(16)); $requestId = bin2hex(random_bytes(16)); $canonical = "POST\n{$path}\n{$timestamp}\n{$nonce}\n{$requestId}\n" . hash('sha256', $body); $signature = hash_hmac('sha256', $canonical, 'YOUR_API_SECRET');

Signature dihitung terhadap byte body persis yang dikirim. Nonce dan request ID yang pernah dipakai akan ditolak sebagai replay.

POST/api/v2/profile

Profil & saldo

Mengambil identitas, level, dan saldo account API.

Body JSON

{}

Contoh respons

{ "result": true, "data": { "username": "merchant01", "balance": 150000, "level": "Reseller", "api_version": 2, "request_id": "REQUEST_ID" }, "message": "Detail akun berhasil didapatkan." }
POST/api/v2/service

Daftar layanan

Membaca layanan aktif dengan harga sesuai role. Produk pascabayar mengembalikan price=null dan requires_inquiry=true karena nominal tagihan harus berasal dari inquiry provider.

Body JSON

{ "filter_type": "brand", "filter_value": "Mobile Legends", "filter_status": "available", "page": 1, "per_page": 50 }

Contoh respons

{ "result": true, "data": [ { "code": "SERVICE_CODE", "category_code": "CATEGORY_CODE", "name": "Nama layanan", "variant": "Nominal", "product_mode": "PREPAID", "requires_inquiry": false, "price": 10000, "pricing_source": "GLOBAL", "status": "available" } ], "meta": { "page": 1, "per_page": 50, "total": 1, "total_pages": 1 } }
POST/api/v2/postpaid-inquiry

Inquiry pascabayar

Wajib sebelum order untuk layanan yang requires_inquiry=true. Inquiry terikat pada credential, service, target, reference provider, nominal tagihan, dan hari inquiry. Jangan membuat inquiry baru hanya karena response pembayaran belum pasti.

Body JSON

{ "service": "PLNPAS", "target": "CUSTOMER_ID", "idempotency_key": "BILL_INQUIRY_20260918_001" }

Contoh respons

{ "result": true, "data": { "inquiry_token": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "service": "PLNPAS", "target": "CUSTOMER_ID", "customer_name": "NAMA PELANGGAN", "subtotal": 152750, "expires_at": "2026-09-18 12:30:00", "bill": { "customer_name": "NAMA PELANGGAN", "price": 150000, "admin": 2750 } }, "message": "Tagihan ditemukan." }
POST/api/v2/order

Buat order saldo

Membuat order dari saldo account. Harga, promo, quantity, dan saldo dihitung ulang server. Untuk pascabayar quantity wajib 1 dan inquiry_token dari endpoint inquiry wajib dikirim.

Body JSON

{ "service": "SERVICE_CODE", "target": "USER_ID|ZONE_ID", "quantity": 1, "idempotency_key": "CLIENT_UNIQUE_KEY_001", "inquiry_token": null }

Contoh respons

{ "result": true, "data": { "order_id": "AF240101000000ABC123", "target": "USER_ID|ZONE_ID", "code": "SERVICE_CODE", "quantity": 1, "payment_status": "PAID", "fulfillment_status": "QUEUED", "grand_total": 10000, "duplicate": false }, "message": "Pesanan berhasil dibuat." }
POST/api/v2/status

Status order

Mengambil order milik credential yang sedang digunakan; order milik account lain tidak dapat dibaca.

Body JSON

{ "order_id": "AF240101000000ABC123", "limit": 20 }

Contoh respons

{ "result": true, "data": [ { "order_id": "AF240101000000ABC123", "fulfillment_status": "success", "payment_status": "paid", "quantity": 1, "grand_total": 10000, "items": { "success": 1 } } ] }
Webhook keluar

Callback status

Jika callback HTTPS publik dikonfigurasi pada account, AF STORES mengirim JSON berikut ketika status dipublikasikan:

{ "order_id": "AF240101000000ABC123", "data": "USER_ID - ZONE_ID", "service": "SERVICE_CODE", "status": "success", "note": "Keterangan aman", "price": 10000 }

Header X-AF-Callback-Signature berisi HMAC SHA-256 terhadap raw JSON body memakai API secret account. Receiver harus memverifikasi signature sebelum memproses payload dan merespons HTTP 2xx.

Response contract

Status dan error

HTTPMakna
200 / 201Request berhasil / order dibuat
400Payload atau header tidak lengkap
401Credential atau signature tidak valid
403IP ditolak, timestamp kedaluwarsa, atau replay
404Resource milik account tidak ditemukan
413Body melewati batas
422Data bisnis tidak valid
429Rate limit tercapai
503Maintenance atau layanan sementara tidak tersedia
Compatibility

API v1 legacy

API v1 hanya tersedia jika operator menetapkan API_V1_LEGACY_ENABLED=true. Client lama memakai /api/profile, /api/service, /api/order, dan /api/status dengan key serta sign = md5(UID + API_SECRET). Karena v1 tidak mempunyai replay protection setara v2, aktifkan hanya selama migrasi dan gunakan API v2 HMAC sebagai target akhir. Produk pascabayar legacy tetap memerlukan inquiry_token.