PaymentButton

Komponent PaymentButton to komponent React, który zapewnia kompletny interfejs płatności do przyjmowania płatności Solana. Wewnętrznie obsługuje połączenie portfela, wybór tokena, przetwarzanie transakcji i zarządzanie stanem interfejsu. Domyślnie zawiera konfigurowalne przyciski i modale:

Przycisk napiwku

Przycisk napiwkuPrzycisk napiwku

Modal płatnościModal płatności

Modal koszykaModal koszyka

Instalacja

pnpm add @solana-commerce/kit

Właściwości komponentu

PaymentButtonProps

Komponent PaymentButton przyjmuje następujące właściwości:

Wymagane właściwości

  • config (SolanaCommerceConfig) - Główny obiekt konfiguracyjny komponentu płatności. Jest to jedyna wymagana właściwość. Zobacz SolanaCommerceConfig poniżej.

Opcjonalne właściwości

  • paymentConfig (PaymentConfig) - Konfiguracja specyficzna dla płatności, obejmująca produkty, nadpisania cen i niestandardowe mechanizmy pobierania cen. Zobacz PaymentConfig poniżej.

  • onPayment ((amount: number, currency: string) => void) - Wywoływana, gdy płatność jest inicjowana po potwierdzeniu kwoty i waluty przez użytkownika. Otrzymuje kwotę płatności (w jednostkach tokena, nie lamportach) oraz identyfikator waluty.

  • onPaymentStart (() => void) - Wywoływana, gdy rozpoczyna się proces płatności, przed faktycznym przesłaniem transakcji. Użyj tego do wyświetlania stanów ładowania lub śledzenia analitycznego.

  • onPaymentSuccess ((signature: string) => void) - Wywoływana, gdy transakcja zostanie potwierdzona w blockchainie. Otrzymuje sygnaturę transakcji. Tutaj powinieneś zaktualizować status zamówienia, wysłać e-maile potwierdzające itp.

  • onPaymentError ((error: Error) => void) - Wywoływana, gdy płatność nie powiedzie się na dowolnym etapie (połączenie portfela, przesłanie transakcji lub potwierdzenie). Obiekt błędu zawiera szczegóły dotyczące tego, co poszło nie tak.

  • onCancel (() => void) - Wywoływana, gdy użytkownik jawnie anuluje proces płatności (zamyka modal lub klika anuluj).

  • children (React.ReactNode) - Opcjonalny niestandardowy element wyzwalający. Jeśli zostanie podany, zastępuje domyślny przycisk płatności. Element potomny powinien być klikalny (np. przycisk).

  • className (string) - Nazwa klasy CSS stosowana do przycisku wyzwalającego (używana tylko wtedy, gdy nie podano niestandardowych elementów potomnych).

  • style (React.CSSProperties) - Style inline stosowane do przycisku wyzwalającego (używane tylko wtedy, gdy nie podano niestandardowych elementów potomnych).

  • variant ('default' | 'icon-only') - Wariant przycisku. Domyślnie wyświetla tekst i ikonę, 'icon-only' wyświetla tylko ikonę płatności.


Obiekty konfiguracyjne

SolanaCommerceConfig

Główny obiekt konfiguracyjny przekazywany do właściwości config.

Pola wymagane

  • merchant (MerchantConfig) - Informacje o sprzedawcy i szczegóły odbiorcy płatności. Zobacz MerchantConfig.

  • mode ('cart' | 'tip' | 'buyNow') - Tryb płatności określający tekst wyświetlany na przycisku i przepływ interfejsu użytkownika:

    • 'buyNow' - Zakup pojedynczego produktu o stałej kwocie
    • 'cart' - Koszyk z wieloma produktami
    • 'tip' - Użytkownik wybiera własną kwotę (darowizny/napiwki)

Pola opcjonalne

  • position ('inline' | 'overlay') - Sposób wyświetlania interfejsu płatności. Domyślnie 'overlay'.

    • 'overlay' - Otwiera się w nakładce modalnej/szufladzie
    • 'inline' - Osadzony bezpośrednio na stronie
  • theme (ThemeConfig) - Opcje dostosowania wyglądu. Zobacz ThemeConfig.

  • network ('mainnet' | 'devnet' | 'testnet') - Sieć Solana do użycia. Domyślnie 'mainnet'.

  • rpcUrl (string) - Niestandardowy adres URL punktu końcowego RPC. Jeśli nie zostanie podany, używa domyślnego publicznego punktu końcowego dla wybranej sieci.

  • allowedMints (string[]) - Tablica adresów mint tokenów w celu ograniczenia metod płatności. Jeśli nie zostanie podana, dostępne są wszystkie obsługiwane tokeny (SOL, USDC, USDT).

  • showQR (boolean) - Określa, czy wyświetlać opcję płatności kodem QR. Przydatne w przypadku urządzeń mobilnych i integracji z Solana Pay.

  • enableWalletConnect (boolean) - Czy włączyć połączenie z portfelem. Ustaw na false, jeśli obsługujesz połączenie z portfelem zewnętrznie.

  • showMerchantInfo (boolean) - Czy wyświetlać nazwę i logo sprzedawcy w interfejsie płatności.

  • debug (boolean) - Włącza szczegółowe logowanie w konsoli do debugowania.

MerchantConfig

Definiuje odbiorcę płatności i informacje o firmie.

Wymagane pola

  • name (string) - Nazwa firmy lub sprzedawcy wyświetlana użytkownikom podczas składania zamówienia.

  • wallet (string) - Adres portfela Solana, który otrzyma płatności. Musi być prawidłowym adresem Solana zakodowanym w base58.

Pola opcjonalne

  • logo (string) - Adres URL do grafiki logo sprzedawcy. Wyświetlane w interfejsie płatności, gdy włączona jest opcja showMerchantInfo.

  • description (string) - Opis firmy pokazywany użytkownikom.

ThemeConfig

Dostosowanie wizualne interfejsu płatności.

Wszystkie pola są opcjonalne i mają rozsądne wartości domyślne.

  • primaryColor (string) - Główny kolor marki używany do przycisków i akcentów. Domyślnie: '#9945FF' (fioletowy Solana).

  • secondaryColor (string) - Dodatkowy kolor akcentujący. Domyślnie: '#14F195' (zielony Solana).

  • backgroundColor (string) - Kolor tła okna modalnego/kontenera. Domyślnie: '#ffffff'.

  • textColor (string) - Główny kolor tekstu. Domyślnie: '#111827'.

  • borderRadius ('none' | 'sm' | 'md' | 'lg' | 'xl' | 'full') - Promień zaokrąglenia stosowany do elementów interfejsu. Domyślnie: 'lg'.

    • 'none' = 0px
    • 'sm' = 12px
    • 'md' = 16px
    • 'lg' = 20px
    • 'xl' = 24px
    • 'full' = Całkowicie zaokrąglone (zależne od kontekstu)
  • fontFamily (string) - Krój czcionki dla całego tekstu. Domyślnie: 'system-ui, -apple-system, sans-serif'.

  • buttonShadow ('none' | 'sm' | 'md' | 'lg' | 'xl') - Cień dla przycisków. Domyślnie: 'md'.

  • buttonBorder ('none' | 'black-10') - Styl obramowania dla przycisków. Domyślnie: 'black-10' (subtelne czarne obramowanie).

PaymentConfig

Zaawansowana konfiguracja płatności dla cen, miejsc dziesiętnych i produktów.

Wszystkie pola są opcjonalne.

  • products (Product[]) - Tablica produktów dla trybów 'cart' lub 'buyNow'. Wymagane przy używaniu tych trybów. Każdy produkt zawiera:

    • id (string, wymagane) - Unikalny identyfikator produktu
    • name (string, wymagane) - Nazwa produktu wyświetlana użytkownikowi
    • quantity (number, wymagane) - Ilość tego produktu
    • price (number, opcjonalne) - Cena za jednostkę w USD
    • unitAmount (number, opcjonalne) - Alternatywa dla pola price
    • description (string, opcjonalne) - Opis produktu
  • solPriceUsd (number) - Stała cena SOL w USD. Użyj tego do testowania lub gdy chcesz zablokować cenę SOL. Jeśli nie podano, komponent pobiera aktualną cenę z CoinGecko.

  • getSolPrice (() => Promise<number>) - Niestandardowa funkcja do pobierania ceny SOL. Użyj tego do:

    • Prywatnych wyroczni cenowych
    • Unikania limitów publicznych API
    • Niestandardowej logiki cenowej
    • Aplikacji korporacyjnych

    Jeśli nie podano, domyślnie używa publicznego API CoinGecko z 1-minutowym cache'owaniem.

  • tokenDecimals ({ [currency: string]: number }) - Nadpisanie precyzji miejsc dziesiętnych tokena. Przydatne dla niestandardowych tokenów. Przykład:

    tokenDecimals: {
    'CUSTOM': 8,
    'USDC': 6 // Can override defaults
    }
  • fallbackSolPriceUsd (number) - Zapasowa cena SOL, jeśli API cen zawiedzie i brak jest dostępnego cache'a. Bez tego interfejs płatności wyświetli błąd, jeśli pobieranie ceny nie powiedzie się.


Wewnętrzne hooki

Komponent PaymentButton używa kilku wewnętrznych hooków do zarządzania stanem i obliczania wartości:

useTheme(theme?: ThemeConfig)

Łączy konfigurację motywu dostarczoną przez użytkownika z domyślnymi wartościami motywu. Zwraca kompletny obiekt ThemeConfig ze wszystkimi wypełnionymi polami.

Domyślne wartości motywu:

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

Hook jest zmemoizowany i przelicza się tylko wtedy, gdy zmienia się konfiguracja motywu.

useTotalAmount(mode, paymentConfig?)

Oblicza całkowitą kwotę płatności na podstawie trybu handlowego i produktów.

Zachowanie w zależności od trybu:

  • Tryb 'tip' - Zwraca 0 (kwota jest określana przez użytkownika)
  • Tryby 'cart' i 'buyNow' - Sumuje price * quantity dla wszystkich produktów w paymentConfig.products

Hook obsługuje przypadki brzegowe:

  • Brakujące lub nieprawidłowe ceny domyślnie przyjmują wartość 0
  • Brakujące lub nieprawidłowe ilości domyślnie przyjmują wartość 0
  • Zapewnia, że wszystkie wartości są liczbami skończonymi
  • Obsługuje zarówno pola produktów price, jak i unitAmount

Zwraca całkowitą kwotę jako liczbę (w USD dla koszyka/buyNow, 0 dla napiwku).

usePaymentUrl(merchant, amount, mode)

Generuje URL Solana Pay dla płatności. Ten URL może zostać zakodowany jako kod QR do skanowania przez portfel mobilny.

Zwraca: URL protokołu solana: z parametrami zapytania dla:

  • recipient - Adres portfela sprzedawcy
  • amount - Kwota płatności
  • reference - Unikalna referencja płatności (generowana z timestamp + losowy ciąg znaków)
  • label - Nazwa sprzedawcy (oczyszczona dla bezpieczeństwa URL)
  • message - Kontekstowy komunikat oparty na trybie

Zwraca pusty ciąg znaków, jeśli portfel sprzedawcy jest nieprawidłowy lub kwota wynosi <= 0.

Bezpieczeństwo: Nazwa sprzedawcy jest oczyszczana za pomocą sanitizeString(), aby zapobiec atakom XSS poprzez wstrzykiwanie URL.


Walidacja i obsługa błędów

Komponent przeprowadza walidację przed renderowaniem:

  1. Walidacja portfela - Używa isAddress() z gill do walidacji adresu portfela sprzedawcy. Jeśli jest nieprawidłowy, renderuje stan błędu zamiast interfejsu płatności.

  2. Walidacja cen - Zapewnia, że cennik jest poprawnie skonfigurowany:

    • Dla trybu 'tip': Zawsze prawidłowy (użytkownik wybiera kwotę)
    • Dla trybów 'cart' i 'buyNow': Waliduje, że totalAmount > 0
  3. Bezpieczeństwo SSR - Wykorzystuje detekcję po stronie klienta, aby zapobiec niezgodnościom hydratacji. Stan isClient zapewnia, że funkcje działające tylko w przeglądarce (takie jak localStorage do trwałości portfela) uruchamiają się wyłącznie po stronie klienta.


Architektura komponentu

PaymentButton owija wszystkie elementy potomne w dwa dostawcy kontekstu:

  1. AppProvider - Zapewnia stan połączenia portfela i klienta łącznika

    • Automatyczne połączenie: domyślnie wyłączone
    • Pamięć masowa: Wykorzystuje localStorage gdy dostępne (tylko po stronie klienta)
    • Tryb debugowania: konfigurowalny przez config
  2. ArcProvider - Zapewnia klienta blockchainu Solana i połączenie RPC

    • Sieć: Określana na podstawie config.network
    • URL RPC: Wykorzystuje rozwiązywanie po stronie serwera z awaryjnym przełączeniem na publiczne punkty końcowe

Rozwiązywanie adresu URL RPC

Komponent zawiera zaawansowane rozwiązywanie adresu URL RPC:

  • Jeśli podano config.rpcUrl, jest używany bezpośrednio
  • W przeciwnym razie wywołuje resolver po stronie serwera, który wybiera niezawodne punkty końcowe
  • Przełącza awaryjnie na https://api.mainnet-beta.solana.com w przypadku niepowodzenia rozwiązywania
  • Rozwiązywanie odbywa się asynchronicznie przy montowaniu i aktualizuje stan

Tryby renderowania

Tryb nakładki (position: 'overlay' lub domyślny):

  • Renderuje przycisk wyzwalający (niestandardowy lub domyślny)
  • Otwiera interfejs płatności w responsywnym oknie modalnym (desktop) lub szufladzie (mobile)
  • Wykorzystuje komponent ResponsiveShell do adaptacyjnych układów

Tryb wbudowany (position: 'inline'):

  • Osadza interfejs płatności bezpośrednio na stronie
  • Nie wymaga przycisku wyzwalającego
  • Przydatny na dedykowanych stronach kasy

Oba tryby wykorzystują wewnętrznie SecureIframeShell do renderowania interfejsu płatności w przestrzennie izolowanym iframe dla bezpieczeństwa.


Przykłady użycia

Podstawowa płatność

<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 napiwków z niestandardowym pobieraniem ceny

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

Koszyk zakupowy z niestandardowym motywem

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

Niestandardowy przycisk wyzwalający

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

Zarządzane przez

© 2026 Solana Foundation.
Wszelkie prawa zastrzeżone.
Bądź na bieżąco