postMessage to embed frames directly in web applications without installing any MoonPay packages.
Read the manual integration
overview for core concepts
before you continue.
Setup
Encryption
The connect and check frames require X25519 key exchange to encrypt client credentials. The examples below use @noble/curves, but you can use any library that supports X25519 and AES-GCM.Message utilities
Create helper functions for sending and receiving frame messages. All messages follow the frames protocol.messageUtils.ts
Encryption utility
The connect and check frames return encrypted credentials. Generate an X25519 keypair and provide the public key to the frame.Key generation
crypto.ts
Decryption
decrypt.ts
Check frame
The check frame verifies whether a customer already has an active connection. It’s headless — no UI is rendered. Use it to skip the connect flow for returning customers. See check frame reference for event details.Initialize the frame
Handle events
Usage
Connect frame
The connect frame establishes a customer connection to your application. See connect frame reference for event details.Initialize the frame
Handle events
Usage
Auth frame
The auth frame authenticates a customer with email or SMS one-time passcode and returns fully scoped credentials — without the hosted KYC UI in the connect frame. Launch it after the check frame returnsconnectionRequired, typically when you drive onboarding through the Customer API. See auth frame reference for event details.
Initialize the frame
Handle events
Usage
Add Card frame
The add card frame lets a customer save a new card to their account. See add card frame reference for event details.What you’ll need
Before you initialize the add card frame, you need:- A
clientTokenfrom a successful connect flow
Initialize the frame
Handle events
Usage
Buy Button frame
The Buy Button frame takes a quote to payment. It renders the Apple Pay, Google Pay, or card button that matches the payment method in your quote, and supports guest checkout when your quote allows it. For card and bank transfer quotes, you can also run it in headless mode behind your own purchase button. See the Buy Button frame reference for event details, and Pay with the buy button for the full walkthrough.Apple Pay and Google Pay need the
payment permission
policy,
so set allow="payment" on the iframe. If you sandbox the iframe, include
allow-scripts, allow-popups, allow-same-origin, and allow-forms, plus
allow-modals for the test-mode payment dialog. See
Permissions.Apple Pay is available in Safari on macOS and in every iOS browser. Check
availability before you request an Apple Pay quote.
What you’ll need
Before you initialize the Buy Button frame, you need:- A
clientTokenfrom a successful connect flow - A valid quote signature for the transaction
Initialize the frame
The function creates the iframe inside a container element with the IDmoonpay-buy-button and sizes it 44px tall. The button fills the container width. See Size.
applePayButtonSettings and googlePayButtonSettings are optional. The frame
applies the one that matches the button it renders. URLSearchParams
URL-encodes each value. For the keys and validation rules, see Apple Pay
button settings and
Google Pay button
settings.
Handle events
Update the quote
When the quote expires or changes, send a new quote to the frame:Challenge handling
When the Buy Button frame emits achallenge event, for example for 3-D Secure, open the challenge URL in a new iframe inside a modal. The challenge frame is self-driving after the handshake. Opened without resume, as below, it finishes the purchase for every payment method and sends complete. To have the customer finish an Apple Pay or Google Pay purchase on your buy button instead, see Finish on your buy button.
Usage
Headless mode
For card and bank transfer quotes, you can draw your own purchase button and run the Buy Button frame withheadless=true. The frame renders nothing and starts the purchase as soon as it loads, so mount it at zero size when the customer confirms the purchase in your UI, not before. See Headless mode.
setupBuyButtonListener, updateBuyButtonQuote, and challenge handling with the headless iframe. In headless mode, the frame:
- Sends
ready, then exactly one ofcomplete,challenge, orerror. - Never sends
buttonPressedorcancelled. - Accepts card and bank transfer (SEPA) quotes only. An Apple Pay or Google Pay quote returns
errorwithunsupportedPaymentMethod. - Needs a connected customer. A guest checkout quote returns
errorwithinvalidQuote. - Reads
setQuoteonly after anerrorwithquoteExpired.
challenge, open the challenge frame without resume, as in challenge handling. It finishes the purchase and sends its own complete.
After complete, or an error other than quoteExpired, stop the listener and remove the iframe. Mount a new frame if the customer tries again.
complete event returns the transaction id. Fetch the transaction by id, and show the customer the bank details from bankTransferDepositInfo and the amount to send from source.amount in your own UI so they can send the transfer. See Pay with bank transfer.
Widget frame
To hand the whole purchase to MoonPay, including amount entry and payment method selection, use the widget frame. It renders the full MoonPay buy experience inside an iframe, including payment collection and transaction confirmation. See pay with widget for a full walkthrough.What you’ll need
Before you initialize the widget frame, you need:- A
clientTokenfrom a successful connect flow - A valid quote signature for the transaction
Initialize the frame
The widget iframe requires the
payment permission
policy
to process payments.Handle events
Usage
Reset frame
The reset frame is headless. Use it when the customer signs out of your app to clear MoonPay session state on MoonPay’s domain. See reset frame reference. Pass the sameclientToken you received from connect or auth so your domain is authorized to embed the frame. Do not block sign-out if reset fails or times out.