Qu'est-ce que x402 ?
Le protocole x402 est un protocole ouvert pour les paiements natifs sur internet. Le code d'erreur 402 signifie « Paiement requis » et existe depuis longtemps dans les spécifications HTTP, mais ce n'est que maintenant qu'il est devenu viable grâce à l'essor des réseaux blockchain. Le protocole 402 consiste à implémenter le schéma HTTP 402 Payment Required : le serveur exige un paiement avant de renvoyer une réponse protégée. Sur Solana, cela est généralement mis en œuvre en demandant au client d'effectuer un petit transfert, puis le serveur le vérifie on-chain et sert le contenu.
Pour le moment, il n'est pas encore clair quel SDK 402 sera le plus populaire. Dans ce guide, nous montrerons comment implémenter x402 à l'aide d'un serveur et d'un client minimaux, et nous listerons tous les SDKs 402 disponibles avec le support Solana actuel décrit.
Comment ça fonctionne ?
Il existe plusieurs façons d'implémenter x402, allant du plus léger au entièrement géré.
Idée du protocole : Utiliser du HTTP simple. Un client appelle votre URL → vous répondez 402 Payment Required avec un objet JSON Payment Requirements → le client paie et réessaie avec un en-tête X-PAYMENT → vous vérifiez/réglez → vous répondez 200 OK. Pas de comptes, pas d'OAuth.
Diagramme de flux x402
Remarque : Le facilitateur est entièrement optionnel et vous pouvez également implémenter votre propre logique de validation avec quelques lignes de code. Le facilitateur abstrait les détails d'intégration blockchain côté serveur et client, ce qui facilite l'implémentation.
Points clés de la spécification : La structure PaymentRequirements, l'en-tête X-PAYMENT encodé en base64, le X-PAYMENT-RESPONSE optionnel en cas de succès, et l'API (optionnelle) du facilitateur pour /verify, /settle, /supported. Le schéma concret actuel est exact (payer un montant spécifique). D'autres comme upto sont proposés.
Support Solana : Le protocole lui-même est agnostique vis-à-vis de la chaîne ; sur Solana, il prend en charge tous les tokens SPL. Le support Solana est disponible ou en cours de développement pour la plupart des SDKs 402.
Plus bas se trouve une liste des SDKs 402 disponibles avec leur support Solana actuel.
Cas d'usage
x402 permet une large gamme de scénarios de micropaiement et de paiement à l'utilisation qui n'étaient pas économiquement viables avant la blockchain. Imaginez Netflix payant pour chaque visionnage ou Spotify payant pour chaque chanson plutôt que pour des abonnements. Voici quelques idées possibles. Mais tout le spectre des possibilités est ouvert à l'imagination :
IA & Commerce entre agents :
- Accès API pour agents IA : Payer par inférence LLM, génération d'image ou appel d'API de modèle IA (Voir exemple ACK)
- Monétisation de serveurs MCP : Facturer l'utilisation des outils Model Context Protocol, des sources de données et des capacités d'agents spécialisés (Voir MCPay.tech)
- Paiements entre agents : Permettre aux agents autonomes de réaliser des transactions entre eux pour des services et des données (Voir exemple a2a-x402)
- Données d'entraînement IA premium : Vendre l'accès à des jeux de données sélectionnés par requête
Contenu & Médias :
- Articles sous paywall : Facturer de micro-montants par article plutôt que des abonnements complets
- Streaming vidéo/audio : Payer par visionnage ou par minute de contenu
- Images haute résolution : Débloquer les téléchargements en pleine résolution après paiement (voir exemple ACK) ou exemple x402 coinbase
- Accès premium aux newsletters : Monétiser les numéros individuels de newsletters
Services pour développeurs :
- Comptage d'API : Payer par appel RPC, requête de base de données ou unité de calcul (Voir exemple Corbits)
- Fonctions serverless : Facturer les exécutions de fonctions individuelles
Données & Analytique :
- Données de marché en temps réel : Flux de prix par cotation ou par tick
- Tableaux de bord analytiques : Débloquer des rapports ou exports de données spécifiques
- Données de capteurs IoT : Micropaiements pour les relevés de capteurs issus des réseaux DePIN
Jeux & Biens virtuels :
- Accès aux serveurs de jeux : Payer par session ou par heure
- Téléchargements de mods/assets : Monétiser le contenu généré par les utilisateurs
- Frais d'inscription aux tournois : Distribution automatisée des prix
Divers :
- Filtrage des e-mails/DM : Exiger un paiement pour atteindre votre boîte de réception (protection contre le spam)
- Ressources de calcul : Payer par heure CPU, minute GPU ou Go de stockage
- Accès VPN/Proxy : Tarification par Go de bande passante
- Téléchargements de fichiers uniques : Vendre des fichiers numériques sans frais d'abonnement (Voir exemple ACK)
L'avantage clé de x402 sur Solana réside dans les faibles coûts de transaction (fractions de centime) rendant les vrais micropaiements viables, ainsi que le règlement instantané permettant un contrôle d'accès en temps réel.
SDKs et leur support Solana
Il s'agit d'une liste évolutive qui sera mise à jour au fur et à mesure que de nouveaux SDKs seront publiés ou que le support Solana sera ajouté.
| SDK / Projet | Support Solana | Notes | Docs / URL |
|---|---|---|---|
| Corbits | Oui | SDK pratique pour le 402 sur Solana | Docs |
| MCPay.tech | Oui | Payer les serveurs MCP en micropaiements | Site |
| PayAI Facilitator | Oui | Facilitateur x402 avec support Solana | payai.network |
| Coinbase | Oui / Python en cours | L'implémentation de référence Coinbase du protocole x402 | GitHub |
| ACK | En PR | Un protocole de paiement pour agents avec support x402 | GitHub |
| Crossmint | En développement | Paiements, portefeuilles ; finance agentique ; non spécifique à x402 | crossmint.com |
| A2A x402 (Google) | En développement | Paiements agent-à-agent utilisant Google AI | GitHub |
| Nexus (Thirdweb) | En développement | Wrapper x402 autour des clés API | Nexus |
| x402scan | N/A (Explorateur) | Explorateur de l'écosystème x402 (pas un SDK) | x402scan.com |
| Exemple natif | Oui | Exemple minimal sans dépendances | Exemples |
Corbits
SDK Solana-first pour implémenter rapidement les flux x402 sur Solana. Voir la documentation : https://corbits.dev/
Exemple permettant de payer des requêtes RPC Solana.
npm install @faremeter/payment-solana @faremeter/fetch @faremeter/info@solana/web3.js
Créez un fichier payer-wallet.json et alimentez-le avec quelques USDC et un peu de SOL sur le 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
Cela paiera la requête RPC et retournera la hauteur de bloc en utilisant le protocole corbits 402.
Coinbase
L'implémentation de référence de Coinbase du protocole x402 fournit des bibliothèques TypeScript et des exemples pour les flux client et serveur. Le dépôt inclut des tests de bout en bout couvrant 6 scénarios SVM (Solana Virtual Machine) différents. L'implémentation couvre la vérification des paiements, la génération de reçus et la gestion des erreurs.
Fonctionnalités clés :
- Implémentations client et serveur en TypeScript
- Utilitaires de vérification des paiements
- Support de plusieurs schémas de paiement (montant exact, montant maximal)
- Suite de tests avec des exemples de transactions Solana
- Séparation entre la logique protocolaire et la logique métier
Vous trouverez un exemple facile à utiliser avec un serveur et un client minimaux ici.
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()}});});
Le support Python est en cours de développement avec un exemple fonctionnel de bout en bout disponible ici.
ACK
L'Agent Commerce Kit (ACK) prend en charge le protocole x402, mais ajoute des couches essentielles pour l'économie des agents : une identité d'agent vérifiable (ACK-ID) utilisant les DID/VC du W3C et des reçus cryptographiquement sécurisés (ACK-Pay) sous forme de Verifiable Credentials. Cela permet aux agents de prouver leur propriété, de s'authentifier de manière autonome et de générer des preuves de paiement conformes, répondant ainsi à la crise d'identité et aux obstacles transactionnels qui empêchent les agents IA de participer au commerce.
Diagramme de flux ACK
Une PR avec un exemple e2e n'a pas encore été fusionnée, mais elle fonctionne. Il existe également un exemple en direct montrant comment soumettre des images à un paywall, une jukebox et une API capable d'animer des images. Le code source des exemples, ainsi qu'un bot Twitter utilisant l'API pour animer des images sur le fil d'actualité, peuvent être trouvés ici.
MCPay.tech
Micropaiements à la requête pour les serveurs MCP (Model Context Protocol) utilisant des flux de type x402. Permet aux développeurs de monétiser les outils et ressources MCP en exigeant de petits paiements pour chaque appel API ou invocation d'outil, facilitant ainsi la facturation de l'accès des agents IA à des sources de données premium, des outils spécialisés ou des ressources de calcul. Site : https://mcpay.tech/
PayAI Facilitator
Facilitateur x402 Solana-first avec un marchand echo en production pour tester et rembourser les paiements. PayAI prend en charge tous les frais de transaction pour le moment. Site : https://payai.network/
A2A x402 (Google)
Initiative de paiement agent-à-agent explorant des flux standardisés de type paiement requis. Le support Solana est actuellement en cours et un exemple de chat fonctionnel peut être trouvé ici
Crossmint
Crossmint est une plateforme tout-en-un pour les entreprises et les agents souhaitant intégrer les rails crypto — y compris les portefeuilles, les onramps, l'orchestration de stablecoins, et bien plus. Le support Solana x402 est actuellement en cours de développement et devrait être finalisé d'ici le 30.10.2025. Site : https://www.crossmint.com/
x402scan
Explorateur de l'écosystème x402 fournissant des statistiques complètes, des listes de projets et des analyses pour les implémentations x402. Suivez les volumes de transactions, découvrez les marchands actifs et surveillez la croissance des endpoints à paiement requis sur différents réseaux. Site : https://x402scan.com/
Nexus (Thirdweb)
Thirdweb Nexus développe un wrapper x402 autour des clés API (actuellement en développement). Site : https://nexus.thirdweb.com/
Exemple natif
Un exemple natif sans dépendances avec un serveur et un client minimaux.
Vous pouvez cloner le dépôt et lancer l'exemple :
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
Aperçu du flux
- Le client demande
/premium. - Le serveur répond 402 avec les conditions de paiement : destinataire, montant.
- Le client crée une transaction avec une instruction de transfert vers le destinataire.
- Le client réessaie
/premiumavec la charge utile de la transaction. - Le serveur vérifie la transaction et l'envoie au réseau.
- Une fois confirmée, le serveur répond 200.
Alternative spécifique à Solana : Sur Solana, vous pourriez implémenter une variante où le client soumet la transaction directement au réseau avec une instruction memo (plutôt que de l'envoyer au serveur), puis envoie uniquement la signature de transaction au serveur pour vérification. Cela résout le problème de perte de connexion — si le client se déconnecte après le paiement mais avant de recevoir le contenu, il peut réessayer avec la même signature puisque le paiement est déjà confirmé on-chain. Cependant, cette approche s'écarte du flux standard x402.org (qui attend que le serveur diffuse la transaction), c'est pourquoi nous utilisons l'approche standard dans cet exemple.
Remarque : Le code de cet exemple n'a pas été audité, n'est pas prêt pour la production et est fourni à des fins de démonstration uniquement. Il montre que vous pouvez implémenter x402 sans dépendances et sans recourir à un facilitateur. Utiliser un facilitateur est pratique car il masque la complexité et peut prendre en charge les frais de transaction, mais il peut également constituer un point de défaillance unique, par exemple lorsque le portefeuille du facilitateur manque de fonds. Le serveur d'exemple soumet des transactions signées par le client. Vous devrez peut-être les valider.
Serveur minimal (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"));
Client minimal (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);
Améliorations
- Envisagez de retourner un JWT après le paiement afin que les clients puissent réutiliser l'accès brièvement. ACK rend cela très facile.
- Assurez-vous que vos clés ne fuient pas et placez-les dans des variables d'environnement.
Is this page helpful?