Bukapay memiliki fitur untuk melakukan kostumisasi tampilan halaman payment menggunakan kode html dan shortcode. Anda bisa melakukan perubahan pada warna, susunan kartu, text, bahkan seluruh tata letaknya. Server hanya bertugas mengisi data transaksi ke dalam tema itu sebelum dikirim ke apk olshop. Seluruh pengaturannya dilakukan langsung dari aplikasi bukaOlshop, lewat tiga menu terpisah:
Ketiganya berdiri sendiri, punya gaya dan skripnya masing-masing, jadi anda bisa mengubah salah satunya tanpa memengaruhi yang lain. Hapus kode html yang sudah dikostum, makan otomatis akan kembali memakai tema bawaan template.
Artikel ini menjelaskan cara mengedit tema: apa saja shortcode yang tersedia, bagian mana yang tidak boleh disentuh, dan isi lengkap dari shortcode {{metode_json}}, sumber data untuk daftar metode pembayaran.
Teks, warna, susunan, dan kelas CSS bebas anda ubah. Namun ada beberapa hal yang tidak kami sarankan untuk dilakukan perubahan:
{{script_cek_status}} di bagian bawah halaman pembayaran. Itulah yang memantau status pembayaran dan memindahkan pembeli ke halaman berhasil begitu dana masuk. Tanpa itu, halaman akan diam terusNilai contoh di bawah diambil dari transaksi topup saldo dengan nominal Rp 4.600 dengan kode unik 53, sehingga totalnya Rp 4.653.
Kelompok ini dikirim oleh aplikasi yang membuat tagihan, bukan oleh sistem pembayaran. Isinya menyesuaikan informasi aplikasi anda sendiri.
| Shortcode | Isi | Contoh nilai |
|---|---|---|
{{nama_aplikasi}} |
Nama aplikasi/Nama APK | BukaOlshop |
{{nama_toko}} |
Nama toko | BukaOlshop Store |
{{url_logo}} |
URL logo aplikasi | https://images.bukaolshop.com/...png |
{{kode_warna}} |
Warna utama aplikasi, format heksadesimal | #D50000 |
{{nama_user}} |
Nama pembeli | John Doe |
{{email_user}} |
Email pembeli | johndoe@gmail.com |
{{hp_user}} |
Nomor HP pembeli | 085212300000 |
{{jenis_pembayaran}} |
Keterangan produk yang dibayar | TopUp saldo/Bayar Transaksi |
Kelompok ini dikirim oleh sistem BukaPay yang membuat tagihan, gunakan data berikut untuk melacak transaksi:
| Shortcode | Isi | Contoh nilai |
|---|---|---|
{{id_request}} |
Nomor tagihan di sistem BukaPay | 360 |
{{token_request}} |
Token Topup / Nomor pembayaran | 1442249215 |
{{status_bayar}} |
Status mentah, dipakai sebagai kelas CSS | pending / lunas / expired |
{{status_teks}} |
Status dalam bahasa manusia | Menunggu Pembayaran |
{{alasan}} |
Keterangan tambahan status. Hanya di halaman sukses dan gagal |
{{status_bayar}} dipakai di dua tempat sekaligus pada tema bawaan, dan ini trik yang berguna: sebagai atribut di <body> dan sebagai kelaspada lencana status.
<body data-status="{{status_bayar}}">
<span class="lencana-status {{status_bayar}}">{{status_teks}}</span>
Dengan begitu anda bisa mewarnai lencana lewat CSS tanpa satu baris JavaScript pun:
.lencana-status.pending{background:var(--peringatan-lembut); color:var(--peringatan)}
.lencana-status.lunas {background:var(--sukses-lembut); color:var(--sukses)}
.lencana-status.expired{background:var(--bahaya-lembut); color:var(--bahaya)}
Setiap nominal tersedia dalam dua bentuk: angka mentah untuk dipakai di JavaScript atau atribut, dan versi berformat rupiah untuk ditampilkan langsung di HTML.
| Shortcode | Isi | Contoh nilai |
|---|---|---|
{{jumlah_bayar_final}} |
Total yang harus dibayar, angka mentah | 4653 |
{{jumlah_bayar_final_format}} |
Total, berformat rupiah | Rp 4.653 |
{{jumlah_dana}} |
Nominal sebelum kode unik | 4600 |
{{jumlah_dana_format}} |
Nominal sebelum kode unik, berformat | Rp 4.600 |
{{kode_unik}} |
Kode unik, angka mentah | 53 |
{{kode_unik_format}} |
Kode unik dengan pemisah ribuan | 53 |
{{biaya_admin}} |
Biaya admin, angka mentah | 0 |
{{biaya_admin_format}} |
Biaya admin, berformat | Rp 0 |
{{jumlah_bayar}} |
Nominal pokok tanpa kode unik dan biaya admin | 4600 |
{{jumlah_bayar_format}} |
Nominal pokok, berformat | Rp 4.600 |
Anda tidak perlu melakukan penjumlahan apapun di kode html, semua penjumlahan sudah di handle oleh {{jumlah_bayar_final}}
Versi mentah dipakai tema bawaan untuk tombol salin, supaya yang tersalin ke clipboard adalah angka bersih 4653, bukan teks Rp 4.653 yang akan ditolak aplikasi bank:
<button class="salin" type="button" data-salin="{{jumlah_bayar_final}}">
Salin
</button>
| Shortcode | Isi | Contoh nilai |
|---|---|---|
{{tanggal_expired}} |
Batas waktu, format mesin. Dipakai JavaScript hitung mundur | 2026-09-16 16:29:12 |
{{tanggal_expired_desc}} |
Batas waktu, format manusia | 16 September 2026, 16:29 WIB |
{{tanggal_buat}} |
Waktu tagihan dibuat | 16 September 2026, 16:09 WIB |
{{tanggal_paid}} |
Waktu pembayaran diterima. Hanya di halaman sukses | — |
Dua shortcode tanggal ini tidak bisa saling tukar. {{tanggal_expired}} harus dipakai di JavaScript karena formatnya bisa dibacanew Date(). {{tanggal_expired_desc}} untuk ditampilkan ke pembeli. Kalau tertukar, hitung mundurnya akan menampilkan NaN.
Begini cara tema bawaan memakai keduanya:
<!-- untuk dibaca pembeli -->
<p>Selesaikan sebelum <b>{{tanggal_expired_desc}}</b></p>
<!-- untuk dibaca JavaScript -->
<script>
var TANGGAL_EXPIRED_SERVER = "{{tanggal_expired}}";
</script>
Perhatikan bahwa {{tanggal_expired}} diapit tanda kutip karena ia sebuah teks. Ini berbeda dengan {{metode_json}} yang justru tidak boleh diapit kutip — akan dijelaskan di bagian 6.
| Shortcode | Isi |
|---|---|
{{url_konfirmasi_manual}} |
URL Halaman upload bukti transfer. |
{{url_status}} |
URL Halaman hasil, berhasil atau gagal |
{{url_gateway}} |
URL Halaman pembayaran lewat payment gateway eksternal |
Semua tautan ini sudah membawa tanda tangan digitalnya sendiri, jadi cukup dipasang apa adanya:
<a href="{{url_konfirmasi_manual}}">Sudah transfer? Konfirmasi manual</a>
Jangan melakukan perubahan pada link ini. Bagian sign= di dalamnya adalah tanda tangan yang mengunci link pada satu tagihan. Mengubah satu huruf saja membuat halaman tujuan menolak dengan pesan “Link tidak valid”.
Dua shortcode berikut tidak diisi teks, melainkan potongan kode HTML. Cara memasangnya berbeda dan paling sering jadi sumber kesalahan.
{{catatan_nominal}} — teks berisi HTMLIsinya kalimat peringatan yang berubah mengikuti ada atau tidaknya kode unik, dan di dalamnya sudah mengandung tag <b>:
<div class="catatan">{{catatan_nominal}}</div>
Hasilnya pada transaksi contoh:
Bayar tepat sampai 3 angka terakhir. Nominal yang berbeda
tidak akan terdeteksi otomatis oleh sistem.
Jika anda ingin menggunakan text catatan nominal sendiri, anda boleh menghapus shortcode {{catatan_nominal}} ini dan menulis text baru sendiri.
{{script_cek_status}} — blok script utuhShortcode ini diisi satu blok <script>...</script> lengkap. Isinya adalah pemantau yang menanyakan status pembayaran ke server secara berkala.
{{metode_json}}Daftar metode pembayaran yang aktif di server BukaPay dikirim dari server sebagai data JSON, lalu digambar oleh JavaScript. Dengan begitu, menambah atau menonaktifkan rekening cukup dilakukan di aplikasi bukaOlshop. Metode ini juga memungkinkan pihak bukapay melakukan penonaktifkan pada rekening yang sedang tidak bisa digunakan atau sedang offline, sehingga dapat mencegah user melakukan transfer ke rekening yang tidak aktif.
Sebelum masuk ke datanya, satu hal perlu dipahami dulu: halaman pembayaran bekerja dalam 2 step yang bergantian ditampilkan tanpa melakukan refresh halaman.
Step 1 : menampilkan daftar metode channel pembayaran
Step 2 : menampilkan detail metode yang dipilih berupa kartu QRIS atau kartu rekening, atau payment gateway eksternal
{{metode_json}} diisi array JSON mentah, jadi ia tidak boleh diapit tanda kutip:
<script>
var METODE_SERVER = {{metode_json}};
</script>
Bila belum ada metode aktif sama sekali, server mengisinya dengan array kosong [], bukan dengan nilai kosong. JavaScript anda tidak akan error, hanya menampilkan pesan “belum ada metode pembayaran”.
Isinya selalu array berisi objek. Satu objek sama dengan satu baris metode pada
tahap 1:
[
{
"id": "qris",
"jenis": "qris",
"nama": "QRIS",
"keterangan": "GoPay, OVO, DANA, ShopeePay, LinkAja, m-banking",
"logo": "https://payment.bukaolshop.net/assets/qris.png",
"nomor": null,
"atas_nama": "BukaPay Digital",
"petunjuk": "petunjuk transfer",
"qr": "show_payment?id_request=369&sign=ca4ab9ba7a9bb87f15b55759dfe4b9eb4d3b02e02faa5b33ed022e6ed9942971&qr=1"
},
{
"id": "rek-1",
"jenis": "bank",
"nama": "BCA",
"keterangan": "Kode bank 014",
"logo": "https://payment.bukaolshop.net/assets/bca.png",
"nomor": "0344133000",
"atas_nama": "Nama rekening",
"petunjuk": "petunjuk transfer",
"qr": null
},
{
"id": "payment_gateway_eksternal",
"jenis": "payment_gateway",
"nama": "Virtual Account/Credit Card/E-wallet/Outlet",
"keterangan": "Dikenakan biaya admin Rp3.000",
"logo": null,
"link_payment": "pay_via_gateway?id_request=369&sign=1b2fa0a4c5fc8960c7cb87856bbe7b13c4193051a8d519e378b89c1068a53376",
"qr": null
}
]
| Kolom | Tipe | Isi |
|---|---|---|
id |
teks | Pengenal metode. qris untuk QRIS, rek-1, rek-3 dan seterusnya untuk rekening bank, payment_gateway_eksternal untuk gateway. Angkanya mengikuti id rekening di database, jadi tidak selalu berurutan |
jenis |
teks | Penentu tampilan mana yang dipakai. Isinya qris, bank, atau payment_gateway |
nama |
teks | Nama metode yang tampil besar. Contoh: QRIS, BCA, MANDIRI |
keterangan |
teks | Baris kecil di bawah nama. Contoh: Kode bank 014 |
logo |
teks atau null |
URL gambar logo. Bisa null, dan bisa juga gagal dimuat — tema bawaan sudah menyiapkan backupnya. |
nomor |
teks atau null |
Nomor rekening. Selalu null pada QRIS |
atas_nama |
teks | Nama pemilik rekening. Pada QRIS, isinya nama merchant |
petunjuk |
HTML | Petunjuk cara pembayaran, sudah berbentuk HTML. |
qr |
teks atau null |
Alamat gambar QRIS untuk tagihan ini. Hanya terisi pada metode QRIS |
link_payment |
teks | Hanya ada pada metode gateway. Alamat halaman pembayaran pihak ketiga |
Tidak semua objek punya kolom yang sama. Objek payment_gateway tidak memiliki nomor, atas_nama, maupun petunjuk sama sekali bukan bernilai null, tetapi memang tidak ada.
Berikut ini hal-hal yang harus anda ketahui dari data-data diatas:
qr dan link_payment berupa alamat relatif tanpa https:// dan nama domain. Ini disengaja supaya halaman tetap benar di domain mana pun. Jangan ditambahi domain sendiri.logo bisa null seperti pada gateway di contoh. Pada template tema bawaan, jika logo bernilai null, maka akan diganti menjadi inisial nama channel.Step 1 hanya perlu empat kolom: logo, nama, keterangan, dan posisi indeksnya untuk diingat saat diklik.
var METODE_SERVER = {{metode_json}};
var METODE = (typeof METODE_SERVER !== "undefined" && METODE_SERVER) ? METODE_SERVER : [];
METODE.forEach(function(m, i) {
var node = tpl.content.firstElementChild.cloneNode(true);
var logo = node.querySelector(".metode-logo");
var badge = node.querySelector(".metode-lencana");
badge.textContent = inisial(m.nama); /* cadangan huruf, mis. "BC" */
if (m.logo) {
logo.src = m.logo;
logo.hidden = false;
badge.hidden = true;
logo.onerror = function() {
/* logo gagal dimuat */
logo.hidden = true;
badge.hidden = false; /* kembali ke huruf */
};
}
node.querySelector(".metode-nama").textContent = m.nama || "";
node.querySelector(".metode-ket").textContent = m.keterangan || "";
node.addEventListener("click", function() {
bukaDetail(i, true);
});
wadah.appendChild(node);
});
Tahap 2 memilih tampilan berdasarkan jenis:
if (m.jenis === "qris") {
/* tampilkan kartu QR, isi gambar dari m.qr, merchant dari m.atas_nama */
} else if (m.jenis === "payment_gateway") {
/* pindah ke tahap 3, isi tombol dengan m.link_payment */
} else {
/* semua jenis lain diperlakukan sebagai rekening:
m.logo, m.nama, m.nomor, m.atas_nama */
}
Pertahankan else di cabang terakhir, jangan diubah jadi else if (m.jenis === "bank"). Ini disengaja: kalau suatu saat ada jenis metode baru, ia tetap tampil sebagai kartu rekening dan halaman tidak jadi kosong.
Jika anda ingin membangun tampilan sendiri dari awal dengan cara sendiri, kerangka paling sederhananya seperti ini:
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title> Contoh Pembayaran </title>
</head>
<body>
<section id="step1">
<h3> Step 1: Pilih metode pembayaran </h3>
<div id="daftar"></div>
</section>
<section id="step2" hidden>
<h3>Step 2: Detail pembayaran</h3>
<fieldset id="detail">
</fieldset>
<p><button onclick="kembali()">Kembali</button></p>
</section>
<script>
const metode = {{metode_json}};
const step1 = document.getElementById("step1");
const step2 = document.getElementById("step2");
const daftar = document.getElementById("daftar");
const detail = document.getElementById("detail");
metode.forEach(item => {
const baris = document.createElement("p");
const tombol = document.createElement("button");
tombol.textContent = item.nama;
tombol.onclick = () => pilih(item.id);
baris.appendChild(tombol);
daftar.appendChild(baris);
});
function pilih(id) {
const item = metode.find(metode => metode.id === id);
if (!item) return;
let isi = "";
if (item.jenis === "qris") {
isi = ` <p>${item.atas_nama}</p> <img src="${item.qr}" alt="Kode QRIS pembayaran" width="240"> <p>Scan QRIS menggunakan aplikasi pembayaran Anda.</p> `;
} else if (item.jenis === "payment_gateway") {
isi = ` <p><a href="${item.link_payment}"> Lanjut ke payment gateway </a></p> `;
}else{
isi = ` <p>Nomor rekening: <strong>${item.nomor}</strong></p> <p>Atas nama: ${item.atas_nama}</p> <p>${item.petunjuk}</p> `;
}
detail.innerHTML = ` <legend>${item.nama}</legend> <p>${item.keterangan}</p> ${isi} `;
step1.hidden = true;
step2.hidden = false;
}
function kembali() {
step1.hidden = false;
step2.hidden = true;
}
</script>
</body >
</html>
| Gejala | Penyebab | Perbaikan |
|---|---|---|
| Kurung kurawal muncul mentah di halaman | Salah ketik nama shortcode, atau ada spasi di dalam kurung | Tulis rapat tanpa spasi, dan cocokkan ejaannya dengan tabel di artikel ini |
| Daftar metode kosong padahal rekening aktif | {{metode_json}} diapit tanda kutip |
Hapus tanda kutipnya: var METODE_SERVER = {{metode_json}}; |
Hitung mundur menampilkan NaN |
Memakai {{tanggal_expired_desc}} di JavaScript |
Ganti dengan {{tanggal_expired}} yang formatnya bisa dibaca mesin |
| Halaman diam terus meski sudah dibayar | {{script_cek_status}} terhapus, atau ditaruh di dalam <script> |
Kembalikan ke badan halaman, sebelum </body> |
| Tombol salin tidak berfungsi | Atribut data-salin terhapus, atau isinya masih shortcode mentah |
Pastikan atributnya ada dan terisi angka mentah |
| Halaman pembayaran menolak dengan “Link tidak valid” | Tautan bertanda tangan diketik ulang atau dipotong | Pakai shortcode tautannya apa adanya, jangan diubah sedikit pun |
| Warna tema tidak berubah meski sudah diganti | Warna aplikasi menimpa lewat {{kode_warna}} |
Hapus blok script warna, atau ganti {{kode_warna}} dengan kode warna anda |
Inti dari kustomisasi tema di BukaPay sebenarnya sederhana: tampilan milik anda, data milik server. Selama shortcode dan beberapa id penting tetap pada tempatnya, anda bebas membongkar seluruh tata letaknya tanpa takut merusak proses pembayaran. Kalau anda baru pertama kali mengedit, mulailah dari yang paling kecil: ganti --warna-utama, ubah beberapa kalimat, lalu buka satu tagihan untuk melihat hasilnya.
Demikian penjelasan tentang Fitur Kostum Halaman Payment di BukaPay, semoga bermanfaat. Terimakasih.