Bezgłowe przepływy płatności

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 sprzedawcy
  • amount - Cena produktu (skopiowana z product.price)
  • currency - Waluta płatności (skopiowana z product.currency)
  • products - Tablica zawierająca pojedynczy produkt
  • memo - 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 lamports
currency: "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 sprzedawcy
  • amount - 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ów
  • memo, 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 napiwku
  • amount - Kwota napiwku
  • currency - 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 z gill. 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 z expectedAmount), 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 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
}

Logika Weryfikacji

Funkcja wykonuje następujące sprawdzenia:

  1. Poprawność sygnatury: Sprawdza, czy sygnatura jest poprawna.

  2. Istnienie transakcji: Pobiera transakcję za pomocą rpc.getTransaction(). Jeśli nie zostanie znaleziona, zwraca verified: false.

  3. Status potwierdzenia: Sprawdza, czy transakcja została zarejestrowana w łańcuchu.

  4. Walidacja transferu SOL (jeśli podano expectedRecipient i expectedAmount oraz brak expectedMint):

    • Znajduje indeks konta odbiorcy w transakcji
    • Porównuje preBalances i postBalances, aby obliczyć zmianę salda
    • Weryfikuje, czy zmiana wynosi co najmniej expectedAmount
  5. 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 postTokenBalances w 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 z gill.

  • 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> - Zwraca true, jeśli transakcja osiągnie status confirmed lub finalized w określonym limicie czasu, w przeciwnym razie false.

Przykład:

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");
}

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żyj createRecipient(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żyj createSPLToken(address))
    • reference (opcjonalnie) - Klucz publiczny referencyjny do śledzenia
    • label (opcjonalnie) - Nazwa sprzedawcy
    • message (opcjonalnie) - Komunikat o sukcesie
    • memo (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 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?

Zarządzane przez

© 2026 Solana Foundation.
Wszelkie prawa zastrzeżone.
Bądź na bieżąco