CtrlK
BlogDocsLog inGet started
Tessl Logo

moonpay

MoonPay fiat-to-crypto on-ramp integration. Buy and sell crypto with credit cards, bank transfers, and mobile payments.

69

Quality

59%

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Advisory

Suggest reviewing before use

Optimize this skill with Tessl

npx tessl skill review --optimize ./public/skills/0xterrybit/moonpay/SKILL.md
SKILL.md
Quality
Evals
Security

MoonPay 🌙

Leading fiat-to-crypto on-ramp. Buy crypto with cards, bank transfers, and mobile payments in 160+ countries.

Environment Variables

VariableDescriptionRequired
MOONPAY_API_KEYPublishable API KeyYes
MOONPAY_SECRET_KEYSecret Key for signingYes
MOONPAY_ENVsandbox or productionNo

Features

  • 💳 Card Payments - Visa, Mastercard, Apple Pay, Google Pay
  • 🏦 Bank Transfers - SEPA, ACH, Faster Payments
  • 📱 Mobile Payments - PIX, GCash, GrabPay
  • 🔄 Off-Ramp - Sell crypto to fiat
  • 🎨 NFT Checkout - Fiat-to-NFT purchases

API Base URLs

  • Sandbox: https://api.moonpay.com (use test API key)
  • Production: https://api.moonpay.com

Get Supported Currencies

API_KEY="${MOONPAY_API_KEY}"

# Get crypto currencies
curl -s "https://api.moonpay.com/v3/currencies" \
  -H "Authorization: Api-Key ${API_KEY}" | jq '.[] | select(.type == "crypto") | {code: .code, name: .name, minBuyAmount: .minBuyAmount}'

# Get fiat currencies
curl -s "https://api.moonpay.com/v3/currencies" \
  -H "Authorization: Api-Key ${API_KEY}" | jq '.[] | select(.type == "fiat") | {code: .code, name: .name}'

Get Quote

API_KEY="${MOONPAY_API_KEY}"
BASE_CURRENCY="usd"
QUOTE_CURRENCY="eth"
BASE_AMOUNT="100"

curl -s "https://api.moonpay.com/v3/currencies/${QUOTE_CURRENCY}/buy_quote" \
  -G \
  --data-urlencode "apiKey=${API_KEY}" \
  --data-urlencode "baseCurrencyCode=${BASE_CURRENCY}" \
  --data-urlencode "baseCurrencyAmount=${BASE_AMOUNT}" | jq '{
    quoteCurrencyAmount: .quoteCurrencyAmount,
    feeAmount: .feeAmount,
    networkFeeAmount: .networkFeeAmount,
    totalAmount: .totalAmount,
    extraFeeAmount: .extraFeeAmount
  }'

Generate Widget URL

API_KEY="${MOONPAY_API_KEY}"
SECRET_KEY="${MOONPAY_SECRET_KEY}"

# Build widget URL
BASE_URL="https://buy.moonpay.com"
PARAMS="?apiKey=${API_KEY}&currencyCode=eth&walletAddress=<WALLET>&baseCurrencyAmount=100"

# Sign URL (required for production)
SIGNATURE=$(echo -n "${PARAMS}" | openssl dgst -sha256 -hmac "${SECRET_KEY}" -binary | base64 | tr '+/' '-_' | tr -d '=')

WIDGET_URL="${BASE_URL}${PARAMS}&signature=${SIGNATURE}"
echo "Widget URL: $WIDGET_URL"

Create Transaction (Server-Side)

API_KEY="${MOONPAY_API_KEY}"
SECRET_KEY="${MOONPAY_SECRET_KEY}"

curl -s -X POST "https://api.moonpay.com/v3/transactions" \
  -H "Authorization: Api-Key ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "baseCurrencyCode": "usd",
    "baseCurrencyAmount": 100,
    "quoteCurrencyCode": "eth",
    "walletAddress": "<WALLET_ADDRESS>",
    "returnUrl": "https://your-app.com/success",
    "externalCustomerId": "customer-123"
  }' | jq '.'

Check Transaction Status

API_KEY="${MOONPAY_API_KEY}"
TX_ID="<TRANSACTION_ID>"

curl -s "https://api.moonpay.com/v3/transactions/${TX_ID}" \
  -H "Authorization: Api-Key ${API_KEY}" | jq '{
    status: .status,
    cryptoTransactionId: .cryptoTransactionId,
    quoteCurrencyAmount: .quoteCurrencyAmount,
    walletAddress: .walletAddress
  }'

Transaction Status Codes

StatusDescription
waitingPaymentAwaiting payment
pendingPayment received, processing
waitingAuthorizationAwaiting 3DS/bank auth
completedSuccessfully completed
failedTransaction failed

Supported Payment Methods

MethodRegionsSpeed
Credit/Debit CardGlobalInstant
Apple PayGlobalInstant
Google PayGlobalInstant
SEPAEurope1-2 days
ACHUSA3-5 days
Faster PaymentsUKInstant
PIXBrazilInstant
iDEALNetherlandsInstant

Supported Cryptocurrencies

CategoryTokens
MajorBTC, ETH, SOL, MATIC, AVAX
StablecoinsUSDT, USDC, DAI
L2ARB, OP, BASE tokens
MemeDOGE, SHIB

Webhook Events

# Webhook payload structure
{
  "type": "transaction_updated",
  "data": {
    "id": "tx-123",
    "status": "completed",
    "cryptoTransactionId": "0x...",
    "quoteCurrencyAmount": 0.05,
    "walletAddress": "0x..."
  }
}

Verify Webhook Signature

verify_webhook() {
  local payload="$1"
  local signature="$2"
  
  local expected=$(echo -n "$payload" | openssl dgst -sha256 -hmac "$MOONPAY_SECRET_KEY" -binary | base64)
  
  [[ "$signature" == "$expected" ]]
}

Widget Customization

# Widget parameters
PARAMS="?apiKey=${API_KEY}"
PARAMS+="&currencyCode=eth"
PARAMS+="&walletAddress=<WALLET>"
PARAMS+="&baseCurrencyAmount=100"
PARAMS+="&baseCurrencyCode=usd"
PARAMS+="&lockAmount=true"           # Lock amount
PARAMS+="&colorCode=%23FF6B00"       # Custom color
PARAMS+="&language=en"               # Language
PARAMS+="&showWalletAddressForm=false"  # Hide wallet input

Safety Rules

  1. ALWAYS sign widget URLs in production
  2. NEVER expose secret key client-side
  3. VERIFY webhook signatures
  4. CHECK transaction status before fulfilling

Error Codes

CodeDescription
invalid_api_keyInvalid API key
invalid_signatureURL signature mismatch
currency_not_supportedCurrency unavailable
amount_too_lowBelow minimum
amount_too_highAbove maximum

Links

  • MoonPay Docs
  • Dashboard
  • Widget Builder
Repository
Demerzels-lab/elsamultiskillagent
Last updated
Created

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.