¿Qué es x402?
x402 es un protocolo abierto para pagos nativos en internet. El código de error 402 significa "Pago Requerido" y existe desde hace mucho tiempo en las especificaciones HTTP, pero solo ahora se ha vuelto viable gracias al auge de las redes blockchain. El protocolo 402 hace referencia a la implementación del patrón HTTP 402 Payment Required: el servidor exige un pago antes de devolver una respuesta protegida. En Solana, esto se implementa habitualmente solicitando al cliente que envíe una pequeña transferencia; luego el servidor la verifica en la cadena y sirve el contenido.
Por el momento aún no está claro cuál de los SDKs de 402 será el más popular. Por eso, en esta guía mostraremos cómo implementar x402 usando un servidor y cliente mínimos, y listaremos todos los SDKs de 402 disponibles con el soporte actual de Solana descrito.
¿Cómo funciona?
Hay varias formas de implementar x402, desde soluciones ultraligeras hasta completamente gestionadas.
Idea del protocolo: Usa HTTP plano. Un cliente accede a tu URL → respondes 402 Payment Required con un objeto JSON de Requisitos de Pago → el cliente paga y reintenta con una cabecera X-PAYMENT → verificas/liquidas → respondes 200 OK. Sin cuentas, sin OAuth.
Diagrama de flujo x402
Nota: El facilitador es completamente opcional y también puedes implementar tu propia lógica de validación con unas pocas líneas de código. El facilitador abstrae los detalles de integración con la blockchain tanto del servidor como del cliente, lo que facilita la implementación.
Aspectos clave de la especificación: La estructura PaymentRequirements, la cabecera X-PAYMENT codificada en base64, el X-PAYMENT-RESPONSE opcional en caso de éxito, y la API (opcional) del facilitador para /verify, /settle, /supported. El esquema concreto actual es exact (pagar una cantidad específica). Otros como upto están propuestos.
Soporte de Solana: El protocolo en sí es agnóstico a la cadena; en Solana admite todos los tokens SPL. El soporte de Solana está disponible o en desarrollo para la mayoría de los SDKs de 402.
Más abajo encontrarás una lista de los SDKs de 402 disponibles con su soporte actual de Solana.
Casos de Uso
x402 habilita una amplia variedad de escenarios de micropagos y pago por uso que antes no eran económicamente viables con blockchain. Imagina que Netflix pagara por cada visualización o Spotify por cada canción en lugar de cobrar suscripciones. Aquí tienes algunas ideas posibles. Pero todo el espectro de posibilidades está abierto a la imaginación:
IA y Comercio de Agentes:
- Acceso a API de Agentes de IA: Paga por inferencia LLM, generación de imágenes o llamada a la API de un modelo de IA (Ver ejemplo ACK)
- Monetización de Servidores MCP: Cobra por herramientas del Protocolo de Contexto de Modelo, fuentes de datos y capacidades especializadas de agentes (Ver MCPay.tech)
- Pagos entre Agentes: Permite que agentes autónomos realicen transacciones entre sí por servicios y datos (Ver ejemplo a2a-x402)
- Datos Premium de Entrenamiento de IA: Vende acceso a conjuntos de datos curados por consulta
Contenido y Medios:
- Artículos de Pago: Cobra micro-importes por artículo en lugar de suscripciones completas
- Streaming de Video/Audio: Paga por visualización o por minuto de contenido
- Imágenes de Alta Resolución: Desbloquea descargas en alta resolución tras el pago (ver ejemplo ACK) o ejemplo x402 de coinbase
- Acceso a Newsletter Premium: Monetiza números individuales de boletines
Servicios para Desarrolladores:
- Medición de API: Paga por llamada RPC, consulta de base de datos o unidad de cómputo (Ver ejemplo de Corbits)
- Funciones Serverless: Cobra por ejecuciones individuales de funciones
Datos y Analítica:
- Datos de Mercado en Tiempo Real: Feeds de precios por cotización o por tick
- Paneles de Analítica: Desbloquea informes específicos o exportaciones de datos
- Datos de Sensores IoT: Micropagos por lecturas de sensores de redes DePIN
Juegos y Bienes Virtuales:
- Acceso a Servidor de Juegos: Paga por sesión o por hora
- Descargas de Mods/Assets: Monetiza contenido generado por usuarios
- Cuotas de Inscripción a Torneos: Distribución automatizada del premio acumulado
Miscelánea:
- Filtrado de Email/DM: Requiere pago para llegar a tu bandeja de entrada (prevención de spam)
- Recursos de Cómputo: Paga por hora de CPU, minuto de GPU o GB de almacenamiento
- Acceso VPN/Proxy: Precio por GB de ancho de banda
- Descargas de Archivos Únicos: Vende archivos digitales sin costes de suscripción (Ver ejemplo ACK)
La principal ventaja de x402 en Solana son sus bajos costes de transacción (fracciones de centavo), lo que hace viables los verdaderos micropagos, además de la liquidación instantánea que permite el control de acceso en tiempo real.
SDKs y su soporte en Solana
Esta es una lista en constante evolución que se actualizará a medida que se lancen más SDKs o se añada soporte para Solana.
| SDK / Proyecto | Soporte de Solana | Notas | Docs / URL |
|---|---|---|---|
| Corbits | Sí | SDK conveniente para 402 en Solana | Docs |
| MCPay.tech | Sí | Paga por servidores MCP en micropagos | Sitio web |
| PayAI Facilitator | Sí | Facilitador x402 con soporte para Solana | payai.network |
| Coinbase | Sí / Python en progreso | La implementación de referencia de Coinbase del protocolo x402 | GitHub |
| ACK | En PR | Un protocolo de pago para agentes con soporte x402 | GitHub |
| Crossmint | En desarrollo | Pagos, billeteras; finanzas agénticas; no específico de x402 | crossmint.com |
| A2A x402 (Google) | En desarrollo | Pagos entre agentes usando Google AI | GitHub |
| Nexus (Thirdweb) | En desarrollo | Envoltorio x402 sobre claves de API | Nexus |
| x402scan | N/A (Explorador) | Explorador del ecosistema x402 (no es un SDK) | x402scan.com |
| Ejemplo Nativo | Sí | Ejemplo mínimo sin dependencias | Ejemplos |
Corbits
SDK centrado en Solana para implementar flujos x402 rápidamente en Solana. Consulta la documentación: https://corbits.dev/
Ejemplo que te permite pagar por solicitudes RPC de Solana.
npm install @faremeter/payment-solana @faremeter/fetch @faremeter/info@solana/web3.js
Crea un archivo payer-wallet.json y recárgalo con algo de USDC y algo de SOL en mainnet.
import {Keypair,PublicKey,VersionedTransaction,Connection} from "@solana/web3.js";import { createPaymentHandler } from "@faremeter/payment-solana/exact";import { wrap } from "@faremeter/fetch";import { lookupKnownSPLToken } from "@faremeter/info/solana";import * as fs from "fs";// Load keypair from fileconst keypairData = JSON.parse(fs.readFileSync("./payer-wallet.json", "utf-8"));const keypair = Keypair.fromSecretKey(Uint8Array.from(keypairData));const network = "mainnet-beta";const connection = new Connection("https://api.mainnet.solana.com");const usdcInfo = lookupKnownSPLToken(network, "USDC");const usdcMint = new PublicKey(usdcInfo.address);// Create wallet interfaceconst wallet = {network,publicKey: keypair.publicKey,updateTransaction: async (tx: VersionedTransaction) => {tx.sign([keypair]);return tx;}};// Setup payment handlerconst handler = createPaymentHandler(wallet, usdcMint, connection);const fetchWithPayer = wrap(fetch, { handlers: [handler] });// Call the API - payment happens automaticallyconst response = await fetchWithPayer("https://helius.api.corbits.dev", {method: "POST",headers: { "Content-Type": "application/json" },body: JSON.stringify({jsonrpc: "2.0",id: 1,method: "getBlockHeight"})});const data = await response.json();console.log(data);
npx tsx e2e.ts
Esto pagará por la solicitud RPC y devolverá la altura del bloque, realizando el pago usando el protocolo corbits 402.
Coinbase
La implementación de referencia de Coinbase del protocolo x402 proporciona bibliotecas TypeScript y ejemplos tanto para flujos de cliente como de servidor. El repositorio incluye pruebas de extremo a extremo que cubren 6 escenarios diferentes de SVM (Solana Virtual Machine). La implementación abarca la verificación de pagos, la generación de recibos y el manejo de errores.
Características principales:
- Implementaciones de cliente y servidor en TypeScript
- Utilidades de verificación de pagos
- Soporte para múltiples esquemas de pago (importe exacto, importe máximo)
- Suite de pruebas con ejemplos de transacciones en Solana
- Separación entre lógica de protocolo y lógica de negocio
Puedes encontrar un ejemplo fácil de usar con un servidor y cliente mínimos aquí.
const app = express();const PORT = 3000;// Apply x402 payment middleware// This automatically handles:// - 402 responses with payment requirements// - Payment verification (pre-flight checks)// - Transaction submission via facilitator// - Settlement confirmationapp.use(paymentMiddleware(RECIPIENT, {// Protected endpoint: requires $0.001 USDC payment"GET /premium": {price: "$0.0001", // Price in USD (converted to USDC)network: "solana-devnet" // Solana devnet},// Another endpoint with different price"GET /expensive": {price: "$0.001",network: "solana-devnet"}}));// Protected endpoints - only accessible after paymentapp.get("/premium", (req, res) => {res.json({message: "🎉 Premium content accessed!",data: {secret: "This is premium content",timestamp: new Date().toISOString()}});});
El soporte para Python está en desarrollo y hay un ejemplo funcional de extremo a extremo disponible aquí.
ACK
El Agent Commerce Kit (ACK) es compatible con el protocolo x402, pero añade capas críticas para la economía de agentes: identidad verificable de agentes (ACK-ID) mediante DIDs/VCs de W3C y recibos criptográficamente seguros (ACK-Pay) como Credenciales Verificables. Esto permite a los agentes demostrar propiedad, autenticarse de forma autónoma y generar pruebas de pago listas para el cumplimiento normativo, abordando la crisis de identidad y las barreras de transacción que impiden a los agentes de IA participar en el comercio.
Diagrama de flujo ACK
Hay un PR con un ejemplo e2e que aún no ha sido fusionado, pero que funciona. También existe un Ejemplo en Vivo que muestra cómo proteger imágenes con pago, una sinfonola y una API que puede animar imágenes. El código fuente de los ejemplos junto con un bot de Twitter que usa la API para animar imágenes en la línea de tiempo se puede encontrar aquí.
MCPay.tech
Micropagos por solicitud para servidores MCP (Protocolo de Contexto de Modelo) mediante flujos similares a x402. Permite a los desarrolladores monetizar herramientas y recursos MCP exigiendo pequeños pagos por cada llamada a la API o invocación de herramienta, facilitando el cobro por el acceso de agentes de IA a fuentes de datos premium, herramientas especializadas o recursos computacionales. Sitio: https://mcpay.tech/
PayAI Facilitator
Facilitador x402 centrado en Solana con un comerciante echo en vivo para probar y reembolsar pagos. PayAI está asumiendo actualmente todas las comisiones de transacción. Sitio: https://payai.network/
A2A x402 (Google)
Iniciativa de pagos 402 entre agentes que explora flujos estandarizados de pago requerido. El soporte de Solana está actualmente en progreso y se puede encontrar un ejemplo de chat funcional aquí
Crossmint
Crossmint es una plataforma todo en uno para que empresas y agentes integren infraestructura cripto — incluyendo billeteras, rampas de entrada, orquestación de stablecoins y más. El soporte de x402 en Solana está actualmente en progreso y se espera que esté listo para el 30.10.2025. Sitio: https://www.crossmint.com/
x402scan
Explorador del ecosistema x402 que proporciona estadísticas completas, listados de proyectos y analítica para implementaciones de x402. Rastrea volúmenes de transacciones, descubre comerciantes activos y monitorea el crecimiento de endpoints de pago requerido en diferentes redes. Sitio: https://x402scan.com/
Nexus (Thirdweb)
Thirdweb Nexus desarrolla un envoltorio x402 sobre claves de API (actualmente en desarrollo). Sitio: https://nexus.thirdweb.com/
Ejemplo nativo
Un ejemplo nativo sin dependencias y con un servidor y cliente mínimos.
Puedes clonar el repositorio y ejecutar el ejemplo:
git clone https://github.com/Woody4618/x402-solana-examplesnpm install# Terminal 1: Start servernpm run usdc:server# Terminal 2: Run client (requires devnet USDC)npm run usdc:client
Resumen del Flujo
- El cliente solicita
/premium. - El servidor responde 402 con los términos de pago: destinatario e importe.
- El cliente crea una transacción con una instrucción de transferencia al destinatario.
- El cliente reintenta
/premiumcon el payload de la transacción. - El servidor verifica la transacción y la envía a la red.
- Una vez confirmada, el servidor responde 200.
Alternativa específica de Solana: En Solana, podrías implementar una variante en la que el cliente envíe la transacción directamente a la red con una instrucción de memo (en lugar de enviarla al servidor), y luego envíe solo la firma de la transacción al servidor para su verificación. Esto resuelve el problema de pérdida de conexión: si el cliente se desconecta después del pago pero antes de recibir el contenido, puede reintentar con la misma firma, ya que el pago ya está confirmado en la cadena. Sin embargo, este enfoque se desvía del flujo estándar de x402.org (que espera que el servidor transmita la transacción), por lo que en este ejemplo utilizamos el enfoque estándar.
Nota: El código de este ejemplo no ha sido auditado, no está listo para producción y es solo para fines de demostración. Muestra que puedes implementar x402 sin dependencias y sin el uso de un facilitador. Usar un facilitador es conveniente porque oculta la complejidad y puede asumir las tarifas de transacción, pero también puede ser un punto único de fallo, por ejemplo cuando la billetera del facilitador se queda sin fondos. El servidor de ejemplo envía transacciones firmadas por el cliente. Es posible que necesites validarlas con un validator.
Servidor Mínimo (Express)
// x402-compliant server with USDC (SPL Token) paymentsimport express from "express";import { Connection, PublicKey, Transaction } from "@solana/web3.js";import { TOKEN_PROGRAM_ID, getAssociatedTokenAddress } from "@solana/spl-token";const connection = new Connection("https://api.devnet.solana.com", "confirmed");// Devnet USDC mint addressconst USDC_MINT = new PublicKey("4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU");// Your recipient wallet address (same as SOL example)const RECIPIENT_WALLET = new PublicKey("seFkxFkXEY9JGEpCyPfCWTuPZG9WK6ucf95zvKCfsRX");// Derive the recipient's USDC token account (Associated Token Account)const RECIPIENT_TOKEN_ACCOUNT = await getAssociatedTokenAddress(USDC_MINT,RECIPIENT_WALLET);// Picking a small USDC priceconst PRICE_USDC = 100; // 0.0001 USDCconst app = express();app.use(express.json());// x402 endpoint - Quote or verify paymentapp.get("/premium", async (req, res) => {const xPaymentHeader = req.header("X-Payment");// If client provided X-Payment header, verify and submit transactionif (xPaymentHeader) {try {// Decode base64 and parse JSON (x402 standard)const paymentData = JSON.parse(Buffer.from(xPaymentHeader, "base64").toString("utf-8")) as {x402Version: number;scheme: string;network: string;payload: {serializedTransaction: string;};};console.log("Received USDC payment proof from client");console.log(` Network: ${paymentData.network}`);// Deserialize the transactionconst txBuffer = Buffer.from(paymentData.payload.serializedTransaction,"base64");const tx = Transaction.from(txBuffer);console.log("Verifying SPL Token transfer instructions...");// Step 1: Introspect and decode SPL Token transfer instructionconst instructions = tx.instructions;let validTransfer = false;let transferAmount = 0;for (const ix of instructions) {// Check if this is a Token Program instructionif (ix.programId.equals(TOKEN_PROGRAM_ID)) {// SPL Token Transfer instruction layout:// [0] = instruction type (3 for Transfer)// [1-8] = amount (u64, little-endian)if (ix.data.length >= 9 && ix.data[0] === 3) {// Read the amount (u64 in little-endian, starts at byte 1)transferAmount = Number(ix.data.readBigUInt64LE(1));// Verify accounts: [source, destination, owner]if (ix.keys.length >= 2) {const destAccount = ix.keys[1].pubkey;if (destAccount.equals(RECIPIENT_TOKEN_ACCOUNT) &&transferAmount >= PRICE_USDC) {validTransfer = true;console.log(` ✓ Valid USDC transfer: ${transferAmount / 1000000} USDC`);console.log(` To: ${RECIPIENT_TOKEN_ACCOUNT.toBase58()}`);break;}}}}}if (!validTransfer) {return res.status(402).json({error:"Transaction does not contain valid USDC transfer to recipient with correct amount",details:transferAmount > 0? `Found transfer of ${transferAmount}, expected ${PRICE_USDC}`: "No valid token transfer instruction found"});}// Step 2: Simulate the transaction BEFORE submittingconsole.log("Simulating transaction...");try {const simulation = await connection.simulateTransaction(tx);if (simulation.value.err) {console.error("Simulation failed:", simulation.value.err);return res.status(402).json({error: "Transaction simulation failed",details: simulation.value.err,logs: simulation.value.logs});}console.log(" ✓ Simulation successful");} catch (simError) {console.error("Simulation error:", simError);return res.status(402).json({error: "Failed to simulate transaction",details:simError instanceof Error ? simError.message : "Unknown error"});}// Step 3: Submit the transaction (only if verified and simulated successfully)// Note: Solana blockchain automatically rejects duplicate transaction signaturesconsole.log("Submitting transaction to network...");const signature = await connection.sendRawTransaction(txBuffer, {skipPreflight: false,preflightCommitment: "confirmed"});console.log(`Transaction submitted: ${signature}`);// Wait for confirmationconst confirmation = await connection.confirmTransaction(signature,"confirmed");if (confirmation.value.err) {return res.status(402).json({error: "Transaction failed onchain",details: confirmation.value.err});}// Fetch the transaction to verify payment detailsconst confirmedTx = await connection.getTransaction(signature, {commitment: "confirmed",maxSupportedTransactionVersion: 0});if (!confirmedTx) {return res.status(402).json({error: "Could not fetch confirmed transaction"});}// Verify token balance changes from transaction metadataconst postTokenBalances = confirmedTx.meta?.postTokenBalances ?? [];const preTokenBalances = confirmedTx.meta?.preTokenBalances ?? [];// Find the recipient's token account in the balance changeslet amountReceived = 0;for (let i = 0; i < postTokenBalances.length; i++) {const postBal = postTokenBalances[i];const preBal = preTokenBalances.find((pre) => pre.accountIndex === postBal.accountIndex);// Check if this is the recipient's accountconst accountKey =confirmedTx.transaction.message.staticAccountKeys[postBal.accountIndex];if (accountKey && accountKey.equals(RECIPIENT_TOKEN_ACCOUNT)) {const postAmount = postBal.uiTokenAmount.amount;const preAmount = preBal?.uiTokenAmount.amount ?? "0";amountReceived = Number(postAmount) - Number(preAmount);break;}}if (amountReceived < PRICE_USDC) {return res.status(402).json({error: `Insufficient payment: received ${amountReceived}, expected ${PRICE_USDC}`});}console.log(`Payment verified: ${amountReceived / 1000000} USDC received`);console.log(`View transaction: https://explorer.solana.com/tx/${signature}?cluster=devnet`);// Payment verified! Return premium contentreturn res.json({data: "Premium content - USDC payment verified!",paymentDetails: {signature,amount: amountReceived,amountUSDC: amountReceived / 1000000,recipient: RECIPIENT_TOKEN_ACCOUNT.toBase58(),explorerUrl: `https://explorer.solana.com/tx/${signature}?cluster=devnet`}});} catch (e) {console.error("Payment verification error:", e);return res.status(402).json({error: "Payment verification failed",details: e instanceof Error ? e.message : "Unknown error"});}}// No payment provided - return 402 with payment detailsconsole.log("New USDC payment quote requested");return res.status(402).json({payment: {recipientWallet: RECIPIENT_WALLET.toBase58(),tokenAccount: RECIPIENT_TOKEN_ACCOUNT.toBase58(),mint: USDC_MINT.toBase58(),amount: PRICE_USDC,amountUSDC: PRICE_USDC / 1000000,cluster: "devnet",message: "Send USDC to the token account"}});});app.listen(3001, () => console.log("x402 USDC server listening on :3001"));
Cliente Mínimo (Node)
import { Connection, Keypair, PublicKey, Transaction } from "@solana/web3.js";import {createTransferInstruction,getOrCreateAssociatedTokenAccount,createAssociatedTokenAccountInstruction,getAccount} from "@solana/spl-token";import fetch from "node-fetch";import { readFileSync } from "fs";const connection = new Connection("https://api.devnet.solana.com", "confirmed");const keypairData = JSON.parse(readFileSync("./pay-in-usdc/client.json", "utf-8"));const payer = Keypair.fromSecretKey(Uint8Array.from(keypairData));async function run() {// 1) Request payment quote from serverconst quote = await fetch("http://localhost:3001/premium");const q = (await quote.json()) as {payment: {tokenAccount: string;mint: string;amount: number;amountUSDC: number;cluster: string;};};if (quote.status !== 402) throw new Error("Expected 402 quote");const recipientTokenAccount = new PublicKey(q.payment.tokenAccount);const mint = new PublicKey(q.payment.mint);const amount = q.payment.amount;console.log("USDC Payment required:");console.log(` Recipient Token Account: ${q.payment.tokenAccount}`);console.log(` Mint (USDC): ${q.payment.mint}`);console.log(` Amount: ${q.payment.amountUSDC} USDC (${amount} smallest units)`);// 2) Get or create the payer's associated token accountconsole.log("\nChecking/creating associated token account...");const payerTokenAccount = await getOrCreateAssociatedTokenAccount(connection,payer,mint,payer.publicKey);console.log(` Payer Token Account: ${payerTokenAccount.address.toBase58()}`);// Check if payer has enough USDCconst balance = await connection.getTokenAccountBalance(payerTokenAccount.address);console.log(` Current Balance: ${balance.value.uiAmountString} USDC`);if (Number(balance.value.amount) < amount) {throw new Error(`Insufficient USDC balance. Have: ${balance.value.uiAmountString}, Need: ${q.payment.amountUSDC}`);}// 3) Check if recipient token account exists, create if notconsole.log("\nChecking recipient token account...");let recipientAccountExists = false;try {await getAccount(connection, recipientTokenAccount);recipientAccountExists = true;console.log(" ✓ Recipient token account exists");} catch (error) {console.log(" ⚠ Recipient token account doesn't exist, will create it");}// 4) Create USDC transfer transaction (but DON'T submit it)const { blockhash } = await connection.getLatestBlockhash();const tx = new Transaction({feePayer: payer.publicKey,blockhash,lastValidBlockHeight: (await connection.getLatestBlockhash()).lastValidBlockHeight});// Add create account instruction if neededif (!recipientAccountExists) {// We need to know the recipient wallet address to create the ATA// The server should provide this, so let's get it from the wallet address// Usually the server will already have the token account, but to be sure for the examples// lets create one.const recipientWallet = new PublicKey("seFkxFkXEY9JGEpCyPfCWTuPZG9WK6ucf95zvKCfsRX");const createAccountIx = createAssociatedTokenAccountInstruction(payer.publicKey, // payerrecipientTokenAccount, // associated token account addressrecipientWallet, // ownermint // mint);tx.add(createAccountIx);console.log(" + Added create token account instruction");}// Add transfer instructionconst transferIx = createTransferInstruction(payerTokenAccount.address, // sourcerecipientTokenAccount, // destinationpayer.publicKey, // owneramount // amount in smallest units);tx.add(transferIx);// Sign the transaction (but don't send it, the server will do that)tx.sign(payer);// Serialize the signed transactionconst serializedTx = tx.serialize().toString("base64");console.log("\nTransaction created and signed (not submitted yet)");console.log(` Instructions: ${tx.instructions.length}`);// 4) Send X-Payment header with serialized transaction (x402 standard)const paymentProof = {x402Version: 1,scheme: "exact",network:q.payment.cluster === "devnet" ? "solana-devnet" : "solana-mainnet",payload: {serializedTransaction: serializedTx}};// Base64 encode the payment proofconst xPaymentHeader = Buffer.from(JSON.stringify(paymentProof)).toString("base64");console.log("\nSending payment proof to server (server will submit transaction)...");const paid = await fetch("http://localhost:3001/premium", {headers: {"X-Payment": xPaymentHeader}});const result = (await paid.json()) as {data?: string;error?: string;paymentDetails?: {signature: string;amount: number;amountUSDC: number;recipient: string;explorerUrl: string;};};console.log("\nServer response:");console.log(result);// Display explorer link if payment was successfulif (result.paymentDetails?.explorerUrl) {console.log("\n🔗 View transaction on Solana Explorer:");console.log(result.paymentDetails.explorerUrl);}}run().catch(console.error);
Mejoras
- Considera devolver un JWT tras el pago para que los clientes puedan reutilizar el acceso brevemente. ACK lo hace bastante sencillo.
- Asegúrate de que tus claves no se filtren y colócalas en variables de entorno.
Is this page helpful?