Dokumentasi lengkap REST API untuk integrasi Payment Gateway — QRIS, GoPay Merchant, OVO, dan multi e-wallet.
YOUR_API_KEY_HERE.
Semua request API menggunakan base URL berikut:
https://www.bayar.gg/api
Semua request API harus menyertakan API Key di header:
X-API-Key: YOUR_API_KEY_HERE
Atau sebagai query parameter:
?apiKey=YOUR_API_KEY_HERE
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/create-payment.php | Membuat pembayaran baru |
| GET | /api/check-payment.php | Cek status pembayaran |
| GET | /api/list-payments.php | Daftar pembayaran dengan filter & pagination |
Membuat pembayaran baru dengan opsi produk digital, foto produk, dan redirect URL.
| Parameter | Type | Required | Description |
|---|---|---|---|
amount | number | Required | Nominal pembayaran (minimal Rp 1.000, maksimal Rp 500.000 untuk QRIS Admin) |
description | string | Optional | Deskripsi pembayaran |
customer_name | string | Optional | Nama pelanggan |
customer_email | string | Optional | Email pelanggan |
customer_phone | string | Optional | No. HP pelanggan |
callback_url | string | Optional | URL webhook saat pembayaran sukses |
redirect_url | string | Optional | URL redirect setelah pembayaran sukses New |
file_id | number | Optional | ID file digital yang akan diberikan setelah bayar New |
content_id | number | Optional | ID hidden content yang akan dibuka setelah bayar New |
product_image_id | number | Optional | ID foto produk yang ditampilkan di halaman pembayaran New |
payment_method | string | Optional | Metode pembayaran: qris, qris_user, gopay_qris, atau ovo (default: qris) |
use_qris_converter | boolean | Optional | Aktifkan QRIS Converter untuk membuat QRIS dinamis dengan nominal tertanam (default: false). QRIS string otomatis diambil dari akun yang terhubung (GoPay Merchant / BRI QRIS) sesuai metode pembayaran. |
qris — QRIS (default, maks. Rp 500.000)qris_user — BRI QRIS (memerlukan langganan aktif + konfigurasi BRI, tanpa limit)gopay_qris — GoPay QRIS (memerlukan langganan aktif + akun GoPay Merchant terhubung via OTP, tanpa limit) Recommendedovo — OVO (memerlukan langganan aktif + akun OVO terhubung)Aktifkan use_qris_converter: true untuk membuat QRIS dinamis dengan nominal tertanam otomatis.
payment_methodgopay_qris → dari GoPay QRISqris_user → dari BRI QRISqris → dari QRISqris_string secara manualqris_converter: trueUntuk metode pembayaran qris maksimal nominal adalah Rp 500.000. Untuk nominal lebih besar, gunakan metode qris_user atau gopay_qris (GoPay Merchant QRIS — hubungkan via OTP, tanpa limit).
/api/get-payment-methods untuk mengecek ketersediaan dan user_status.has_active_subscription.
curl -X POST https://www.bayar.gg/api/create-payment.php \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY_HERE" \
-d '{
"amount": 50000,
"description": "Pembayaran Produk A",
"payment_method": "gopay_qris"
}'$response = file_get_contents('https://www.bayar.gg/api/create-payment.php', false,
stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\nX-API-Key: YOUR_API_KEY_HERE",
'content' => json_encode([
'amount' => 50000,
'description' => 'Pembayaran Produk A',
'payment_method' => 'gopay_qris'
])
]
])
);
$data = json_decode($response, true);const res = await fetch('https://www.bayar.gg/api/create-payment.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'YOUR_API_KEY_HERE'
},
body: JSON.stringify({
amount: 50000,
description: 'Pembayaran Produk A',
payment_method: 'gopay_qris'
})
});
const data = await res.json();import requests
response = requests.post(
'https://www.bayar.gg/api/create-payment.php',
headers={'X-API-Key': 'YOUR_API_KEY_HERE'},
json={
'amount': 50000,
'description': 'Pembayaran Produk A',
'payment_method': 'gopay_qris'
}
)
data = response.json(){
"success": true,
"payment": {
"invoice_id": "PAY-admin-1234567890-ABC123",
"amount": 50000,
"unique_code": 347,
"final_amount": 50347,
"payment_method": "gopay_qris",
"status": "pending",
"expires_at": "2026-04-16 12:30:00"
},
"payment_url": "https://www.bayar.gg/pay?invoice=PAY-admin-1234567890-ABC123"
}Mengecek status pembayaran berdasarkan Invoice ID.
| Parameter | Type | Required | Description |
|---|---|---|---|
invoice | string | Required | Invoice ID pembayaran |
curl -X GET "https://www.bayar.gg/api/check-payment.php?invoice=PAY-admin-1234567890-ABC123" \
-H "X-API-Key: YOUR_API_KEY_HERE"$invoice = 'PAY-admin-1234567890-ABC123';
$response = file_get_contents(
'https://www.bayar.gg/api/check-payment.php?invoice=' . urlencode($invoice),
false,
stream_context_create([
'http' => ['header' => "X-API-Key: YOUR_API_KEY_HERE"]
])
);
$data = json_decode($response, true);const invoice = 'PAY-admin-1234567890-ABC123';
const res = await fetch(
`https://www.bayar.gg/api/check-payment.php?invoice=${invoice}`,
{ headers: { 'X-API-Key': 'YOUR_API_KEY_HERE' } }
);
const data = await res.json();import requests
response = requests.get(
'https://www.bayar.gg/api/check-payment.php',
headers={'X-API-Key': 'YOUR_API_KEY_HERE'},
params={'invoice': 'PAY-admin-1234567890-ABC123'}
)
data = response.json(){
"success": true,
"invoice_id": "PAY-admin-1234567890-ABC123",
"status": "paid",
"amount": 50000,
"final_amount": 50347,
"payment_method": "gopay_qris",
"paid_at": "2026-04-16 12:25:30",
"paid_reff_num": "TRX123456789",
"expires_at": "2026-04-16 12:30:00"
}Mendapatkan daftar pembayaran dengan filter, search, dan pagination.
| Parameter | Type | Required | Description |
|---|---|---|---|
search | string | Optional | Cari berdasarkan invoice, deskripsi, nama/email/HP pelanggan New |
status | string | Optional | Filter by status: pending, paid, expired, cancelled |
payment_method | string | Optional | Filter by method: qris, qris_user, gopay_qris, ovo New |
paid_via | string | Optional | Filter pembayaran sukses by method: qris, qris_user, gopay_qris, ovo New |
start_date | string | Optional | Filter dari tanggal (YYYY-MM-DD) |
end_date | string | Optional | Filter sampai tanggal (YYYY-MM-DD) |
page | number | Optional | Halaman (default: 1) |
limit | number | Optional | Jumlah per halaman (default: 20, max: 100) |
curl -X GET "https://www.bayar.gg/api/list-payments.php?status=paid&page=1&limit=10" \
-H "X-API-Key: YOUR_API_KEY_HERE"$response = file_get_contents(
'https://www.bayar.gg/api/list-payments.php?status=paid&page=1&limit=10',
false,
stream_context_create([
'http' => ['header' => "X-API-Key: YOUR_API_KEY_HERE"]
])
);
$data = json_decode($response, true);const res = await fetch(
'https://www.bayar.gg/api/list-payments.php?status=paid&page=1&limit=10',
{ headers: { 'X-API-Key': 'YOUR_API_KEY_HERE' } }
);
const data = await res.json();import requests
response = requests.get(
'https://www.bayar.gg/api/list-payments.php',
headers={'X-API-Key': 'YOUR_API_KEY_HERE'},
params={'status': 'paid', 'page': 1, 'limit': 10}
)
data = response.json(){
"success": true,
"data": [
{
"invoice_id": "PAY-admin-1234567890-ABC123",
"amount": 50000,
"final_amount": 50347,
"status": "paid",
"payment_method": "gopay_qris",
"paid_at": "2026-04-16 12:25:30",
"created_at": "2026-04-16 12:20:00"
}
],
"pagination": { "page": 1, "limit": 10, "total": 42, "total_pages": 5 }
}| Method | Endpoint | Description |
|---|---|---|
| GET | /api/get-payment-methods.php | Daftar metode pembayaran & ketersediaan |
| GET | /api/get-account-status.php | Status akun & integrasi |
| GET | /api/get-statistics.php | Statistik pembayaran |
Mendapatkan daftar metode pembayaran dan status ketersediaan. Response menyertakan user_status.has_active_subscription (langganan aktif diperlukan untuk create payment dan metode qris_user, gopay_qris, ovo).
curl -X GET "https://www.bayar.gg/api/get-payment-methods.php" \
-H "X-API-Key: YOUR_API_KEY_HERE"$response = file_get_contents(
'https://www.bayar.gg/api/get-payment-methods.php',
false,
stream_context_create([
'http' => ['header' => "X-API-Key: YOUR_API_KEY_HERE"]
])
);
$data = json_decode($response, true);const res = await fetch(
'https://www.bayar.gg/api/get-payment-methods.php',
{ headers: { 'X-API-Key': 'YOUR_API_KEY_HERE' } }
);
const data = await res.json();import requests
response = requests.get(
'https://www.bayar.gg/api/get-payment-methods.php',
headers={'X-API-Key': 'YOUR_API_KEY_HERE'}
)
data = response.json(){
"success": true,
"methods": [
{"id": "qris", "name": "QRIS", "available": true},
{"id": "gopay_qris", "name": "GoPay QRIS", "available": true}
],
"user_status": {"has_active_subscription": true}
}Mendapatkan status akun, integrasi, dan ringkasan statistik.
curl -X GET "https://www.bayar.gg/api/get-account-status.php" \
-H "X-API-Key: YOUR_API_KEY_HERE"$response = file_get_contents(
'https://www.bayar.gg/api/get-account-status.php',
false,
stream_context_create([
'http' => ['header' => "X-API-Key: YOUR_API_KEY_HERE"]
])
);
$data = json_decode($response, true);const res = await fetch(
'https://www.bayar.gg/api/get-account-status.php',
{ headers: { 'X-API-Key': 'YOUR_API_KEY_HERE' } }
);
const data = await res.json();import requests
response = requests.get(
'https://www.bayar.gg/api/get-account-status.php',
headers={'X-API-Key': 'YOUR_API_KEY_HERE'}
)
data = response.json(){
"success": true,
"account": {
"username": "admin",
"email": "admin@bayar.gg",
"is_verified": true
},
"integrations": {"gopay": true, "bri": false, "ovo": false}
}Mendapatkan statistik pembayaran detail dengan breakdown per metode.
| Parameter | Type | Required | Description |
|---|---|---|---|
period | string | Optional | Periode statistik: all, today, week, month, year (default: all) |
curl -X GET "https://www.bayar.gg/api/get-statistics.php?period=month" \
-H "X-API-Key: YOUR_API_KEY_HERE"$response = file_get_contents(
'https://www.bayar.gg/api/get-statistics.php?period=month',
false,
stream_context_create([
'http' => ['header' => "X-API-Key: YOUR_API_KEY_HERE"]
])
);
$data = json_decode($response, true);const res = await fetch(
'https://www.bayar.gg/api/get-statistics.php?period=month',
{ headers: { 'X-API-Key': 'YOUR_API_KEY_HERE' } }
);
const data = await res.json();import requests
response = requests.get(
'https://www.bayar.gg/api/get-statistics.php',
headers={'X-API-Key': 'YOUR_API_KEY_HERE'},
params={'period': 'month'}
)
data = response.json(){
"success": true,
"period": "month",
"total_transactions": 150,
"total_amount": 7500000,
"total_paid": 120,
"breakdown": {"qris": 80, "gopay_qris": 30, "ovo": 10}
}| Method | Endpoint | Description |
|---|---|---|
| GET | /api/list-files.php | Daftar file digital |
| GET | /api/list-contents.php | Daftar hidden content |
| GET | /api/list-images.php | Daftar foto produk |
Mendapatkan daftar file digital yang sudah diupload.
| Parameter | Type | Required | Description |
|---|---|---|---|
active_only | boolean | Optional | Hanya file aktif (default: true) |
curl -X GET "https://www.bayar.gg/api/list-files.php?active_only=true" \
-H "X-API-Key: YOUR_API_KEY_HERE"$response = file_get_contents(
'https://www.bayar.gg/api/list-files.php?active_only=true',
false,
stream_context_create([
'http' => ['header' => "X-API-Key: YOUR_API_KEY_HERE"]
])
);
$data = json_decode($response, true);const res = await fetch(
'https://www.bayar.gg/api/list-files.php?active_only=true',
{ headers: { 'X-API-Key': 'YOUR_API_KEY_HERE' } }
);
const data = await res.json();import requests
response = requests.get(
'https://www.bayar.gg/api/list-files.php',
headers={'X-API-Key': 'YOUR_API_KEY_HERE'},
params={'active_only': 'true'}
)
data = response.json(){
"success": true,
"data": [
{"id": 1, "filename": "ebook.pdf", "size": 2048576, "active": true}
]
}Mendapatkan daftar hidden content yang sudah dibuat.
| Parameter | Type | Required | Description |
|---|---|---|---|
active_only | boolean | Optional | Hanya konten aktif (default: true) |
curl -X GET "https://www.bayar.gg/api/list-contents.php?active_only=true" \
-H "X-API-Key: YOUR_API_KEY_HERE"$response = file_get_contents(
'https://www.bayar.gg/api/list-contents.php?active_only=true',
false,
stream_context_create([
'http' => ['header' => "X-API-Key: YOUR_API_KEY_HERE"]
])
);
$data = json_decode($response, true);const res = await fetch(
'https://www.bayar.gg/api/list-contents.php?active_only=true',
{ headers: { 'X-API-Key': 'YOUR_API_KEY_HERE' } }
);
const data = await res.json();import requests
response = requests.get(
'https://www.bayar.gg/api/list-contents.php',
headers={'X-API-Key': 'YOUR_API_KEY_HERE'},
params={'active_only': 'true'}
)
data = response.json(){
"success": true,
"data": [
{"id": 1, "title": "License Key", "type": "text", "active": true}
]
}Mendapatkan daftar foto produk yang sudah diupload.
| Parameter | Type | Required | Description |
|---|---|---|---|
active_only | boolean | Optional | Hanya gambar aktif (default: true) |
curl -X GET "https://www.bayar.gg/api/list-images.php?active_only=true" \
-H "X-API-Key: YOUR_API_KEY_HERE"$response = file_get_contents(
'https://www.bayar.gg/api/list-images.php?active_only=true',
false,
stream_context_create([
'http' => ['header' => "X-API-Key: YOUR_API_KEY_HERE"]
])
);
$data = json_decode($response, true);const res = await fetch(
'https://www.bayar.gg/api/list-images.php?active_only=true',
{ headers: { 'X-API-Key': 'YOUR_API_KEY_HERE' } }
);
const data = await res.json();import requests
response = requests.get(
'https://www.bayar.gg/api/list-images.php',
headers={'X-API-Key': 'YOUR_API_KEY_HERE'},
params={'active_only': 'true'}
)
data = response.json(){
"success": true,
"data": [
{"id": 1, "filename": "product.jpg", "url": "https://...", "active": true}
]
}| Method | Endpoint | Description |
|---|---|---|
| POST | /api/qris-convert.php | Konversi QRIS statis → dinamis dengan nominal |
| GET POST | /api/qris-info.php | Info & validasi QRIS |
Mengkonversi QRIS statis ke QRIS dinamis dengan nominal tertanam. Support input text QRIS atau gambar QRIS.
| Parameter | Type | Required | Description |
|---|---|---|---|
nominal | number | Required | Nominal yang akan ditanam di QRIS (dalam Rupiah) |
qris | string | Pilih salah satu | String QRIS yang akan dikonversi |
image | string | Pilih salah satu | Base64 encoded gambar QR code |
image_url | string | Pilih salah satu | URL gambar QR code |
| Field | Type | Description |
|---|---|---|
nominal | number | Nominal yang akan ditanam |
image | file | File gambar QR code (JPEG, PNG, GIF, WebP) |
qr_image_url untuk menampilkan QR code yang sudah dikonversi langsung di aplikasi Anda.
curl -X POST https://www.bayar.gg/api/qris-convert.php \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY_HERE" \
-d '{
"qris": "00020101021126...",
"nominal": 50000
}'$response = file_get_contents('https://www.bayar.gg/api/qris-convert.php', false,
stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\nX-API-Key: YOUR_API_KEY_HERE",
'content' => json_encode([
'qris' => '00020101021126...',
'nominal' => 50000
])
]
])
);
$data = json_decode($response, true);const res = await fetch('https://www.bayar.gg/api/qris-convert.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'YOUR_API_KEY_HERE'
},
body: JSON.stringify({
qris: '00020101021126...',
nominal: 50000
})
});
const data = await res.json();import requests
response = requests.post(
'https://www.bayar.gg/api/qris-convert.php',
headers={'X-API-Key': 'YOUR_API_KEY_HERE'},
json={
'qris': '00020101021126...',
'nominal': 50000
}
)
data = response.json(){
"success": true,
"qris": "00020101021226...",
"qr_image_url": "https://www.bayar.gg/qris-info/api/qr.php?data=...",
"merchant_name": "GOPAY MERCHANT",
"amount": 50000
}Mendapatkan informasi dari QRIS tanpa mengkonversinya. Berguna untuk validasi dan preview.
| Parameter | Type | Required | Description |
|---|---|---|---|
qris | string | Required | String QRIS untuk dianalisis |
curl -X GET "https://www.bayar.gg/api/qris-info.php?qris=00020101021126..." \
-H "X-API-Key: YOUR_API_KEY_HERE"$response = file_get_contents(
'https://www.bayar.gg/api/qris-info.php?qris=00020101021126...',
false,
stream_context_create([
'http' => ['header' => "X-API-Key: YOUR_API_KEY_HERE"]
])
);
$data = json_decode($response, true);const res = await fetch(
'https://www.bayar.gg/api/qris-info.php?qris=00020101021126...',
{ headers: { 'X-API-Key': 'YOUR_API_KEY_HERE' } }
);
const data = await res.json();import requests
response = requests.get(
'https://www.bayar.gg/api/qris-info.php',
headers={'X-API-Key': 'YOUR_API_KEY_HERE'},
params={'qris': '00020101021126...'}
)
data = response.json(){
"success": true,
"merchant_name": "GOPAY MERCHANT",
"merchant_city": "JAKARTA",
"amount": 0,
"is_dynamic": false
}| Method | Endpoint | Description |
|---|---|---|
| GET | /api/wa-store-orders.php | Daftar pesanan WA Store |
| POST | /api/wa-store-complete.php | Update status pesanan |
Ambil daftar pesanan WhatsApp Store atau detail pesanan tertentu. Mendukung pencarian berdasarkan nomor order, nama customer, atau nomor telepon.
| Parameter | Tipe | Required | Keterangan |
|---|---|---|---|
order_number | string | Optional | Ambil detail satu pesanan (e.g. WA260329-A1B2) |
status | string | Optional | Filter: pending, waiting_payment, paid, processing, completed, cancelled |
search | string | Optional | Cari berdasarkan nomor order, nama customer, nomor telepon, atau invoice ID |
limit | integer | Optional | Max 100, default 50 |
offset | integer | Optional | Pagination offset |
curl -X GET "https://www.bayar.gg/api/wa-store-orders.php?status=paid&limit=10" \
-H "X-API-Key: YOUR_API_KEY_HERE"$response = file_get_contents(
'https://www.bayar.gg/api/wa-store-orders.php?status=paid&limit=10',
false,
stream_context_create([
'http' => ['header' => "X-API-Key: YOUR_API_KEY_HERE"]
])
);
$data = json_decode($response, true);const res = await fetch(
'https://www.bayar.gg/api/wa-store-orders.php?status=paid&limit=10',
{ headers: { 'X-API-Key': 'YOUR_API_KEY_HERE' } }
);
const data = await res.json();import requests
response = requests.get(
'https://www.bayar.gg/api/wa-store-orders.php',
headers={'X-API-Key': 'YOUR_API_KEY_HERE'},
params={'status': 'paid', 'limit': 10}
)
data = response.json(){
"success": true,
"data": [
{
"order_number": "WA260329-A1B2",
"customer_name": "Rahim",
"status": "paid",
"total": 75000
}
],
"total": 5
}Update status pesanan WA Store (completed, cancelled). Pesanan hanya bisa diselesaikan (completed) jika sudah dibayar (status: paid/processing). Pesanan yang sudah selesai tidak bisa dibatalkan. Notifikasi WhatsApp otomatis dikirim ke customer.
| Parameter | Tipe | Required | Keterangan |
|---|---|---|---|
order_number | string | Required | Nomor order WA Store |
status | string | Optional | completed, cancelled (default: completed) |
notify | boolean | Optional | Kirim notifikasi WhatsApp ke customer (default: true) |
completed hanya bisa diset jika pesanan sudah berstatus paid atau processing. Pesanan completed tidak bisa di-cancel.
curl -X POST https://www.bayar.gg/api/wa-store-complete.php \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY_HERE" \
-d '{
"order_number": "WA260329-A1B2",
"status": "completed",
"notify": true
}'$response = file_get_contents('https://www.bayar.gg/api/wa-store-complete.php', false,
stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\nX-API-Key: YOUR_API_KEY_HERE",
'content' => json_encode([
'order_number' => 'WA260329-A1B2',
'status' => 'completed',
'notify' => true
])
]
])
);
$data = json_decode($response, true);const res = await fetch('https://www.bayar.gg/api/wa-store-complete.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'YOUR_API_KEY_HERE'
},
body: JSON.stringify({
order_number: 'WA260329-A1B2',
status: 'completed',
notify: true
})
});
const data = await res.json();import requests
response = requests.post(
'https://www.bayar.gg/api/wa-store-complete.php',
headers={'X-API-Key': 'YOUR_API_KEY_HERE'},
json={
'order_number': 'WA260329-A1B2',
'status': 'completed',
'notify': True
}
)
data = response.json(){
"success": true,
"message": "Order completed successfully",
"order": {
"order_number": "WA260329-A1B2",
"status": "completed"
}
}Integrasi OVO memungkinkan Anda menerima pembayaran langsung ke akun OVO Anda dengan pencocokan nominal otomatis.
| Step | Proses |
|---|---|
| 1 | Customer membayar ke nomor OVO Anda dengan nominal yang tepat (termasuk kode unik) |
| 2 | Sistem mengecek mutasi OVO setiap beberapa detik |
| 3 | Jika ditemukan transaksi masuk dengan nominal yang cocok, pembayaran otomatis dikonfirmasi |
| 4 | Callback dikirim ke URL yang Anda tentukan |
curl -X POST https://www.bayar.gg/api/create-payment.php \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY_HERE" \
-d '{
"amount": 50000,
"description": "Pembayaran Produk A",
"payment_method": "ovo"
}'
BRI Merchant QRIS memungkinkan Anda menerima pembayaran langsung ke rekening BRI Anda sendiri dengan QRIS merchant Anda.
qris_usercurl -X POST https://www.bayar.gg/api/create-payment.php \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY_HERE" \
-d '{
"amount": 50000,
"description": "Pembayaran Produk A",
"payment_method": "qris_user"
}'
GoPay Merchant QRIS memungkinkan Anda menerima pembayaran langsung ke akun GoPay Merchant Anda sendiri menggunakan QRIS.
gopay_qriscurl -X POST https://www.bayar.gg/api/create-payment.php \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY_HERE" \
-d '{
"amount": 50000,
"description": "Pembayaran Produk A",
"payment_method": "gopay_qris"
}'
{
"success": true,
"payment": {
"invoice_id": "PAY-admin-1234567890-ABC123",
"amount": 50000,
"unique_code": 347,
"final_amount": 50347,
"payment_method": "gopay_qris",
"status": "pending",
"expires_at": "2026-02-15 12:30:00"
},
"payment_url": "https://www.bayar.gg/pay?invoice=PAY-admin-1234567890-ABC123"
}
Jika Anda menyertakan callback_url saat membuat pembayaran, sistem akan mengirim POST request ke URL tersebut saat pembayaran berhasil.
{
"event": "payment.paid",
"invoice_id": "PAY-admin-1234567890-ABC123",
"status": "paid",
"amount": 50000,
"final_amount": 50123,
"unique_code": 123,
"paid_at": "2024-01-15 12:25:30",
"paid_amount": 50123,
"paid_reff_num": "TRX123456789",
"customer_name": "John Doe",
"customer_email": "john@example.com",
"customer_phone": "08123456789",
"description": "Pembayaran Produk A",
"redirect_url": "https://yoursite.com/thank-you",
"has_file": true,
"has_content": false,
"timestamp": 1705312530,
"signature": "sha256_hmac_signature"
}
| Header | Description |
|---|---|
Content-Type | application/json |
X-Webhook-Event | payment.paid |
X-Webhook-Signature | HMAC SHA256 signature untuk verifikasi |
X-Webhook-Timestamp | Unix timestamp saat callback dikirim |
X-Invoice-ID | Invoice ID pembayaran |
<?php
// Verifikasi callback signature
$payload = json_decode(file_get_contents('php://input'), true);
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? '';
// Buat signature untuk verifikasi
$signatureData = $payload['invoice_id'] . '|' . $payload['status'] . '|' . $payload['final_amount'] . '|' . $timestamp;
$expectedSignature = hash_hmac('sha256', $signatureData, 'YOUR_WEBHOOK_SECRET'); // Pengaturan → Webhook
if (hash_equals($expectedSignature, $signature)) {
// Signature valid, proses callback
if ($payload['status'] === 'paid') {
// Update order status
http_response_code(200);
echo json_encode(['success' => true]);
}
} else {
// Signature tidak valid
http_response_code(401);
echo json_encode(['error' => 'Invalid signature']);
}
?>
Konfigurasi webhook tersedia di Pengaturan → Webhook:
| Setting | Keterangan |
|---|---|
Default Callback URL | URL default yang otomatis digunakan jika callback_url tidak disertakan saat create payment. |
Webhook Secret Key | Secret key unik per user (whsec_xxx) untuk memverifikasi signature callback. Bisa di-regenerate kapan saja. |
Callback Logs | Riwayat 20 callback terakhir beserta status HTTP response. |
Webhook Secret Key Anda (bukan API Key). Dapatkan di Pengaturan → Webhook.
| Status | Description |
|---|---|
| pending | Menunggu pembayaran |
| paid | Pembayaran berhasil |
| expired | Pembayaran expired (melebihi batas waktu) |
| cancelled | Pembayaran dibatalkan |
| HTTP Code | Description |
|---|---|
200 | Success |
400 | Bad Request — Parameter tidak valid |
401 | Unauthorized — API Key tidak valid |
404 | Not Found — Resource tidak ditemukan |
405 | Method Not Allowed |
429 | Too Many Requests — Rate limit exceeded |
500 | Internal Server Error |