Skip to main content
Use this guide to execute a card transaction after you have a connected customer. You will list stored cards, add new ones through a MoonPay-hosted frame, get a quote, and execute the transaction — with MoonPay handling PCI-compliant card collection, payment orchestration, and all verification challenges inside hosted frames. See the Going Live section for requirements you must meet before taking this integration to production.

Prerequisites

  • A MoonPay account with card payments enabled. Contact your MoonPay account team to enable it.
  • A connected customer (via client.getConnection() or client.connect()).
  • A UI surface where you can render MoonPay frames (iframe on web, or WebView on mobile).
  • A destination wallet address for the purchased crypto.

Flow overview

1

List payment methods

Fetch the customer’s available payment method types and stored cards.
The result contains two collections:
  • paymentMethodConfigs — available payment method types. Check for type: "card" to confirm card payments are available for this customer.
  • paymentMethods — the customer’s stored cards. Each entry includes brand, last4, expirationMonth, expirationYear, cardType, and availability.
Display active cards in your payment method picker. For inactive cards (availability.active: false), show the reasons value and prompt the user to add a new card.
If paymentMethods is empty and paymentMethodConfigs includes type: "card", guide the customer to add one using the Add Card frame (Step 2).
2

Add a card

When the customer needs to add a new card, set up the Add Card frame. The frame collects card details and billing address inside a PCI-compliant MoonPay-hosted UI — card data never touches your domain. For the frame URL, size, and events, see the Add Card frame reference.
Add a card
The complete event returns the new card’s full details including its id. Use this id directly to get a quote in Step 3 — no need to re-fetch payment methods.
3

Get a quote

With a stored card selected, request a quote. Pass the card’s id in paymentMethod so MoonPay can evaluate card-specific requirements.
Display the quote in your buy confirmation screen: source amount, destination amount, fees, and exchange rate. Monitor expiresAt and refresh the quote before it expires. If the buy frame is already loaded, call buyResult.value.setQuote(newSignature) instead of re-creating the frame.
4

Execute the transaction

Headless buy frame

Use client.setupBuy() when you want full control over your purchase UI. The frame is headless — no visible UI — and emits events for you to handle. For the frame URL, parameters, and events, see the Buy frame reference.
setupBuy
5

Handle challenges

When the buy frame emits a challenge event, the customer must complete one or more verification steps before the transaction can proceed. Set up the challenge frame with the URL from the event payload — do not construct the URL yourself. For the frame URL, parameters, and events, see the Challenge frame reference.The frame is self-driving: after initialization, it sequences through all required verification steps, creates the transaction, and emits complete when the pipeline finishes.
Handle challenges
When you receive complete, cancelled, or error from the challenge frame, call buyResult.value.dispose() to also tear down the buy frame.
The frame handles all verification types automatically — KYC, Strong Customer Authentication (SCA), CVC re-entry, wallet ownership, micro-authorization, and 3D Secure (3DS). You never need to distinguish between them.
6

Track the transaction

When the buy frame or challenge frame emits complete, the payload includes { transaction: { id, status } }. The transaction is created and payment is processing.
Track the transaction

Transaction statuses

Transactions have the following statuses:
  • Pending: The transaction has been initiated and the payment accepted. The assets are being transferred.
  • Complete: The transaction is finalized. The payment is complete and the assets have been delivered to their destination.
  • Failed: The transaction has failed. The payment was not executed and funds were not transferred.
Webhook support is coming soon. Until then, use polling to track transaction status.
7

Delete a stored card (optional)

Let customers remove stored cards at any time.
Delete a stored card
  • Deleting an already-deleted card returns success (idempotent).
  • Deleting a card with a pending transaction is rejected.
  • Only payment methods with allowsDeletion: true can be deleted.