DOCUMENTATION

Prayana PayGate API Docs

Satu API untuk semua payment gateway Indonesia. Daftar 1x, langsung bisa pake Duitku, Midtrans, iPaymu, dan QRIS.

Getting Started

Base URL: https://paygate.prayana.id

1. Daftar & Dapatkan API Key

  1. Buka halaman registrasi
  2. Isi form: nama, email, password
  3. Setelah berhasil, Anda langsung mendapatkan API Key

2. Setup HTTP Client

Setiap request memerlukan header x-api-key.

curl -X GET https://paygate.prayana.id/api/v1/health \
  -H "x-api-key: your_platform_api_key"

3. Buat Transaksi Pertama

curl -X POST https://paygate.prayana.id/api/v1/transactions \
  -H "Content-Type: application/json" \
  -H "x-api-key: your_api_key" \
  -d '{
    "orderId": "TEST-001",
    "gateway": "duitku",
    "amount": 10000,
    "paymentMethod": "BC",
    "customerName": "Test",
    "customerEmail": "test@mail.com"
  }'

4. Setup Webhook

Daftarkan endpoint Anda di dashboard untuk menerima notifikasi real-time.

// Next.js App Router
export async function POST(request: Request) {
  const { event, data } = await request.json()

  if (event === 'payment.success') {
    // Update order status
    await updateOrderStatus(data.orderId, 'PAID')
  }

  return Response.json({ received: true })
}

Authentication

Setiap platform memiliki satu API Key unik. Kirim di header x-api-key setiap request.

HEADER FORMAT

x-api-key: prayana_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p
API Key
Platform-to-platform API calls
x-api-key
Session
Admin dashboard
Cookie (authjs.session-token)
401 Error: API Key salah atau tidak dikirim

Create Transaction

ENDPOINT

POST /api/v1/transactions

HEADERS

Content-Type: application/json
x-api-key: your_api_key

Request Body

{
  "orderId": "INV-001",         // required - unique from your system
  "gateway": "duitku",          // required - "duitku" | "midtrans" | "ipaymu"
  "amount": 100000,             // required - amount without fee
  "fee": 4000,                  // optional - admin fee
  "totalAmount": 104000,        // optional - amount + fee (auto if empty)
  "paymentMethod": "BC",        // required - channel code
  "customerName": "John Doe",   // optional
  "customerEmail": "john@...",  // optional
  "customerPhone": "08123...",  // optional
  "productDetails": "Paket Basic", // optional
  "expiryPeriod": 1440,         // optional - minutes (default 1440 = 24h)
  "metadata": { "orderId": "abc123" } // optional - extra data
}

Response (201 Created)

{
  "data": {
    "id": "clx...",
    "orderId": "INV-001",
    "gateway": "duitku",
    "amount": 100000,
    "totalAmount": 104000,
    "status": "PENDING",
    "paymentUrl": "https://app.duitku.com/payment/REF123",
    "vaNumber": "881234567890",  // Virtual Account (for VA channels)
    "qrString": null,             // QRIS string (for QRIS channels)
    "reference": "REF123456"      // Gateway reference
  }
}

Check Status

POST /api/v1/transactions/{id}/check-status

{
  "data": {
    "status": "SUCCESS",
    "gatewayStatus": "settlement"
  }
}

Webhook

Prayana PayGate mengirim webhook ke URL Anda ketika status transaksi berubah. Daftarkan webhook URL di dashboard > Edit Platform.

WEBHOOK EVENTS

EventDescription
transaction.createdTransaksi baru dibuat
payment.successPembayaran berhasil
payment.failedPembayaran gagal
payment.expiredTransaksi kadaluarsa

Payload

{
  "event": "payment.success",
  "data": {
    "transactionId": "clx...",
    "orderId": "INV-001",
    "gateway": "duitku",
    "amount": 100000,
    "status": "SUCCESS",
    "reference": "REF123456",
    "paidAt": "2024-01-01T12:05:00.000Z"
  }
}

Signature Verification

const crypto = require('crypto')

const body = JSON.stringify(req.body) // raw JSON
const expected = crypto
  .createHmac('sha256', webhookSecret)
  .update(body)
  .digest('hex')

const isValid = (expected === req.headers['x-webhook-signature'])

Payment Channels

Duitku

CodeChannelType
BCBCA Virtual Accountva
M2Mandiri Virtual Accountva
I1BNI Virtual Accountva
BRBRI Virtual Accountva
OVOVOewallet
DADANAewallet
SAShopeePayewallet
FTAlfamartretail
IRIndomaretretail
VCKartu Kreditcredit_card
SPQRIS (ShopeePay)qris

Midtrans

CodeChannelType
bca_vaBCA Virtual Accountva
bni_vaBNI Virtual Accountva
bri_vaBRI Virtual Accountva
mandiri_billMandiri Billva
gopayGoPayewallet
shopeepayShopeePayewallet
danaDANAewallet
qrisQRISqris
indomaretIndomaretretail
alfamartAlfamartretail
credit_cardKartu Kreditcredit_card

iPaymu

CodeChannelType
vaVA (Auto Routing)va
bcaBCA Virtual Accountva
mandiriMandiri VAva
bniBNI VAva
briBRI VAva
qrisQRISqris
alfamartAlfamartretail
indomaretIndomaretretail
kartu_kreditKartu Kreditcredit_card
Gunakan endpoint GET /api/v1/gateways?gateway=duitku untuk mendapatkan daftar channel terkini.

QRIS & Unique Code

Sistem kode unik (2/3 digit) ditambahkan ke nominal pembayaran. Ketika user membayar, sistem mencocokkan jumlah yang dibayar dengan kode unik.

Contoh Flow

  1. Base amount: Rp 100.000
  2. Kode unik: 523
  3. Total yang harus dibayar: Rp 100.523
  4. User transfer Rp 100.523
  5. Sistem verifikasi: 100523 % 1000 = 523 → cocok!

Generate QRIS Dinamis

POST /api/v1/qris/generate

{
  "qrisString": "000201010211...",
  "baseAmount": 100000,
  "type": "ORDER",
  "referenceId": "INV-001"
}

{
  "data": {
    "dynamicQrisString": "000201010212...",
    "uniqueAmount": 100523,
    "code": 523,
    "codeFormatted": "523"
  }
}

Generate Kode Unik (tanpa QRIS)

POST /api/v1/unique-codes/generate

{
  "type": "ORDER",
  "referenceId": "INV-001",
  "amount": 100000
}

{
  "data": {
    "code": 523,
    "uniqueAmount": 100523,
    "codeFormatted": "523",
    "note": "Bayar tepat Rp 100.523"
  }
}

Verify Payment

POST /api/v1/unique-codes/verify

{ "amount": 100523 }

{
  "matched": true,
  "data": {
    "code": 523,
    "type": "ORDER",
    "referenceId": "INV-001",
    "amount": 100000,
    "uniqueAmount": 100523
  }
}

Security

Encryption at Rest (AES-256-GCM)

Semua gateway credentials dienkripsi sebelum disimpan ke database. Format:

iv_hex:auth_tag_hex:ciphertext_hex

Best Practices

  • Jangan simpan API Key di client-side code
  • Gunakan backend proxy untuk semua panggilan ke Prayana PayGate
  • Rotasi API Key secara berkala
  • Set webhook secret untuk verifikasi callback
  • Gunakan HTTPS di production

Status Codes

StatusKeterangan
PENDINGMenunggu pembayaran
SUCCESSPembayaran berhasil
FAILEDPembayaran gagal
EXPIREDTransaksi kadaluarsa
REFUNDEDTransaksi di-refund

Error Handling

HTTPArtiPenyebab
201CreatedTransaksi berhasil
400Bad RequestParameter kurang / tidak valid
401UnauthorizedAPI Key salah
404Not FoundTransaksi tidak ditemukan
409ConflictOrder ID sudah pernah dipakai
502Bad GatewayError dari payment gateway

Semua error response format: { "error": "deskripsi error" }

Siap integrasi?

Daftar Sekarang