Компонент 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[]) - Массив адресов минта токенов для ограничения способов оплаты. Если не указан, доступны все поддерживаемые токены (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 цены не сработает и кэш недоступен. Без этого интерфейс платежей покажет ошибку при неудаче получения цены.
Внутренние хуки
Компонент 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
Возвращает общую сумму в виде числа (в долларах США для корзины/мгновенной покупки, 0 для чаевых).
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 - RPC URL: Использует серверное разрешение с возвратом к публичным эндпоинтам
- Сеть: Определяется из
Разрешение RPC URL
Компонент включает сложное разрешение RPC URL:
- Если предоставлен
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?