Flussi di Pagamento
Il pacchetto @solana-commerce/headless fornisce funzioni indipendenti dal
framework per costruire flussi di pagamento commerce. Questi strumenti aiutano a
creare oggetti di richiesta pagamento, generare URL Solana Pay e verificare i
pagamenti on-chain. Il pacchetto è progettato per funzionare in qualsiasi
ambiente JavaScript: React, Vue, Svelte, vanilla JS, Node.js o funzioni
serverless.
Installazione
pnpm add @solana-commerce/headless
Funzioni di Richiesta Pagamento
Queste funzioni creano oggetti di richiesta pagamento standardizzati per diversi pattern commerce. Non eseguono operazioni blockchain—strutturano semplicemente i dati per l'uso in wallet, URL Solana Pay o interfacce di pagamento personalizzate.
createBuyNowRequest()
Crea una richiesta di pagamento standardizzata per l'acquisto di un singolo prodotto.
function createBuyNowRequest(recipient: string,product: any,options?: {memo?: string;label?: string;message?: string;}): PaymentRequest;
Parametri
-
recipient(string, obbligatorio) - Indirizzo wallet del commerciante (chiave pubblica Solana codificata in base58) che riceverà il pagamento. -
product(any, obbligatorio) - Oggetto prodotto contenente:price(numero, obbligatorio) - Prezzo del prodotto. L'unità dipende dal contesto (ad es., lamport per SOL, unità minori per i token).currency(stringa, obbligatoria) - Valuta di pagamento. Può essere'SOL'o un indirizzo mint del token.name(stringa, obbligatoria) - Nome del prodotto, utilizzato per memo/etichetta predefinita se non fornita.- Campi aggiuntivi (id, description, image, ecc.) vengono passati nell'array
products.
-
options(oggetto, facoltativo) - Opzioni di personalizzazione:memo(stringa) - Memo on-chain per la transazione. Predefinito:"Purchase: {product.name}".label(stringa) - Etichetta di visualizzazione per la richiesta di pagamento (usata in Solana Pay). Predefinito:product.name.message(stringa) - Messaggio di successo mostrato dopo il pagamento. Predefinito:"Thank you for purchasing {product.name}!".
Valore di Ritorno
Un oggetto PaymentRequest contenente:
recipient- L'indirizzo wallet del commercianteamount- Il prezzo del prodotto (copiato daproduct.price)currency- Valuta di pagamento (copiata daproduct.currency)products- Array contenente il singolo prodottomemo- Memo della transazione (opzione o predefinito: "Acquisto: (product.name)")label- Etichetta di pagamento (opzione o predefinito: "product.name")message- Messaggio di successo (opzione o predefinito: "Grazie per aver acquistato (product.name)!")
Esempio:
const payment = createBuyNowRequest("merchant-wallet-address",{id: "prod_123",name: "Premium Subscription",price: 50000000, // 0.05 SOL in lamportscurrency: "SOL"},{label: "Premium Subscription",message: "Thank you for subscribing!"});
createCartRequest()
Crea una richiesta di pagamento per più prodotti in un carrello.
function createCartRequest(recipient: string,products: any[],options?: {memo?: string;label?: string;message?: string;currency?: string;}): PaymentRequest;
Parametri
-
recipient(string, obbligatorio) - Indirizzo del wallet del commerciante che riceverà il pagamento. -
products(any[], obbligatorio) - Array di oggetti prodotto. -
options(object, facoltativo) - Opzioni di personalizzazione:currency(string) - Valuta di pagamento per l'intero carrello.memo(string) - Memo on-chain. Predefinito:"Cart purchase (products.length items)".label(string) - Etichetta del pagamento. Predefinito:"Cart Checkout".message(string) - Messaggio di successo. Predefinito:"Thank you for your purchase!".
Restituisce
Un oggetto PaymentRequest con:
recipient- L'indirizzo del wallet del commercianteamount- Somma di tutti i prezzi dei prodotti (products.reduce((sum, p) => sum + p.price, 0))currency- Valuta di pagamento (da options, o undefined)products- L'array dei prodottimemo,label,message- Valori delle opzioni o predefiniti
Esempio:
const cart = createCartRequest("merchant-wallet-address",[{ id: "1", name: "Product A", price: 25 },{ id: "2", name: "Product B", price: 15 },{ id: "3", name: "Product C", price: 10 }],{currency: "USDC",label: "My Store Checkout",message: "Thank you for your order!"});// cart.amount === 50 (sum of prices)
createTipRequest()
Crea una richiesta di pagamento per mance o donazioni con un importo definito dall'utente.
function createTipRequest(recipient: string,amount: number,options?: {currency?: string;memo?: string;label?: string;message?: string;}): PaymentRequest;
Parametri
-
recipient(string, obbligatorio) - Indirizzo del wallet del destinatario della mancia (creatore, streamer, ente benefico, ecc.). -
amount(number, obbligatorio) - Importo della mancia. L'unità dipende dalla valuta (lamport per SOL, unità minori per i token). -
options(object, facoltativo) - Opzioni di personalizzazione:currency(string) - Valuta di pagamento. Predefinito: undefined (tipicamente trattato come SOL dai consumatori).memo(string) - Memo on-chain. Predefinito:"Thank you for your support!".label(string) - Etichetta del pagamento. Predefinito:"Tip".message(string) - Messaggio di successo. Predefinito:"Thanks for the tip!".
Restituisce
Un oggetto PaymentRequest con:
recipient- L'indirizzo del wallet del destinatario della manciaamount- L'importo della manciacurrency- Valuta di pagamento (da options, o undefined)memo,label,message- Valori delle opzioni o predefiniti
Esempio:
const tip = createTipRequest("creator-wallet-address",5_000_000, // 0.005 SOL in lamports{currency: "SOL",label: "Tip for Content Creator",message: "Thanks for the support!"});
Funzioni di Verifica Pagamento
Queste funzioni interagiscono con Solana per verificare le transazioni e
attendere le conferme. Richiedono un client RPC Solana dalla libreria gill.
verifyPayment()
Verifica che una transazione esista on-chain e opzionalmente convalida l'importo del pagamento, il destinatario e il token.
async function verifyPayment(rpc: SolanaClient["rpc"],signatureString: string,expectedAmount?: number,expectedRecipient?: string,expectedMint?: string): Promise<PaymentVerificationResult>;
Parametri
-
rpc(SolanaClient['rpc'], obbligatorio) - Client RPC dagill. Creare concreateSolanaClient(rpcUrl).rpc. -
signatureString(string, obbligatorio) - Firma della transazione (codificata in base58) da verificare. -
expectedAmount(number, facoltativo) - Importo di pagamento previsto da convalidare. L'unità deve corrispondere alla valuta:- Per SOL: lamport (1 SOL = 1.000.000.000 lamport)
- Per token SPL: unità minori basate sui decimali del token (es. USDC usa 6 decimali)
Se non fornito, la convalida dell'importo viene saltata.
-
expectedRecipient(string, facoltativo) - Indirizzo del wallet del destinatario previsto. Se fornito (insieme aexpectedAmount), la funzione convalida che il destinatario abbia ricevuto almeno questo importo. Se non fornito, la convalida viene saltata. -
expectedMint(string, facoltativo) - Indirizzo mint del token SPL. Richiesto solo per trasferimenti di token SPL. Se non fornito, la funzione presume un trasferimento SOL.
Valore Restituito
Un oggetto Promise<PaymentVerificationResult>:
interface PaymentVerificationResult {verified: boolean; // True if payment is validsignature?: string; // Transaction signature (echoed back)amount?: number; // Expected amount (echoed back)recipient?: string; // Expected recipient (echoed back)error?: string; // Error message if verification failed}
Logica di Verifica
La funzione esegue questi controlli:
-
Validità della Firma: Verifica che la firma sia valida.
-
Esistenza della Transazione: Recupera la transazione usando
rpc.getTransaction(). Se non trovata, restituisceverified: false. -
Stato di Conferma: Verifica che la transazione sia stata confermata on-chain.
-
Convalida Trasferimento SOL (se
expectedRecipienteexpectedAmountsono forniti, e nessunexpectedMint):- Trova l'indice dell'account del destinatario nella transazione
- Confronta
preBalancesepostBalancesper calcolare il delta del saldo - Verifica che il delta sia almeno
expectedAmount
-
Validazione Trasferimento Token SPL (se
expectedMintfornito):- Deriva l'Associated Token Account (ATA) del destinatario sia per il Token Program che per il Token-2022 Program
- Controlla
postTokenBalancesper un ATA corrispondente con il mint previsto - Verifica che l'importo del token sia almeno
expectedAmount
Considerazioni sulla Sicurezza
- Verifica Lato Client: Questa funzione recupera i dati della transazione da RPC. Non esporre il tuo URL RPC al client.
- Finalizzazione: La funzione controlla le transazioni confermate, ma per
pagamenti di alto valore, considera di attendere lo stato
finalized.
Esempio:
import { verifyPayment } from "@solana-commerce/headless";import { createSolanaClient } from "gill";const client = createSolanaClient({urlOrMoniker: "mainnet"});const result = await verifyPayment(client.rpc,"transaction-signature-here",50_000_000, // 0.05 SOL in lamports"merchant-wallet-address"// No mint = SOL transfer);if (result.verified) {console.log("Payment confirmed!");} else {console.error("Verification failed:", result.error);}
waitForConfirmation()
Interroga la blockchain finché una transazione non raggiunge lo stato confermato o finalizzato, o va in timeout.
async function waitForConfirmation(rpc: SolanaClient["rpc"],signatureStr: string,timeoutMs?: number): Promise<boolean>;
Parametri
-
rpc(SolanaClient['rpc'], obbligatorio) - Client RPC dagill. -
signatureStr(string, obbligatorio) - Firma della transazione da attendere. -
timeoutMs(number, facoltativo) - Tempo massimo di attesa in millisecondi. Predefinito:30000(30 secondi).
Restituisce
Promise<boolean>- Restituiscetruese la transazione raggiunge lo statoconfirmedofinalizedentro il timeout, altrimentifalse.
Esempio:
import { waitForConfirmation } from "@solana-commerce/headless";import { createSolanaClient } from "gill";const client = createSolanaClient({urlOrMoniker: "mainnet"});// After sending transactionconst signature = await wallet.sendTransaction(transaction);// Wait for confirmation (30 second timeout)const confirmed = await waitForConfirmation(client.rpc, signature, 30000);if (confirmed) {console.log("Transaction confirmed!");} else {console.log("Timeout - transaction not confirmed within 30 seconds");}
Funzioni Solana Pay
Queste funzioni generano URL Solana Pay e codici QR stilizzati per la scansione da wallet mobile.
createSolanaPayRequest()
Crea un URL Solana Pay e un codice QR stilizzato.
async function createSolanaPayRequest(request: TransferRequestURLFields,options: SolanaPayRequestOptions): Promise<{ url: URL; qr: string }>;
Parametri
-
request(TransferRequestURLFields, obbligatorio) - Campi della richiesta di trasferimento Solana Pay:recipient- Chiave pubblica del destinatario (usacreateRecipient(address)da@solana-commerce/solana-pay)amount- (facoltativo) Importo del pagamento in unità minori (lamport per SOL)splToken(facoltativo) - Chiave pubblica del mint del token SPL (usacreateSPLToken(address))reference(facoltativo) - Chiave pubblica di riferimento per il tracciamentolabel(facoltativo) - Nome del commerciantemessage(facoltativo) - Messaggio di successomemo(facoltativo) - Memo on-chain
-
options(SolanaPayRequestOptions, obbligatorio) - Opzioni di stile del codice QR:size(numero) - Larghezza/altezza del codice QR in pixel. Predefinito:256.background(stringa) - Colore di sfondo (hex/rgb). Predefinito:'white'.color(stringa) - Colore del codice QR (hex/rgb). Predefinito:'black'.margin(numero) - Margine intorno al codice QR in moduli.errorCorrectionLevel('L' | 'M' | 'Q' | 'H') - Livello di correzione degli errori. Livelli più alti consentono maggiori danni ma creano codici più densi.logo(stringa) - URL dell'immagine del logo da incorporare al centro del codice QR.logoSize(numero) - Dimensione del logo come percentuale della dimensione del codice QR.logoBackgroundColor(stringa) - Colore di sfondo dietro il logo.logoMargin(numero) - Margine intorno al logo.dotStyle('dots' | 'rounded' | 'square') - Forma dei moduli del codice QR.cornerStyle('square' | 'rounded' | 'extra-rounded' | 'full-rounded' | 'maximum-rounded') - Forma dei marcatori d'angolo.
Valori Restituiti
Una Promise che si risolve in un oggetto:
url(URL) - URL Solana Pay (ad es.,solana:recipient?amount=10&spl-token=...)qr(stringa) - URL dei dati con codifica Base64 dell'immagine del codice QR (da usare come<img src={qr} />)
Esempio:
import {createSolanaPayRequest,createRecipient,createSPLToken} from "@solana-commerce/solana-pay";const payment = await createSolanaPayRequest({recipient: createRecipient("merchant-wallet-address"),amount: 10_000_000, // 0.01 SOL in lamportssplToken: createSPLToken("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"), // USDClabel: "My Store",message: "Thank you for your purchase!"},{size: 400,background: "#FFFFFF",color: "#000000",logo: "/logo.png",logoSize: 20,errorCorrectionLevel: "H"});// Display QR codedocument.getElementById("qr").src = payment.qr;console.log(payment.url.toString()); // solana:merchant...?amount=10000000&spl-token=...
Is this page helpful?