PaymentButton

El componente PaymentButton es un componente de React que proporciona una interfaz completa de pago para aceptar pagos en Solana. Maneja internamente la conexión de billeteras, la selección de tokens, el procesamiento de transacciones y la gestión del estado de la interfaz. De forma predeterminada, viene con botones y modales personalizables:

Botón de Propina

Botón de PropinaBotón de Propina

Modal de PagoModal de Pago

Modal del CarritoModal del Carrito

Instalación

pnpm add @solana-commerce/kit

Props del Componente

PaymentButtonProps

El componente PaymentButton acepta las siguientes props:

Props Requeridas

  • config (SolanaCommerceConfig) - Objeto de configuración principal para el componente de pago. Esta es la única prop requerida. Consulte SolanaCommerceConfig a continuación.

Props Opcionales

  • paymentConfig (PaymentConfig) - Configuración específica del pago que incluye productos, sobreescrituras de precios y captadores de precios personalizados. Consulte PaymentConfig a continuación.

  • onPayment ((amount: number, currency: string) => void) - Se invoca cuando se inicia un pago después de que el usuario confirma el monto y la moneda. Recibe el monto del pago (en unidades de token, no en lamports) y el identificador de la moneda.

  • onPaymentStart (() => void) - Se invoca cuando comienza el flujo de pago, antes de que se envíe la transacción real. Úselo para mostrar estados de carga o seguimiento de análisis.

  • onPaymentSuccess ((signature: string) => void) - Se invoca cuando la transacción se confirma en la cadena. Recibe la firma de la transacción. Aquí es donde debe actualizar el estado del pedido, enviar correos de confirmación, etc.

  • onPaymentError ((error: Error) => void) - Se invoca cuando el pago falla en cualquier etapa (conexión de billetera, envío de transacción o confirmación). El objeto de error contiene detalles sobre lo que salió mal.

  • onCancel (() => void) - Se invoca cuando el usuario cancela explícitamente el flujo de pago (cierra el modal o hace clic en cancelar).

  • children (React.ReactNode) - Elemento disparador personalizado opcional. Si se proporciona, reemplaza el botón de pago predeterminado. El elemento hijo debe ser clicable (por ejemplo, un botón).

  • className (string) - Nombre de clase CSS aplicado al botón disparador (solo se usa cuando no se proporcionan elementos hijos personalizados).

  • style (React.CSSProperties) - Estilos en línea aplicados al botón disparador (solo se usan cuando no se proporcionan elementos hijos personalizados).

  • variant ('default' | 'icon-only') - Variante del botón. Por defecto muestra texto e icono, 'icon-only' muestra solo el icono de pago.


Objetos de Configuración

SolanaCommerceConfig

El objeto de configuración principal que se pasa a la prop config.

Campos Requeridos

  • merchant (MerchantConfig) - Información del comerciante y detalles del destinatario del pago. Ver MerchantConfig.

  • mode ('cart' | 'tip' | 'buyNow') - Modo de pago que determina el texto mostrado en el botón y el flujo de la interfaz:

    • 'buyNow' - Compra de un solo producto con monto fijo
    • 'cart' - Carrito de compras con múltiples productos
    • 'tip' - El usuario elige su propio monto (donaciones/propinas)

Campos Opcionales

  • position ('inline' | 'overlay') - Cómo se muestra la interfaz de pago. Por defecto es 'overlay'.

    • 'overlay' - Se abre en una superposición modal/drawer
    • 'inline' - Integrado directamente en la página
  • theme (ThemeConfig) - Opciones de personalización visual. Ver ThemeConfig.

  • network ('mainnet' | 'devnet' | 'testnet') - Red de Solana a utilizar. Por defecto es 'mainnet'.

  • rpcUrl (string) - URL del endpoint RPC personalizado. Si no se proporciona, utiliza un endpoint público predeterminado para la red seleccionada.

  • allowedMints (string[]) - Array de direcciones mint de tokens para restringir los métodos de pago. Si no se proporciona, todos los tokens compatibles (SOL, USDC, USDT) están disponibles.

  • showQR (boolean) - Si se debe mostrar la opción de pago con código QR. Útil para móviles e integración con Solana Pay.

  • enableWalletConnect (boolean) - Si se habilita la conexión de billetera. Configúralo como false si estás gestionando la conexión de billetera externamente.

  • showMerchantInfo (boolean) - Si se muestra el nombre y logotipo del comerciante en la interfaz de pago.

  • debug (boolean) - Habilita el registro detallado en consola para depuración.

MerchantConfig

Define el destinatario del pago y la información del negocio.

Campos Obligatorios

  • name (string) - Nombre del negocio o comerciante mostrado a los usuarios durante la compra.

  • wallet (string) - Dirección de billetera Solana que recibirá los pagos. Debe ser una dirección Solana válida codificada en base58.

Campos Opcionales

  • logo (string) - URL de la imagen del logotipo del comerciante. Se muestra en la interfaz de pago cuando showMerchantInfo está habilitado.

  • description (string) - Descripción del negocio mostrada a los usuarios.

ThemeConfig

Personalización visual para la interfaz de pago.

Todos los campos son opcionales y tienen valores predeterminados razonables.

  • primaryColor (string) - Color principal de la marca usado para botones y acentos. Predeterminado: '#9945FF' (púrpura Solana).

  • secondaryColor (string) - Color de acento secundario. Predeterminado: '#14F195' (verde Solana).

  • backgroundColor (string) - Color de fondo del modal/contenedor. Predeterminado: '#ffffff'.

  • textColor (string) - Color de texto principal. Predeterminado: '#111827'.

  • borderRadius ('none' | 'sm' | 'md' | 'lg' | 'xl' | 'full') - Radio de borde aplicado a los elementos de la interfaz. Predeterminado: 'lg'.

    • 'none' = 0px
    • 'sm' = 12px
    • 'md' = 16px
    • 'lg' = 20px
    • 'xl' = 24px
    • 'full' = Completamente redondeado (según el contexto)
  • fontFamily (string) - Familia de fuentes para todo el texto. Predeterminado: 'system-ui, -apple-system, sans-serif'.

  • buttonShadow ('none' | 'sm' | 'md' | 'lg' | 'xl') - Sombra proyectada para botones. Predeterminado: 'md'.

  • buttonBorder ('none' | 'black-10') - Estilo de borde para botones. Predeterminado: 'black-10' (borde negro sutil).

PaymentConfig

Configuración avanzada de pago para precios, decimales y productos.

Todos los campos son opcionales.

  • products (Product[]) - Array de productos para los modos 'cart' o 'buyNow'. Requerido al usar estos modos. Cada producto tiene:

    • id (string, requerido) - Identificador único del producto
    • name (string, requerido) - Nombre del producto mostrado al usuario
    • quantity (number, requerido) - Cantidad de este producto
    • price (number, opcional) - Precio por unidad en USD
    • unitAmount (number, opcional) - Alternativa al campo price
    • description (string, opcional) - Descripción del producto
  • solPriceUsd (number) - Precio fijo de SOL en USD. Úsalo para pruebas o cuando quieras fijar el precio de SOL. Si no se proporciona, el componente obtiene el precio actual de CoinGecko.

  • getSolPrice (() => Promise<number>) - Función personalizada para obtener el precio de SOL. Úsala para:

    • Oráculos de precios privados
    • Evitar límites de tasa de APIs públicas
    • Lógica de precios personalizada
    • Aplicaciones empresariales

    Si no se proporciona, por defecto usa la API pública de CoinGecko con caché de 1 minuto.

  • tokenDecimals ({ [currency: string]: number }) - Anula la precisión decimal del token. Útil para tokens personalizados. Ejemplo:

    tokenDecimals: {
    'CUSTOM': 8,
    'USDC': 6 // Can override defaults
    }
  • fallbackSolPriceUsd (number) - Precio de respaldo de SOL si la API de precios falla y no hay caché disponible. Sin esto, la interfaz de pago mostrará un error si falla la obtención del precio.


Hooks Internos

El componente PaymentButton utiliza varios hooks internos para gestionar el estado y calcular valores:

useTheme(theme?: ThemeConfig)

Combina la configuración de tema proporcionada por el usuario con los valores de tema predeterminados. Devuelve un objeto ThemeConfig completo con todos los campos poblados.

Valores de tema predeterminados:

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

El hook está memoizado y solo recalcula cuando cambia la configuración del tema.

useTotalAmount(mode, paymentConfig?)

Calcula el monto total del pago basado en el modo de comercio y los productos.

Comportamiento por modo:

  • Modo 'tip' - Devuelve 0 (el monto lo determina el usuario)
  • Modos 'cart' y 'buyNow' - Suma price * quantity para todos los productos en paymentConfig.products

El hook maneja casos especiales:

  • Los precios faltantes o inválidos se establecen por defecto en 0
  • Las cantidades faltantes o inválidas se establecen por defecto en 0
  • Asegura que todos los valores sean números finitos
  • Soporta tanto los campos de producto price como unitAmount

Devuelve el monto total como un número (en USD para carrito/comprar ahora, 0 para propina).

usePaymentUrl(merchant, amount, mode)

Genera una URL de Solana Pay para el pago. Esta URL puede codificarse como un código QR para escanear con billeteras móviles.

Devuelve: Una URL del protocolo solana: con parámetros de consulta para:

  • recipient - Dirección de billetera del comerciante
  • amount - Monto del pago
  • reference - Referencia de pago única (generada a partir de marca de tiempo + cadena aleatoria)
  • label - Nombre del comerciante (sanitizado para seguridad de URL)
  • message - Mensaje contextual basado en el modo

Devuelve una cadena vacía si la billetera del comerciante es inválida o el monto es <= 0.

Seguridad: El nombre del comerciante se sanitiza usando sanitizeString() para prevenir ataques XSS a través de inyección de URL.


Validación y Manejo de Errores

El componente realiza validación antes de renderizar:

  1. Validación de Billetera - Usa isAddress() de gill para validar la dirección de billetera del comerciante. Si es inválida, renderiza un estado de error en lugar de la interfaz de pago.

  2. Validación de Precios - Asegura que haya precios válidos configurados:

    • Para modo 'tip': Siempre válido (el usuario elige el monto)
    • Para modos 'cart' y 'buyNow': Valida que totalAmount > 0
  3. Seguridad SSR - Utiliza detección del lado del cliente para prevenir discrepancias de hidratación. El estado isClient asegura que las funcionalidades exclusivas del navegador (como localStorage para la persistencia de billeteras) solo se ejecuten en el cliente.


Arquitectura de Componentes

El PaymentButton envuelve todos los elementos hijos en dos proveedores de contexto:

  1. AppProvider - Proporciona el estado de conexión de la billetera y el cliente conector

    • Conexión automática: deshabilitada por defecto
    • Almacenamiento: Utiliza localStorage cuando está disponible (solo del lado del cliente)
    • Modo de depuración: configurable mediante configuración
  2. ArcProvider - Proporciona el cliente de blockchain de Solana y la conexión RPC

    • Red: Determinada desde config.network
    • URL RPC: Utiliza resolución del lado del servidor con respaldo a endpoints públicos

Resolución de URL RPC

El componente incluye resolución sofisticada de URL RPC:

  • Si se proporciona config.rpcUrl, se utiliza directamente
  • De lo contrario, llama a un resolvedor del lado del servidor que selecciona endpoints confiables
  • Recurre a https://api.mainnet-beta.solana.com si falla la resolución
  • La resolución ocurre de forma asíncrona al montar y actualiza el estado

Modos de Renderizado

Modo overlay (position: 'overlay' o por defecto):

  • Renderiza un botón disparador (personalizado o predeterminado)
  • Abre la interfaz de pago en un modal responsivo (escritorio) o cajón (móvil)
  • Utiliza el componente ResponsiveShell para diseños adaptativos

Modo inline (position: 'inline'):

  • Incrusta la interfaz de pago directamente en la página
  • No requiere botón disparador
  • Útil para páginas de pago dedicadas

Ambos modos utilizan SecureIframeShell internamente para renderizar la interfaz de pago en un iframe aislado por seguridad.


Ejemplos de Uso

Pago Básico

<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 de Propina con Obtención de Precio Personalizada

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

Carrito de Compras con Tema Personalizado

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

Botón Disparador Personalizado

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

Gestionado por

© 2026 Fundación Solana.
Todos los derechos reservados.
Conéctate