Use this file to discover all available pages before exploring further.
Render the Challenge frame in your app to resolve verification steps required
by another flow (for example, a buy transaction or an identity capture). The
provider mounts the frame as a react-native-webview. The challenge frame is
self-driving — after initialization, it sequences through all required
verification steps and emits complete when the pipeline finishes.Unlike other setup methods, setupChallenge() takes a url provided by the
upstream flow’s challenge event. Pass it through as-is — the URL already
carries the channelId the SDK needs to wire up the frame. Do not modify the
URL yourself.For more context, see the Handle
challenges guide.
Setup challenge
import { useMoonPay, type BuyEvent, type ChallengeEvent,} from "@moonpay/platform-sdk-react-native";export function CheckoutScreen({ quoteSignature }: { quoteSignature: string }) { const { client } = useMoonPay(); const start = async () => { const buyResult = await client.setupBuy({ quote: quoteSignature, onEvent: async (event: BuyEvent) => { if (event.kind !== "challenge") return; // The url comes from the challenge event — pass it through as-is. const challengeResult = await client.setupChallenge({ url: event.payload.url, onEvent: (event: ChallengeEvent) => { switch (event.kind) { case "ready": // Challenge UI is rendered and visible to the customer break; case "complete": if (event.payload.flow === "buy") { console.log(event.payload.transaction); } else if (event.payload.flow === "identity") { console.log(event.payload.identityId); } buyResult.value.dispose(); break; case "cancelled": // Customer dismissed the challenge — offer a retry path buyResult.value.dispose(); break; case "error": console.error(event.payload.message); buyResult.value.dispose(); break; } }, }); if (!challengeResult.ok) { // Handle error console.error( challengeResult.error.kind, challengeResult.error.message, ); return; } }, }); }; // ...}
The URL from the upstream flow’s challenge event payload. Pass it through unchanged. The URL must include the channelId query parameter (the upstream flow always sets it).
onEvent
(event: ChallengeEvent) => void
Callback invoked for Challenge flow events. See ChallengeEvent.
This method does not require a separate auth token. The client uses stored
credentials from an active connection.
onEvent receives events as the challenge flow progresses. Use event.kind to
decide how to handle each event. The complete and cancelled payloads are
discriminated by payload.flow so you can branch on the originating flow.
kind
Payload
When you receive it
"ready"
—
The Challenge UI is rendered and visible to the customer.
The challenge frame is self-driving. After acknowledging the initial
handshake, the SDK does not send further messages to the frame. The frame
internally handles all verification types automatically — including CVC
confirmation, 3D Secure, identity verification (KYC), Strong Customer
Authentication (SCA), micro-deposit authorization, and wallet ownership proof.
You never need to distinguish between them.
Unmounts the frame. After you call this, no further events are dispatched to your onEvent callback.
Unlike setupBuy(), setupApplePay(), and setupGooglePay(), the
ChallengeFrame does not expose a setQuote() method. The challenge frame
runs to completion on its own.