Przepływy płatności
Pakiet @solana-commerce/headless dostarcza niezależne od frameworka funkcje do
budowania przepływów płatności w handlu elektronicznym. Te narzędzia pomagają
tworzyć obiekty żądań płatności, generować adresy URL Solana Pay oraz
weryfikować płatności on-chain. Pakiet jest projektowany do działania w każdym
środowisku JavaScript: React, Vue, Svelte, vanilla JS, Node.js lub funkcje
bezserwerowe.
Instalacja
pnpm add @solana-commerce/headless
Funkcje żądań płatności
Te funkcje tworzą ustandaryzowane obiekty żądań płatności dla różnych wzorców handlowych. Nie wykonują żadnych operacji blockchain — po prostu strukturyzują dane do użycia w portfelach, adresach URL Solana Pay lub niestandardowych interfejsach płatności.
createBuyNowRequest()
Tworzy ustandaryzowane żądanie płatności dla zakupu pojedynczego produktu.
function createBuyNowRequest(recipient: string,product: any,options?: {memo?: string;label?: string;message?: string;}): PaymentRequest;
Parametry
-
recipient(string, wymagany) - Adres portfela sprzedawcy (zakodowany w base58 klucz publiczny Solana), który otrzyma płatność. -
product(any, wymagany) - Obiekt produktu zawierający:price(number, wymagany) - Cena produktu. Jednostka zależy od kontekstu (np. lamporty dla SOL, mniejsze jednostki dla tokenów).currency(string, wymagany) - Waluta płatności. Może być'SOL'lub adresem mint tokena.name(string, wymagany) - Nazwa produktu, używana jako domyślne memo/etykieta, jeśli nie została podana.- Dodatkowe pola (id, description, image, itp.) są przekazywane w tablicy
products.
-
options(object, opcjonalny) - Opcje personalizacji:memo(string) - Memo on-chain dla transakcji. Domyślnie:"Purchase: {product.name}".label(string) - Etykieta wyświetlana dla żądania płatności (używana w Solana Pay). Domyślnie:product.name.message(string) - Komunikat sukcesu wyświetlany po płatności. Domyślnie:"Thank you for purchasing {product.name}!".
Zwraca
Obiekt PaymentRequest zawierający:
recipient- Adres portfela sprzedawcyamount- Cena produktu (skopiowana zproduct.price)currency- Waluta płatności (skopiowana zproduct.currency)products- Tablica zawierająca pojedynczy produktmemo- Memo transakcji (opcja lub domyślnie: "Zakup: (product.name)")label- Etykieta płatności (opcja lub domyślnie: "product.name")message- Komunikat sukcesu (opcja lub domyślnie: "Dziękujemy za zakup (product.name)!")
Przykład:
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()
Tworzy żądanie płatności dla wielu produktów w koszyku zakupowym.
function createCartRequest(recipient: string,products: any[],options?: {memo?: string;label?: string;message?: string;currency?: string;}): PaymentRequest;
Parametry
-
recipient(string, wymagany) - Adres portfela sprzedawcy, który otrzyma płatność. -
products(any[], wymagany) - Tablica obiektów produktów. -
options(obiekt, opcjonalny) - Opcje dostosowania:currency(ciąg znaków) - Waluta płatności dla całego koszyka.memo(ciąg znaków) - Notatka on-chain. Domyślnie:"Cart purchase (products.length items)".label(ciąg znaków) - Etykieta płatności. Domyślnie:"Cart Checkout".message(ciąg znaków) - Komunikat o sukcesie. Domyślnie:"Thank you for your purchase!".
Zwraca
Obiekt PaymentRequest zawierający:
recipient- Adres portfela sprzedawcyamount- Suma cen wszystkich produktów (products.reduce((sum, p) => sum + p.price, 0))currency- Waluta płatności (z opcji lub undefined)products- Tablica produktówmemo,label,message- Wartości opcji lub wartości domyślne
Przykład:
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()
Tworzy żądanie płatności dla napiwków lub darowizn z kwotą określoną przez użytkownika.
function createTipRequest(recipient: string,amount: number,options?: {currency?: string;memo?: string;label?: string;message?: string;}): PaymentRequest;
Parametry
-
recipient(string, wymagany) - Adres portfela odbiorcy napiwku (twórcy, streamera, organizacji charytatywnej itp.). -
amount(number, wymagany) - Kwota napiwku. Jednostka zależy od waluty (lamporty dla SOL, jednostki minimalne dla tokenów). -
options(obiekt, opcjonalny) - Opcje dostosowania:currency(ciąg znaków) - Waluta płatności. Domyślnie: undefined (zazwyczaj traktowane jako SOL przez konsumentów).memo(ciąg znaków) - Notatka on-chain. Domyślnie:"Thank you for your support!".label(ciąg znaków) - Etykieta płatności. Domyślnie:"Tip".message(ciąg znaków) - Komunikat o sukcesie. Domyślnie:"Thanks for the tip!".
Zwraca
Obiekt PaymentRequest zawierający:
recipient- Adres portfela odbiorcy napiwkuamount- Kwota napiwkucurrency- Waluta płatności (z opcji lub undefined)memo,label,message- Wartości opcji lub wartości domyślne
Przykład:
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!"});
Funkcje Weryfikacji Płatności
Te funkcje współpracują z Solaną w celu weryfikacji transakcji i oczekiwania na
potwierdzenia. Wymagają klienta RPC Solana z biblioteki gill.
verifyPayment()
Weryfikuje, że transakcja istnieje w łańcuchu i opcjonalnie waliduje kwotę płatności, odbiorcę oraz token.
async function verifyPayment(rpc: SolanaClient["rpc"],signatureString: string,expectedAmount?: number,expectedRecipient?: string,expectedMint?: string): Promise<PaymentVerificationResult>;
Parametry
-
rpc(SolanaClient['rpc'], wymagany) - Klient RPC zgill. Utwórz za pomocącreateSolanaClient(rpcUrl).rpc. -
signatureString(string, wymagany) - Sygnatura transakcji (zakodowana w base58) do weryfikacji. -
expectedAmount(number, opcjonalny) - Oczekiwana kwota płatności do walidacji. Jednostka powinna być zgodna z walutą:- Dla SOL: lamporty (1 SOL = 1 000 000 000 lamportów)
- Dla tokenów SPL: jednostki pomocnicze oparte na liczbie miejsc dziesiętnych tokena (np. USDC używa 6 miejsc dziesiętnych)
Jeśli nie podano, walidacja kwoty jest pomijana.
-
expectedRecipient(string, opcjonalny) - Oczekiwany adres portfela odbiorcy. Jeśli podany (wraz zexpectedAmount), funkcja sprawdza, czy odbiorca otrzymał co najmniej tę kwotę. Jeśli nie podano, walidacja jest pomijana. -
expectedMint(string, opcjonalny) - Adres mint tokena SPL. Wymagany tylko dla transferów tokenów SPL. Jeśli nie podano, funkcja zakłada transfer SOL.
Zwracana wartość
Obiekt 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}
Logika Weryfikacji
Funkcja wykonuje następujące sprawdzenia:
-
Poprawność sygnatury: Sprawdza, czy sygnatura jest poprawna.
-
Istnienie transakcji: Pobiera transakcję za pomocą
rpc.getTransaction(). Jeśli nie zostanie znaleziona, zwracaverified: false. -
Status potwierdzenia: Sprawdza, czy transakcja została zarejestrowana w łańcuchu.
-
Walidacja transferu SOL (jeśli podano
expectedRecipientiexpectedAmountoraz brakexpectedMint):- Znajduje indeks konta odbiorcy w transakcji
- Porównuje
preBalancesipostBalances, aby obliczyć zmianę salda - Weryfikuje, czy zmiana wynosi co najmniej
expectedAmount
-
Walidacja transferu tokena SPL (jeśli podano
expectedMint):- Wyprowadza Associated Token Account (ATA) odbiorcy zarówno dla Token Program, jak i Token-2022 Program
- Sprawdza
postTokenBalancesw poszukiwaniu pasującego ATA z oczekiwanym mintem - Weryfikuje, czy kwota tokena wynosi co najmniej
expectedAmount
Kwestie bezpieczeństwa
- Weryfikacja po stronie klienta: Ta funkcja pobiera dane transakcji z RPC. Nie udostępniaj swojego URL RPC klientowi.
- Finalizacja: Funkcja sprawdza potwierdzone transakcje, ale w przypadku
płatności o wysokiej wartości rozważ oczekiwanie na status
finalized.
Przykład:
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()
Odpytuje blockchain, aż transakcja osiągnie status potwierdzony lub sfinalizowany, lub upłynie limit czasu.
async function waitForConfirmation(rpc: SolanaClient["rpc"],signatureStr: string,timeoutMs?: number): Promise<boolean>;
Parametry
-
rpc(SolanaClient['rpc'], wymagany) - Klient RPC zgill. -
signatureStr(string, wymagany) - Sygnatura transakcji, na którą należy czekać. -
timeoutMs(number, opcjonalny) - Maksymalny czas oczekiwania w milisekundach. Domyślnie:30000(30 sekund).
Zwraca
Promise<boolean>- Zwracatrue, jeśli transakcja osiągnie statusconfirmedlubfinalizedw określonym limicie czasu, w przeciwnym raziefalse.
Przykład:
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");}
Funkcje Solana Pay
Te funkcje generują URL-e Solana Pay oraz stylizowane kody QR do skanowania przez mobilne portfele.
createSolanaPayRequest()
Tworzy URL Solana Pay oraz stylizowany kod QR.
async function createSolanaPayRequest(request: TransferRequestURLFields,options: SolanaPayRequestOptions): Promise<{ url: URL; qr: string }>;
Parametry
-
request(TransferRequestURLFields, wymagany) - Pola żądania transferu Solana Pay:recipient- Klucz publiczny odbiorcy (użyjcreateRecipient(address)z@solana-commerce/solana-pay)amount- (opcjonalnie) Kwota płatności w jednostkach minimalnych (lamporty dla SOL)splToken(opcjonalnie) - Klucz publiczny minta tokena SPL (użyjcreateSPLToken(address))reference(opcjonalnie) - Klucz publiczny referencyjny do śledzenialabel(opcjonalnie) - Nazwa sprzedawcymessage(opcjonalnie) - Komunikat o sukcesiememo(opcjonalnie) - Notatka on-chain
-
options(SolanaPayRequestOptions, wymagane) - Opcje stylizacji kodu QR:size(liczba) - Szerokość/wysokość kodu QR w pikselach. Domyślnie:256.background(ciąg znaków) - Kolor tła (hex/rgb). Domyślnie:'white'.color(ciąg znaków) - Kolor kodu QR (hex/rgb). Domyślnie:'black'.margin(liczba) - Margines wokół kodu QR w modułach.errorCorrectionLevel('L' | 'M' | 'Q' | 'H') - Poziom korekcji błędów. Wyższe poziomy pozwalają na większe uszkodzenia, ale tworzą gęstsze kody.logo(ciąg znaków) - Adres URL obrazu logo do osadzenia w centrum kodu QR.logoSize(liczba) - Rozmiar logo jako procent rozmiaru kodu QR.logoBackgroundColor(ciąg znaków) - Kolor tła za logo.logoMargin(liczba) - Margines wokół logo.dotStyle('dots' | 'rounded' | 'square') - Kształt modułów kodu QR.cornerStyle('square' | 'rounded' | 'extra-rounded' | 'full-rounded' | 'maximum-rounded') - Kształt znaczników narożnych.
Zwracana wartość
Promise rozwiązująca się do obiektu:
url(URL) - Adres URL Solana Pay (np.solana:recipient?amount=10&spl-token=...)qr(ciąg znaków) - Zakodowany w Base64 adres URL danych obrazu kodu QR (użyj jako<img src={qr} />)
Przykład:
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?