Fluxos de Pagamento
O pacote @solana-commerce/headless fornece funções independentes de framework
para construir fluxos de pagamento de comércio. Essas ferramentas ajudam a criar
objetos de solicitação de pagamento, gerar URLs do Solana Pay e verificar
pagamentos on-chain. O pacote foi projetado para funcionar em qualquer ambiente
JavaScript: React, Vue, Svelte, JavaScript puro, Node.js ou funções serverless.
Instalação
pnpm add @solana-commerce/headless
Funções de Solicitação de Pagamento
Essas funções criam objetos de solicitação de pagamento padronizados para diferentes padrões de comércio. Elas não realizam nenhuma operação blockchain—apenas estrutura dados para uso em carteiras, URLs do Solana Pay ou interfaces de pagamento personalizadas.
createBuyNowRequest()
Cria uma solicitação de pagamento padronizada para a compra de um único produto.
function createBuyNowRequest(recipient: string,product: any,options?: {memo?: string;label?: string;message?: string;}): PaymentRequest;
Parâmetros
-
recipient(string, obrigatório) - Endereço da carteira do comerciante (chave pública Solana codificada em base58) que receberá o pagamento. -
product(any, obrigatório) - Objeto do produto contendo:price(número, obrigatório) - Preço do produto. A unidade depende do contexto (por exemplo, lamports para SOL, unidades menores para tokens).currency(string, obrigatório) - Moeda de pagamento. Pode ser'SOL'ou um endereço de mint de token.name(string, obrigatório) - Nome do produto, usado para memo/etiqueta padrão se não fornecido.- Campos adicionais (id, descrição, imagem, etc.) são passados no array
products.
-
options(objeto, opcional) - Opções de personalização:memo(string) - Memo on-chain para a transação. Padrão:"Purchase: {product.name}".label(string) - Etiqueta de exibição para a solicitação de pagamento (usada no Solana Pay). Padrão:product.name.message(string) - Mensagem de sucesso exibida após o pagamento. Padrão:"Thank you for purchasing {product.name}!".
Retorno
Um objeto PaymentRequest contendo:
recipient- O endereço da carteira do comercianteamount- O preço do produto (copiado deproduct.price)currency- Moeda de pagamento (copiado deproduct.currency)products- Array contendo o único produtomemo- Memo da transação (opção ou padrão: "Compra: (product.name)")label- Etiqueta de pagamento (opção ou padrão: "product.name")message- Mensagem de sucesso (opção ou padrão: "Obrigado por comprar (product.name)!")
Exemplo:
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()
Cria uma solicitação de pagamento para múltiplos produtos num carrinho de compras.
function createCartRequest(recipient: string,products: any[],options?: {memo?: string;label?: string;message?: string;currency?: string;}): PaymentRequest;
Parâmetros
-
recipient(string, obrigatório) - Endereço da carteira do comerciante que receberá o pagamento. -
products(any[], obrigatório) - Array de objetos de produtos. -
options(objeto, opcional) - Opções de personalização:currency(string) - Moeda de pagamento para todo o carrinho.memo(string) - Memorando on-chain. Padrão:"Cart purchase (products.length items)".label(string) - Rótulo do pagamento. Padrão:"Cart Checkout".message(string) - Mensagem de sucesso. Padrão:"Thank you for your purchase!".
Retorna
Um objeto PaymentRequest com:
recipient- O endereço da carteira do comercianteamount- Soma de todos os preços dos produtos (products.reduce((sum, p) => sum + p.price, 0))currency- Moeda de pagamento (das opções, ou indefinido)products- O array de produtosmemo,label,message- Valores das opções ou padrões
Exemplo:
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()
Cria uma solicitação de pagamento para gorjetas ou doações com um valor definido pelo utilizador.
function createTipRequest(recipient: string,amount: number,options?: {currency?: string;memo?: string;label?: string;message?: string;}): PaymentRequest;
Parâmetros
-
recipient(string, obrigatório) - Endereço da carteira do destinatário da gorjeta (criador, streamer, instituição de caridade, etc.). -
amount(number, obrigatório) - Valor da gorjeta. A unidade depende da moeda (lamports para SOL, unidades menores para tokens). -
options(objeto, opcional) - Opções de personalização:currency(string) - Moeda de pagamento. Padrão: indefinido (normalmente tratado como SOL pelos consumidores).memo(string) - Memorando on-chain. Padrão:"Thank you for your support!".label(string) - Rótulo do pagamento. Padrão:"Tip".message(string) - Mensagem de sucesso. Padrão:"Thanks for the tip!".
Retorna
Um objeto PaymentRequest com:
recipient- O endereço da carteira do destinatário da gorjetaamount- O valor da gorjetacurrency- Moeda de pagamento (das opções, ou indefinido)memo,label,message- Valores das opções ou padrões
Exemplo:
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!"});
Funções de Verificação de Pagamento
Essas funções interagem com a Solana para verificar transações e aguardar
confirmações. Elas requerem um cliente RPC Solana da biblioteca gill.
verifyPayment()
Verifica se uma transação existe on-chain e opcionalmente valida o valor do pagamento, destinatário e token.
async function verifyPayment(rpc: SolanaClient["rpc"],signatureString: string,expectedAmount?: number,expectedRecipient?: string,expectedMint?: string): Promise<PaymentVerificationResult>;
Parâmetros
-
rpc(SolanaClient['rpc'], obrigatório) - Cliente RPC dagill. Crie comcreateSolanaClient(rpcUrl).rpc. -
signatureString(string, obrigatório) - Assinatura da transação (codificada em base58) para verificar. -
expectedAmount(number, opcional) - Valor esperado do pagamento a validar. A unidade deve corresponder à moeda:- Para SOL: lamports (1 SOL = 1.000.000.000 lamports)
- Para tokens SPL: unidades menores baseadas nas casas decimais do token (ex.: USDC usa 6 casas decimais)
Se não fornecido, a validação do valor é ignorada.
-
expectedRecipient(string, opcional) - Endereço esperado da carteira do destinatário. Se fornecido (juntamente comexpectedAmount), a função valida que o destinatário recebeu pelo menos este valor. Se não fornecido, a validação é ignorada. -
expectedMint(string, opcional) - Endereço mint do token SPL. Necessário apenas para transferências de tokens SPL. Se não fornecido, a função assume transferência de SOL.
Retorno
Um objeto 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}
Lógica de Verificação
A função realiza estas verificações:
-
Validade da Assinatura: Verifica se a assinatura é válida.
-
Existência da Transação: Busca a transação usando
rpc.getTransaction(). Se não encontrada, retornaverified: false. -
Status de Confirmação: Verifica se a transação foi registrada on-chain.
-
Validação de Transferência SOL (se
expectedRecipienteexpectedAmountfornecidos, e semexpectedMint):- Localiza o índice da conta do destinatário na transação
- Compara
preBalancesepostBalancespara calcular a variação do saldo - Verifica se a variação é pelo menos
expectedAmount
-
Validação de Transferência de Token SPL (se
expectedMintfornecido):- Deriva a Conta de Token Associada (ATA) do destinatário tanto para o Programa de Token quanto para o Programa Token-2022
- Verifica
postTokenBalancespara uma ATA correspondente com o mint esperado - Verifica se a quantidade de tokens é pelo menos
expectedAmount
Considerações de Segurança
- Verificação do Lado do Cliente: Esta função busca dados de transação do RPC. Não exponha sua URL RPC ao cliente.
- Finalização: A função verifica transações confirmadas, mas para pagamentos
de alto valor, considere aguardar o status
finalized.
Exemplo:
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()
Consulta a blockchain até que uma transação alcance o status confirmado ou finalizado, ou atinja o tempo limite.
async function waitForConfirmation(rpc: SolanaClient["rpc"],signatureStr: string,timeoutMs?: number): Promise<boolean>;
Parâmetros
-
rpc(SolanaClient['rpc'], obrigatório) - Cliente RPC degill. -
signatureStr(string, obrigatório) - Assinatura da transação a aguardar. -
timeoutMs(number, opcional) - Tempo máximo de espera em milissegundos. Padrão:30000(30 segundos).
Retorna
Promise<boolean>- Retornatruese a transação alcançar o statusconfirmedoufinalizeddentro do tempo limite,falsecaso contrário.
Exemplo:
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");}
Funções do Solana Pay
Essas funções geram URLs do Solana Pay e códigos QR estilizados para leitura por carteiras móveis.
createSolanaPayRequest()
Cria uma URL do Solana Pay e um código QR estilizado.
async function createSolanaPayRequest(request: TransferRequestURLFields,options: SolanaPayRequestOptions): Promise<{ url: URL; qr: string }>;
Parâmetros
-
request(TransferRequestURLFields, obrigatório) - Campos de solicitação de transferência do Solana Pay:recipient- Chave pública do destinatário (usecreateRecipient(address)de@solana-commerce/solana-pay)amount- (opcional) Valor do pagamento em unidades menores (lamports para SOL)splToken(opcional) - Chave pública do mint do token SPL (usecreateSPLToken(address))reference(opcional) - Chave pública de referência para rastreamentolabel(opcional) - Nome do comerciantemessage(opcional) - Mensagem de sucessomemo(opcional) - Memo on-chain
-
options(SolanaPayRequestOptions, obrigatório) - Opções de estilo do código QR:size(número) - Largura/altura do código QR em pixels. Padrão:256.background(string) - Cor de fundo (hex/rgb). Padrão:'white'.color(string) - Cor do código QR (hex/rgb). Padrão:'black'.margin(número) - Margem ao redor do código QR em módulos.errorCorrectionLevel('L' | 'M' | 'Q' | 'H') - Nível de correção de erros. Níveis mais altos permitem mais danos, mas criam códigos mais densos.logo(string) - URL da imagem do logotipo para incorporar no centro do código QR.logoSize(número) - Tamanho do logotipo como percentagem do tamanho do código QR.logoBackgroundColor(string) - Cor de fundo atrás do logotipo.logoMargin(número) - Margem ao redor do logotipo.dotStyle('dots' | 'rounded' | 'square') - Forma dos módulos do código QR.cornerStyle('square' | 'rounded' | 'extra-rounded' | 'full-rounded' | 'maximum-rounded') - Forma dos marcadores de canto.
Retorna
Uma Promise que resolve para um objeto:
url(URL) - URL do Solana Pay (por exemplo,solana:recipient?amount=10&spl-token=...)qr(string) - URL de dados codificada em Base64 da imagem do código QR (use como<img src={qr} />)
Exemplo:
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?