PaymentButton

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 TipTombol Tip

Modal BayarModal Bayar

Modal KeranjangModal 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 ke false jika 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 ketika showMerchantInfo diaktifkan.

  • 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 produk
    • name (string, wajib) - Nama produk yang ditampilkan kepada pengguna
    • quantity (number, wajib) - Kuantitas produk ini
    • price (number, opsional) - Harga per unit dalam USD
    • unitAmount (number, opsional) - Alternatif untuk bidang price
    • description (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' - Mengembalikan 0 (jumlah ditentukan oleh pengguna)
  • Mode 'cart' dan 'buyNow' - Menjumlahkan price * quantity untuk semua produk di paymentConfig.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 price dan unitAmount

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 merchant
  • amount - Jumlah pembayaran
  • reference - 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:

  1. Validasi Wallet - Menggunakan isAddress() dari gill untuk memvalidasi alamat wallet merchant. Jika tidak valid, merender state error alih-alih UI pembayaran.

  2. Validasi Harga - Memastikan penetapan harga yang valid dikonfigurasi:

    • Untuk mode 'tip': Selalu valid (pengguna memilih jumlah)
    • Untuk mode 'cart' dan 'buyNow': Memvalidasi bahwa totalAmount > 0
  3. Keamanan SSR - Menggunakan deteksi sisi klien untuk mencegah ketidakcocokan hidrasi. Status isClient memastikan fitur khusus browser (seperti localStorage untuk persistensi wallet) hanya berjalan di sisi klien.


Arsitektur Komponen

PaymentButton membungkus semua children dalam dua context provider:

  1. AppProvider - Menyediakan status koneksi wallet dan klien konektor

    • Auto-connect: dinonaktifkan secara default
    • Storage: Menggunakan localStorage jika tersedia (sisi klien saja)
    • Mode debug: dapat dikonfigurasi melalui config
  2. ArcProvider - Menyediakan klien blockchain Solana dan koneksi RPC

    • Network: Ditentukan dari config.network
    • RPC URL: Menggunakan resolusi sisi server dengan fallback ke endpoint publik

Resolusi RPC URL

Komponen ini mencakup resolusi RPC URL yang canggih:

  • Jika config.rpcUrl disediakan, akan langsung digunakan
  • Jika tidak, akan memanggil resolver sisi server yang memilih endpoint yang andal
  • Fallback ke https://api.mainnet-beta.solana.com jika 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 ResponsiveShell untuk 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

<PaymentButton
config={{
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

<PaymentButton
config={{
merchant: {
name: "Content Creator",
wallet: "creator-wallet"
},
mode: "tip"
}}
paymentConfig={{
// Use your own price API to avoid rate limits
getSolPrice: async () => {
const res = await fetch("/custom-api/solana-price");
const data = await res.json();
return data.price;
},
// Fallback if your API fails
fallbackSolPriceUsd: 200
}}
/>

Keranjang Belanja dengan Tema Kustom

<PaymentButton
config={{
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 backend
fetch("/api/verify-payment", {
method: "POST",
body: JSON.stringify({ signature })
});
}}
/>

Tombol Trigger Kustom

<PaymentButton
config={{
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?

Dikelola oleh

© 2026 Yayasan Solana.
Semua hak dilindungi.
Terhubung