Τα αιτήματα μεταφοράς είναι η πιο απλή μορφή ενσωμάτωσης Solana Pay. Δημιουργούν μη διαδραστικά URL πληρωμών που τα πορτοφόλια μπορούν να χρησιμοποιήσουν για να συνθέσουν και να στείλουν άμεσα συναλλαγές χωρίς να απαιτείται διακομιστής.
Επισκόπηση
Ένα URL αιτήματος μεταφοράς ακολουθεί αυτή τη μορφή:
solana:<recipient>?amount=<amount>&spl-token=<spl-token>&reference=<reference>&label=<label>&message=<message>&memo=<memo>
Βασική Μεταφορά SOL
Δημιουργήστε ένα απλό αίτημα πληρωμής SOL:
import { address } from "@solana/kit";import { encodeURL } from "@solana/pay";// Recipient's Solana wallet addressconst recipient = address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB");// Create the payment URLconst url = encodeURL({recipient,amount: 0.01, // 0.01 SOLlabel: "My Store",message: "Thanks for your purchase!"});console.log(url.toString());// Output: solana:FvJ8k8Hh...?amount=0.01&label=My%20Store&message=Thanks%20for%20your%20purchase!
Μεταφορά SPL Token
Δημιουργήστε ένα αίτημα πληρωμής USDC:
import { address } from "@solana/kit";import { encodeURL } from "@solana/pay";// USDC mint address on mainnetconst usdcMint = address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");const url = encodeURL({recipient: address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB"),amount: 10.5, // $10.50 USDCsplToken: usdcMint,label: "Coffee Shop",message: "Grande Latte + Tip"});console.log(url.toString());
Παράμετροι URL
Υποχρεωτικές Παράμετροι
Παραλήπτης
Η διεύθυνση πορτοφολιού Solana του παραλήπτη (κωδικοποιημένη σε base58):
const recipient = address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB");
Προαιρετικές Παράμετροι
Ποσό
Ποσό πληρωμής σε φιλικές προς τον χρήστη μονάδες (SOL ή μονάδες token):
// SOL amountsconst solAmount = 1.5; // 1.5 SOLconst smallAmount = 0.001; // 0.001 SOL// Token amounts (USDC example)const usdcAmount = 25.99; // $25.99 USDC
Εάν παραληφθεί, το πορτοφόλι θα ζητήσει από τον χρήστη να εισαγάγει το ποσό.
SPL Token
Για μεταφορές token, καθορίστε τη διεύθυνση mint:
// Common SPL tokensconst USDC = address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");const USDT = address("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB");// Omit splToken for native SOL transfers
Αναφορά
Μοναδικά αναγνωριστικά για την παρακολούθηση πληρωμών. Δημιουργήστε μια διεύθυνση για χρήση ως κλειδί αναφοράς:
import { generateKeyPair, getAddressFromPublicKey } from "@solana/kit";// Generate a unique referenceconst keypair = await generateKeyPair();const reference = await getAddressFromPublicKey(keypair.publicKey);
Ετικέτα
Όνομα εμπόρου ή εφαρμογής που εμφανίζεται στους χρήστες:
const label = "Acme Coffee Shop";
Μήνυμα
Περιγραφή της πληρωμής:
const message = "Order #12345 - 2x Americano";
Σημείωση
Σημείωση στην αλυσίδα (δημόσια ορατή):
const memo = "OrderId:12345";
Ενσωμάτωση Κωδικού QR
Δημιουργήστε κωδικούς QR χρησιμοποιώντας την ενσωματωμένη συνάρτηση createQR:
import { address } from "@solana/kit";import { encodeURL, createQR } from "@solana/pay";const url = encodeURL({recipient: address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB"),amount: 0.05,label: "Donation",message: "Support our project"});// Generate a QR code elementconst qr = createQR(url);// Append to DOMconst element = document.getElementById("qr-code");qr.append(element);
Επικύρωση Πληρωμής
Χρήση του Merchant Client
Ο απλούστερος τρόπος για να βρείτε και να επικυρώσετε πληρωμές:
import { address } from "@solana/kit";import { createMerchantClient } from "@solana/pay";const merchant = createMerchantClient({rpcUrl: "https://api.mainnet-beta.solana.com"});const recipient = address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB");const reference = address("YOUR_REFERENCE_ADDRESS");// Find the transaction by referenceconst found = await merchant.pay.findReference(reference);// Validate the transfer matches expected fieldsawait merchant.pay.validateTransfer(found.signature, {recipient,amount: 0.1});console.log("Payment confirmed!", found.signature);
Χρήση Αυτόνομων Συναρτήσεων
import { createSolanaRpc, address } from "@solana/kit";import { findReference, validateTransfer } from "@solana/pay";const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");const reference = address("YOUR_REFERENCE_ADDRESS");// Find transaction by referenceconst found = await findReference(rpc, reference);// Validate transaction detailsawait validateTransfer(rpc, found.signature, {recipient: address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB"),amount: 0.1});console.log("Payment confirmed!", found.signature);
Παρακολούθηση Πληρωμών (WebSocket)
Η προτεινόμενη προσέγγιση — το watchReference εγγράφεται μέσω WebSocket και
επιλύεται μόλις εντοπιστεί μια αντίστοιχη συναλλαγή. Δεν απαιτείται polling.
async function waitForPayment(reference, recipient, amount) {const merchant = createMerchantClient({rpcUrl: "https://api.mainnet-beta.solana.com"});// Resolves on the first transaction mentioning this referenceconst result = await merchant.pay.watchReference(reference);if (result.err) {throw new Error(`Transaction failed: ${JSON.stringify(result.err)}`);}// Validate that the transaction matches the expected paymentawait merchant.pay.validateTransfer(result.signature, { recipient, amount });return { signature: result.signature };}
Polling για Πληρωμές (εναλλακτική λύση HTTP)
Εάν οι εγγραφές WebSocket δεν είναι διαθέσιμες (π.χ. κάποιοι πάροχοι RPC),
χρησιμοποιήστε εναλλακτικά τη μέθοδο polling με findReference:
async function pollForPayment(reference, recipient, amount) {const merchant = createMerchantClient({rpcUrl: "https://api.mainnet-beta.solana.com"});const checkPayment = async () => {try {const found = await merchant.pay.findReference(reference);await merchant.pay.validateTransfer(found.signature, {recipient,amount});return { success: true, signature: found.signature };} catch {return { success: false };}};// Check every 2 secondsreturn new Promise((resolve) => {const interval = setInterval(async () => {const result = await checkPayment();if (result.success) {clearInterval(interval);resolve(result);}}, 2000);});}
Πλήρες Παράδειγμα
Ακολουθεί ένα πλήρες παράδειγμα με δημιουργία κωδικού QR και παρακολούθηση πληρωμής:
import { address, generateKeyPair, getAddressFromPublicKey } from "@solana/kit";import { encodeURL, createQR, createMerchantClient } from "@solana/pay";const recipient = address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB");const amount = 0.1;// Generate unique reference for this paymentconst keypair = await generateKeyPair();const reference = await getAddressFromPublicKey(keypair.publicKey);// Create payment URL and QR codeconst url = encodeURL({recipient,amount,reference,label: "Demo Store",message: "Test Purchase"});const qr = createQR(url);qr.append(document.getElementById("qr-code"));// Monitor for paymentconst merchant = createMerchantClient({rpcUrl: "https://api.mainnet-beta.solana.com"});const interval = setInterval(async () => {try {const found = await merchant.pay.findReference(reference);await merchant.pay.validateTransfer(found.signature, {recipient,amount,reference});clearInterval(interval);console.log("Payment confirmed!", found.signature);} catch {// Payment not found yet, keep polling}}, 2000);
Βέλτιστες Πρακτικές
Ασφάλεια
- Να επικυρώνετε πάντα τις πληρωμές από την πλευρά του διακομιστή
- Να χρησιμοποιείτε μοναδικές αναφορές για κάθε πληρωμή
- Να επαληθεύετε τα ποσά και τους παραλήπτες των συναλλαγών
- Να ελέγχετε την κατάσταση επιτυχίας των συναλλαγών
Εμπειρία Χρήστη
- Να εμφανίζετε σαφή ποσά και περιγραφές πληρωμών
- Να παρέχετε ενημερώσεις κατάστασης πληρωμής
- Να διαχειρίζεστε τη σύνδεση πορτοφολιού με ομαλό τρόπο
- Να υποστηρίζετε τόσο κωδικούς QR όσο και απευθείας συνδέσμους
Διαχείριση Σφαλμάτων
- Να διαχειρίζεστε αποτυχίες σύνδεσης πορτοφολιού
- Να παρέχετε εναλλακτική λύση για μη υποστηριζόμενα πορτοφόλια
- Να εμφανίζετε χρήσιμα μηνύματα σφάλματος
- Να εφαρμόζετε χρονικά όρια για τις πληρωμές
Συνήθεις Περιπτώσεις Χρήσης
Σημείο Πώλησης
const posPayment = encodeURL({recipient: merchantWallet,amount: 15.99,label: "Local Coffee Shop",message: `Receipt #${receiptNumber}`,memo: `POS-${terminalId}-${Date.now()}`});
Δωρεές
// Flexible donation amount (user enters amount in wallet)const donationUrl = encodeURL({recipient: charityWallet,label: "Save the Ocean",message: "Support marine conservation"});
Ολοκλήρωση Αγοράς E-commerce
const checkoutUrl = encodeURL({recipient: storeWallet,amount: cartTotal,reference: orderReference,label: storeName,message: `Order ${orderId}`,memo: `ORDER:${orderId}`});
Is this page helpful?