Zahlungsabläufe
Das Paket @solana-commerce/headless bietet Framework-unabhängige Funktionen
zum Erstellen von Commerce-Zahlungsabläufen. Diese Tools helfen beim Erstellen
von Zahlungsanforderungsobjekten, beim Generieren von Solana Pay-URLs und beim
Verifizieren von On-Chain-Zahlungen. Das Paket ist so konzipiert, dass es in
jeder JavaScript-Umgebung funktioniert: React, Vue, Svelte, Vanilla JS, Node.js
oder serverlose Funktionen.
Installation
pnpm add @solana-commerce/headless
Zahlungsanforderungsfunktionen
Diese Funktionen erstellen standardisierte Zahlungsanforderungsobjekte für verschiedene Commerce-Muster. Sie führen keine Blockchain-Operationen durch – sie strukturieren lediglich Daten zur Verwendung in Wallets, Solana Pay-URLs oder benutzerdefinierten Zahlungs-UIs.
createBuyNowRequest()
Erstellt eine standardisierte Zahlungsanforderung für den Kauf eines einzelnen Produkts.
function createBuyNowRequest(recipient: string,product: any,options?: {memo?: string;label?: string;message?: string;}): PaymentRequest;
Parameter
-
recipient(string, erforderlich) - Händler-Wallet-Adresse (base58-kodierter Solana-Public-Key), die die Zahlung erhält. -
product(any, erforderlich) - Produktobjekt mit:price(number, erforderlich) - Produktpreis. Die Einheit hängt vom Kontext ab (z. B. lamport für SOL, Untereinheiten für Token).currency(string, erforderlich) - Zahlungswährung. Kann'SOL'oder eine Token-Mint-Adresse sein.name(string, erforderlich) - Produktname, wird für Standard-Memo/Label verwendet, falls nicht angegeben.- Zusätzliche Felder (id, description, image, etc.) werden im
products-Array weitergegeben.
-
options(object, optional) - Anpassungsoptionen:memo(string) - On-Chain-Memo für die Transaktion. Standard:"Purchase: {product.name}".label(string) - Anzeigelabel für die Zahlungsanforderung (verwendet in Solana Pay). Standard:product.name.message(string) - Erfolgsmeldung, die nach der Zahlung angezeigt wird. Standard:"Thank you for purchasing {product.name}!".
Rückgabewert
Ein PaymentRequest-Objekt mit:
recipient- Die Händler-Wallet-Adresseamount- Der Produktpreis (kopiert vonproduct.price)currency- Zahlungswährung (kopiert vonproduct.currency)products- Array mit dem einzelnen Produktmemo- Transaktions-Memo (Option oder Standard: "Kauf: (product.name)")label- Zahlungslabel (Option oder Standard: "product.name")message- Erfolgsmeldung (Option oder Standard: "Vielen Dank für den Kauf von (product.name)!")
Beispiel:
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()
Erstellt eine Zahlungsanfrage für mehrere Produkte in einem Warenkorb.
function createCartRequest(recipient: string,products: any[],options?: {memo?: string;label?: string;message?: string;currency?: string;}): PaymentRequest;
Parameter
-
recipient(string, erforderlich) - Wallet-Adresse des Händlers, die die Zahlung erhalten wird. -
products(any[], erforderlich) - Array von Produktobjekten. -
options(Objekt, optional) - Anpassungsoptionen:currency(String) - Zahlungswährung für den gesamten Warenkorb.memo(String) - On-Chain-Memo. Standard:"Cart purchase (products.length items)".label(String) - Zahlungsbezeichnung. Standard:"Cart Checkout".message(String) - Erfolgsmeldung. Standard:"Thank you for your purchase!".
Rückgabewert
Ein PaymentRequest-Objekt mit:
recipient- Die Wallet-Adresse des Händlersamount- Summe aller Produktpreise (products.reduce((sum, p) => sum + p.price, 0))currency- Zahlungswährung (aus Optionen oder undefined)products- Das Array von Produktenmemo,label,message- Optionswerte oder Standardwerte
Beispiel:
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()
Erstellt eine Zahlungsanfrage für Trinkgelder oder Spenden mit einem vom Benutzer definierten Betrag.
function createTipRequest(recipient: string,amount: number,options?: {currency?: string;memo?: string;label?: string;message?: string;}): PaymentRequest;
Parameter
-
recipient(string, erforderlich) - Wallet-Adresse des Trinkgeldempfängers (Creator, Streamer, Wohltätigkeitsorganisation usw.). -
amount(number, erforderlich) - Trinkgeldbetrag. Die Einheit hängt von der Währung ab (Lamports für SOL, Untereinheiten für Token). -
options(Objekt, optional) - Anpassungsoptionen:currency(String) - Zahlungswährung. Standard: undefined (wird typischerweise von Verbrauchern als SOL behandelt).memo(String) - On-Chain-Memo. Standard:"Thank you for your support!".label(String) - Zahlungsbezeichnung. Standard:"Tip".message(String) - Erfolgsmeldung. Standard:"Thanks for the tip!".
Rückgabewert
Ein PaymentRequest-Objekt mit:
recipient- Die Wallet-Adresse des Trinkgeldempfängersamount- Der Trinkgeldbetragcurrency- Zahlungswährung (aus Optionen oder undefined)memo,label,message- Optionswerte oder Standardwerte
Beispiel:
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!"});
Funktionen zur Zahlungsverifizierung
Diese Funktionen interagieren mit Solana, um Transaktionen zu verifizieren und
auf Bestätigungen zu warten. Sie benötigen einen Solana RPC-Client aus der
gill-Bibliothek.
verifyPayment()
Überprüft, ob eine Transaktion on-chain existiert und validiert optional den Zahlungsbetrag, den Empfänger und den Token.
async function verifyPayment(rpc: SolanaClient["rpc"],signatureString: string,expectedAmount?: number,expectedRecipient?: string,expectedMint?: string): Promise<PaymentVerificationResult>;
Parameter
-
rpc(SolanaClient['rpc'], erforderlich) - RPC-Client ausgill. Erstellen Sie diesen mitcreateSolanaClient(rpcUrl).rpc. -
signatureString(string, erforderlich) - Zu verifizierende Transaktionssignatur (base58-kodiert). -
expectedAmount(number, optional) - Erwarteter Zahlungsbetrag zur Validierung. Die Einheit sollte der Währung entsprechen:- Für SOL: lamport (1 SOL = 1.000.000.000 lamport)
- Für SPL-Token: Kleinste Einheiten basierend auf den Token-Dezimalstellen (z. B. verwendet USDC 6 Dezimalstellen)
Falls nicht angegeben, wird die Betragsvalidierung übersprungen.
-
expectedRecipient(string, optional) - Erwartete Empfänger-Wallet-Adresse. Falls angegeben (zusammen mitexpectedAmount), validiert die Funktion, dass der Empfänger mindestens diesen Betrag erhalten hat. Falls nicht angegeben, wird die Validierung übersprungen. -
expectedMint(string, optional) - SPL-Token-Mint-Adresse. Nur erforderlich für SPL-Token-Transfers. Falls nicht angegeben, geht die Funktion von einem SOL-Transfer aus.
Rückgabewert
Ein Promise<PaymentVerificationResult>-Objekt:
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}
Verifizierungslogik
Die Funktion führt folgende Prüfungen durch:
-
Signatur-Gültigkeit: Überprüft, dass die Signatur gültig ist.
-
Transaktionsexistenz: Ruft die Transaktion mit
rpc.getTransaction()ab. Falls nicht gefunden, gibtverified: falsezurück. -
Bestätigungsstatus: Überprüft, dass die Transaktion on-chain gelandet ist.
-
SOL-Transfer-Validierung (falls
expectedRecipientundexpectedAmountangegeben sind und keinexpectedMint):- Findet den Konten-Index des Empfängers in der Transaktion
- Vergleicht
preBalancesundpostBalances, um die Saldodifferenz zu berechnen - Überprüft, dass die Differenz mindestens
expectedAmountbeträgt
-
SPL Token Transfer Validierung (falls
expectedMintbereitgestellt):- Leitet das Associated Token Account (ATA) des Empfängers sowohl für das Token Program als auch für das Token-2022 Program ab
- Prüft
postTokenBalancesauf ein übereinstimmendes ATA mit der erwarteten Mint - Verifiziert, dass der Token-Betrag mindestens
expectedAmountbeträgt
Sicherheitserwägungen
- Client-seitige Verifizierung: Diese Funktion ruft Transaktionsdaten vom RPC ab. Legen Sie Ihre RPC-URL nicht gegenüber dem Client offen.
- Finalisierung: Die Funktion prüft auf bestätigte Transaktionen, aber bei
hochwertige Zahlungen sollten Sie erwägen, auf den
finalized-Status zu warten.
Beispiel:
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()
Fragt die Blockchain ab, bis eine Transaktion den Status "confirmed" oder "finalized" erreicht oder ein Timeout auftritt.
async function waitForConfirmation(rpc: SolanaClient["rpc"],signatureStr: string,timeoutMs?: number): Promise<boolean>;
Parameter
-
rpc(SolanaClient['rpc'], erforderlich) - RPC-Client vongill. -
signatureStr(string, erforderlich) - Transaktionssignatur, auf die gewartet werden soll. -
timeoutMs(number, optional) - Maximale Wartezeit in Millisekunden. Standard:30000(30 Sekunden).
Rückgabewert
Promise<boolean>- Gibttruezurück, wenn die Transaktion den Statusconfirmedoderfinalizedinnerhalb des Timeouts erreicht, andernfallsfalse.
Beispiel:
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");}
Solana Pay Funktionen
Diese Funktionen generieren Solana Pay URLs und gestylte QR-Codes zum Scannen mit mobilen Wallets.
createSolanaPayRequest()
Erstellt eine Solana Pay URL und einen gestylten QR-Code.
async function createSolanaPayRequest(request: TransferRequestURLFields,options: SolanaPayRequestOptions): Promise<{ url: URL; qr: string }>;
Parameter
-
request(TransferRequestURLFields, erforderlich) - Solana Pay Transfer- Anforderungsfelder:recipient- Öffentlicher Schlüssel des Empfängers (verwenden SiecreateRecipient(address)von@solana-commerce/solana-pay)amount- (optional) Zahlungsbetrag in kleinsten Einheiten (Lamports für SOL)splToken(optional) - Öffentlicher Schlüssel der SPL-Token-Mint (verwenden SiecreateSPLToken(address))reference(optional) - Referenz-öffentlicher Schlüssel zur Nachverfolgunglabel(optional) - Name des Händlersmessage(optional) - Erfolgsmeldungmemo(optional) - On-Chain-Memo
-
options(SolanaPayRequestOptions, erforderlich) - QR-Code-Styling-Optionen:size(number) - QR-Code-Breite/-Höhe in Pixeln. Standard:256.background(string) - Hintergrundfarbe (hex/rgb). Standard:'white'.color(string) - QR-Code-Farbe (hex/rgb). Standard:'black'.margin(number) - Rand um den QR-Code in Modulen.errorCorrectionLevel('L' | 'M' | 'Q' | 'H') - Fehlerkorrekturlevel. Höhere Level ermöglichen mehr Beschädigungen, erzeugen aber dichtere Codes.logo(string) - Logo-Bild-URL zur Einbettung in der Mitte des QR-Codes.logoSize(number) - Logo-Größe als Prozentsatz der QR-Code-Größe.logoBackgroundColor(string) - Hintergrundfarbe hinter dem Logo.logoMargin(number) - Rand um das Logo.dotStyle('dots' | 'rounded' | 'square') - Form der QR-Code-Module.cornerStyle('square' | 'rounded' | 'extra-rounded' | 'full-rounded' | 'maximum-rounded') - Form der Eckmarkierungen.
Rückgabewert
Ein Promise, das zu einem Objekt aufgelöst wird:
url(URL) - Solana Pay URL (z. B.solana:recipient?amount=10&spl-token=...)qr(string) - Base64-kodierte Daten-URL des QR-Code-Bildes (als<img src={qr} />verwenden)
Beispiel:
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?