Tài liệu SolanaBắt Đầu Nhanh

PaymentButton

Component PaymentButton là một component React cung cấp giao diện thanh toán hoàn chỉnh để chấp nhận thanh toán Solana. Nó xử lý kết nối ví, chọn token, xử lý giao dịch và quản lý trạng thái UI ngay trong component. Ngay từ đầu, nó đi kèm với nút và modal có thể tùy chỉnh:

Nút Tip

Nút TipNút Tip

Modal Thanh toánModal Thanh toán

Modal Giỏ hàngModal Giỏ hàng

Cài đặt

pnpm add @solana-commerce/kit

Props của Component

PaymentButtonProps

Component PaymentButton chấp nhận các props sau:

Props Bắt buộc

  • config (SolanaCommerceConfig) - Object cấu hình chính cho component thanh toán. Đây là prop bắt buộc duy nhất. Xem SolanaCommerceConfig bên dưới.

Props Tùy chọn

  • paymentConfig (PaymentConfig) - Cấu hình riêng cho thanh toán bao gồm sản phẩm, ghi đè giá và bộ lấy giá tùy chỉnh. Xem PaymentConfig bên dưới.

  • onPayment ((amount: number, currency: string) => void) - Được gọi khi một thanh toán được khởi tạo sau khi người dùng xác nhận số tiền và loại tiền. Nhận số tiền thanh toán (tính theo đơn vị token, không phải lamport) và định danh loại tiền.

  • onPaymentStart (() => void) - Được gọi khi luồng thanh toán bắt đầu, trước khi giao dịch thực sự được gửi đi. Sử dụng để hiển thị trạng thái loading hoặc theo dõi phân tích.

  • onPaymentSuccess ((signature: string) => void) - Được gọi khi giao dịch được xác nhận trên chuỗi. Nhận chữ ký giao dịch. Đây là nơi bạn nên cập nhật trạng thái đơn hàng, gửi email xác nhận, v.v.

  • onPaymentError ((error: Error) => void) - Được gọi khi thanh toán thất bại ở bất kỳ giai đoạn nào (kết nối ví, gửi giao dịch hoặc xác nhận). Object lỗi chứa chi tiết về nguyên nhân thất bại.

  • onCancel (() => void) - Được gọi khi người dùng hủy rõ ràng luồng thanh toán (đóng modal hoặc nhấp hủy).

  • children (React.ReactNode) - Phần tử kích hoạt tùy chỉnh (tùy chọn). Nếu được cung cấp, sẽ thay thế nút thanh toán mặc định. Phần tử con phải có thể nhấp được (ví dụ: một nút bấm).

  • className (string) - Tên lớp CSS được áp dụng cho nút kích hoạt (chỉ được sử dụng khi không có phần tử con tùy chỉnh).

  • style (React.CSSProperties) - Kiểu nội tuyến được áp dụng cho nút kích hoạt (chỉ được sử dụng khi không có phần tử con tùy chỉnh).

  • variant ('default' | 'icon-only') - Biến thể nút bấm. Mặc định hiển thị văn bản và biểu tượng, 'icon-only' chỉ hiển thị biểu tượng thanh toán.


Các Đối Tượng Cấu Hình

SolanaCommerceConfig

Đối tượng cấu hình chính được truyền vào prop config.

Trường Bắt Buộc

  • merchant (MerchantConfig) - Thông tin người bán và chi tiết người nhận thanh toán. Xem MerchantConfig.

  • mode ('cart' | 'tip' | 'buyNow') - Chế độ thanh toán xác định văn bản hiển thị trên nút và luồng giao diện:

    • 'buyNow' - Mua sản phẩm đơn lẻ với số tiền cố định
    • 'cart' - Giỏ hàng với nhiều sản phẩm
    • 'tip' - Người dùng tự chọn số tiền (quyên góp/tiền boa)

Trường Tùy Chọn

  • position ('inline' | 'overlay') - Cách hiển thị giao diện thanh toán. Mặc định là 'overlay'.

    • 'overlay' - Mở trong lớp phủ modal/drawer
    • 'inline' - Nhúng trực tiếp vào trang
  • theme (ThemeConfig) - Tùy chọn tùy chỉnh giao diện. Xem ThemeConfig.

  • network ('mainnet' | 'devnet' | 'testnet') - Mạng Solana sẽ sử dụng. Mặc định là 'mainnet'.

  • rpcUrl (string) - URL điểm cuối RPC tùy chỉnh. Nếu không được cung cấp, sẽ sử dụng điểm cuối công khai mặc định cho mạng đã chọn.

  • allowedMints (string[]) - Mảng các địa chỉ mint token để hạn chế phương thức thanh toán. Nếu không được cung cấp, tất cả các token được hỗ trợ (SOL, USDC, USDT) đều khả dụng.

  • showQR (boolean) - Có hiển thị tùy chọn thanh toán bằng mã QR hay không. Hữu ích cho thiết bị di động và tích hợp Solana Pay.

  • enableWalletConnect (boolean) - Bật hay tắt kết nối ví. Đặt thành false nếu bạn đang xử lý kết nối ví bên ngoài.

  • showMerchantInfo (boolean) - Hiển thị hay ẩn tên và logo người bán trong giao diện thanh toán.

  • debug (boolean) - Bật ghi log chi tiết trên console để gỡ lỗi.

MerchantConfig

Xác định người nhận thanh toán và thông tin doanh nghiệp.

Trường Bắt Buộc

  • name (string) - Tên doanh nghiệp hoặc người bán được hiển thị cho người dùng trong quá trình thanh toán.

  • wallet (string) - Địa chỉ ví Solana sẽ nhận thanh toán. Phải là địa chỉ Solana hợp lệ được mã hóa base58.

Trường Tùy Chọn

  • logo (string) - URL đến hình ảnh logo người bán. Được hiển thị trong giao diện thanh toán khi showMerchantInfo được bật.

  • description (string) - Mô tả doanh nghiệp hiển thị cho người dùng.

ThemeConfig

Tùy chỉnh giao diện cho UI thanh toán.

Tất cả các trường đều là tùy chọn và có giá trị mặc định hợp lý.

  • primaryColor (string) - Màu thương hiệu chính được sử dụng cho nút bấm và điểm nhấn. Mặc định: '#9945FF' (tím Solana).

  • secondaryColor (string) - Màu điểm nhấn phụ. Mặc định: '#14F195' (xanh lá Solana).

  • backgroundColor (string) - Màu nền của modal/container. Mặc định: '#ffffff'.

  • textColor (string) - Màu văn bản chính. Mặc định: '#111827'.

  • borderRadius ('none' | 'sm' | 'md' | 'lg' | 'xl' | 'full') - Bán kính bo tròn áp dụng cho các phần tử UI. Mặc định: 'lg'.

    • 'none' = 0px
    • 'sm' = 12px
    • 'md' = 16px
    • 'lg' = 20px
    • 'xl' = 24px
    • 'full' = Bo tròn hoàn toàn (tùy theo ngữ cảnh)
  • fontFamily (string) - Họ font chữ cho tất cả văn bản. Mặc định: 'system-ui, -apple-system, sans-serif'.

  • buttonShadow ('none' | 'sm' | 'md' | 'lg' | 'xl') - Bóng đổ cho nút bấm. Mặc định: 'md'.

  • buttonBorder ('none' | 'black-10') - Kiểu viền cho nút bấm. Mặc định: 'black-10' (viền đen nhẹ).

PaymentConfig

Cấu hình thanh toán nâng cao cho giá cả, số thập phân và sản phẩm.

Tất cả các trường đều là tùy chọn.

  • products (Product[]) - Mảng các sản phẩm cho chế độ 'cart' hoặc 'buyNow'. Bắt buộc khi sử dụng các chế độ này. Mỗi sản phẩm có:

    • id (chuỗi, bắt buộc) - Mã định danh duy nhất của sản phẩm
    • name (chuỗi, bắt buộc) - Tên sản phẩm hiển thị cho người dùng
    • quantity (số, bắt buộc) - Số lượng của sản phẩm này
    • price (số, tùy chọn) - Giá mỗi đơn vị tính bằng USD
    • unitAmount (số, tùy chọn) - Thay thế cho trường price
    • description (chuỗi, tùy chọn) - Mô tả sản phẩm
  • solPriceUsd (number) - Giá SOL cố định tính bằng USD. Sử dụng tính năng này để thử nghiệm hoặc khi bạn muốn khóa giá SOL. Nếu không được cung cấp, component sẽ lấy giá hiện tại từ CoinGecko.

  • getSolPrice (() => Promise<number>) - Hàm tùy chỉnh để lấy giá SOL. Sử dụng cho:

    • Các oracle giá riêng tư
    • Tránh giới hạn tốc độ của API công khai
    • Logic định giá tùy chỉnh
    • Ứng dụng doanh nghiệp

    Nếu không được cung cấp, mặc định sử dụng API công khai CoinGecko với bộ nhớ đệm 1 phút.

  • tokenDecimals ({ [currency: string]: number }) - Ghi đè độ chính xác số thập phân của token. Hữu ích cho các token tùy chỉnh. Ví dụ:

    tokenDecimals: {
    'CUSTOM': 8,
    'USDC': 6 // Can override defaults
    }
  • fallbackSolPriceUsd (number) - Giá SOL dự phòng nếu API giá thất bại và không có bộ nhớ đệm khả dụng. Nếu không có giá trị này, giao diện thanh toán sẽ hiển thị lỗi khi việc lấy giá thất bại.


Hooks Nội Bộ

Component PaymentButton sử dụng một số hooks nội bộ để quản lý trạng thái và tính toán các giá trị:

useTheme(theme?: ThemeConfig)

Kết hợp cấu hình giao diện do người dùng cung cấp với các giá trị giao diện mặc định. Trả về một đối tượng ThemeConfig hoàn chỉnh với tất cả các trường đã được điền đầy đủ.

Giá trị giao diện mặc định:

  • primaryColor: '#9945FF'
  • secondaryColor: '#14F195'
  • backgroundColor: '#ffffff'
  • textColor: '#111827'
  • borderRadius: 'lg'
  • fontFamily: 'system-ui, -apple-system, sans-serif'
  • buttonShadow: 'md'
  • buttonBorder: 'black-10'

Hook được ghi nhớ và chỉ tính toán lại khi cấu hình giao diện thay đổi.

useTotalAmount(mode, paymentConfig?)

Tính toán tổng số tiền thanh toán dựa trên chế độ thương mại và sản phẩm.

Hành vi theo chế độ:

  • Chế độ 'tip' - Trả về 0 (số tiền do người dùng quyết định)
  • Chế độ 'cart''buyNow' - Tính tổng price * quantity cho tất cả sản phẩm trong paymentConfig.products

Hook xử lý các trường hợp đặc biệt:

  • Giá bị thiếu hoặc không hợp lệ mặc định là 0
  • Số lượng bị thiếu hoặc không hợp lệ mặc định là 0
  • Đảm bảo tất cả các giá trị là số hữu hạn
  • Hỗ trợ cả trường sản phẩm priceunitAmount

Trả về tổng số tiền dưới dạng số (tính bằng USD cho giỏ hàng/mua ngay, 0 cho tiền boa).

usePaymentUrl(merchant, amount, mode)

Tạo URL Solana Pay cho thanh toán. URL này có thể được mã hóa thành mã QR để quét bằng ví di động.

Trả về: Một URL giao thức solana: với các tham số truy vấn cho:

  • recipient - Địa chỉ ví người bán
  • amount - Số tiền thanh toán
  • reference - Tham chiếu thanh toán duy nhất (được tạo từ dấu thời gian + chuỗi ngẫu nhiên)
  • label - Tên người bán (được làm sạch cho URL an toàn)
  • message - Thông điệp theo ngữ cảnh dựa trên chế độ

Trả về chuỗi rỗng nếu ví người bán không hợp lệ hoặc số tiền là <= 0.

Bảo mật: Tên người bán được làm sạch bằng sanitizeString() để ngăn chặn các cuộc tấn công XSS thông qua chèn URL.


Xác thực & Xử lý Lỗi

Component thực hiện xác thực trước khi render:

  1. Xác thực Ví - Sử dụng isAddress() từ gill để xác thực địa chỉ ví người bán. Nếu không hợp lệ, render trạng thái lỗi thay vì giao diện thanh toán.

  2. Xác thực Giá - Đảm bảo giá được cấu hình hợp lệ:

    • Đối với chế độ 'tip': Luôn hợp lệ (người dùng chọn số tiền)
    • Đối với chế độ 'cart''buyNow': Xác thực rằng totalAmount > 0
  3. An toàn SSR - Sử dụng phát hiện phía client để tránh lỗi không khớp hydration. Trạng thái isClient đảm bảo các tính năng chỉ dành cho trình duyệt (như localStorage để lưu trữ ví) chỉ chạy trên client.


Kiến trúc Component

PaymentButton bọc tất cả các children trong hai context provider:

  1. AppProvider - Cung cấp trạng thái kết nối ví và connector client

    • Tự động kết nối: tắt theo mặc định
    • Lưu trữ: Sử dụng localStorage khi khả dụng (chỉ phía client)
    • Chế độ debug: có thể cấu hình qua config
  2. ArcProvider - Cung cấp Solana blockchain client và kết nối RPC

    • Network: Được xác định từ config.network
    • RPC URL: Sử dụng phân giải phía server với dự phòng đến các endpoint công khai

Phân giải RPC URL

Component bao gồm cơ chế phân giải RPC URL tinh vi:

  • Nếu config.rpcUrl được cung cấp, nó sẽ được sử dụng trực tiếp
  • Nếu không, nó gọi một resolver phía server để chọn các endpoint đáng tin cậy
  • Dự phòng về https://api.mainnet-beta.solana.com nếu phân giải thất bại
  • Phân giải diễn ra bất đồng bộ khi mount và cập nhật state

Chế độ Hiển thị

Chế độ overlay (position: 'overlay' hoặc mặc định):

  • Hiển thị nút kích hoạt (tùy chỉnh hoặc mặc định)
  • Mở giao diện thanh toán trong modal responsive (desktop) hoặc drawer (mobile)
  • Sử dụng component ResponsiveShell cho bố cục thích ứng

Chế độ inline (position: 'inline'):

  • Nhúng giao diện thanh toán trực tiếp vào trang
  • Không cần nút kích hoạt
  • Hữu ích cho các trang thanh toán chuyên dụng

Cả hai chế độ đều sử dụng SecureIframeShell bên trong để hiển thị giao diện thanh toán trong iframe được sandbox hóa để đảm bảo bảo mật.


Ví dụ Sử dụng

Thanh toán Cơ bản

<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 với Custom Price Fetcher

<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
}}
/>

Giỏ hàng với Giao diện Tùy chỉnh

<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 })
});
}}
/>

Nút Kích hoạt Tùy chỉnh

<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?

Quản lý bởi

© 2026 Solana Foundation.
Đã đăng ký bản quyền.
Kết nối