法定通貨から仮想通貨へのオンランプは、かつては数週間にわたるコンプライアンス書類作成、銀行との関係構築、そしてKYCベンダーをダクトテープでつなぎ合わせたようなものでした。MoonPay APIは、その複雑なプロセスを単一の統合に集約します。署名付きURLを生成し、ウィジェットをアプリに組み込むだけで、MoonPayがカード処理、銀行振込、本人確認、ユーザーのウォレットへの支払いをすべて処理します。
このガイドでは、MoonPay APIをエンドツーエンドで使用する方法を説明します。具体的には、パートナーアカウントの設定、ウィジェットと直接APIの比較、署名付きURLの構築、ウェブフックの検証、売却フロー、NFTチェックアウト、そして計画に含める必要のあるコンプライアンス制限についてです。以下のすべてのリクエストはサンドボックスでテストされ、MoonPay公式開発者ポータルに記載されています。構築中にApidog内で同じ呼び出しを実行できます。
まだプロバイダーを比較している場合は、Transak、Ramp、Stripe Cryptoと比較してMoonPayがどこに位置するかを確認するために、最適な法定通貨オンランプ/オフランプAPIのまとめから始めてください。カストディアルインフラストラクチャを評価している開発者は、スタックのUSDC側の視点を得るために、Circle APIの使用方法も読むべきです。
TL;DR
- MoonPayは、160カ国以上でウォレット、NFTマーケットプレイス、取引所によって使用されている、規制された法定通貨から仮想通貨へのオンランプおよびオフランプです。
- 2つの統合パス:Ramps SDK/ウィジェット(最速、MoonPayホストのUI)または直接REST API(完全な制御、UIは自分で構築)。
- すべてのウィジェットURLは、秘密鍵を使用してHMAC-SHA256で署名する必要があります。署名されていないURLは本番環境では拒否されます。
- KYC、カード処理、銀行連携はMoonPayによってサーバー側で処理されます。ステータスは、同じHMACパターンで署名されたウェブフックを介して受け取ります。
- 料金は、処理手数料(カードで3.5%~4.5%、銀行振込ではより低い)と基盤となるネットワーク手数料で構成され、ユーザーには透過的に提示されます。
- オフランプ(売却)は購入フローを反映しています。署名付きURL、ユーザーが仮想通貨を入金アドレスに送信、MoonPayがユーザーの銀行に法定通貨を送金します。
MoonPayとは?
MoonPayは、ユーザーがカード、銀行振込、Apple Pay、Google Pay、SEPA、および地域の決済手段を使用して仮想通貨を売買できるようにする、認可された決済会社です。米国では送金業者(money services business)として運営され、EUではEMIライセンスを保有し、英国、カナダ、オーストラリアで登録されています。実質的な効果として、カードを受け入れてETHをユーザーのウォレットに送金するために、送金業者になる必要はありません。
このプラットフォームは、40以上のネットワーク(Ethereum、Solana、Bitcoin、Polygon、Base、Arbitrum)にわたる110以上の仮想通貨、およびNFTチェックアウトをカバーしています。MetaMask、Trust Wallet、OpenSeaの内部オンランプとして機能しています。
認証と設定
moonpay.com/businessでパートナーアカウントにサインアップしてください。承認後、サンドボックスと本番環境の2組のキーが付与されます。各セットには公開可能キー(pk_test_...)と秘密キー(sk_test_...)があります。秘密キーはデータベースパスワードのように扱い、すべてのURLに署名し、すべてのウェブフックを検証するために使用されます。
環境に設定します。
export MOONPAY_API_KEY="pk_test_123..."
export MOONPAY_SECRET_KEY="sk_test_abc..."
export MOONPAY_BASE_URL="https://api.moonpay.com"
サンドボックスは本番環境と同じエンドポイントを持っていますが、ダッシュボードを使用して状態を切り替えられるテストトランザクションを返します。完全なハッピーパスのために使用し、MoonPayとのコンプライアンス審査が完了したら本番環境のキーに切り替えてください。
コアエンドポイント
MoonPayは、通貨、見積もり、トランザクション、ウェブフックなど、最も頻繁に利用するいくつかのエンドポイントグループを公開しています。完全なRESTリファレンスにはすべてのリソースがリストされています。
サポートされている通貨をリストする
ピッカーを構築する前に、ライブリストを取得してください。利用可能性は国によって異なるため、ユーザーのIPまたは宣言された場所でフィルタリングする必要があります。
curl -X GET "https://api.moonpay.com/v3/currencies" \
-H "Authorization: Api-Key $MOONPAY_API_KEY"
レスポンスは、code、name、type(cryptoまたはfiat)、minBuyAmount、maxBuyAmount、および複数のチェーン上に存在するトークンのネットワークごとのメタデータを含む配列を返します。
リアルタイム見積もりを取得する
見積もりは、ユーザーがコミットする前に受け取る仮想通貨の正確な量を伝えます。手数料が含まれます。
curl -X GET "https://api.moonpay.com/v3/currencies/eth/buy_quote?apiKey=$MOONPAY_API_KEY&baseCurrencyAmount=100&baseCurrencyCode=usd" \
-H "Content-Type: application/json"
quoteCurrencyAmount、feeAmount、networkFeeAmount、およびtotalAmountが返されます。ユーザーがクリックするまでの数秒間、見積もりをキャッシュしてください。MoonPayは約60秒間、それを尊重します。
署名付き購入ウィジェットURLを構築する(Node)
購入ウィジェットは、機能する統合への最速のパスです。クエリパラメータを含むURLを構築し、秘密鍵で署名し、ユーザーをリダイレクトするか、iframeに読み込みます。以下はNode版です。
import crypto from "node:crypto";
function buildMoonPayBuyUrl({ walletAddress, currencyCode, baseAmount, email }) {
const params = new URLSearchParams({
apiKey: process.env.MOONPAY_API_KEY,
currencyCode,
walletAddress,
baseCurrencyCode: "usd",
baseCurrencyAmount: String(baseAmount),
email,
redirectURL: "https://yourapp.com/moonpay/complete",
});
const originalUrl = `https://buy.moonpay.com?${params.toString()}`;
const signature = crypto
.createHmac("sha256", process.env.MOONPAY_SECRET_KEY)
.update(new URL(originalUrl).search)
.digest("base64");
return `${originalUrl}&signature=${encodeURIComponent(signature)}`;
}
このURLをユーザーに渡します。署名はパラメータをあなたのアカウントにバインドするため、悪意のあるクライアントがwalletAddressを入れ替えたり、金額を変更したりしても、それを無効にすることはできません。購入ウィジェットクイックスタートには、サポートされているすべてのパラメータが記載されています。
ウェブフック署名を検証する
MoonPayは、transaction_created、transaction_updated、transaction_failed、および売却/NFT関連のイベントなど、ライフサイクルイベントをあなたのエンドポイントに送信します。すべてのリクエストにはMoonpay-Signature-V2ヘッダーが含まれており、ペイロードを信頼する前にこれを検証する必要があります。
import crypto from "node:crypto";
export function verifyMoonPayWebhook(rawBody, header, secret) {
const [tPart, sPart] = header.split(",");
const timestamp = tPart.split("=")[1];
const signature = sPart.split("=")[1];
const expected = crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected, "hex"),
Buffer.from(signature, "hex"),
);
}
リプレイ攻撃を防ぐため、5分より古いリクエストは拒否してください。ウェブフックリファレンスには、すべてのイベントタイプとペイロードの形式が記載されています。
売却(オフランプ)フロー
売却フローは購入フローを反映しています。sell.moonpay.comを指す署名付きURLを構築し、ユーザーが仮想通貨と金額を選択すると、MoonPayが入金アドレスを生成し、ユーザーはウォレットから資金を送信します。トランザクションがオンチェーンで確認されると、MoonPayはユーザーのリンクされた銀行口座に法定通貨を送金します。
const sellParams = new URLSearchParams({
apiKey: process.env.MOONPAY_API_KEY,
baseCurrencyCode: "eth",
baseCurrencyAmount: "0.5",
quoteCurrencyCode: "usd",
refundWalletAddress: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbc",
});
const sellUrl = `https://sell.moonpay.com?${sellParams.toString()}`;
// sign the same way as the buy URL
refundWalletAddressは重要です。ユーザーが誤った資産を送った場合や、トランザクションがKYCに失敗した場合、MoonPayはそこに資金を返還します。
NFTチェックアウト
NFTチェックアウトでは、ユーザーはカードでリストされたNFTを購入できます。あなたはMoonPayにリストを登録し(またはサポートされているマーケットプレイス統合を使用し)、contractAddress、tokenId、listingIdを含む署名付きURLを生成します。MoonPayは法定通貨による支払いとオンチェーン転送を単一のフローで処理するため、高額な一次販売での離脱率を劇的に低減します。
よくあるエラーとレート制限
ほとんどの統合問題は、以下の短いリストに集約されます。
400 invalid_signatureは、あなたのHMAC入力がサーバーのものと一致しないことを意味します。最も頻繁な原因は、クライアントと署名者の間のURLエンコーディングの違いです。送信する正確なクエリ文字列を署名してください。403 geo_restrictedは、ユーザーのIPが、MoonPayがその通貨に対してサービスを提供していない国に該当することを示します。通貨オブジェクトのisAllowedフィールドをレンダリングする前に確認してください。422 transaction_limit_exceededは、ユーザーが日次、週次、または月次の上限に達したことを意味します。カードの制限は通常、強化されたKYCを完了するまで、1日あたり2,000ドル、1ヶ月あたり10,000ドルです。429 rate_limitedは、公開エンドポイントでAPIキーあたり毎分約100リクエストでトリガーされます。通貨リストと見積もりを積極的にキャッシュしてください。
状態については、ユーザーのブラウザではなくウェブフックを信頼してください。リダイレクト前にタブを閉じたユーザーでも、status: completedのtransaction_updatedイベントが発火すれば、ウォレットには資金が供給されます。
マルチウォレットサポートを構築している場合、MetaMask APIの使用方法と最適な仮想通貨ウォレットAPIに関するガイドは、このガイドと相性が良いです。コンプライアンスの本人確認側については、最適なKYC APIのまとめをご覧ください。
MoonPayの料金
MoonPayは、処理手数料とネットワーク手数料を請求し、両方ともウィジェット内でユーザーに表示されます。
- カード購入: 法定通貨額の3.5%~4.5%で、最低$3.99。
- 銀行振込(ACH、SEPA、オープンバンキング): 1%~1.9%で、高額な取引でははるかに安価です。
- ネットワーク手数料: 実費で転嫁され、チェーンと混雑状況によって異なります。
- 売却フロー: 同様の構造で、支払手数料は送金先の手段によって異なります。
パートナーへのレベニューシェアは、取引量が増加した時点で別途交渉されます。高取引量の統合では、通常、カスタム料金と専任のコンプライアンス担当者が割り当てられます。
ApidogでMoonPayをテストする
署名付きURLとHMACウェブフックは、ほとんどのMoonPay統合が破綻する2つの箇所であり、どちらもアプリケーションコードよりも適切なAPIクライアントでデバッグする方が高速です。Apidogを使用すると、MoonPay OpenAPI仕様をインポートし、サンドボックスキーを環境変数として保存し、バックエンドに触れることなく、購入見積もり、トランザクションステータス、ウェブフックのリプレイサイクル全体を実行できます。

実用的なワークフロー:sandbox用とproduction用にApidog環境を作成し、上記のNode cryptoスニペットを使用して署名生成をプレリクエストフックとしてスクリプト化し、サンプル取引IDを変数として保存することで、createTransactionからgetTransactionStatusに直接ジャンプできます。本番環境でウェブフックが到着したら、その生データをApidogのモックサーバーにコピーし、検証が成功するまでローカルエンドポイントに対してリプレイしてください。Apidogをダウンロードして、署名フック、モックサーバー、環境スイッチャーを一つの場所で手に入れてください。
よくある質問
MoonPay以外に独自のKYCベンダーが必要ですか?いいえ。MoonPayがサーバー側で本人確認を実行するため、あなたのアプリが本人確認書類を見ることはありません。製品の他の部分で事前に本人確認を行いたい場合は、最適なKYC APIの比較をご覧ください。
MoonPayのブランド入りウィジェットを表示せずに使用できますか?はい、直接APIまたはヘッドレスRamps SDKを介して可能です。ただし、ブランド入りのフローが多くの必要な開示を自動的にカバーするため、追加のコンプライアンス審査が必要です。ほとんどのチームはまずウィジェットを導入し、取引量が審査を正当化するようになった時点で移行します。
MoonPayはどの国をサポートしていますか?購入は160カ国以上、売却はそれより少ない国(約50カ国)をサポートしており、通貨と決済方法の利用可能性は地域によって異なります。通貨エンドポイントは、ユーザーの場所ごとの現在のマトリックスを返します。
取引にはどのくらい時間がかかりますか?カード購入は、問題がなければ5分以内にユーザーのウォレットに決済されます。銀行振込は、仮想通貨がリリースされる前に法定通貨の清算に1~3営業日かかります。売却取引は、オンチェーン確認後1~3日でユーザーの銀行に法定通貨が決済されます。
ウェブフックの配信が失敗した場合、どうなりますか?MoonPayは、最大24時間指数関数的バックオフで再試行します。イベントを永続化させた後にのみ2xxレスポンスを返し、再試行によって重複が発生する可能性があるため、idで重複排除を行う必要があります。
サンドボックスは本番環境と同等ですか?近いですが、同一ではありません。地理的制限は緩和され、テストドキュメントでKYCがバイパスされ、トランザクションはダッシュボードの制御に基づいて状態が遷移します。キーが発行された後には、必ず最終的な本番環境のスモークテストを実行してください。
