Le composant PaymentButton est un composant React qui fournit une interface de
paiement complète pour accepter les paiements Solana. Il gère la connexion au
portefeuille, la sélection de jetons, le traitement des transactions et la
gestion de l'état de l'interface utilisateur en interne. Prêt à l'emploi, il est
livré avec des boutons et des modales personnalisables :
Bouton de Pourboire
Bouton de Pourboire
Modale de Paiement
Modale de Paiement
Modale QR Code Solana Pay
Modale Panier
Installation
pnpm add @solana-commerce/kit
Propriétés du Composant
PaymentButtonProps
Le composant PaymentButton accepte les propriétés suivantes :
Propriétés Requises
config(SolanaCommerceConfig) - Objet de configuration principal pour le composant de paiement. Il s'agit de la seule propriété requise. Voir SolanaCommerceConfig ci-dessous.
Propriétés Optionnelles
-
paymentConfig(PaymentConfig) - Configuration spécifique au paiement incluant les produits, les remplacements de tarifs et les récupérateurs de prix personnalisés. Voir PaymentConfig ci-dessous. -
onPayment((amount: number, currency: string) => void) - Appelé lorsqu'un paiement est initié après que l'utilisateur a confirmé le montant et la devise. Reçoit le montant du paiement (en unités de jeton, pas en lamports) et l'identifiant de devise. -
onPaymentStart(() => void) - Appelé lorsque le flux de paiement commence, avant que la transaction réelle ne soit soumise. Utilisez-le pour afficher des états de chargement ou le suivi analytique. -
onPaymentSuccess((signature: string) => void) - Appelé lorsque la transaction est confirmée sur la chaîne. Reçoit la signature de transaction. C'est ici que vous devez mettre à jour le statut de commande, envoyer des e-mails de confirmation, etc. -
onPaymentError((error: Error) => void) - Appelé lorsque le paiement échoue à n'importe quelle étape (connexion au portefeuille, soumission de transaction ou confirmation). L'objet erreur contient des détails sur ce qui a mal tourné. -
onCancel(() => void) - Appelé lorsque l'utilisateur annule explicitement le flux de paiement (ferme la modale ou clique sur annuler). -
children(React.ReactNode) - Élément déclencheur personnalisé optionnel. S'il est fourni, il remplace le bouton de paiement par défaut. L'élément enfant doit être cliquable (par exemple, un bouton). -
className(string) - Nom de classe CSS appliqué au bouton déclencheur (utilisé uniquement lorsqu'aucun élément enfant personnalisé n'est fourni). -
style(React.CSSProperties) - Styles en ligne appliqués au bouton déclencheur (utilisés uniquement lorsqu'aucun élément enfant personnalisé n'est fourni). -
variant('default' | 'icon-only') - Variante du bouton. Par défaut, affiche le texte et l'icône,'icon-only'n'affiche que l'icône de paiement.
Objets de configuration
SolanaCommerceConfig
L'objet de configuration principal transmis à la prop config.
Champs requis
-
merchant(MerchantConfig) - Informations sur le marchand et détails du destinataire du paiement. Voir MerchantConfig. -
mode('cart' | 'tip' | 'buyNow') - Mode de paiement qui détermine le texte d'affichage du bouton et le flux de l'interface utilisateur :'buyNow'- Achat d'un produit unique avec montant fixe'cart'- Panier d'achat avec plusieurs produits'tip'- L'utilisateur choisit son propre montant (dons/pourboires)
Champs optionnels
-
position('inline' | 'overlay') - Manière dont l'interface de paiement est affichée. Par défaut'overlay'.'overlay'- S'ouvre dans une fenêtre modale/tiroir superposé'inline'- Intégré directement dans la page
-
theme(ThemeConfig) - Options de personnalisation visuelle. Voir ThemeConfig. -
network('mainnet' | 'devnet' | 'testnet') - Réseau Solana à utiliser. Par défaut'mainnet'. -
rpcUrl(string) - URL de point de terminaison RPC personnalisé. S'il n'est pas fourni, utilise un point de terminaison public par défaut pour le réseau sélectionné. -
allowedMints(string[]) - Tableau d'adresses de frappe de jetons pour restreindre les méthodes de paiement. S'il n'est pas fourni, tous les jetons pris en charge (SOL, USDC, USDT) sont disponibles. -
showQR(boolean) - Indique s'il faut afficher l'option de paiement par QR code. Utile pour l'intégration mobile et Solana Pay. -
enableWalletConnect(boolean) - Définit si la connexion au portefeuille doit être activée. Définir surfalsesi vous gérez la connexion au portefeuille en externe. -
showMerchantInfo(boolean) - Définit si le nom et le logo du commerçant doivent être affichés dans l'interface de paiement. -
debug(boolean) - Active la journalisation détaillée dans la console pour le débogage.
MerchantConfig
Définit le destinataire du paiement et les informations commerciales.
Champs obligatoires
-
name(string) - Nom de l'entreprise ou du commerçant affiché aux utilisateurs pendant le paiement. -
wallet(string) - Adresse du portefeuille Solana qui recevra les paiements. Doit être une adresse Solana valide encodée en base58.
Champs optionnels
-
logo(string) - URL vers l'image du logo du commerçant. Affichée dans l'interface de paiement lorsqueshowMerchantInfoest activé. -
description(string) - Description de l'entreprise présentée aux utilisateurs.
ThemeConfig
Personnalisation visuelle de l'interface de paiement.
Tous les champs sont optionnels et possèdent des valeurs par défaut appropriées.
-
primaryColor(string) - Couleur principale de la marque utilisée pour les boutons et les accents. Par défaut :'#9945FF'(violet Solana). -
secondaryColor(string) - Couleur d'accent secondaire. Par défaut :'#14F195'(vert Solana). -
backgroundColor(string) - Couleur de fond du modal/conteneur. Par défaut :'#ffffff'. -
textColor(string) - Couleur du texte principal. Par défaut :'#111827'. -
borderRadius('none' | 'sm' | 'md' | 'lg' | 'xl' | 'full') - Rayon de bordure appliqué aux éléments de l'interface. Par défaut :'lg'.'none'= 0px'sm'= 12px'md'= 16px'lg'= 20px'xl'= 24px'full'= Complètement arrondi (selon le contexte)
-
fontFamily(string) - Famille de police pour tout le texte. Par défaut :'system-ui, -apple-system, sans-serif'. -
buttonShadow('none' | 'sm' | 'md' | 'lg' | 'xl') - Ombre portée pour les boutons. Par défaut :'md'. -
buttonBorder('none' | 'black-10') - Style de bordure pour les boutons. Par défaut :'black-10'(bordure noire subtile).
PaymentConfig
Configuration avancée des paiements pour la tarification, les décimales et les produits.
Tous les champs sont facultatifs.
-
products(Product[]) - Tableau de produits pour les modes'cart'ou'buyNow'. Requis lors de l'utilisation de ces modes. Chaque produit contient :id(string, requis) - Identifiant unique du produitname(string, requis) - Nom du produit affiché à l'utilisateurquantity(number, requis) - Quantité de ce produitprice(number, facultatif) - Prix unitaire en USDunitAmount(number, facultatif) - Alternative au champpricedescription(string, facultatif) - Description du produit
-
solPriceUsd(number) - Prix fixe du SOL en USD. Utilisez ceci pour les tests ou lorsque vous souhaitez verrouiller le prix du SOL. Si non fourni, le composant récupère le prix actuel depuis CoinGecko. -
getSolPrice(() => Promise<number>) - Fonction personnalisée pour récupérer le prix du SOL. Utilisez ceci pour :- Oracles de prix privés
- Éviter les limites de taux des API publiques
- Logique de tarification personnalisée
- Applications d'entreprise
Si non fourni, utilise par défaut l'API publique de CoinGecko avec une mise en cache d'1 minute.
-
tokenDecimals({ [currency: string]: number }) - Remplace la précision décimale du jeton. Utile pour les jetons personnalisés. Exemple :tokenDecimals: {'CUSTOM': 8,'USDC': 6 // Can override defaults} -
fallbackSolPriceUsd(number) - Prix de repli du SOL si l'API de prix échoue et qu'aucun cache n'est disponible. Sans cela, l'interface de paiement affichera une erreur si la récupération du prix échoue.
Hooks internes
Le composant PaymentButton utilise plusieurs hooks internes pour gérer l'état
et calculer les valeurs :
useTheme(theme?: ThemeConfig)
Fusionne la configuration de thème fournie par l'utilisateur avec les valeurs de
thème par défaut. Renvoie un objet ThemeConfig complet avec tous les champs
remplis.
Valeurs de thème par défaut :
primaryColor: '#9945FF'secondaryColor: '#14F195'backgroundColor: '#ffffff'textColor: '#111827'borderRadius: 'lg'fontFamily: 'system-ui, -apple-system, sans-serif'buttonShadow: 'md'buttonBorder: 'black-10'
Le hook est mémorisé et ne recalcule que lorsque la configuration du thème change.
useTotalAmount(mode, paymentConfig?)
Calcule le montant total du paiement en fonction du mode de commerce et des produits.
Comportement par mode :
- Mode
'tip'- Retourne0(le montant est déterminé par l'utilisateur) - Modes
'cart'et'buyNow'- Additionneprice * quantitypour tous les produits danspaymentConfig.products
Le hook gère les cas limites :
- Les prix manquants ou invalides sont définis par défaut à
0 - Les quantités manquantes ou invalides sont définies par défaut à
0 - Garantit que toutes les valeurs sont des nombres finis
- Prend en charge les champs de produit
priceetunitAmount
Retourne le montant total sous forme de nombre (en USD pour cart/buyNow, 0 pour tip).
usePaymentUrl(merchant, amount, mode)
Génère une URL Solana Pay pour le paiement. Cette URL peut être encodée sous forme de QR code pour la numérisation par portefeuille mobile.
Retourne : Une URL de protocole solana: avec des paramètres de requête
pour :
recipient- Adresse du portefeuille du commerçantamount- Montant du paiementreference- Référence de paiement unique (générée à partir de l'horodatage + chaîne aléatoire)label- Nom du commerçant (assaini pour la sécurité de l'URL)message- Message contextuel basé sur le mode
Retourne une chaîne vide si le portefeuille du commerçant est invalide ou si le
montant est <= 0.
Sécurité : Le nom du commerçant est assaini en utilisant sanitizeString()
pour prévenir les attaques XSS par injection d'URL.
Validation et gestion des erreurs
Le composant effectue une validation avant le rendu :
-
Validation du portefeuille - Utilise
isAddress()degillpour valider l'adresse du portefeuille du commerçant. Si invalide, affiche un état d'erreur au lieu de l'interface de paiement. -
Validation des prix - Garantit qu'une tarification valide est configurée :
- Pour le mode
'tip': Toujours valide (l'utilisateur choisit le montant) - Pour les modes
'cart'et'buyNow': Valide quetotalAmount > 0
- Pour le mode
-
Sécurité SSR - Utilise la détection côté client pour éviter les incompatibilités d'hydratation. L'état
isClientgarantit que les fonctionnalités réservées au navigateur (commelocalStoragepour la persistance du portefeuille) s'exécutent uniquement côté client.
Architecture des composants
Le PaymentButton enveloppe tous les enfants dans deux fournisseurs de contexte
:
-
AppProvider- Fournit l'état de connexion du portefeuille et le client connecteur- Connexion automatique : désactivée par défaut
- Stockage : Utilise
localStoragelorsque disponible (côté client uniquement) - Mode débogage : configurable via config
-
ArcProvider- Fournit le client blockchain Solana et la connexion RPC- Réseau : Déterminé à partir de
config.network - URL RPC : Utilise la résolution côté serveur avec repli vers les points de terminaison publics
- Réseau : Déterminé à partir de
Résolution de l'URL RPC
Le composant inclut une résolution sophistiquée de l'URL RPC :
- Si
config.rpcUrlest fourni, il est utilisé directement - Sinon, il appelle un résolveur côté serveur qui sélectionne des points de terminaison fiables
- Se replie sur
https://api.mainnet-beta.solana.comsi la résolution échoue - La résolution s'effectue de manière asynchrone au montage et met à jour l'état
Modes de rendu
Mode superposition (position: 'overlay' ou par défaut) :
- Affiche un bouton déclencheur (personnalisé ou par défaut)
- Ouvre l'interface de paiement dans une modale responsive (ordinateur) ou un tiroir (mobile)
- Utilise le composant
ResponsiveShellpour des mises en page adaptatives
Mode en ligne (position: 'inline') :
- Intègre l'interface de paiement directement dans la page
- Aucun bouton déclencheur nécessaire
- Utile pour les pages de paiement dédiées
Les deux modes utilisent SecureIframeShell en interne pour afficher
l'interface de paiement dans une iframe isolée pour la sécurité.
Exemples d'utilisation
Paiement de base
<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);}}/>
Widget de pourboire avec récupérateur de prix personnalisé
<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}}/>
Panier d'achat avec thème personnalisé
<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 })});}}/>
Bouton déclencheur personnalisé
<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?