Komponen PaymentButton adalah komponen React yang menyediakan antarmuka
pembayaran lengkap untuk menerima pembayaran Solana. Komponen ini menangani
koneksi dompet, pemilihan token, pemrosesan transaksi, dan manajemen status UI
secara internal. Tersedia langsung dengan tombol dan modal yang dapat
disesuaikan:
Tombol Tip
Tombol Tip
Modal Bayar
Modal Bayar
Modal Kode QR Solana Pay
Modal Keranjang
Instalasi
pnpm add @solana-commerce/kit
Props Komponen
PaymentButtonProps
Komponen PaymentButton menerima props berikut:
Props Wajib
config(SolanaCommerceConfig) - Objek konfigurasi utama untuk komponen pembayaran. Ini adalah satu-satunya props yang wajib. Lihat SolanaCommerceConfig di bawah.
Props Opsional
-
paymentConfig(PaymentConfig) - Konfigurasi khusus pembayaran termasuk produk, penggantian harga, dan pengambil harga kustom. Lihat PaymentConfig di bawah. -
onPayment((amount: number, currency: string) => void) - Dipanggil ketika pembayaran dimulai setelah pengguna mengonfirmasi jumlah dan mata uang. Menerima jumlah pembayaran (dalam unit token, bukan lamport) dan pengidentifikasi mata uang. -
onPaymentStart(() => void) - Dipanggil ketika alur pembayaran dimulai, sebelum transaksi yang sebenarnya dikirimkan. Gunakan ini untuk menampilkan status loading atau pelacakan analitik. -
onPaymentSuccess((signature: string) => void) - Dipanggil ketika transaksi dikonfirmasi on-chain. Menerima tanda tangan transaksi. Di sinilah Anda harus memperbarui status pesanan, mengirim email konfirmasi, dll. -
onPaymentError((error: Error) => void) - Dipanggil ketika pembayaran gagal pada tahap mana pun (koneksi dompet, pengiriman transaksi, atau konfirmasi). Objek error berisi detail tentang apa yang salah. -
onCancel(() => void) - Dipanggil ketika pengguna secara eksplisit membatalkan alur pembayaran (menutup modal atau mengklik batal). -
children(React.ReactNode) - Elemen pemicu kustom opsional. Jika disediakan, menggantikan tombol pembayaran default. Elemen anak harus dapat diklik (misalnya, sebuah tombol). -
className(string) - Nama kelas CSS yang diterapkan pada tombol pemicu (hanya digunakan ketika tidak ada anak kustom yang disediakan). -
style(React.CSSProperties) - Gaya inline yang diterapkan pada tombol pemicu (hanya digunakan ketika tidak ada anak kustom yang disediakan). -
variant('default' | 'icon-only') - Varian tombol. Default menampilkan teks dan ikon,'icon-only'hanya menampilkan ikon pembayaran.
Objek Konfigurasi
SolanaCommerceConfig
Objek konfigurasi utama yang diteruskan ke prop config.
Bidang Wajib
-
merchant(MerchantConfig) - Informasi merchant dan detail penerima pembayaran. Lihat MerchantConfig. -
mode('cart' | 'tip' | 'buyNow') - Mode pembayaran yang menentukan teks tampilan tombol dan alur UI:'buyNow'- Pembelian produk tunggal dengan jumlah tetap'cart'- Keranjang belanja dengan beberapa produk'tip'- Pengguna memilih jumlah mereka sendiri (donasi/tip)
Bidang Opsional
-
position('inline' | 'overlay') - Cara UI pembayaran ditampilkan. Default ke'overlay'.'overlay'- Dibuka dalam overlay modal/drawer'inline'- Disematkan langsung di halaman
-
theme(ThemeConfig) - Opsi kustomisasi visual. Lihat ThemeConfig. -
network('mainnet' | 'devnet' | 'testnet') - Jaringan Solana yang akan digunakan. Default ke'mainnet'. -
rpcUrl(string) - URL endpoint RPC kustom. Jika tidak disediakan, menggunakan endpoint publik default untuk jaringan yang dipilih. -
allowedMints(string[]) - Array alamat mint token untuk membatasi metode pembayaran. Jika tidak disediakan, semua token yang didukung (SOL, USDC, USDT) tersedia. -
showQR(boolean) - Apakah akan menampilkan opsi pembayaran kode QR. Berguna untuk integrasi mobile dan Solana Pay. -
enableWalletConnect(boolean) - Apakah mengaktifkan koneksi dompet. Atur kefalsejika Anda menangani koneksi dompet secara eksternal. -
showMerchantInfo(boolean) - Apakah menampilkan nama merchant dan logo di antarmuka pembayaran. -
debug(boolean) - Mengaktifkan logging konsol verbose untuk debugging.
MerchantConfig
Mendefinisikan penerima pembayaran dan informasi bisnis.
Kolom Wajib
-
name(string) - Nama bisnis atau merchant yang ditampilkan kepada pengguna selama checkout. -
wallet(string) - Alamat dompet Solana yang akan menerima pembayaran. Harus berupa alamat Solana yang valid dengan encoding base58.
Kolom Opsional
-
logo(string) - URL ke gambar logo merchant. Ditampilkan di antarmuka pembayaran ketikashowMerchantInfodiaktifkan. -
description(string) - Deskripsi bisnis yang ditampilkan kepada pengguna.
ThemeConfig
Kustomisasi visual untuk antarmuka pembayaran.
Semua kolom bersifat opsional dan memiliki nilai default yang wajar.
-
primaryColor(string) - Warna brand utama yang digunakan untuk tombol dan aksen. Default:'#9945FF'(ungu Solana). -
secondaryColor(string) - Warna aksen sekunder. Default:'#14F195'(hijau Solana). -
backgroundColor(string) - Warna latar belakang modal/kontainer. Default:'#ffffff'. -
textColor(string) - Warna teks utama. Default:'#111827'. -
borderRadius('none' | 'sm' | 'md' | 'lg' | 'xl' | 'full') - Radius border yang diterapkan pada elemen UI. Default:'lg'.'none'= 0px'sm'= 12px'md'= 16px'lg'= 20px'xl'= 24px'full'= Sepenuhnya bulat (tergantung konteks)
-
fontFamily(string) - Font family untuk semua teks. Default:'system-ui, -apple-system, sans-serif'. -
buttonShadow('none' | 'sm' | 'md' | 'lg' | 'xl') - Bayangan drop untuk tombol. Default:'md'. -
buttonBorder('none' | 'black-10') - Gaya border untuk tombol. Default:'black-10'(border hitam halus).
PaymentConfig
Konfigurasi pembayaran lanjutan untuk harga, desimal, dan produk.
Semua bidang bersifat opsional.
-
products(Product[]) - Array produk untuk mode'cart'atau'buyNow'. Diperlukan saat menggunakan mode ini. Setiap produk memiliki:id(string, wajib) - Pengenal unik produkname(string, wajib) - Nama produk yang ditampilkan kepada penggunaquantity(number, wajib) - Kuantitas produk iniprice(number, opsional) - Harga per unit dalam USDunitAmount(number, opsional) - Alternatif untuk bidangpricedescription(string, opsional) - Deskripsi produk
-
solPriceUsd(number) - Harga SOL tetap dalam USD. Gunakan ini untuk pengujian atau saat Anda ingin mengunci harga SOL. Jika tidak disediakan, komponen akan mengambil harga terkini dari CoinGecko. -
getSolPrice(() => Promise<number>) - Fungsi kustom untuk mengambil harga SOL. Gunakan ini untuk:- Oracle harga privat
- Menghindari batasan rate API publik
- Logika penetapan harga kustom
- Aplikasi enterprise
Jika tidak disediakan, default ke API publik CoinGecko dengan caching 1 menit.
-
tokenDecimals({ [currency: string]: number }) - Timpa presisi desimal token. Berguna untuk token kustom. Contoh:tokenDecimals: {'CUSTOM': 8,'USDC': 6 // Can override defaults} -
fallbackSolPriceUsd(number) - Harga SOL cadangan jika API harga gagal dan tidak ada cache yang tersedia. Tanpa ini, UI pembayaran akan menampilkan kesalahan jika pengambilan harga gagal.
Hook Internal
Komponen PaymentButton menggunakan beberapa hook internal untuk mengelola
state dan menghitung nilai:
useTheme(theme?: ThemeConfig)
Menggabungkan konfigurasi tema yang disediakan pengguna dengan nilai tema
default. Mengembalikan objek ThemeConfig lengkap dengan semua bidang terisi.
Nilai tema default:
primaryColor: '#9945FF'secondaryColor: '#14F195'backgroundColor: '#ffffff'textColor: '#111827'borderRadius: 'lg'fontFamily: 'system-ui, -apple-system, sans-serif'buttonShadow: 'md'buttonBorder: 'black-10'
Hook ini di-memoize dan hanya menghitung ulang ketika konfigurasi tema berubah.
useTotalAmount(mode, paymentConfig?)
Menghitung total jumlah pembayaran berdasarkan mode commerce dan produk.
Perilaku berdasarkan mode:
- Mode
'tip'- Mengembalikan0(jumlah ditentukan oleh pengguna) - Mode
'cart'dan'buyNow'- Menjumlahkanprice * quantityuntuk semua produk dipaymentConfig.products
Hook menangani kasus khusus:
- Harga yang hilang atau tidak valid default ke
0 - Kuantitas yang hilang atau tidak valid default ke
0 - Memastikan semua nilai adalah angka terbatas
- Mendukung field produk
pricedanunitAmount
Mengembalikan total jumlah sebagai angka (dalam USD untuk cart/buyNow, 0 untuk tip).
usePaymentUrl(merchant, amount, mode)
Menghasilkan URL Solana Pay untuk pembayaran. URL ini dapat dikodekan sebagai kode QR untuk pemindaian wallet mobile.
Mengembalikan: URL protokol solana: dengan parameter query untuk:
recipient- Alamat wallet merchantamount- Jumlah pembayaranreference- Referensi pembayaran unik (dihasilkan dari timestamp + string acak)label- Nama merchant (disanitasi untuk keamanan URL)message- Pesan kontekstual berdasarkan mode
Mengembalikan string kosong jika wallet merchant tidak valid atau jumlah adalah
<= 0.
Keamanan: Nama merchant disanitasi menggunakan sanitizeString() untuk
mencegah serangan XSS melalui injeksi URL.
Validasi & Penanganan Error
Komponen melakukan validasi sebelum rendering:
-
Validasi Wallet - Menggunakan
isAddress()darigilluntuk memvalidasi alamat wallet merchant. Jika tidak valid, merender state error alih-alih UI pembayaran. -
Validasi Harga - Memastikan penetapan harga yang valid dikonfigurasi:
- Untuk mode
'tip': Selalu valid (pengguna memilih jumlah) - Untuk mode
'cart'dan'buyNow': Memvalidasi bahwatotalAmount > 0
- Untuk mode
-
Keamanan SSR - Menggunakan deteksi sisi klien untuk mencegah ketidakcocokan hidrasi. Status
isClientmemastikan fitur khusus browser (sepertilocalStorageuntuk persistensi wallet) hanya berjalan di sisi klien.
Arsitektur Komponen
PaymentButton membungkus semua children dalam dua context provider:
-
AppProvider- Menyediakan status koneksi wallet dan klien konektor- Auto-connect: dinonaktifkan secara default
- Storage: Menggunakan
localStoragejika tersedia (sisi klien saja) - Mode debug: dapat dikonfigurasi melalui config
-
ArcProvider- Menyediakan klien blockchain Solana dan koneksi RPC- Network: Ditentukan dari
config.network - RPC URL: Menggunakan resolusi sisi server dengan fallback ke endpoint publik
- Network: Ditentukan dari
Resolusi RPC URL
Komponen ini mencakup resolusi RPC URL yang canggih:
- Jika
config.rpcUrldisediakan, akan langsung digunakan - Jika tidak, akan memanggil resolver sisi server yang memilih endpoint yang andal
- Fallback ke
https://api.mainnet-beta.solana.comjika resolusi gagal - Resolusi terjadi secara asynchronous saat mount dan memperbarui state
Mode Rendering
Mode overlay (position: 'overlay' atau default):
- Merender tombol trigger (kustom atau default)
- Membuka UI pembayaran dalam modal responsif (desktop) atau drawer (mobile)
- Menggunakan komponen
ResponsiveShelluntuk layout adaptif
Mode inline (position: 'inline'):
- Menyematkan UI pembayaran langsung di halaman
- Tidak perlu tombol trigger
- Berguna untuk halaman checkout khusus
Kedua mode menggunakan SecureIframeShell secara internal untuk merender
antarmuka pembayaran dalam iframe yang terisolasi demi keamanan.
Contoh Penggunaan
Pembayaran Dasar
<PaymentButtonconfig={{merchant: {name: "Coffee Shop",wallet: "your-wallet-address"},mode: "buyNow"}}paymentConfig={{products: [{id: "coffee-001",name: "Espresso",price: 4.5,quantity: 1}]}}onPaymentSuccess={(sig) => {console.log("Payment confirmed:", sig);}}/>
Widget Tip dengan Pengambil Harga Kustom
<PaymentButtonconfig={{merchant: {name: "Content Creator",wallet: "creator-wallet"},mode: "tip"}}paymentConfig={{// Use your own price API to avoid rate limitsgetSolPrice: async () => {const res = await fetch("/custom-api/solana-price");const data = await res.json();return data.price;},// Fallback if your API failsfallbackSolPriceUsd: 200}}/>
Keranjang Belanja dengan Tema Kustom
<PaymentButtonconfig={{merchant: {name: "My Store",wallet: "store-wallet",logo: "/logo.png"},mode: "cart",theme: {primaryColor: "#FF6B6B",backgroundColor: "#1a1a1a",textColor: "#ffffff",borderRadius: "xl",buttonShadow: "lg"},showMerchantInfo: true}}paymentConfig={{products: [{ id: "1", name: "T-Shirt", price: 25, quantity: 2 },{ id: "2", name: "Hoodie", price: 45, quantity: 1 }]}}onPaymentSuccess={(signature) => {// Verify transaction on your backendfetch("/api/verify-payment", {method: "POST",body: JSON.stringify({ signature })});}}/>
Tombol Trigger Kustom
<PaymentButtonconfig={{merchant: { name: "Shop", wallet: "address" },mode: "buyNow"}}paymentConfig={{products: [{ id: "1", name: "Product", price: 10, quantity: 1 }]}}><button className="custom-button">🚀 Pay with Solana</button></PaymentButton>
Is this page helpful?