Dokumentasi API

REST API untuk membuat QRIS dinamis dari akun GoPay Merchant kamu dan mengecek pembayaran masuk, dari website atau aplikasi mana pun. Semua respons berformat JSON.

Hubungkan akun GoPay kamu lewat dashboard (login OTP, sekali saja), lalu panggil endpoint di bawah dengan API key kamu.

Base URL dan autentikasi

Setiap akun punya base URL dan API key sendiri. Ambil keduanya di halaman Pengaturan. {ID_AKUN} adalah ID unik akunmu — URL lengkapnya muncul otomatis saat kamu login.

https://gw.gopaygateway.shop/t/{ID_AKUN}

Kirim API key di header X-Api-Key pada setiap request (atau lewat query ?api_key=). Panggil API dari server, bukan dari browser pembeli, supaya API key tidak terlihat.

X-Api-Key: API_KEY_KAMU

Alur integrasi

  1. Saat pembeli checkout, backend kamu memanggil POST /create-qris dengan nominal pesanan. Simpan trx_id (dan qris_id) di data pesanan.
  2. Tampilkan QR ke pembeli: arahkan ke qris_url, atau render sendiri dari qris_code.
  3. Tahu pembayaran masuk dengan salah satu cara:
    • Callback (disarankan): set URL callback sekali di Pengaturan. Gateway otomatis POST ke URL itu begitu QRIS dibayar — tanpa polling.
    • Polling: panggil GET /check-payment atau GET /transaction/{qris_id} secara berkala.

QRIS berlaku 5 menit. Kalau memakai polling, beri jeda minimal 8 detik antar pengecekan; pengecekan yang terlalu sering bisa memicu pembatasan akun GoPay. Callback tidak kena batasan itu karena gateway yang memeriksa.

POST/create-qris

Membuat QRIS dinamis dari QRIS statis toko. Menerima body JSON (POST) atau query string (GET). QRIS statis harus sudah diatur di halaman GoPay.

Parameter

NamaTipeKeterangan
amountnumberWajib. Nominal dalam Rupiah, lebih dari 0.
merchant_refstringOpsional. ID pesanan dari sistem kamu (maks 64 karakter). Dikembalikan apa adanya di respons dan di callback, untuk mencocokkan pembayaran dengan pesanan.

Contoh request

curl -X POST https://gw.gopaygateway.shop/t/{ID_AKUN}/create-qris \
  -H "X-Api-Key: API_KEY_KAMU" \
  -H "Content-Type: application/json" \
  -d '{"amount": 25000}'

Contoh respons

{
  "success": true,
  "data": {
    "qris_id": "abc123xy",
    "trx_id": "TRX-A3F8K2M9",
    "merchant_ref": "INV-00123",
    "qris_url": "https://gw.gopaygateway.shop/t/{ID_AKUN}/qr/abc123xy",
    "qris_code": "00020101021226...",
    "amount": 25000,
    "expires_in": "5 menit"
  }
}
GET/check-payment

Mencari transaksi masuk yang nominalnya cocok. Satu transaksi hanya bisa diklaim oleh satu trx_id, jadi dua pesanan dengan nominal sama tidak saling mengklaim. Menerima query string (GET) atau body JSON (POST).

Parameter

NamaTipeKeterangan
amountnumberWajib. Nominal yang dicari.
trx_idstringSangat disarankan. Nilai trx_id dari /create-qris.

Contoh request

curl "https://gw.gopaygateway.shop/t/{ID_AKUN}/check-payment?amount=25000&trx_id=TRX-A3F8K2M9" \
  -H "X-Api-Key: API_KEY_KAMU"

Respons: sudah dibayar

{
  "success": true,
  "paid": true,
  "transaction": {
    "transaction_id": "gopay-internal-tx-id",
    "order_id": "GP-1234567890",
    "amount": 25000,
    "payer_issuer": "GoPay / Bank",
    "payment_type": "QRIS",
    "transaction_time": "2026-10-12T00:15:12.000Z"
  }
}

Respons: belum dibayar

{
  "success": true,
  "paid": false,
  "message": "Pembayaran belum ditemukan atau sudah pernah diklaim"
}
GET/transaction/{qris_id}

Mengecek status satu transaksi berdasarkan qris_id dari /create-qris. Berguna sebagai cadangan bila callback belum sampai. Butuh API key.

Contoh request

curl https://gw.gopaygateway.shop/t/{ID_AKUN}/transaction/abc123xy \
  -H "X-Api-Key: API_KEY_KAMU"

Contoh respons

{
  "success": true,
  "status": "PAID",
  "paid": true,
  "data": {
    "qris_id": "abc123xy",
    "trx_id": "TRX-A3F8K2M9",
    "merchant_ref": "INV-00123",
    "amount": 25000,
    "status": "PAID",
    "transaction": {
      "transaction_id": "gopay-internal-tx-id",
      "order_id": "GP-1234567890",
      "amount": 25000,
      "payer_issuer": "GoPay / Bank",
      "payment_type": "QRIS",
      "transaction_time": "2026-10-12T00:15:12.000Z"
    }
  }
}

Nilai status: PENDING, PAID, EXPIRED, atau NOT_FOUND (HTTP 404). Objek transaction hanya terisi saat PAID.

GET/transactions

Mengambil daftar transaksi masuk (3 hari terakhir).

Parameter

NamaTipeKeterangan
pageSizenumberOpsional. Jumlah transaksi (maks 100). Default: 20.

Contoh request

curl "https://gw.gopaygateway.shop/t/{ID_AKUN}/transactions?pageSize=10" \
  -H "X-Api-Key: API_KEY_KAMU"

Contoh respons

{
  "success": true,
  "total_amount": "25000",
  "data": {
    "transactions": [
      {
        "amount": 25000,
        "status": "settlement",
        "time": "2026-10-12T00:15:12.000Z",
        "issuer": "GoPay / Bank",
        "order_id": "GP-1234567890",
        "transaction_id": "gopay-internal-tx-id"
      }
    ]
  }
}
GET/token-status

Memeriksa apakah sesi GoPay Merchant masih aktif. Berguna untuk pemantauan.

curl https://gw.gopaygateway.shop/t/{ID_AKUN}/token-status \
  -H "X-Api-Key: API_KEY_KAMU"
{
  "success": true,
  "data": { "token_status": "valid", "message": "Token dan Sesi GoPay Merchant Aktif" }
}
GET/qr/{qris_id}

Halaman pembayaran siap pakai untuk pembeli: gambar QR, hitung mundur 5 menit, dan tombol cek status. Tidak butuh API key, jadi aman dibuka di browser pembeli. Tambahkan ?format=raw untuk dialihkan langsung ke gambar QR.

https://gw.gopaygateway.shop/t/{ID_AKUN}/qr/abc123xy
GET/api/qr-status/{qris_id}

Status pembayaran untuk satu QRIS. Tidak butuh API key, jadi boleh dipanggil dari frontend kamu sendiri.

{
  "success": true,
  "paid": false,
  "status": "PENDING",
  "message": "Belum ada pembayaran masuk"
}

Nilai status: PENDING, PAID, EXPIRED, atau NOT_FOUND. Saat PAID, respons menyertakan objek transaction.

Callback (Webhook)

Daripada polling, gateway bisa memberitahu website kamu otomatis. Set URL Callback sekali di halaman Pengaturan. Setelah itu, setiap QRIS yang dibayar (atau kedaluwarsa) memicu request POST berisi JSON ke URL tersebut.

  1. Gateway mendeteksi pembayaran (dari buka halaman QR pembeli maupun dari pengecekan latar belakang tiap ~10 detik).
  2. Gateway mengirim POST JSON ke URL callback kamu dengan header tanda tangan.
  3. Endpoint kamu memverifikasi tanda tangan, menandai pesanan lunas, lalu membalas HTTP 200 secepatnya.

Bila endpoint tidak membalas 2xx, gateway mengulang pengiriman sampai 4 kali dengan jeda menaik (1s, 2s, 4s). Riwayat pengiriman terakhir tampil di halaman Pengaturan. Callback dikirim satu kali per transaksi saat berhasil (2xx).

Header request

HeaderKeterangan
X-Callback-Eventpayment.success atau payment.expired.
X-Callback-SignatureHMAC‑SHA256 (hex) dari raw body, memakai signature secret kamu.
Content-Typeapplication/json
POST(URL callback kamu)

Isi body (JSON) yang dikirim gateway ke URL callback kamu:

FieldTipeKeterangan
eventstringpayment.success atau payment.expired.
statusstringPAID atau EXPIRED.
providerstringSumber pembayaran, mis. gopay.
trx_idstringID transaksi dari /create-qris.
qris_idstringID QRIS dari /create-qris.
merchant_refstringID pesanan milikmu, bila tadi dikirim. Bisa null.
amountnumberNominal dalam Rupiah.
referencestringID transaksi internal GoPay (saat PAID).
payer_issuerstringPenerbit pembayar, mis. GoPay / Bank.
paid_atstringWaktu transaksi (ISO 8601), saat PAID.

Contoh body

{
  "event": "payment.success",
  "status": "PAID",
  "provider": "gopay",
  "trx_id": "TRX-A3F8K2M9",
  "qris_id": "abc123xy",
  "merchant_ref": "INV-00123",
  "amount": 25000,
  "reference": "gopay-internal-tx-id",
  "order_id": "GP-1234567890",
  "payer_issuer": "GoPay / Bank",
  "payment_type": "QRIS",
  "paid_at": "2026-10-12T00:15:12.000Z"
}

Verifikasi signature

Selalu verifikasi sebelum memproses: hitung HMAC‑SHA256 dari raw body (byte mentah, sebelum di-parse) memakai signature secret dari halaman Pengaturan, lalu bandingkan dengan header X-Callback-Signature. Tolak bila tidak cocok.

Route::post('/gateway/callback', function (Request $request) {
    $secret = config('services.gateway.callback_secret');
    $expected = hash_hmac('sha256', $request->getContent(), $secret);

    if (! hash_equals($expected, $request->header('X-Callback-Signature', ''))) {
        abort(401, 'Invalid signature');
    }

    $p = $request->json();
    if ($p->get('status') === 'PAID') {
        // tandai pesanan $p->get('merchant_ref') lunas (idempoten)
    }

    return response()->json(['ok' => true]); // balas 200 cepat
});

Proses callback secara idempoten: callback yang sama bisa terkirim lebih dari sekali bila endpoint kamu sempat lambat/gagal. Pakai trx_id atau merchant_ref sebagai kunci agar pesanan tidak diproses dua kali.

Kode error

HTTPArtiYang perlu dilakukan
401API key salah atau tidak dikirimPeriksa header X-Api-Key.
400Parameter tidak valid, atau GoPay belum terhubungPeriksa amount, lalu cek halaman GoPay di dashboard.
500QRIS statis belum diatur, atau GoPay menolak permintaanBaca message atau error pada respons.
{
  "success": false,
  "message": "Autentikasi Gagal: API Key tidak valid"
}