Skip to main content
Use WKWebView to embed frames in native iOS applications. The WebView communicates with frames via JavaScript message handlers and script injection.
Read the manual integration overview for core concepts before you continue.

Setup

Dependencies

The examples below use swift-crypto for X25519 key exchange, but you can use any library that supports X25519 and AES-GCM.

Key generation

Decryption utility

Base frame controller

Create a reusable base view controller for frame communication:

Handle JavaScript dialogs

In test mode, the Buy Button frame renders a mock Apple Pay button for an Apple Pay quote and uses window.prompt to simulate the Apple Pay payment sheet. By default, WKWebView silently dismisses alert, confirm, and prompt: window.prompt returns null with no UI shown. The frame interprets that as the customer cancelling, so every test transaction comes back with status: "failed". This WKWebView requirement is captured on the Buy Button frame reference, which is the source of truth. To surface the simulated payment sheet, conform your base view controller to WKUIDelegate and present the text input panel as a UIAlertController with a text field. The confirm panel handler covers any other dialog the frame might show:
In the prompt, OK authorizes the test payment with the billing contact in the text field (the frame emits complete with a non-failed status); Cancel declines it (the frame emits complete with status: "failed").
Wire the UI delegate even if you only plan to ship live mode. The WKWebView default behavior applies to any window.confirm, alert, or prompt the frame might surface, and it makes test-mode debugging impossible without it.

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.

Check controller

Usage


Connect frame

The connect frame establishes a customer connection to your application. See connect frame reference for event details.

Connect controller

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 returns connectionRequired, typically when you drive onboarding through the Customer API. See auth frame reference for event details.

Auth controller

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.

Add Card controller

Usage


Buy Button frame

The Buy Button frame takes a quote to payment. It renders the Apple 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.
For the Apple Pay button, your base view controller must handle JavaScript dialogs. Google Pay isn’t available in a WKWebView, so offer another payment method. See Mobile WebViews.

What you’ll need

Before you initialize the Buy Button frame, you need:
  1. A clientToken from a successful connect flow
  2. A valid quote signature for the transaction

Buy Button controller

Pass headless: true to configure to run the purchase without a button, as described in Headless mode.

Challenge handling

When the Buy Button frame emits a challenge event, for example for 3-D Secure, present a MoonPayChallengeViewController with the challenge URL. Opened without resume, as below, the challenge frame finishes the purchase for every payment method and sends complete. On completion, cancellation, or error, dismiss the challenge view controller, which tears down its web view, and call dispose() on the Buy Button view controller. To have the customer finish an Apple Pay purchase on your buy button instead, see Finish on your buy button.

Usage

Size the button container 44pt tall. See Size.

Headless mode

For card and bank transfer quotes, you can draw your own purchase button and pass headless: true to configure. The frame loads with headless=true, renders nothing, and starts the purchase as soon as it loads. Add it as a zero-size child when the customer confirms the purchase in your UI, not before. See Headless mode. In headless mode, the frame:
  • Sends ready, then exactly one of complete, challenge, or error.
  • Never sends buttonPressed or cancelled.
  • Accepts card and bank transfer (SEPA) quotes only. An Apple Pay or Google Pay quote returns error with unsupportedPaymentMethod.
  • Needs a connected customer. A guest checkout quote returns error with invalidQuote.
  • Reads setQuote only after an error with quoteExpired.
On challenge, present the challenge frame without resume, as in challenge handling. It finishes the purchase and sends its own complete. For a bank transfer (SEPA) quote, buyButtonDidComplete receives 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 natively so they can send the transfer. See Pay with bank transfer.
For bank transfers, the customer must include the payment reference from bankTransferDepositInfo with their transfer, or it is rejected. Render the deposit details, including the reference, in your own UI. See the transaction object.
Reuse the BuyButtonFrameDelegate and ChallengeFrameDelegate methods from the usage example above. They dispose the frame and set buyButtonVC to nil after its final event: complete, or an error other than quoteExpired. Call this from your purchase button’s action:

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 a WKWebView, including payment collection and transaction confirmation. See pay with widget for a full walkthrough.

Widget controller

Usage


Reset frame

The reset frame is headless. Use it when the customer signs out to clear MoonPay session state on MoonPay’s domain. See reset frame reference. Pass your clientToken so your app is authorized to embed the frame. Do not block sign-out if reset fails.

Reset controller

Usage