決済フロー
@solana-commerce/headlessパッケージは、コマース決済フローを構築するためのフレームワーク非依存の関数を提供します。これらのツールは、決済リクエストオブジェクトの作成、Solana
Pay
URLの生成、オンチェーン決済の検証を支援します。このパッケージは、React、Vue、Svelte、バニラJS、Node.js、サーバーレス関数など、あらゆるJavaScript環境で動作するように設計されています。
インストール
pnpm add @solana-commerce/headless
決済リクエスト関数
これらの関数は、異なるコマースパターンに対応した標準化された決済リクエストオブジェクトを作成します。ブロックチェーン操作は実行せず、ウォレット、Solana Pay URL、カスタム決済UIで使用するためのデータを構造化するだけです。
createBuyNowRequest()
単一商品の購入に対する標準化された決済リクエストを作成します。
function createBuyNowRequest(recipient: string,product: any,options?: {memo?: string;label?: string;message?: string;}): PaymentRequest;
パラメータ
-
recipient(string、必須) - 支払いを受け取るマーチャントウォレットアドレス(base58エンコードされたSolanaパブリックキー)。 -
product(any、必須) - 以下を含む商品オブジェクト:price(number、必須) - 商品価格。単位は文脈に依存します(例: SOLの場合はlamport、トークンの場合は最小単位)。currency(string、必須) - 支払い通貨。'SOL'またはトークンミントアドレスを指定できます。name(string、必須) - 商品名。指定されていない場合、デフォルトのメモ/ラベルとして使用されます。- その他のフィールド(id、description、imageなど)は、
products配列に渡されます。
-
options(object、任意) - カスタマイズオプション:memo(string) - トランザクションのオンチェーンメモ。デフォルト:"Purchase: {product.name}"。label(string) - 決済リクエストの表示ラベル(Solana Payで使用)。デフォルト:product.name。message(string) - 支払い後に表示される成功メッセージ。デフォルト:"Thank you for purchasing {product.name}!"。
戻り値
以下を含むPaymentRequestオブジェクト:
recipient- マーチャントウォレットアドレスamount- 商品価格(product.priceからコピー)currency- 支払い通貨(product.currencyからコピー)products- 単一商品を含む配列memo- トランザクションメモ(オプションまたはデフォルト: "Purchase: (product.name)")label- 決済ラベル(オプションまたはデフォルト: "product.name")message- 成功メッセージ(オプションまたはデフォルト: "Thank you for purchasing (product.name)!")
例:
const payment = createBuyNowRequest("merchant-wallet-address",{id: "prod_123",name: "Premium Subscription",price: 50000000, // 0.05 SOL in lamportscurrency: "SOL"},{label: "Premium Subscription",message: "Thank you for subscribing!"});
createCartRequest()
ショッピングカート内の複数の商品に対する支払いリクエストを作成します。
function createCartRequest(recipient: string,products: any[],options?: {memo?: string;label?: string;message?: string;currency?: string;}): PaymentRequest;
パラメータ
-
recipient(string、必須) - 支払いを受け取るマーチャントのウォレットアドレス。 -
products(any[]、必須) - 商品オブジェクトの配列。 -
options(object、オプション) - カスタマイズオプション:currency(string) - カート全体の支払い通貨。memo(string) - オンチェーンメモ。デフォルト:"Cart purchase (products.length items)"。label(string) - 支払いラベル。デフォルト:"Cart Checkout"。message(string) - 成功メッセージ。デフォルト:"Thank you for your purchase!"。
戻り値
以下を含むPaymentRequestオブジェクト:
recipient- マーチャントのウォレットアドレスamount- すべての商品価格の合計 (products.reduce((sum, p) => sum + p.price, 0))currency- 支払い通貨(オプションから、または未定義)products- 商品の配列memo、label、message- オプション値またはデフォルト値
例:
const cart = createCartRequest("merchant-wallet-address",[{ id: "1", name: "Product A", price: 25 },{ id: "2", name: "Product B", price: 15 },{ id: "3", name: "Product C", price: 10 }],{currency: "USDC",label: "My Store Checkout",message: "Thank you for your order!"});// cart.amount === 50 (sum of prices)
createTipRequest()
チップや寄付のための支払いリクエストを、ユーザー定義の金額で作成します。
function createTipRequest(recipient: string,amount: number,options?: {currency?: string;memo?: string;label?: string;message?: string;}): PaymentRequest;
パラメータ
-
recipient(string、必須) - チップの受取人のウォレットアドレス (クリエイター、ストリーマー、チャリティなど)。 -
amount(number、必須) - チップの金額。単位は通貨に依存 (SOLの場合はlamport、トークンの場合は最小単位)。 -
options(object、オプション) - カスタマイズオプション:currency(string) - 支払い通貨。デフォルト: 未定義(通常、消費者によってSOLとして扱われます)。memo(string) - オンチェーンメモ。デフォルト:"Thank you for your support!"。label(string) - 支払いラベル。デフォルト:"Tip"。message(string) - 成功メッセージ。デフォルト:"Thanks for the tip!"。
戻り値
以下を含むPaymentRequestオブジェクト:
recipient- チップ受取人のウォレットアドレスamount- チップの金額currency- 支払い通貨(オプションから、または未定義)memo、label、message- オプション値またはデフォルト値
例:
const tip = createTipRequest("creator-wallet-address",5_000_000, // 0.005 SOL in lamports{currency: "SOL",label: "Tip for Content Creator",message: "Thanks for the support!"});
支払い検証関数
これらの関数はSolanaと連携してトランザクションを検証し、承認を待機します。gillライブラリのSolana
RPCクライアントが必要です。
verifyPayment()
トランザクションがオンチェーンに存在することを検証し、オプションで支払い額、受取人、トークンを検証します。
async function verifyPayment(rpc: SolanaClient["rpc"],signatureString: string,expectedAmount?: number,expectedRecipient?: string,expectedMint?: string): Promise<PaymentVerificationResult>;
パラメータ
-
rpc(SolanaClient['rpc']、必須)-gillのRPCクライアント。createSolanaClient(rpcUrl).rpcで作成します。 -
signatureString(string、必須)- 検証するトランザクション署名(base58エンコード)。 -
expectedAmount(number、オプション)- 検証する予想支払い額。単位は通貨に合わせる必要があります:- SOLの場合:lamport(1 SOL = 1,000,000,000 lamport)
- SPLトークンの場合:トークンの小数点以下の桁数に基づく最小単位(例:USDCは6桁)
指定しない場合、金額の検証はスキップされます。
-
expectedRecipient(string、オプション)- 予想される受取人のウォレットアドレス。指定した場合(expectedAmountと共に)、関数は受取人が少なくともこの金額を受け取ったことを検証します。指定しない場合、検証はスキップされます。 -
expectedMint(string、オプション)- SPLトークンのミントアドレス。SPLトークン転送の場合のみ必要です。指定しない場合、関数はSOL転送と見なします。
戻り値
Promise<PaymentVerificationResult>オブジェクト:
interface PaymentVerificationResult {verified: boolean; // True if payment is validsignature?: string; // Transaction signature (echoed back)amount?: number; // Expected amount (echoed back)recipient?: string; // Expected recipient (echoed back)error?: string; // Error message if verification failed}
検証ロジック
この関数は以下のチェックを実行します:
-
署名の妥当性: 署名が有効であることを確認します。
-
トランザクションの存在:
rpc.getTransaction()を使用してトランザクションを取得します。見つからない場合はverified: falseを返します。 -
承認ステータス: トランザクションがオンチェーンに記録されていることを確認します。
-
SOL転送の検証(
expectedRecipientとexpectedAmountが指定され、expectedMintが指定されていない場合):- トランザクション内の受取人のアカウントインデックスを特定
preBalancesとpostBalancesを比較して残高差分を計算- 差分が少なくとも
expectedAmountであることを検証
-
SPLトークン転送の検証(
expectedMintが指定されている場合):- 受取人のトークンプログラムとToken-2022プログラムの両方についてAssociated Token Account(ATA)を導出します
postTokenBalancesで期待されるミントと一致するATAを確認します- トークン量が少なくとも
expectedAmount以上であることを検証します
セキュリティに関する考慮事項
- クライアント側での検証: この関数はRPCからトランザクションデータを取得します。RPC URLをクライアントに公開しないでください。
- ファイナライゼーション:
この関数は確認済みトランザクションをチェックしますが、高額の支払いについては、
finalizedステータスを待つことを検討してください。
例:
import { verifyPayment } from "@solana-commerce/headless";import { createSolanaClient } from "gill";const client = createSolanaClient({urlOrMoniker: "mainnet"});const result = await verifyPayment(client.rpc,"transaction-signature-here",50_000_000, // 0.05 SOL in lamports"merchant-wallet-address"// No mint = SOL transfer);if (result.verified) {console.log("Payment confirmed!");} else {console.error("Verification failed:", result.error);}
waitForConfirmation()
トランザクションが確認済みまたはファイナライズ済みステータスに達するか、タイムアウトするまでブロックチェーンをポーリングします。
async function waitForConfirmation(rpc: SolanaClient["rpc"],signatureStr: string,timeoutMs?: number): Promise<boolean>;
パラメータ
-
rpc(SolanaClient['rpc']、必須) -gillのRPCクライアント。 -
signatureStr(string、必須) - 待機するトランザクション署名。 -
timeoutMs(number、オプション) - 待機する最大時間(ミリ秒単位)。デフォルト:30000(30秒)。
戻り値
Promise<boolean>- トランザクションがタイムアウト内にconfirmedまたはfinalizedステータスに達した場合はtrueを返し、それ以外の場合はfalseを返します。
例:
import { waitForConfirmation } from "@solana-commerce/headless";import { createSolanaClient } from "gill";const client = createSolanaClient({urlOrMoniker: "mainnet"});// After sending transactionconst signature = await wallet.sendTransaction(transaction);// Wait for confirmation (30 second timeout)const confirmed = await waitForConfirmation(client.rpc, signature, 30000);if (confirmed) {console.log("Transaction confirmed!");} else {console.log("Timeout - transaction not confirmed within 30 seconds");}
Solana Pay関数
これらの関数は、モバイルウォレットでスキャン可能なSolana PayのURLとスタイル付きQRコードを生成します。
createSolanaPayRequest()
Solana Pay URLとスタイル付きQRコードを作成します。
async function createSolanaPayRequest(request: TransferRequestURLFields,options: SolanaPayRequestOptions): Promise<{ url: URL; qr: string }>;
パラメータ
-
request(TransferRequestURLFields、必須) - Solana Pay転送リクエストフィールド:recipient- 受取人の公開鍵(@solana-commerce/solana-payのcreateRecipient(address)を使用)amount- (オプション)最小単位での支払い額(SOLの場合はlamport)splToken(オプション) - SPLトークンミントの公開鍵(INLINE_CODE_PLACEHOLDER_6a70865e237b811fを使用_END)reference(オプション) - 追跡用の参照公開鍵label(オプション) - 加盟店名message(オプション) - 成功メッセージmemo(オプション) - オンチェーンメモ
-
options(SolanaPayRequestOptions、必須) - QRコードのスタイル設定オプション:size(数値) - QRコードの幅/高さ(ピクセル単位)。デフォルト:256。background(文字列) - 背景色(hex/rgb)。デフォルト:'white'。color(文字列) - QRコードの色(hex/rgb)。デフォルト:'black'。margin(数値) - QRコード周囲のマージン(モジュール単位)。errorCorrectionLevel('L' | 'M' | 'Q' | 'H') - 誤り訂正レベル。レベルが高いほど損傷に強くなりますが、コードの密度が高くなります。logo(文字列) - QRコードの中央に埋め込むロゴ画像のURL。logoSize(数値) - QRコードサイズに対するロゴサイズの割合。logoBackgroundColor(文字列) - ロゴ背景の背景色。logoMargin(数値) - ロゴ周囲のマージン。dotStyle('dots' | 'rounded' | 'square') - QRコードモジュールの形状。cornerStyle('square' | 'rounded' | 'extra-rounded' | 'full-rounded' | 'maximum-rounded') - コーナーマーカーの形状。
戻り値
以下のオブジェクトに解決されるPromise:
url(URL) - Solana PayのURL(例:solana:recipient?amount=10&spl-token=...)qr(文字列) - QRコード画像のBase64エンコードされたデータURL(<img src={qr} />として使用)
例:
import {createSolanaPayRequest,createRecipient,createSPLToken} from "@solana-commerce/solana-pay";const payment = await createSolanaPayRequest({recipient: createRecipient("merchant-wallet-address"),amount: 10_000_000, // 0.01 SOL in lamportssplToken: createSPLToken("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"), // USDClabel: "My Store",message: "Thank you for your purchase!"},{size: 400,background: "#FFFFFF",color: "#000000",logo: "/logo.png",logoSize: 20,errorCorrectionLevel: "H"});// Display QR codedocument.getElementById("qr").src = payment.qr;console.log(payment.url.toString()); // solana:merchant...?amount=10000000&spl-token=...
Is this page helpful?