Les demandes de transfert constituent la forme d'intégration Solana Pay la plus simple. Elles créent des URL de paiement non interactives que les portefeuilles peuvent utiliser pour composer et envoyer directement des transactions sans nécessiter de serveur.
Aperçu
Une URL de demande de transfert suit ce format :
solana:<recipient>?amount=<amount>&spl-token=<spl-token>&reference=<reference>&label=<label>&message=<message>&memo=<memo>
Transfert SOL de base
Créez une demande de paiement SOL simple :
import { address } from "@solana/kit";import { encodeURL } from "@solana/pay";// Recipient's Solana wallet addressconst recipient = address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB");// Create the payment URLconst url = encodeURL({recipient,amount: 0.01, // 0.01 SOLlabel: "My Store",message: "Thanks for your purchase!"});console.log(url.toString());// Output: solana:FvJ8k8Hh...?amount=0.01&label=My%20Store&message=Thanks%20for%20your%20purchase!
Transfert de jeton SPL
Créez une demande de paiement USDC :
import { address } from "@solana/kit";import { encodeURL } from "@solana/pay";// USDC mint address on mainnetconst usdcMint = address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");const url = encodeURL({recipient: address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB"),amount: 10.5, // $10.50 USDCsplToken: usdcMint,label: "Coffee Shop",message: "Grande Latte + Tip"});console.log(url.toString());
Paramètres d'URL
Paramètres requis
Destinataire
L'adresse du portefeuille Solana du destinataire (encodée en base58) :
const recipient = address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB");
Paramètres optionnels
Montant
Montant du paiement en unités conviviales (SOL ou unités de jetons) :
// SOL amountsconst solAmount = 1.5; // 1.5 SOLconst smallAmount = 0.001; // 0.001 SOL// Token amounts (USDC example)const usdcAmount = 25.99; // $25.99 USDC
Si omis, le portefeuille invitera l'utilisateur à saisir le montant.
Jeton SPL
Pour les transferts de jetons, spécifiez l'adresse de frappe :
// Common SPL tokensconst USDC = address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");const USDT = address("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB");// Omit splToken for native SOL transfers
Référence
Identifiants uniques pour le suivi des paiements. Générez une adresse à utiliser comme clé de référence :
import { generateKeyPair, getAddressFromPublicKey } from "@solana/kit";// Generate a unique referenceconst keypair = await generateKeyPair();const reference = await getAddressFromPublicKey(keypair.publicKey);
Libellé
Nom du commerçant ou de l'application affiché aux utilisateurs :
const label = "Acme Coffee Shop";
Message
Description du paiement :
const message = "Order #12345 - 2x Americano";
Mémo
Mémo on-chain (visible publiquement) :
const memo = "OrderId:12345";
Intégration du code QR
Générez des codes QR en utilisant la fonction intégrée createQR :
import { address } from "@solana/kit";import { encodeURL, createQR } from "@solana/pay";const url = encodeURL({recipient: address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB"),amount: 0.05,label: "Donation",message: "Support our project"});// Generate a QR code elementconst qr = createQR(url);// Append to DOMconst element = document.getElementById("qr-code");qr.append(element);
Validation des paiements
Utilisation du client marchand
La méthode la plus simple pour rechercher et valider les paiements :
import { address } from "@solana/kit";import { createMerchantClient } from "@solana/pay";const merchant = createMerchantClient({rpcUrl: "https://api.mainnet-beta.solana.com"});const recipient = address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB");const reference = address("YOUR_REFERENCE_ADDRESS");// Find the transaction by referenceconst found = await merchant.pay.findReference(reference);// Validate the transfer matches expected fieldsawait merchant.pay.validateTransfer(found.signature, {recipient,amount: 0.1});console.log("Payment confirmed!", found.signature);
Utilisation des fonctions autonomes
import { createSolanaRpc, address } from "@solana/kit";import { findReference, validateTransfer } from "@solana/pay";const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");const reference = address("YOUR_REFERENCE_ADDRESS");// Find transaction by referenceconst found = await findReference(rpc, reference);// Validate transaction detailsawait validateTransfer(rpc, found.signature, {recipient: address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB"),amount: 0.1});console.log("Payment confirmed!", found.signature);
Surveillance des paiements (WebSocket)
L'approche recommandée — watchReference s'abonne via WebSocket et se résout
dès qu'une transaction correspondante arrive. Aucune interrogation nécessaire.
async function waitForPayment(reference, recipient, amount) {const merchant = createMerchantClient({rpcUrl: "https://api.mainnet-beta.solana.com"});// Resolves on the first transaction mentioning this referenceconst result = await merchant.pay.watchReference(reference);if (result.err) {throw new Error(`Transaction failed: ${JSON.stringify(result.err)}`);}// Validate that the transaction matches the expected paymentawait merchant.pay.validateTransfer(result.signature, { recipient, amount });return { signature: result.signature };}
Interrogation des paiements (repli HTTP)
Si les abonnements WebSocket ne sont pas disponibles (par exemple, certains
fournisseurs RPC), passez au polling avec findReference :
async function pollForPayment(reference, recipient, amount) {const merchant = createMerchantClient({rpcUrl: "https://api.mainnet-beta.solana.com"});const checkPayment = async () => {try {const found = await merchant.pay.findReference(reference);await merchant.pay.validateTransfer(found.signature, {recipient,amount});return { success: true, signature: found.signature };} catch {return { success: false };}};// Check every 2 secondsreturn new Promise((resolve) => {const interval = setInterval(async () => {const result = await checkPayment();if (result.success) {clearInterval(interval);resolve(result);}}, 2000);});}
Exemple complet
Voici un exemple complet avec génération de code QR et surveillance des paiements :
import { address, generateKeyPair, getAddressFromPublicKey } from "@solana/kit";import { encodeURL, createQR, createMerchantClient } from "@solana/pay";const recipient = address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB");const amount = 0.1;// Generate unique reference for this paymentconst keypair = await generateKeyPair();const reference = await getAddressFromPublicKey(keypair.publicKey);// Create payment URL and QR codeconst url = encodeURL({recipient,amount,reference,label: "Demo Store",message: "Test Purchase"});const qr = createQR(url);qr.append(document.getElementById("qr-code"));// Monitor for paymentconst merchant = createMerchantClient({rpcUrl: "https://api.mainnet-beta.solana.com"});const interval = setInterval(async () => {try {const found = await merchant.pay.findReference(reference);await merchant.pay.validateTransfer(found.signature, {recipient,amount,reference});clearInterval(interval);console.log("Payment confirmed!", found.signature);} catch {// Payment not found yet, keep polling}}, 2000);
Bonnes pratiques
Sécurité
- Validez toujours les paiements côté serveur
- Utilisez des références uniques pour chaque paiement
- Vérifiez les montants et les destinataires des transactions
- Contrôlez le statut de réussite des transactions
Expérience utilisateur
- Affichez clairement les montants et les descriptions de paiement
- Fournissez des mises à jour du statut de paiement
- Gérez la connexion au portefeuille de manière fluide
- Prenez en charge à la fois les codes QR et les liens directs
Gestion des erreurs
- Gérez les échecs de connexion au portefeuille
- Prévoyez une solution de secours pour les portefeuilles non pris en charge
- Affichez des messages d'erreur utiles
- Implémentez des délais d'expiration pour les paiements
Cas d'usage courants
Point de vente
const posPayment = encodeURL({recipient: merchantWallet,amount: 15.99,label: "Local Coffee Shop",message: `Receipt #${receiptNumber}`,memo: `POS-${terminalId}-${Date.now()}`});
Dons
// Flexible donation amount (user enters amount in wallet)const donationUrl = encodeURL({recipient: charityWallet,label: "Save the Ocean",message: "Support marine conservation"});
Paiement e-commerce
const checkoutUrl = encodeURL({recipient: storeWallet,amount: cartTotal,reference: orderReference,label: storeName,message: `Order ${orderId}`,memo: `ORDER:${orderId}`});
Is this page helpful?