طلبات التحويل هي أبسط أشكال التكامل مع Solana Pay. فهي تنشئ روابط دفع غير تفاعلية يمكن للمحافظ استخدامها لإنشاء وإرسال المعاملات مباشرة دون الحاجة إلى خادم.
نظرة عامة
يتبع رابط طلب التحويل هذا التنسيق:
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
إنشاء طلب دفع 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());
معاملات الرابط
المعاملات المطلوبة
المستلم
عنوان محفظة سولانا الخاصة بالمستلم (مشفر base58):
const recipient = address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB");
المعاملات الاختيارية
المبلغ
مبلغ الدفع بوحدات سهلة الاستخدام (SOL أو وحدات الرمز):
// 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
لتحويلات الرموز، حدد عنوان السك:
// 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";
تكامل رمز الاستجابة السريعة
قم بإنشاء رموز الاستجابة السريعة باستخدام دالة 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);
التحقق من صحة الدفع
استخدام عميل التاجر
الطريقة الأبسط للعثور على المدفوعات والتحقق من صحتها:
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 ويتم حله بمجرد وصول
معاملة مطابقة. لا حاجة للاستقصاء الدوري.
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 };}
الاستقصاء الدوري للمدفوعات (HTTP كبديل احتياطي)
إذا لم تكن اشتراكات WebSocket متاحة (على سبيل المثال بعض موفري RPC)، استخدم
الاستعلام الدوري مع 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"});
إتمام الشراء للتجارة الإلكترونية
const checkoutUrl = encodeURL({recipient: storeWallet,amount: cartTotal,reference: orderReference,label: storeName,message: `Order ${orderId}`,memo: `ORDER:${orderId}`});
Is this page helpful?