Flussi di Pagamento Headless

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 commerciante
  • amount - Il prezzo del prodotto (copiato da product.price)
  • currency - Valuta di pagamento (copiata da product.currency)
  • products - Array contenente il singolo prodotto
  • memo - 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 lamports
currency: "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 commerciante
  • amount - 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 prodotti
  • memo, 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 mancia
  • amount - L'importo della mancia
  • currency - 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 da gill. Creare con createSolanaClient(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 a expectedAmount), 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 valid
signature?: 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:

  1. Validità della Firma: Verifica che la firma sia valida.

  2. Esistenza della Transazione: Recupera la transazione usando rpc.getTransaction(). Se non trovata, restituisce verified: false.

  3. Stato di Conferma: Verifica che la transazione sia stata confermata on-chain.

  4. Convalida Trasferimento SOL (se expectedRecipient e expectedAmount sono forniti, e nessun expectedMint):

    • Trova l'indice dell'account del destinatario nella transazione
    • Confronta preBalances e postBalances per calcolare il delta del saldo
    • Verifica che il delta sia almeno expectedAmount
  5. Validazione Trasferimento Token SPL (se expectedMint fornito):

    • Deriva l'Associated Token Account (ATA) del destinatario sia per il Token Program che per il Token-2022 Program
    • Controlla postTokenBalances per 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 da gill.

  • signatureStr (string, obbligatorio) - Firma della transazione da attendere.

  • timeoutMs (number, facoltativo) - Tempo massimo di attesa in millisecondi. Predefinito: 30000 (30 secondi).

Restituisce

  • Promise<boolean> - Restituisce true se la transazione raggiunge lo stato confirmed o finalized entro il timeout, altrimenti false.

Esempio:

import { waitForConfirmation } from "@solana-commerce/headless";
import { createSolanaClient } from "gill";
const client = createSolanaClient({
urlOrMoniker: "mainnet"
});
// After sending transaction
const 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 (usa createRecipient(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 (usa createSPLToken(address))
    • reference (facoltativo) - Chiave pubblica di riferimento per il tracciamento
    • label (facoltativo) - Nome del commerciante
    • message (facoltativo) - Messaggio di successo
    • memo (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 lamports
splToken: createSPLToken("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"), // USDC
label: "My Store",
message: "Thank you for your purchase!"
},
{
size: 400,
background: "#FFFFFF",
color: "#000000",
logo: "/logo.png",
logoSize: 20,
errorCorrectionLevel: "H"
}
);
// Display QR code
document.getElementById("qr").src = payment.qr;
console.log(payment.url.toString()); // solana:merchant...?amount=10000000&spl-token=...

Is this page helpful?

Gestito da

© 2026 Solana Foundation.
Tutti i diritti riservati.
Resta connesso