Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Contoh Integrasi Lengkap

Contoh alur integrasi end-to-end untuk berbagai use case.


1. Beli Pulsa (PHP)

<?php
class RelayAPI {
    private $baseUrl;
    private $apiKey;

    public function __construct(string $baseUrl, string $apiKey) {
        $this->baseUrl = rtrim($baseUrl, '/');
        $this->apiKey  = $apiKey;
    }

    public function post(string $path, array $body): array {
        $ch = curl_init("{$this->baseUrl}{$path}");
        curl_setopt_array($ch, [
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => json_encode($body),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER     => [
                'Content-Type: application/json',
                "X-API-Key: {$this->apiKey}",
            ],
        ]);
        $response = curl_exec($ch);
        curl_close($ch);
        return json_decode($response, true);
    }
}

$api    = new RelayAPI('https://api-sandbox.alfakios.com', 'apk_live_xxx');
$result = $api->post('/api/v1/merchant/ppob/phone-credit/transaction', [
    'req_id'     => 'TXN-' . date('YmdHis') . '-' . rand(1000, 9999),
    'product_id' => 'XL5',
    'cust_id'    => '08123456789',
]);

if ($result['data']['status'] === 'SUCCESS') {
    echo "Sukses! SN: " . $result['data']['serial_no'];
} elseif ($result['data']['status'] === 'PENDING') {
    echo "Pending. Cek status dengan req_id: " . $result['data']['req_id'];
} else {
    echo "Gagal: " . $result['data']['description'];
}

2. Disbursement Lengkap (Node.js)

const axios = require('axios');

const API = axios.create({
  baseURL: 'https://api-sandbox.alfakios.com',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': 'apk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  },
  timeout: 15000,
});

async function transferDana(reqId, accountNumber, amount, bankCode = '014') {
  // Step 1: Inquiry
  const inquiry = await API.post('/api/v1/merchant/disbursement/inquiry', {
    product_id: 'DSTF', account_number: accountNumber,
    amount, bank_code: bankCode,
  });
  if (inquiry.data.data.status !== 'SUCCESS') {
    throw new Error(`Inquiry gagal: ${inquiry.data.data.description}`);
  }
  const { account_name, fee, total_cost } = inquiry.data.data;
  console.log(`Nama: ${account_name} | Fee: Rp ${fee} | Total: Rp ${total_cost}`);

  // Step 2: Payment
  const payment = await API.post('/api/v1/merchant/disbursement/payment', {
    req_id: reqId, product_id: 'DSTF',
    account_number: accountNumber, amount, bank_code: bankCode,
  });
  const d = payment.data.data;

  if (d.status === 'SUCCESS') {
    console.log(`✅ Sukses! Ref: ${d.serial_no}, Saldo: Rp ${d.balance}`);
    return d;
  }
  if (d.status === 'PENDING') {
    return await pollDisbursementStatus(reqId, accountNumber, amount, bankCode);
  }
  throw new Error(`Gagal: ${d.description} (RC: ${d.rc})`);
}

async function pollDisbursementStatus(reqId, accountNumber, amount, bankCode) {
  const delays = [30000, 60000, 120000, 300000];
  for (const delay of delays) {
    await new Promise(r => setTimeout(r, delay));
    const res = await API.post('/api/v1/merchant/disbursement/status', {
      product_id: 'DSTF', account_number: accountNumber,
      amount, bank_code: bankCode, req_id: reqId,
    });
    const { status, description } = res.data.data;
    if (status === 'SUCCESS') { console.log('✅ Sukses'); return res.data.data; }
    if (status === 'FAILED')  { throw new Error(`Gagal: ${description}`); }
    console.log('Masih PENDING...');
  }
  throw new Error('Timeout — eskalasi ke support dengan req_id: ' + reqId);
}

transferDana('PAY-' + Date.now(), '1380610457', '100000').catch(console.error);

3. Token PLN Prabayar (Python)

import requests, time, uuid

BASE_URL = "https://api-sandbox.alfakios.com"
HEADERS  = {"Content-Type": "application/json",
            "X-API-Key": "apk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}

def beli_token_pln(nomor_meter: str) -> dict:
    req_id = f"PLN-{int(time.time())}-{uuid.uuid4().hex[:6]}"

    # Inquiry
    r = requests.post(f"{BASE_URL}/api/v1/merchant/ppob/pln/prepaid/inquiry",
                      json={"product_id": "PLNPREP", "cust_id": nomor_meter},
                      headers=HEADERS, timeout=15)
    r.raise_for_status()
    inq = r.json()["data"]
    if inq["status"] != "SUCCESS":
        raise ValueError(f"Inquiry gagal: {inq['description']}")
    print(f"Pelanggan: {inq['data'].get('nama_pelanggan', '-')}, Harga: Rp {inq['unit_price']}")

    # Transaksi
    r = requests.post(f"{BASE_URL}/api/v1/merchant/ppob/pln/prepaid/transaction",
                      json={"req_id": req_id, "product_id": "PLNPREP", "cust_id": nomor_meter},
                      headers=HEADERS, timeout=15)
    r.raise_for_status()
    result = r.json()["data"]

    if result["status"] == "SUCCESS":
        print(f"✅ Token: {result['serial_no']}")
    elif result["status"] == "PENDING":
        print(f"⏳ Pending — req_id: {req_id}")
    else:
        print(f"❌ Gagal: {result['description']}")
    return result

beli_token_pln("12345678901")

4. QRIS PayIn (Go)

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "time"
)

const (
    baseURL = "https://api-sandbox.alfakios.com"
    apiKey  = "apk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
)

func callAPI(path string, body interface{}) map[string]interface{} {
    b, _  := json.Marshal(body)
    req, _ := http.NewRequest("POST", baseURL+path, bytes.NewReader(b))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("X-API-Key", apiKey)
    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()
    raw, _  := io.ReadAll(resp.Body)
    var result map[string]interface{}
    json.Unmarshal(raw, &result)
    return result
}

func main() {
    reqID := fmt.Sprintf("QRIS-%d", time.Now().Unix())

    // Buat QRIS
    res := callAPI("/api/v1/merchant/payin/qris/create", map[string]string{
        "req_id": reqID, "product_id": "GPAY", "amount": "75000",
    })
    data := res["data"].(map[string]interface{})
    traceNumber := data["trace_number"].(string)
    fmt.Printf("QRIS dibuat. Trace: %s\n", traceNumber)

    // Polling sampai dibayar
    for i := 0; i < 12; i++ {
        time.Sleep(5 * time.Second)
        status := callAPI("/api/v1/merchant/payin/qris/check",
            map[string]string{"trace_number": traceNumber})
        d := status["data"].(map[string]interface{})
        s := d["status"].(string)
        fmt.Printf("Status [%d]: %s\n", i+1, s)
        if s == "SUCCESS" { fmt.Println("✅ Pembayaran diterima!"); return }
        if s == "FAILED"  { fmt.Println("❌ QRIS gagal/kedaluwarsa"); return }
    }
    fmt.Println("Timeout polling — buat QRIS baru")
}

5. Cek Saldo (cURL)

curl -s -X POST "https://api-sandbox.alfakios.com/api/v1/balance/merchant" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: apk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -d '{}' | python3 -c "import sys,json; d=json.load(sys.stdin); print('Saldo: Rp', d['data']['balance'])"

6. BPJS Lengkap (PHP)

<?php
$api    = new RelayAPI('https://api-sandbox.alfakios.com', 'apk_live_xxx');
$inqId  = 'INQ-' . time();

// Step 1: Inquiry
$inquiry = $api->post('/api/v1/merchant/ppob/bpjs/inquiry', [
    'product_id' => 'BPJSKS',
    'cust_id'    => '0001234567890',
    'period'     => '01',
    'mobile_no'  => '08123456789',
]);

if ($inquiry['data']['status'] !== 'SUCCESS') {
    die("Inquiry gagal: " . $inquiry['data']['description']);
}

echo "Nama: " . $inquiry['data']['data']['nama_peserta'] . "\n";
echo "Tagihan: Rp " . $inquiry['data']['data']['tagihan'] . "\n";

// Step 2: Payment
$payment = $api->post('/api/v1/merchant/ppob/bpjs/transaction', [
    'req_id'         => 'PAY-' . time(),
    'product_id'     => 'BPJSKS',
    'cust_id'        => '0001234567890',
    'period'         => '01',
    'inquiry_req_id' => $inqId,
    'mobile_no'      => '08123456789',
]);

echo "Status: " . $payment['data']['status'] . "\n";
echo "Struk: "  . $payment['data']['serial_no'] . "\n";