Paspay API v1

← Kembali ke Dashboard

📄 Ikhtisar

Dokumentasi ini mencakup integrasi dasar untuk membuat invoice pembayaran baru (QRIS, VA, dll.) dan menerima notifikasi real-time setelah pembayaran sukses divalidasi. Jika anda menggunakan woocommerce, maka silahkan download Github Paspayid

URL API Dasar

Status Sukses

HTTP 201 / HTTP 200

Format Data

JSON

🔑 Otentikasi API

Semua permintaan API publik harus diotentikasi. API Key Anda bersifat rahasia dan harus selalu dikirimkan melalui Authorization Header.

Header Otorisasi

Authorization: Bearer <API_KEY_ANDA>

API Key Anda dapat dibuat dan dilihat di bagian Profil Dashboard Anda.


➕ POST /transactions

Endpoint untuk membuat invoice pembayaran baru. Ini akan menghasilkan kode unik dan detail pembayaran untuk setiap channel yang diminta.

URL Penuh Endpoint

/transactions

Body Permintaan (JSON)

Kunci Status Deskripsi
project_idWajibID Proyek Anda (Integer).
payment_channel_idWajibArray ID channel yang aktif untuk Proyek Anda (misal: [3, 4]).
amountWajibHarga dasar transaksi (Integer). Minimal Rp 10.000.
internal_ref_idOpsionalID referensi unik dari sistem Anda (Maks. 50 karakter).
descriptionOpsionalDeskripsi transaksi (Maks. 255 karakter).
customer_nameOpsionalNama Pelanggan.
customer_emailOpsionalEmail Pelanggan.
customer_phoneOpsionalNomor Telepon Pelanggan.
Contoh Request Penuh (JSON Body)
{
    "project_id": "YOUR_PROJECT_ID",
    "payment_channel_id": [3, 4],
    "amount": 15000,
    "internal_ref_id": "ORDER-1001",
    "description": "Pembelian 1x Lisensi Pro",
    "customer_name": "Budi Santoso",
    "customer_email": "budi@example.com",
    "customer_phone": "+62812345678"
}
                        
Contoh Respons Sukses (HTTP 201 Created)

Perhatikan kolom total_amount_expected yang sudah termasuk unique_code.

{
    "success": true,
    "transaction_id": 1234,
    "reference_id": "PAY-d602cbf7-4935-44ab-b7a5-38a52de7a956",
    "total_amount_expected": 15696,
    "unique_code": 696,
    "expired_at": 1762721584,
    "payment_channels": [
        {
            "id": 3, "name": "BCA Virtual Account", "is_qris": 0,
            "payment_details": {
                "qris_raw": null,
                "bank_data": "Nomor VA: 1234567890 (a/n Paspay)"
            }
        },
        {
            "id": 4, "name": "QRIS (Static)", "is_qris": 1,
            "payment_details": {
                "qris_raw": "00020101021226500016ID.CO.QREN.WWW011893600010000000000102046487...",
                "bank_data": null
            }
        }
    ]
}
                        

🔄 Webhook Callback (Notifikasi PAID)

Paspay akan mengirim notifikasi status pembayaran real-time ke Webhook URL Proyek Anda setelah dana divalidasi masuk ke rekening Anda.

Verifikasi & Keamanan Webhook

  • Metode: POST
  • URL Target: Webhook URL yang telah dikonfigurasi di Dashboard Proyek Anda.
  • Verifikasi: Verifikasi header Authorization: Bearer harus sesuai dengan Callback Token Proyek Anda untuk mencegah *spoofing*.
  • Respon: Webhook Anda wajib merespons dengan kode HTTP 200 OK dalam waktu 5 detik. Respon selain 200 akan dianggap gagal dan Paspay akan mencoba mengirim ulang.
Contoh Payload Webhook (event: payment.success)
{
    "event": "payment.success",
    "data": {
        "id": 34,
        "project_id": 2,
        "reference_id": "PAY-d602cbf7-4935-44ab-b7a5-38a52de7a956",
        "external_reference": "ORDER-1001", /* internal_ref_id yang Anda kirim */
        "amount": 15000,
        "unique_code": 696,
        "total_amount": 15696,
        "status": "PAID",
        "va_number": "1234567890",
        "customer_name": "Budi Santoso",
        "description": "Pembelian 1x Lisensi Pro",
        "paid_at": 1762635214,
        "created_at": 1762635184,
        "updated_at": 1762635214
    }
}
                        

💻 Contoh Kode Integrasi

Contoh 1: Membuat Transaksi (PHP - cURL)

PHP - cURL

<?php
$apiKey = "API_KEY_ANDA_DI_SINI"; 
$endpoint = "https://paspay.id/api/v1/transactions"; 

// Data wajib dan opsional
$data = [
    'project_id' => 2,
    'payment_channel_id' => [3, 4], // BCA VA & QRIS
    'amount' => 15000,
    'description' => 'Pembelian 1x Lisensi Pro',
    'internal_ref_id' => 'ORDER-' . time(),
    'customer_email' => 'budi@example.com',
];

$ch = curl_init($endpoint);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Content-Type: application/json",
    "Authorization: Bearer " . $apiKey
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode === 201) {
    $result = json_decode($response, true);
    echo "Transaksi Sukses Dibuat! Total: Rp " . number_format($result['total_amount_expected']) . "\n";
    // Logika penampilan detail pembayaran ada di sini
} else {
    $error = json_decode($response, true);
    echo "Gagal membuat transaksi (HTTP Code: $httpCode):\n";
    echo $error['error'] ?? $response;
}
?>
                        
Contoh 2: Membuat Transaksi (Node.js - Fetch API)

Node.js - Fetch API

// Node.js v18+ atau dengan polyfill node-fetch
async function createTransaction() {
    const apiKey = "API_KEY_ANDA_DI_SINI";
    const endpoint = "https://paspay.id/api/v1/transactions";
    const data = {
        project_id: 2,
        payment_channel_id: [3, 4],
        amount: 25000,
        description: 'Pembelian Premium',
        customer_email: 'customer@example.com',
    };

    try {
        const response = await fetch(endpoint, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${apiKey}`,
            },
            body: JSON.stringify(data),
        });

        const result = await response.json();

        if (response.ok) {
            console.log("Transaksi Sukses Dibuat!");
            console.log(`Total Bayar: Rp ${result.total_amount_expected.toLocaleString('id-ID')}`);
            
            // Loop untuk menampilkan semua opsi pembayaran
            result.payment_channels.forEach(channel => {
                console.log(`Channel: ${channel.name}`);
                if (channel.is_qris === 1) {
                    console.log(`  QRIS Raw: ${channel.payment_details.qris_raw}`);
                } else {
                    console.log(`  Detail Bank: ${channel.payment_details.bank_data}`);
                }
            });

        } else {
            console.error(`Gagal (Status ${response.status}):`, result.error || "Kesalahan tak terduga.");
        }

    } catch (error) {
        console.error("Terjadi kesalahan jaringan:", error.message);
    }
}

createTransaction();