BayarBayar.in Payment API · v2.0
Terima pembayaran QRIS dari aplikasi Anda
Diperbarui 27 Juli 2026 · Base URL: https://bayarbayar.in
Satu panduan lengkap untuk membuat tagihan, mengarahkan pelanggan ke halaman pembayaran, menerima pemberitahuan pembayaran, dan memastikan pesanan aman diproses.
Mulai cepat
BayarBayar.in dipanggil dari backend website atau aplikasi Anda. API key tidak boleh ditempatkan di HTML, JavaScript browser, aplikasi pelanggan, URL pembayaran, atau repository publik.
Endpoint yang tersedia
/api/transactioncreate/qrisMembuat tagihan QRIS
GET/api/transactiondetailMembaca status transaksi
POST/api/transactioncancelMembatalkan transaksi pending
GET/api/v1/projects/{project}/payment-methodsMembaca metode pembayaran
GET/pay/t/{payment_token}Halaman pembayaran pelanggan
Contoh transaksi pertama
curl -X POST 'https://bayarbayar.in/api/transactioncreate/qris' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: gpk_test_GANTI_DENGAN_KEY_ANDA' \
-H 'Idempotency-Key: checkout-INV-001' \
-d '{
"project": "toko-satu",
"order_id": "INV-001",
"amount": 10000,
"expiry_minutes": 60
}'
Jika berhasil, buka nilai payment.payment_url dari response pada browser pelanggan. Jangan membuat sendiri URL pembayaran jika response sudah menyediakannya.
status: "completed", memastikan environment: "live", dan mencocokkan project, order ID, serta nominal asli.
A. Persiapan
Daftar atau masuk ke Dashboard BayarBayar.in, lalu buat satu project untuk setiap website atau aplikasi yang akan menerima pembayaran.
A.1. Project
Project memisahkan transaksi, API key, callback URL, webhook secret, rate limit, dan QRIS. Catat dua nilai berikut setelah project dibuat:
project slug— identitas project pada setiap request API.API key— credential rahasia yang hanya ditampilkan saat dibuat.
A.2. QRIS dan akun GoPay Merchant
- Buka menu Keamanan dan hubungkan akun GoPay Merchant milik Anda.
- Buka menu Project, lalu tambahkan QRIS statis milik merchant yang sama.
- Mulai dari mode Sandbox. Ubah ke Live setelah tes integrasi berhasil.
Setiap akun member memakai sesi provider dan QRIS miliknya sendiri. Satu Merchant ID provider tidak dapat dipakai oleh dua akun member.
A.3. Sandbox dan Live
| Mode | Fungsi | Uang nyata |
|---|---|---|
sandbox | Menguji create, payment page, status, dan webhook melalui simulasi dashboard. | Tidak |
live | Membuat QRIS dinamis dan mencocokkan mutasi akun GoPay Merchant terkait. | Ya |
B. Halaman pembayaran
Cara yang disarankan adalah membuat transaksi melalui API, lalu mengarahkan pelanggan ke nilai payment.payment_url dari response. URL ini memakai token acak dan tidak mengekspos tuple invoice.
https://bayarbayar.in/pay/t/{payment_token}Endpoint kompatibilitas berikut juga tersedia untuk transaksi yang sudah dibuat. Gunakan total_payment, bukan nominal asli.
https://bayarbayar.in/pay/toko-satu/10123?order_id=INV-001&qris_only=1
| Parameter | Keterangan |
|---|---|
project | Slug project. |
amount | total_payment dari response create. |
order_id | Nomor invoice pada sistem merchant. |
redirect | URL tujuan setelah lunas. Hostname wajib terdaftar pada redirect allowlist project. |
qris_only=1 | Parameter kompatibilitas. Halaman saat ini memang hanya menampilkan QRIS, sehingga parameter ini tidak mengubah perilaku. |
Halaman pembayaran membaca status dari database BayarBayar.in. Setelah pembayaran terverifikasi, QR dan countdown hilang, lalu diganti tanda berhasil. Jika parameter redirect valid, pelanggan dapat kembali ke website merchant.
C. Autentikasi API
Kirim API key melalui header X-API-Key. Header selalu diprioritaskan jika credential lama juga ada di body atau query.
X-API-Key: gpk_live_CONTOH_BUKAN_CREDENTIAL_ASLI
api_key pada body atau query masih diterima, tetapi deprecated. Integrasi baru wajib memakai header.
API key memiliki environment dan scope. Key sandbox tidak dapat dipakai setelah project berpindah ke live; simpan key baru yang ditampilkan saat pergantian mode.
C.1. Header yang digunakan
| Header | Wajib | Keterangan |
|---|---|---|
Content-Type | POST | Gunakan application/json. |
X-API-Key | Ya | API key project. Jangan kirim ke browser pelanggan. |
Idempotency-Key | Create | Sangat disarankan agar retry tidak membuat transaksi ganda. |
X-Request-ID | Tidak | ID penelusuran milik Anda. BayarBayar.in selalu mengembalikannya pada response. |
C.2. Scope API key
| Scope | Dipakai untuk |
|---|---|
transactions:write | Membuat dan membatalkan transaksi. |
transactions:read | Membaca detail transaksi dan metode pembayaran. |
Gunakan key dengan scope minimum yang diperlukan. Jika key diduga bocor, buat key baru dari Dashboard dan cabut key lama.
D. API: Transaction Create
Membuat satu transaksi QRIS. Jika kode unik aktif, BayarBayar.in menambah kode tersebut ke nominal asli agar mutasi dapat dicocokkan dengan aman.
/api/transactioncreate/qrisD.1. Request
Member dapat menentukan expiry untuk setiap transaksi. Gunakan paling banyak satu field expiry. Rentang yang diterima adalah 5–300 menit (5 menit–5 jam). Jika tidak dikirim, BayarBayar.in menggunakan default 60 menit. Nilai di luar rentang selalu ditolak dengan HTTP 422 dan transaksi tidak dibuat.
| Field | Tipe | Keterangan |
|---|---|---|
project wajib | string | Slug project, 3–63 karakter. |
order_id wajib | string | ID invoice unik dalam project, maksimum 128 karakter. |
amount wajib | integer | Nominal transaksi asli dalam rupiah, maksimum Rp100.000.000. |
expired_at | date-time | Waktu kedaluwarsa ISO 8601 antara 5 menit dan 5 jam sejak request diproses. Untuk batas tepat 5 menit, gunakan expiry_minutes: 5. Jangan kirim bersama field expiry lain. |
expiry_minutes | integer | Durasi dalam menit. Minimum 5, maksimum 300, default 60. Nilai desimal atau nilai di luar batas ditolak. |
expired | integer | Alias lama untuk durasi menit. Gunakan expiry_minutes pada integrasi baru. |
expired_minutes | integer | Alias lama untuk durasi menit. Gunakan expiry_minutes pada integrasi baru. |
api_key deprecated | string | Gunakan header X-API-Key. |
curl -X POST 'https://bayarbayar.in/api/transactioncreate/qris' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: gpk_live_CONTOH' \
-H 'Idempotency-Key: checkout-INV-001' \
-d '{
"project": "toko-satu",
"order_id": "INV-001",
"amount": 10000,
"expiry_minutes": 90
}'
5,60, dan300diterima.4,301, angka desimal, atau lebih dari satu field expiry ditolak dengan HTTP 422.- Gunakan
expiry_minutesuntuk menghindari selisih jam atau latensi jaringan saat menentukan batas. - Expiry tidak dapat diubah setelah QR dibuat. Buat transaksi baru jika membutuhkan waktu berbeda.
E_VALIDATION digunakan untuk bentuk request yang tidak valid, termasuk nilai di bawah batas schema, angka desimal, field tidak dikenal, atau beberapa field expiry sekaligus. E_INVALID_EXPIRY digunakan saat nilai yang formatnya valid tetap berada di luar kebijakan waktu, misalnya expiry_minutes: 301 atau expired_at di luar 5–300 menit.
{
"success": false,
"message": "Waktu kedaluwarsa harus antara 5 menit dan 300 menit.",
"code": "E_INVALID_EXPIRY",
"errors": null,
"request_id": "UUID"
}
D.2. Response sukses
{
"success": true,
"payment": {
"project": "toko-satu",
"order_id": "INV-001",
"amount": 10000,
"fee": 0,
"total_payment": 10123,
"payment_method": "qris",
"payment_number": "000201010212...",
"expired_at": "2030-01-01T12:00:00.000Z",
"environment": "live",
"sandbox": false,
"payment_url": "https://bayarbayar.in/pay/t/OPAQUE_TOKEN"
}
}
amountadalah nominal transaksi asli.total_paymentadalah nominal tepat yang harus dibayar pelanggan.feetetap0; kode unik bukan fee.payment_numberberisi payload QRIS dinamis pada mode live.payment_urladalah URL siap pakai yang harus dibuka pelanggan.
Create mengembalikan HTTP 201, termasuk saat request idempotent mengembalikan transaksi yang sudah ada. Simpan order_id dan response ini pada database merchant.
D.3. Response gagal
{
"success": false,
"message": "Request tidak valid.",
"code": "E_VALIDATION",
"errors": {
"formErrors": [],
"fieldErrors": {
"expiry_minutes": [
"Nilai harus berupa bilangan bulat minimal 5."
]
}
},
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
Untuk error validasi, errors berisi rincian field. Pada error operasional atau autentikasi, nilainya dapat berupa null.
E. API: Transaction Detail
Gunakan endpoint ini sebagai sumber status transaksi. Untuk keputusan fulfillment, cocokkan selalu project, order_id, amount, environment, dan status.
/api/transactiondetail| Query | Tipe | Keterangan |
|---|---|---|
project wajib | string | Slug project pemilik transaksi. |
order_id wajib | string | ID invoice yang dikirim saat create. |
amount wajib | integer | Nominal asli, bukan total_payment. |
api_key deprecated | string | Gunakan header X-API-Key. |
curl --get 'https://bayarbayar.in/api/transactiondetail' \
-H 'X-API-Key: gpk_live_CONTOH' \
--data-urlencode 'project=toko-satu' \
--data-urlencode 'order_id=INV-001' \
--data-urlencode 'amount=10000'
{
"transaction": {
"project": "toko-satu",
"order_id": "INV-001",
"amount": 10000,
"total_payment": 10123,
"refund_amount": 0,
"status": "pending",
"payment_method": "qris",
"completed_at": null,
"environment": "live",
"sandbox": false
}
}
{
"transaction": {
"project": "toko-satu",
"order_id": "INV-001",
"amount": 10000,
"total_payment": 10123,
"refund_amount": 0,
"status": "completed",
"payment_method": "qris",
"completed_at": "2030-01-01T11:55:00.000Z",
"environment": "live",
"sandbox": false
}
}
Webhook adalah mekanisme utama untuk perubahan status. Endpoint detail cocok sebagai verifikasi tambahan atau rekonsiliasi—bukan untuk polling sangat cepat. Jika perlu polling, gunakan interval wajar dan exponential backoff.
F. API: Transaction Cancel
Membatalkan transaksi yang masih pending. QR dinonaktifkan secara lokal dan kode unik dilepas sesuai guard period. Transaksi completed tidak dapat dibatalkan.
/api/transactioncancelcurl -X POST 'https://bayarbayar.in/api/transactioncancel' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: gpk_live_CONTOH' \
-d '{
"project": "toko-satu",
"order_id": "INV-001",
"amount": 10000
}'
{
"success": true,
"status": "cancelled",
"transaction": {
"project": "toko-satu",
"order_id": "INV-001",
"amount": 10000,
"total_payment": 10123,
"refund_amount": 0,
"status": "cancelled",
"payment_method": "qris",
"completed_at": null,
"environment": "live",
"sandbox": false
}
}
manual_review agar diperiksa manusia.
G. API: Payment Methods
Membaca metode pembayaran yang aktif untuk project.
/api/v1/projects/{project}/payment-methodscurl 'https://bayarbayar.in/api/v1/projects/toko-satu/payment-methods' \
-H 'X-API-Key: gpk_live_CONTOH'
{
"success": true,
"data": [
{
"code": "qris",
"name": "QRIS",
"status": "active"
}
]
}
H. Contoh Integrasi
H.1. Node.js
const response = await fetch(
'https://bayarbayar.in/api/transactioncreate/qris',
{
method: 'POST',
headers: {
'content-type': 'application/json',
'x-api-key': process.env.BAYARBAYAR_API_KEY,
'idempotency-key': `checkout-${order.id}`
},
body: JSON.stringify({
project: 'toko-satu',
order_id: order.id,
amount: order.amount,
expiry_minutes: 60
})
}
);
const result = await response.json();
if (!response.ok) throw new Error(result.code);
// Arahkan browser pelanggan ke URL ini.
return result.payment.payment_url;
H.2. PHP
<?php
$orderId = 'INV-001';
$payload = json_encode([
'project' => 'toko-satu',
'order_id' => $orderId,
'amount' => 10000,
'expiry_minutes' => 60,
]);
$curl = curl_init('https://bayarbayar.in/api/transactioncreate/qris');
curl_setopt_array($curl, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-API-Key: ' . getenv('BAYARBAYAR_API_KEY'),
'Idempotency-Key: checkout-' . $orderId,
],
CURLOPT_POSTFIELDS => $payload,
]);
$response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$result = json_decode($response, true);
curl_close($curl);
if ($status < 200 || $status >= 300) {
throw new RuntimeException($result['code'] ?? 'E_UNKNOWN');
}
header('Location: ' . $result['payment']['payment_url']);
exit;
I. Webhook Pembayaran
BayarBayar.in mengirim HTTP POST ke callback URL project setiap kali status transaksi berubah. Event disimpan sebelum dikirim dan dicoba ulang dengan exponential backoff sampai menerima HTTP 2xx.
I.1. Header
| Header | Isi |
|---|---|
X-Gateway-Event-ID | UUID unik untuk deduplikasi event. |
X-Gateway-Timestamp | UNIX timestamp saat request ditandatangani. |
X-Gateway-Signature | HMAC SHA-256 dalam format hexadecimal. |
Content-Type | application/json |
I.2. Jenis event
| Event | Kapan dikirim | Tindakan merchant |
|---|---|---|
transaction.completed | Pembayaran live terverifikasi. | Verifikasi payload, lalu penuhi pesanan satu kali. |
transaction.sandbox_completed | Simulasi sandbox berhasil. | Uji integrasi saja; jangan memenuhi pesanan nyata. |
transaction.expired | Batas pembayaran terlewati. | Tutup invoice pada sistem merchant. |
transaction.cancelled | Merchant membatalkan transaksi. | Tandai invoice dibatalkan. |
transaction.manual_review | Pencocokan tidak aman atau ambigu. | Jangan fulfillment otomatis; periksa dashboard. |
transaction.partially_refunded | Pengembalian dana sebagian terdeteksi. | Catat nilai refund_amount. |
transaction.refunded | Pengembalian dana penuh terdeteksi. | Tandai pembayaran telah dikembalikan. |
I.3. Payload
{
"schema_version": "1.0",
"event_id": "550e8400-e29b-41d4-a716-446655440000",
"event_type": "transaction.completed",
"event_timestamp": "2030-01-01T11:55:01.000Z",
"project": "toko-satu",
"order_id": "INV-001",
"amount": 10000,
"total_payment": 10123,
"status": "completed",
"payment_method": "qris",
"completed_at": "2030-01-01T11:55:00.000Z",
"refund_amount": 0,
"environment": "live",
"sandbox": false
}
I.4. Verifikasi signature
Hitung signature dari raw request body persis seperti diterima:
hex(HMAC_SHA256(timestamp + "." + raw_request_body, webhook_secret))
import crypto from 'node:crypto';
import express from 'express';
const app = express();
app.post('/webhook/bayarbayar',
express.raw({ type: 'application/json' }),
(req, res) => {
const timestamp = req.get('x-gateway-timestamp') || '';
const received = req.get('x-gateway-signature') || '';
const timestampSeconds = Number(timestamp);
const currentSeconds = Math.floor(Date.now() / 1000);
const timestampValid = Number.isSafeInteger(timestampSeconds)
&& Math.abs(currentSeconds - timestampSeconds) <= 300;
if (!timestampValid) return res.sendStatus(401);
const expected = crypto
.createHmac('sha256', process.env.BAYARBAYAR_WEBHOOK_SECRET)
.update(`${timestamp}.${req.body.toString('utf8')}`)
.digest();
const receivedBuffer = /^[a-f0-9]{64}$/.test(received)
? Buffer.from(received, 'hex')
: Buffer.alloc(0);
const valid = receivedBuffer.length === expected.length
&& crypto.timingSafeEqual(receivedBuffer, expected);
if (!valid) return res.sendStatus(401);
const event = JSON.parse(req.body.toString('utf8'));
// Deduplikasi event.event_id sebelum fulfillment.
res.sendStatus(204);
}
);
event_id, verifikasi signature, tolak timestamp yang berselisih lebih dari 5 menit, lalu proses event secara idempotent. Hanya kembalikan HTTP 2xx setelah event berhasil disimpan.
I.5. Urutan aman menerima webhook
- Baca body sebagai raw bytes sebelum JSON parser mengubah formatnya.
- Tolak timestamp yang terlalu lama untuk membatasi replay.
- Hitung HMAC menggunakan webhook secret project dan bandingkan secara constant-time.
- Simpan
X-Gateway-Event-IDpada kolom unik. Event yang sama cukup dibalas HTTP 2xx. - Cocokkan project, order ID, amount, status, dan environment dengan data merchant.
- Simpan perubahan secara atomik, baru balas HTTP 2xx.
Callback URL wajib memakai HTTPS dan domain publik. Host lokal atau loopback, jaringan privat/reserved, serta URL yang memuat username atau password akan ditolak. Respons selain HTTP 2xx dianggap gagal dan akan dicoba ulang.
J. Idempotensi, retry, dan rate limit
Kirim header Idempotency-Key saat membuat transaksi. Gunakan nilai unik dan stabil untuk satu usaha pembuatan pembayaran, misalnya checkout-{order_id}.
- Project, order ID, dan nominal yang sama mengembalikan transaksi yang sudah ada.
- Order ID sama dengan nominal berbeda menghasilkan HTTP 409.
- Idempotency key sama untuk payload berbeda menghasilkan HTTP 409.
- Panjang maksimum idempotency key adalah 128 karakter.
Retry yang aman
- Jika terjadi timeout jaringan, kirim ulang request create dengan body dan
Idempotency-Keyyang sama. - Jangan mengganti
order_idhanya karena response pertama terlambat. - Retry otomatis hanya untuk kegagalan sementara seperti timeout, HTTP 429, 502, atau 503.
- Gunakan exponential backoff dengan jitter dan batasi jumlah percobaan.
- Jangan retry otomatis untuk 400, 401, 403, 404, 409, atau 422 sebelum penyebab request diperbaiki.
Rate limit
BayarBayar.in menerapkan batas global dan batas per project. Saat HTTP 429 diterima, hentikan request sementara dan ikuti header Retry-After. Header berikut dapat disertakan pada response:
| Header | Arti |
|---|---|
RateLimit | Informasi limit global sesuai standar yang digunakan server. |
RateLimit-Policy | Kebijakan window dan batas rate limit global. |
X-RateLimit-Limit | Batas request project per menit. |
X-RateLimit-Remaining | Sisa request pada window project saat ini. |
Retry-After | Jumlah detik minimum sebelum mencoba kembali. |
K. Status dan Error
pendingMenunggu pembayaran.
completedPembayaran berhasil terverifikasi.
expiredMelewati batas waktu pembayaran.
cancelledDibatalkan oleh merchant.
failedPemrosesan transaksi gagal.
manual_reviewMutasi ambigu atau perlu pemeriksaan manual.
partially_refundedDana dikembalikan sebagian.
refundedDana dikembalikan seluruhnya.
K.1. HTTP status
| HTTP | Arti | Contoh kode |
|---|---|---|
400 | Format request tidak dapat diproses. | E_BAD_REQUEST |
401 | API key salah atau tidak tersedia. | E_UNAUTHORIZED |
403 | Project, scope, atau akun provider tidak diizinkan. | E_INSUFFICIENT_SCOPE |
404 | Endpoint atau transaksi tidak ditemukan. | E_TRANSACTION_NOT_FOUND |
409 | Konflik order, idempotensi, nominal, atau status. | E_ORDER_AMOUNT_CONFLICT |
413 | Body request melebihi batas 32 KB. | E_BODY_TOO_LARGE |
422 | Validasi request gagal. | E_VALIDATION |
429 | Rate limit atau kuota pending tercapai. | E_RATE_LIMIT |
500 | Error internal tanpa stack trace. | E_INTERNAL |
502 | Provider mengembalikan respons tidak valid. | E_PROVIDER_UNAVAILABLE |
503 | Sesi provider atau kode unik belum tersedia. | E_PROVIDER_SESSION_NOT_READY |
Simpan request_id dari response gagal untuk pencarian audit dan troubleshooting.
K.2. Kode error yang sering ditemui
| Kode | Penyebab | Yang harus dilakukan |
|---|---|---|
E_UNAUTHORIZED | Slug dan API key tidak cocok, key dicabut, kedaluwarsa, atau berbeda mode. | Periksa project dan gunakan key aktif dari environment yang sama. |
E_INSUFFICIENT_SCOPE | API key tidak memiliki scope endpoint. | Buat key dengan scope read atau write yang diperlukan. |
E_PROJECT_INACTIVE | Project dinonaktifkan. | Aktifkan project dari Dashboard. |
E_PROJECT_PAYMENT_CONFIG_REQUIRED | Merchant ID atau QRIS project belum lengkap. | Tambahkan QRIS milik akun merchant project. |
E_BAD_REQUEST | JSON rusak atau request tidak dapat dibaca. | Perbaiki sintaks JSON dan header Content-Type. |
E_BODY_TOO_LARGE | Body request melebihi 32 KB. | Kirim hanya field API yang didukung. |
E_VALIDATION | Tipe, field, atau kombinasi parameter tidak sesuai schema. | Periksa rincian pada object errors. |
E_INVALID_EXPIRY | Expiry yang berformat valid berada di luar 5–300 menit. | Kirim satu expiry_minutes berupa integer 5–300. |
E_ORDER_AMOUNT_CONFLICT | Order ID sudah ada dengan nominal lain. | Gunakan nominal semula atau order ID baru. |
E_IDEMPOTENCY_CONFLICT | Idempotency key dipakai untuk payload berbeda. | Gunakan payload semula atau key baru. |
E_COMPLETED_CANNOT_CANCEL | Transaksi sudah lunas. | Jangan cancel; jalankan proses refund terpisah bila tersedia. |
E_PROVIDER_SESSION_NOT_READY | Sesi GoPay live belum dapat diverifikasi. | Hubungkan ulang akun provider dari menu Keamanan. |
E_RATE_LIMIT | Terlalu banyak request pada project. | Ikuti Retry-After dan perlambat request. |
L. Pengujian
- Pastikan project berada dalam mode Sandbox.
- Buka menu Tes QRIS dan buat transaksi uji.
- Gunakan tombol simulasi lunas di dashboard. QR sandbox tidak boleh dibayar dengan aplikasi bank.
- Pastikan backend menerima webhook dengan
environment: "sandbox"danevent_type: "transaction.sandbox_completed". - Periksa detail transaksi melalui API sebelum menguji mode Live.
status: "completed", environment: "live", dan identitas order yang cocok yang boleh memenuhi pesanan nyata.
M. Checklist sebelum menerima uang nyata
Selesaikan seluruh pemeriksaan ini sebelum mengubah project ke mode Live.
Status layanan
/healthMenandakan proses aplikasi hidup./readyHTTP 200 jika database siap; HTTP 503 jika belum siap.Gunakan endpoint ini untuk load balancer atau monitoring. Jangan menggunakannya sebagai bukti bahwa akun provider suatu project siap menerima pembayaran; pemeriksaan provider tetap dilakukan saat transaksi live dibuat.
N. Pemecahan masalah
QR sandbox tidak dapat dibayar
Ini normal. QR sandbox hanya untuk simulasi melalui menu Tes QRIS. Ubah project ke Live hanya setelah seluruh integrasi selesai diuji.
Pembayaran live sudah dilakukan, tetapi status masih pending
Pastikan pelanggan membayar persis total_payment, Merchant ID sesuai QRIS project, sesi GoPay terhubung, transaksi belum kedaluwarsa, dan worker berjalan. Jangan mengubah status secara manual. Jika pencocokan tidak tunggal atau pembayaran terlambat, transaksi dapat masuk manual_review.
Create mengembalikan 401 setelah mode project diubah
Perubahan Sandbox/Live menghasilkan credential environment yang sesuai. Gunakan API key baru yang ditampilkan setelah perubahan mode.
Webhook terus dicoba ulang
Pastikan callback dapat diakses melalui HTTPS publik, tidak melakukan redirect, selesai sebelum timeout, dan mengembalikan HTTP 2xx. Periksa riwayat webhook pada Dashboard.
Payment URL menampilkan 404
Gunakan payment_url persis dari response create. Token yang salah, project nonaktif, atau URL yang dipotong akan ditolak.
Bagaimana meminta bantuan?
Catat waktu kejadian, project slug, order ID, HTTP status, error code, dan request_id. Jangan pernah mengirim API key, webhook secret, OTP, cookie, atau session provider.