전송 요청

전송 요청은 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 address
const recipient = address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB");
// Create the payment URL
const url = encodeURL({
recipient,
amount: 0.01, // 0.01 SOL
label: "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 mainnet
const usdcMint = address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const url = encodeURL({
recipient: address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB"),
amount: 10.5, // $10.50 USDC
splToken: usdcMint,
label: "Coffee Shop",
message: "Grande Latte + Tip"
});
console.log(url.toString());

URL 매개변수

필수 매개변수

수신자

수신자의 Solana 지갑 주소(base58 인코딩):

const recipient = address("FvJ8k8HhXp4a3zQyFMZd4FvEqcYdYE7gSZWxrEBRfBsB");

선택적 매개변수

금액

사용자 친화적 단위의 결제 금액(SOL 또는 토큰 단위):

// SOL amounts
const solAmount = 1.5; // 1.5 SOL
const smallAmount = 0.001; // 0.001 SOL
// Token amounts (USDC example)
const usdcAmount = 25.99; // $25.99 USDC

생략할 경우 지갑이 사용자에게 금액 입력을 요청합니다.

SPL 토큰

토큰 전송의 경우 민트 주소를 지정합니다:

// Common SPL tokens
const USDC = address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const USDT = address("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB");
// Omit splToken for native SOL transfers

참조

결제를 추적하기 위한 고유 식별자입니다. 참조 키로 사용할 주소를 생성하세요:

import { generateKeyPair, getAddressFromPublicKey } from "@solana/kit";
// Generate a unique reference
const 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 코드 통합

내장된 createQR 함수를 사용하여 QR 코드를 생성하세요:

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 element
const qr = createQR(url);
// Append to DOM
const 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 reference
const found = await merchant.pay.findReference(reference);
// Validate the transfer matches expected fields
await 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 reference
const found = await findReference(rpc, reference);
// Validate transaction details
await 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 reference
const 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 payment
await 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 seconds
return 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 payment
const keypair = await generateKeyPair();
const reference = await getAddressFromPublicKey(keypair.publicKey);
// Create payment URL and QR code
const url = encodeURL({
recipient,
amount,
reference,
label: "Demo Store",
message: "Test Purchase"
});
const qr = createQR(url);
qr.append(document.getElementById("qr-code"));
// Monitor for payment
const 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?

관리자

© 2026 솔라나 재단.
모든 권리 보유.
연결하기