Компонент PaymentButton — це React-компонент, який надає повноцінний інтерфейс
для прийому платежів у Solana. Він внутрішньо обробляє підключення гаманця,
вибір токенів, обробку транзакцій та керування станом інтерфейсу. Одразу з
коробки він постачається з налаштовуваними кнопками та модальними вікнами:
Кнопка чайових
Кнопка чайових
Модальне вікно оплати
Модальне вікно оплати
Модальне вікно QR-коду Solana Pay
Модальне вікно кошика
Встановлення
pnpm add @solana-commerce/kit
Властивості компонента
PaymentButtonProps
Компонент PaymentButton приймає наступні властивості:
Обов'язкові властивості
config(SolanaCommerceConfig) — Основний об'єкт конфігурації для компонента платежів. Це єдина обов'язкова властивість. Див. SolanaCommerceConfig нижче.
Необов'язкові властивості
-
paymentConfig(PaymentConfig) — Конфігурація для конкретного платежу, включаючи продукти, перевизначення цін та власні запити цін. Див. PaymentConfig нижче. -
onPayment((amount: number, currency: string) => void) — Викликається, коли ініціюється платіж після підтвердження користувачем суми та валюти. Отримує суму платежу (в одиницях токена, а не lamports) та ідентифікатор валюти. -
onPaymentStart(() => void) — Викликається на початку процесу оплати, до фактичного відправлення транзакції. Використовуйте це для відображення станів завантаження або відстеження аналітики. -
onPaymentSuccess((signature: string) => void) — Викликається після підтвердження транзакції в ланцюзі. Отримує підпис транзакції. Тут ви маєте оновити статус замовлення, надіслати листи підтвердження тощо. -
onPaymentError((error: Error) => void) — Викликається, коли платіж не вдається на будь-якому етапі (підключення гаманця, відправлення транзакції або підтвердження). Об'єкт помилки містить деталі про те, що пішло не так. -
onCancel(() => void) — Викликається, коли користувач явно скасовує процес оплати (закриває модальне вікно або натискає скасування). -
children(React.ReactNode) - Необов'язковий власний елемент-тригер. Якщо надано, замінює стандартну кнопку оплати. Дочірній елемент повинен бути клікабельним (наприклад, кнопка). -
className(string) - Ім'я CSS-класу, що застосовується до кнопки-тригера (використовується лише коли власні дочірні елементи не надано). -
style(React.CSSProperties) - Вбудовані стилі, що застосовуються до кнопки-тригера (використовуються лише коли власні дочірні елементи не надано). -
variant('default' | 'icon-only') - Варіант кнопки. За замовчуванням показує текст та іконку,'icon-only'показує лише іконку оплати.
Об'єкти конфігурації
SolanaCommerceConfig
Основний об'єкт конфігурації, що передається до властивості config.
Обов'язкові поля
-
merchant(MerchantConfig) - Інформація про продавця та деталі одержувача платежу. Див. MerchantConfig. -
mode('cart' | 'tip' | 'buyNow') - Режим оплати, що визначає текст кнопки та послідовність інтерфейсу:'buyNow'- Покупка одного товару з фіксованою сумою'cart'- Кошик з кількома товарами'tip'- Користувач обирає власну суму (донати/чайові)
Необов'язкові поля
-
position('inline' | 'overlay') - Спосіб відображення інтерфейсу оплати. За замовчуванням'overlay'.'overlay'- Відкривається у модальному вікні/висувній панелі'inline'- Вбудовується безпосередньо на сторінку
-
theme(ThemeConfig) - Параметри візуального налаштування. Див. ThemeConfig. -
network('mainnet' | 'devnet' | 'testnet') - Мережа Solana для використання. За замовчуванням'mainnet'. -
rpcUrl(string) - URL власної кінцевої точки RPC. Якщо не надано, використовується стандартна публічна кінцева точка для обраної мережі. -
allowedMints(string[]) - Масив адрес mint токенів для обмеження способів оплати. Якщо не надано, доступні всі підтримувані токени (SOL, USDC, USDT). -
showQR(boolean) - Чи показувати опцію оплати через QR-код. Корисно для мобільних пристроїв та інтеграції Solana Pay. -
enableWalletConnect(boolean) - Чи увімкнути підключення гаманця. Встановіть значенняfalse, якщо ви обробляєте підключення гаманця зовні. -
showMerchantInfo(boolean) - Чи відображати назву та логотип продавця в інтерфейсі платежу. -
debug(boolean) - Увімкнути детальне логування в консолі для налагодження.
MerchantConfig
Визначає одержувача платежу та інформацію про бізнес.
Обов'язкові поля
-
name(string) - Назва бізнесу або продавця, що відображається користувачам під час оформлення покупки. -
wallet(string) - Адреса гаманця Solana, що отримуватиме платежі. Має бути дійсною адресою Solana в кодуванні base58.
Необов'язкові поля
-
logo(string) - URL-адреса зображення логотипу продавця. Відображається в інтерфейсі платежу, коли ввімкненоshowMerchantInfo. -
description(string) - Опис бізнесу, що показується користувачам.
ThemeConfig
Візуальне налаштування інтерфейсу платежу.
Усі поля є необов'язковими та мають розумні значення за замовчуванням.
-
primaryColor(string) - Основний колір бренду, що використовується для кнопок та акцентів. За замовчуванням:'#9945FF'(фіолетовий Solana). -
secondaryColor(string) - Другорядний колір акценту. За замовчуванням:'#14F195'(зелений Solana). -
backgroundColor(string) - Колір фону модального вікна/контейнера. За замовчуванням:'#ffffff'. -
textColor(string) - Основний колір тексту. За замовчуванням:'#111827'. -
borderRadius('none' | 'sm' | 'md' | 'lg' | 'xl' | 'full') - Радіус заокруглення, що застосовується до елементів інтерфейсу. За замовчуванням:'lg'.'none'= 0px'sm'= 12px'md'= 16px'lg'= 20px'xl'= 24px'full'= Повністю заокруглений (залежить від контексту)
-
fontFamily(string) - Сімейство шрифтів для всього тексту. За замовчуванням:'system-ui, -apple-system, sans-serif'. -
buttonShadow('none' | 'sm' | 'md' | 'lg' | 'xl') - Тінь для кнопок. За замовчуванням:'md'. -
buttonBorder('none' | 'black-10') - Стиль рамки для кнопок. За замовчуванням:'black-10'(тонка чорна рамка).
PaymentConfig
Розширена конфігурація платежів для ціноутворення, десяткових знаків та продуктів.
Усі поля є опціональними.
-
products(Product[]) - Масив продуктів для режимів'cart'або'buyNow'. Обов'язковий при використанні цих режимів. Кожен продукт має:id(string, обов'язковий) - Унікальний ідентифікатор продуктуname(string, обов'язковий) - Назва продукту, що відображається користувачуquantity(number, обов'язковий) - Кількість цього продуктуprice(number, опціональний) - Ціна за одиницю в USDunitAmount(number, опціональний) - Альтернатива полюpricedescription(string, опціональний) - Опис продукту
-
solPriceUsd(number) - Фіксована ціна SOL у USD. Використовуйте це для тестування або коли ви хочете зафіксувати ціну SOL. Якщо не вказано, компонент отримує поточну ціну з CoinGecko. -
getSolPrice(() => Promise<number>) - Кастомна функція для отримання ціни SOL. Використовуйте це для:- Приватних прайс-оракулів
- Уникнення обмежень швидкості публічних API
- Власної логіки ціноутворення
- Корпоративних додатків
Якщо не вказано, за замовчуванням використовується публічний API CoinGecko з кешуванням на 1 хвилину.
-
tokenDecimals({ [currency: string]: number }) - Перевизначення точності десяткових знаків токена. Корисно для кастомних токенів. Приклад:tokenDecimals: {'CUSTOM': 8,'USDC': 6 // Can override defaults} -
fallbackSolPriceUsd(number) - Резервна ціна SOL, якщо API ціноутворення не спрацює і кеш недоступний. Без цього платіжний UI покаже помилку, якщо отримання ціни не вдасться.
Внутрішні хуки
Компонент PaymentButton використовує кілька внутрішніх хуків для управління
станом і обчислення значень:
useTheme(theme?: ThemeConfig)
Об'єднує користувацьку конфігурацію теми із значеннями теми за замовчуванням.
Повертає повний об'єкт ThemeConfig з усіма заповненими полями.
Значення теми за замовчуванням:
primaryColor: '#9945FF'secondaryColor: '#14F195'backgroundColor: '#ffffff'textColor: '#111827'borderRadius: 'lg'fontFamily: 'system-ui, -apple-system, sans-serif'buttonShadow: 'md'buttonBorder: 'black-10'
Хук мемоізовано і він перераховується лише при зміні конфігурації теми.
useTotalAmount(mode, paymentConfig?)
Обчислює загальну суму платежу на основі режиму комерції та продуктів.
Поведінка за режимами:
- Режим
'tip'- Повертає0(суму визначає користувач) - Режими
'cart'та'buyNow'- Підсумовуєprice * quantityдля всіх продуктів уpaymentConfig.products
Хук обробляє граничні випадки:
- Відсутні або недійсні ціни за замовчуванням дорівнюють
0 - Відсутні або недійсні кількості за замовчуванням дорівнюють
0 - Забезпечує, що всі значення є скінченними числами
- Підтримує поля продуктів як
price, так іunitAmount
Повертає загальну суму як число (у доларах США для cart/buyNow, 0 для tip).
usePaymentUrl(merchant, amount, mode)
Генерує URL Solana Pay для платежу. Цей URL можна закодувати як QR-код для сканування мобільним гаманцем.
Повертає: URL протоколу solana: з параметрами запиту для:
recipient- Адреса гаманця продавцяamount- Сума платежуreference- Унікальний ідентифікатор платежу (згенеровано з мітки часу + випадковий рядок)label- Ім'я продавця (санітизовано для безпеки URL)message- Контекстне повідомлення залежно від режиму
Повертає порожній рядок, якщо гаманець продавця недійсний або сума дорівнює
<= 0.
Безпека: Ім'я продавця санітизується за допомогою sanitizeString() для
запобігання XSS-атакам через ін'єкцію URL.
Валідація та обробка помилок
Компонент виконує валідацію перед рендерингом:
-
Валідація гаманця - Використовує
isAddress()зgillдля валідації адреси гаманця продавця. Якщо адреса недійсна, рендерить стан помилки замість інтерфейсу оплати. -
Валідація ціноутворення - Забезпечує налаштування дійсного ціноутворення:
- Для режиму
'tip': Завжди дійсно (користувач обирає суму) - Для режимів
'cart'та'buyNow': Валідує, щоtotalAmount > 0
- Для режиму
-
Безпека SSR - Використовує виявлення на стороні клієнта для запобігання невідповідностей гідратації. Стан
isClientзабезпечує, що функції лише для браузера (наприклад,localStorageдля збереження гаманця) виконуються тільки на клієнті.
Архітектура компонентів
PaymentButton обгортає всі дочірні елементи у двох провайдерах контексту:
-
AppProvider- Надає стан підключення гаманця та клієнт коннектора- Автопідключення: за замовчуванням вимкнено
- Сховище: Використовує
localStorage, коли доступно (тільки на стороні клієнта) - Режим налагодження: налаштовується через конфігурацію
-
ArcProvider- Надає клієнт блокчейну Solana та RPC-з'єднання- Мережа: Визначається з
config.network - URL RPC: Використовує серверне визначення з резервним переходом до публічних точок доступу
- Мережа: Визначається з
Визначення URL RPC
Компонент включає складне визначення URL RPC:
- Якщо надано
config.rpcUrl, він використовується безпосередньо - Інакше викликається серверний розв'язувач, який вибирає надійні точки доступу
- Резервний перехід до
https://api.mainnet-beta.solana.com, якщо визначення не вдається - Визначення відбувається асинхронно при монтуванні та оновлює стан
Режими відображення
Режим накладання (position: 'overlay' або за замовчуванням):
- Відображає кнопку-тригер (налаштовану або стандартну)
- Відкриває інтерфейс оплати в адаптивному модальному вікні (десктоп) або шухляді (мобільний)
- Використовує компонент
ResponsiveShellдля адаптивних макетів
Вбудований режим (position: 'inline'):
- Вбудовує інтерфейс оплати безпосередньо на сторінку
- Не потребує кнопки-тригера
- Корисно для спеціалізованих сторінок оформлення замовлення
Обидва режими використовують SecureIframeShell всередині для відображення
платіжного інтерфейсу в ізольованому iframe з метою безпеки.
Приклади використання
Базовий платіж
<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);}}/>
Віджет чайових з налаштованим отримувачем цін
<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}}/>
Кошик покупок з налаштованою темою
<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 })});}}/>
Налаштована кнопка-тригер
<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?