Machine Payments Protocol(MPP)は、HTTP認証のセマンティクスを決済に適用するプロトコルです。サーバーは未払いのリクエストに対してチャレンジを返し、クライアントは支払いクレデンシャルを返送し、サーバーは支払いを受理した後にレシートを返します。
MPPは3つの関心事を分離しています:
- インテントは、1回限りの
chargeや従量制のsessionなど、商取引上のやり取りを表します。 - 決済方式は、価値の移動方法を表します。Solana方式では、chargeにおいてネイティブのSOLとSPLトークンをサポートします。
- HTTPトランスポートは、チャレンジ、クレデンシャル、レシート、エラーを運びます。
MPPは一連のInternet-Draftとして公開されています。最新の仕様を正式な情報源として参照してください。ドラフトは作業中のため、詳細は今後変更される可能性があります。
HTTPのやり取り
MPPは、プロトコル固有の決済ヘッダーではなく、標準のHTTP認証フィールドを使用します:
| メッセージ | HTTPでの表現 |
|---|---|
| 支払いチャレンジ | WWW-Authenticate: Payment ...を伴う402 Payment Required |
| 支払いクレデンシャル | Authorization: Payment ...を付けて再送されるリクエスト |
| 成功レシート | Payment-Receipt: ...を含むリソースのレスポンス |
| 無効な支払い詳細 | application/problem+jsonを使用するProblem Detailsボディ |
チャレンジには、サーバーが生成したID、realm、method、intent、エンコードされた支払いリクエスト、有効期限が含まれます。クレデンシャルはチャレンジをそのまま返し、決済方式固有の支払い証明を追加します。サーバーは両方を検証する必要があります。別のチャレンジに属する有効な送金によって、リソースのロックが解除されてはなりません。
Solanaでの1回限りの課金
Solanaのchargeインテントは、2種類のクレデンシャルタイプをサポートします:
- Pullモードは署名済みトランザクションを使用します。クライアントが送金に署名し、そのトランザクションをサーバーに送信します。サーバーは検証を行い、必要に応じてfee payerの署名を追加し、ブロードキャストと承認確認を行って、レシートにトランザクション署名を含めて返します。
- Pushモードはトランザクション署名を使用します。クライアントが先にブロードキャストを行い、確認済みの署名をサーバーに送信します。サーバーはトランザクションを取得して検証してから、リソースを返します。
Pullモードでは、サーバーによる手数料のスポンサーとサーバー側のリトライロジックが可能です。Pushモードは、ウォレットがクライアント自身によるトランザクション送信を必要とする場合に便利ですが、サーバーによる手数料スポンサーは利用できません。
規範となるフィールドと検証ルールについては、Solana charge仕様を参照してください。
Express APIにMPP課金を追加する
Solana Pay Kitは、MPPとx402向けの最新のTypeScript統合を提供します。Expressと一緒にインストールします:
pnpm add @solana/pay-kit @solana/kit@^6.9.0 expresspnpm add --save-dev @types/express tsx
この最小限の例では、ホスト型のSurfpoolサンドボックスと、パッケージの公開デモ用受取先を使用します。ローカル開発専用です:
import express from "express";import { createPayKit, usd } from "@solana/pay-kit";const pay = await createPayKit({accept: ["mpp"],rpcUrl: "https://402.surfnet.dev:8899"});const app = express();app.get("/report", pay.express(usd("0.01")), (_req, res) => {res.json({ report: "Paid report" });});app.listen(4567, () => {console.log("Paid API listening on http://127.0.0.1:4567");});
実行して、未払いのリクエストと、支払いに対応したリクエストを比較します:
pnpm tsx server.tscurl -i http://127.0.0.1:4567/reportpay --sandbox curl http://127.0.0.1:4567/report
ルートハンドラーは、ミドルウェアが支払いを受理した後にのみ実行されます。
本番環境ではサンドボックスの既定値をすべて置き換えてください
明示的なネットワーク、加盟店の受取先、専用RPC、安定したチャレンジバインディング用シークレット、本番用署名者、永続的なリプレイストアを設定してください。実際の支払いをパッケージのデモ用署名者に送ってはいけません。
従量制セッション
クライアントが関連する少額の支払いを何度も行う場合は、Solana MPPのsessionを使用します。セッションは上限デポジット付きのオンチェーン支払いチャネルを開き、利用量の増加に応じて累積署名済みバウチャーを使用します。サーバーはバウチャーをオフチェーンで検証し、受理した最高額を後で精算できます。
これは、トークン従量制の推論、バイト従量制のダウンロード、ライブデータ、繰り返しのツール呼び出しなどに便利です。イベントごとに個別のオンチェーン支払いを送信するのとは異なります。
セッションは、セッション決済、支払いチャネル、または上限付き反復承認と呼んでください。サービスと支払い契約が実際に利用量のストリームを計測している場合にのみ、ストリーミング決済と呼んでください。
本番環境での検証
Solanaのすべての課金について、サーバーは最低限次の点を検証する必要があります:
- チャレンジが正当で、有効期限内であり、このリクエストに紐づけられ、このrealm向けであること。
- トランザクションが、想定されるネットワーク、アセットまたはmint、受取先、金額、token programを使用していること。
- fee payerまたはassociated token accountのinstructionsが明示的に許可されており、サーバーの署名者の資金を流出させないこと。
- トランザクションが、必要なコミットメントレベルで成功していること。
- トランザクション署名がまだ使用済みになっていないこと。
- リプレイチェックと消費処理が、すべてのサーバーインスタンスにわたってアトミックであること。
セッションの場合は、チャネルの状態、受理済みの累積金額、精算ウォーターマークも共有ストアに永続化してください。サーバーが利用できなくなった場合に、クライアントが未使用の資金を回収する方法をドキュメント化してください。
関連リソース
Is this page helpful?