Mount the headless Buy frame in your app and execute a transaction from a quote signature. The frame renders no visible UI — the provider mounts it as a zero-dimensionDocumentation Index
Fetch the complete documentation index at: https://dev.moonpay.com/llms.txt
Use this file to discover all available pages before exploring further.
react-native-webview that drives the buy pipeline in the background and emits events you handle from your own purchase screen.
The Buy frame is headless. When it emits a
challenge event, render a
separate challenge frame with
client.setupChallenge()
at the URL from the event payload. See the Handle
challenges guide for the full flow.Setup buy
Parameters
This method does not require a separate auth token. The client uses stored credentials from an active connection.
BuyEvent
onEvent receives events as the buy pipeline progresses. Use event.kind to decide how to handle each event.
| kind | Payload | When you receive it |
|---|---|---|
"ready" | — | The buy pipeline has started. Show a loading state in your own UI. |
"complete" | { transaction: FrameTransaction } | The transaction was created. Use the transaction id to poll for final status. |
"challenge" | BuyChallengePayload | Verification is required before the transaction can proceed. Render the challenge frame at the provided url using setupChallenge(). |
"error" | BuyEventError | The flow encountered an error. Surface the message to developers and tear down the frame. |
FrameTransaction
This is the transaction object returned when the buy pipeline completes. FrameTransaction is a discriminated union — the failure variant carries failureReason, the non-failure variant always carries id. Pass id to client.getTransaction() to poll for the final status.
| Field | Type | Required | Description |
|---|---|---|---|
status | string | ✅ | The transaction status. On the failure variant, "failed". |
id | string | Required on the non-failure variant; optional when status is "failed" (a transaction may not exist yet on early failure). | |
failureReason | string | Present only on the failure variant (status === "failed"). A developer-friendly reason. |
BuyChallengePayload
| Field | Type | Required | Description |
|---|---|---|---|
kind | string | ✅ | The challenge type (currently always "frame", but typed as string for forward compatibility). |
url | string | ✅ | A fully-formed URL to pass directly to setupChallenge(). Do not modify it. |
BuyEventError
| Field | Type | Required | Description |
|---|---|---|---|
code | string | ✅ | The error category. Includes configurationError, invalidQuote, and backend-specific error codes. |
message | string | ✅ | Developer-friendly details. Not intended to be rendered in UI. |
Result
client.setupBuy() returns a Result<BuyFrame, SetupBuyError>.
Result envelope
Result<BuyFrame, SetupBuyError>
| Field | Type | Required | Description |
|---|---|---|---|
ok | boolean | ✅ | Whether the operation succeeded. |
value | BuyFrame | Present when ok is true. | |
error | SetupBuyError | Present when ok is false. |
BuyFrame
| Field | Type | Required | Description |
|---|---|---|---|
setQuote | (signature: string) => void | ✅ | Updates the quote signature used by the frame. Use this when the current quote expires before the customer completes the purchase — fetch a new quote and pass its signature. |
dispose | () => void | ✅ | Unmounts the frame. After you call this, no further events are dispatched to your onEvent callback. Always call dispose() once the flow finishes or errors out. |
SetupBuyError
| Field | Type | Required | Description |
|---|---|---|---|
kind | "configurationError" | "genericError" | ✅ | The error category. |
message | string | ✅ | Developer-friendly details. |
Full example
The following example walks through the full card-payment flow: get a quote for a stored card, mount the headless Buy frame, hand off to a challenge frame when verification is required, and dispose of the frame when the transaction completes.Buy with a stored card
TS Definitions
TS Definitions
types.ts