법정화폐-암호화폐 온램프는 과거에 수 주간의 규정 준수 서류 작업, 은행 관계, 그리고 덕트 테이프로 땜질한 KYC 공급업체를 의미했습니다. MoonPay API는 이러한 복잡한 과정을 단일 통합으로 단순화합니다: 서명된 URL을 생성하고 앱에 위젯을 삽입하면, MoonPay가 카드 처리, 은행 송금, 신원 확인, 그리고 사용자 지갑으로의 지급을 처리합니다.
이 가이드는 MoonPay API를 처음부터 끝까지 사용하는 방법을 설명합니다: 파트너 계정 설정, 위젯과 직접 API 비교, 서명된 URL 구성, 웹훅 확인, 판매 흐름, NFT 결제, 그리고 고려해야 할 규정 준수 제한 사항들입니다. 아래의 모든 요청은 샌드박스에서 테스트되었으며, MoonPay 공식 개발자 포털에 문서화되어 있습니다. 개발 중에는 Apidog 내에서 동일한 호출을 실행할 수 있습니다.
여전히 제공업체를 비교 중이라면, 최고의 법정화폐 온램프 및 오프램프 API 비교 글을 통해 MoonPay가 Transak, Ramp, Stripe Crypto와 어떻게 다른지 확인해 보세요. 수탁 인프라를 평가하는 개발자는 스택의 USDC 측면을 이해하기 위해 Circle API 사용 방법도 읽어봐야 합니다.
요약 (TL;DR)
- MoonPay는 160개 이상의 국가에서 지갑, NFT 마켓플레이스, 거래소에서 사용되는 규제된 법정화폐-암호화폐 온램프 및 오프램프입니다.
- 두 가지 통합 경로: 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 및 현지 결제 시스템을 통해 암호화폐를 구매하고 판매할 수 있도록 하는 라이선스를 보유한 결제 회사입니다. 미국에서는 송금 서비스 사업자로 운영되며, EU에서는 EMI 라이선스를 보유하고 있으며, 영국, 캐나다, 호주 전역에 등록되어 있습니다. 실질적인 효과: 카드를 받고 사용자 지갑으로 이더리움을 전송하기 위해 송금 사업자가 될 필요가 없습니다.
이 플랫폼은 40개 이상의 네트워크(이더리움, 솔라나, 비트코인, 폴리곤, 베이스, 아비트럼)에서 110개 이상의 암호화폐를 지원하며, NFT 결제 기능도 포함합니다. MetaMask, Trust Wallet, OpenSea 내의 온램프입니다.
인증 및 설정
moonpay.com/business에서 파트너 계정에 가입하세요. 승인 후 샌드박스와 프로덕션용 두 세트의 키를 받게 됩니다. 각 세트에는 공개 키(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는 법정화폐 부분과 온체인 전송을 하나의 흐름으로 처리하여, 고가치 1차 판매에서의 이탈률을 극적으로 줄여줍니다.
일반적인 오류 및 속도 제한
대부분의 통합 문제는 다음의 몇 가지 항목에 해당됩니다:
400 invalid_signature는 귀하의 HMAC 입력이 서버와 일치하지 않음을 의미합니다. 가장 흔한 원인은 클라이언트와 서명자 간의 URL 인코딩 차이입니다. 보내는 쿼리 문자열과 정확히 일치하도록 서명하세요.403 geo_restricted는 사용자 IP가 MoonPay가 해당 통화에 대해 서비스를 제공하지 않는 국가에 있음을 나타냅니다. 통화 객체의isAllowed필드를 확인한 후 렌더링하세요.422 transaction_limit_exceeded는 사용자가 일일, 주간 또는 월간 한도를 초과했음을 의미합니다. 카드 한도는 사용자가 강화된 KYC를 완료하기 전까지 일반적으로 일일 $2,000, 월간 $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 통합이 실패하는 두 지점이며, 둘 다 애플리케이션 코드에서보다 적절한 API 클라이언트에서 디버깅하는 것이 더 빠릅니다. Apidog를 사용하면 MoonPay OpenAPI 사양을 가져오고, 샌드박스 키를 환경 변수로 저장하며, 백엔드에 손대지 않고 전체 구매 견적, 거래 상태 및 웹훅 재실행 주기를 실행할 수 있습니다.

실용적인 워크플로: sandbox용 Apidog 환경과 production용 환경을 생성하고, 위 Node 암호화 스니펫을 사용하여 서명 생성을 사전 요청 훅으로 스크립트하며, 샘플 거래 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는 테스트 문서로 우회되며, 거래는 대시보드 제어에 따라 상태가 변경됩니다. 키가 발급된 후에는 항상 최종 프로덕션 스모크 테스트를 실행하세요.
