Платіжні потоки
Пакет @solana-commerce/headless надає функції, незалежні від фреймворку, для
побудови комерційних платіжних потоків. Ці інструменти допомагають створювати
об'єкти платіжних запитів, генерувати URL-адреси Solana Pay та перевіряти
платежі в ланцюзі. Пакет розроблено для роботи в будь-якому JavaScript
середовищі: React, Vue, Svelte, чистий JS, Node.js або serverless-функції.
Встановлення
pnpm add @solana-commerce/headless
Функції платіжних запитів
Ці функції створюють стандартизовані об'єкти платіжних запитів для різних комерційних патернів. Вони не виконують жодних блокчейн-операцій — вони просто структурують дані для використання в гаманцях, URL-адресах Solana Pay або власних платіжних інтерфейсах.
createBuyNowRequest()
Створює стандартизований платіжний запит для покупки одного товару.
function createBuyNowRequest(recipient: string,product: any,options?: {memo?: string;label?: string;message?: string;}): PaymentRequest;
Параметри
-
recipient(string, обов'язковий) - Адреса гаманця продавця (публічний ключ Solana в кодуванні base58), який отримає платіж. -
product(any, обов'язковий) - Об'єкт товару, що містить:price(number, обов'язковий) - Ціна товару. Одиниця залежить від контексту (наприклад, lamport для SOL, мінорні одиниці для токенів).currency(string, обов'язковий) - Валюта платежу. Може бути'SOL'або адреса mint токена.name(string, обов'язковий) - Назва товару, використовується для стандартного memo/label, якщо не надано.- Додаткові поля (id, description, image тощо) передаються в масиві
products.
-
options(object, необов'язковий) - Параметри налаштування:memo(string) - Мемо в ланцюзі для транзакції. За замовчуванням:"Purchase: {product.name}".label(string) - Відображувана мітка для платіжного запиту (використовується в Solana Pay). За замовчуванням:product.name.message(string) - Повідомлення про успіх, показане після платежу. За замовчуванням:"Thank you for purchasing {product.name}!".
Повертає
Об'єкт PaymentRequest, що містить:
recipient- Адреса гаманця продавцяamount- Ціна товару (скопійована зproduct.price)currency- Валюта платежу (скопійована зproduct.currency)products- Масив, що містить один товарmemo- Мемо транзакції (параметр або за замовчуванням: "Purchase: (product.name)")label- Мітка платежу (параметр або за замовчуванням: "product.name")message- Повідомлення про успіх (параметр або за замовчуванням: "Thank you for purchasing (product.name)!")
Приклад:
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()
Створює запит на оплату для кількох товарів у кошику покупок.
function createCartRequest(recipient: string,products: any[],options?: {memo?: string;label?: string;message?: string;currency?: string;}): PaymentRequest;
Параметри
-
recipient(string, обов'язковий) - Адреса гаманця торговця, який отримає платіж. -
products(any[], обов'язковий) - Масив об'єктів товарів. -
options(об'єкт, необов'язковий) - Параметри налаштування:currency(рядок) - Валюта оплати для всього кошика.memo(рядок) - Примітка в ланцюгу. За замовчуванням:"Cart purchase (products.length items)".label(рядок) - Мітка платежу. За замовчуванням:"Cart Checkout".message(рядок) - Повідомлення про успіх. За замовчуванням:"Thank you for your purchase!".
Повертає
Об'єкт PaymentRequest з:
recipient- Адреса гаманця торговцяamount- Сума всіх цін товарів (products.reduce((sum, p) => sum + p.price, 0))currency- Валюта оплати (з параметрів або undefined)products- Масив товарівmemo,label,message- Значення параметрів або значення за замовчуванням
Приклад:
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()
Створює запит на оплату для чайових або донатів із сумою, визначеною користувачем.
function createTipRequest(recipient: string,amount: number,options?: {currency?: string;memo?: string;label?: string;message?: string;}): PaymentRequest;
Параметри
-
recipient(string, обов'язковий) - Адреса гаманця одержувача чайових (автор контенту, стример, благодійна організація тощо). -
amount(number, обов'язковий) - Сума чайових. Одиниця залежить від валюти (lamport для SOL, дрібні одиниці для токенів). -
options(об'єкт, необов'язковий) - Параметри налаштування:currency(рядок) - Валюта оплати. За замовчуванням: undefined (зазвичай сприймається споживачами як SOL).memo(рядок) - Примітка в ланцюгу. За замовчуванням:"Thank you for your support!".label(рядок) - Мітка платежу. За замовчуванням:"Tip".message(рядок) - Повідомлення про успіх. За замовчуванням:"Thanks for the tip!".
Повертає
Об'єкт PaymentRequest з:
recipient- Адреса гаманця одержувача чайовихamount- Сума чайовихcurrency- Валюта оплати (з параметрів або undefined)memo,label,message- Значення параметрів або значення за замовчуванням
Приклад:
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!"});
Функції перевірки платежів
Ці функції взаємодіють з Solana для перевірки транзакцій та очікування
підтверджень. Вони вимагають клієнта Solana RPC з бібліотеки gill.
verifyPayment()
Перевіряє, що транзакція існує в блокчейні, та опціонально валідує суму платежу, одержувача та токен.
async function verifyPayment(rpc: SolanaClient["rpc"],signatureString: string,expectedAmount?: number,expectedRecipient?: string,expectedMint?: string): Promise<PaymentVerificationResult>;
Параметри
-
rpc(SolanaClient['rpc'], обов'язковий) - RPC клієнт зgill. Створюється за допомогоюcreateSolanaClient(rpcUrl).rpc. -
signatureString(string, обов'язковий) - Підпис транзакції (у форматі base58) для перевірки. -
expectedAmount(number, опціонально) - Очікувана сума платежу для валідації. Одиниця має відповідати валюті:- Для SOL: lamport (1 SOL = 1 000 000 000 lamport)
- Для SPL токенів: мінімальні одиниці на основі десяткових знаків токена (наприклад, USDC використовує 6 десяткових знаків)
Якщо не вказано, валідація суми пропускається.
-
expectedRecipient(string, опціонально) - Очікувана адреса гаманця одержувача. Якщо вказано (разом зexpectedAmount), функція валідує, що одержувач отримав принаймні цю суму. Якщо не вказано, валідація пропускається. -
expectedMint(string, опціонально) - Адреса mint SPL токена. Потрібна лише для переказів SPL токенів. Якщо не вказано, функція припускає переказ SOL.
Повертає
Об'єкт 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}
Логіка перевірки
Функція виконує такі перевірки:
-
Валідність підпису: Перевіряє, що підпис є валідним.
-
Існування транзакції: Отримує транзакцію за допомогою
rpc.getTransaction(). Якщо не знайдено, повертаєverified: false. -
Статус підтвердження: Перевіряє, що транзакція зафіксована в блокчейні.
-
Валідація переказу SOL (якщо вказано
expectedRecipientтаexpectedAmount, і немаєexpectedMint):- Знаходить індекс акаунта одержувача в транзакції
- Порівнює
preBalancesтаpostBalancesдля обчислення зміни балансу - Перевіряє, що зміна становить принаймні
expectedAmount
-
Перевірка переказу SPL-токенів (якщо надано
expectedMint):- Виводить асоційований токен-акаунт (ATA) одержувача для Token Program та Token-2022 Program
- Перевіряє
postTokenBalancesна наявність відповідного ATA з очікуваним mint - Підтверджує, що сума токенів становить принаймні
expectedAmount
Міркування щодо безпеки
- Перевірка на стороні клієнта: Ця функція отримує дані транзакції з RPC. Не розкривайте вашу RPC URL-адресу клієнту.
- Фіналізація: Функція перевіряє підтверджені транзакції, але для платежів з
високою вартістю розгляньте можливість очікування статусу
finalized.
Приклад:
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()
Опитує блокчейн, доки транзакція не досягне статусу підтвердження чи фіналізації, або не вичерпає час очікування.
async function waitForConfirmation(rpc: SolanaClient["rpc"],signatureStr: string,timeoutMs?: number): Promise<boolean>;
Параметри
-
rpc(SolanaClient['rpc'], обов'язковий) - RPC-клієнт зgill. -
signatureStr(string, обов'язковий) - Підпис транзакції для очікування. -
timeoutMs(number, необов'язковий) - Максимальний час очікування в мілісекундах. За замовчуванням:30000(30 секунд).
Повертає
Promise<boolean>- Повертаєtrue, якщо транзакція досягає статусуconfirmedабоfinalizedпротягом часу очікування,falseв іншому випадку.
Приклад:
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
Ці функції генерують URL-адреси Solana Pay та стилізовані QR-коди для сканування мобільними гаманцями.
createSolanaPayRequest()
Створює URL-адресу Solana Pay та стилізований QR-код.
async function createSolanaPayRequest(request: TransferRequestURLFields,options: SolanaPayRequestOptions): Promise<{ url: URL; qr: string }>;
Параметри
-
request(TransferRequestURLFields, обов'язковий) - Поля запиту на переказ Solana Pay:recipient- Публічний ключ одержувача (використовуйтеcreateRecipient(address)з@solana-commerce/solana-pay)amount- (необов'язково) Сума платежу в мінімальних одиницях (lamport для SOL)splToken(необов'язково) - Публічний ключ mint SPL-токена (використовуйтеcreateSPLToken(address))reference(необов'язково) - Референсний публічний ключ для відстеженняlabel(необов'язково) - Назва продавцяmessage(необов'язково) - Повідомлення про успіхmemo(необов'язково) - Мемо в блокчейні
-
options(SolanaPayRequestOptions, обов'язковий) - Параметри стилізації QR-коду:size(число) - Ширина/висота QR-коду в пікселях. За замовчуванням:256.background(рядок) - Колір фону (hex/rgb). За замовчуванням:'white'.color(рядок) - Колір QR-коду (hex/rgb). За замовчуванням:'black'.margin(число) - Відступ навколо QR-коду в модулях.errorCorrectionLevel('L' | 'M' | 'Q' | 'H') - Рівень виправлення помилок. Вищі рівні дозволяють більше пошкоджень, але створюють щільніші коди.logo(рядок) - URL зображення логотипу для вбудовування в центр QR-коду.logoSize(число) - Розмір логотипу у відсотках від розміру QR-коду.logoBackgroundColor(рядок) - Колір фону за логотипом.logoMargin(число) - Відступ навколо логотипу.dotStyle('dots' | 'rounded' | 'square') - Форма модулів QR-коду.cornerStyle('square' | 'rounded' | 'extra-rounded' | 'full-rounded' | 'maximum-rounded') - Форма кутових маркерів.
Повертає
Promise, що розв'язується в об'єкт:
url(URL) - URL Solana Pay (наприклад,solana:recipient?amount=10&spl-token=...)qr(рядок) - Data URL зображення QR-коду в форматі Base64 (використовуйте як<img src={qr} />)
Приклад:
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?