> ## Documentation Index
> Fetch the complete documentation index at: https://dev.moonpay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# <MoonPayChallenge />

> Inline 3DS/challenge frame. Mount it when a payment frame emits a challenge event.

`<MoonPayChallenge>` renders a 3DS or identity challenge frame inline in your
layout. It is the declarative alternative to
[`client.setupChallenge()`](/platform/sdk-reference/react-native/setup-challenge).

Mount this component when a payment frame (Apple Pay, Google Pay, buy button,
or buy frame) emits a `"challenge"` event. Pass the `url` from the event
payload directly. Unmounting the component disposes the frame and stops event
delivery.

```tsx PaymentScreen.tsx theme={null}
import React from "react";
import {
  MoonPayApplePayButton,
  MoonPayChallenge,
  type ApplePayEvent,
  type ChallengeEvent,
} from "@moonpay/platform-sdk-react-native";
import { StyleSheet, View } from "react-native";

export function PaymentScreen({ quoteSignature }: { quoteSignature: string }) {
  const [challengeUrl, setChallengeUrl] = React.useState<string | null>(null);

  const handlePayEvent = (event: ApplePayEvent) => {
    if (event.kind === "challenge") {
      setChallengeUrl(event.payload.url);
    }
  };

  const handleChallengeEvent = (event: ChallengeEvent) => {
    switch (event.kind) {
      case "complete":
        console.log(event.payload);
        setChallengeUrl(null);
        break;
      case "cancelled":
        console.log("Challenge cancelled", event.payload);
        setChallengeUrl(null);
        break;
      case "error":
        console.error(event.payload.code, event.payload.message);
        setChallengeUrl(null);
        break;
    }
  };

  return (
    <View style={styles.container}>
      {challengeUrl ? (
        <MoonPayChallenge url={challengeUrl} onEvent={handleChallengeEvent} />
      ) : (
        <MoonPayApplePayButton
          quote={quoteSignature}
          onEvent={handlePayEvent}
        />
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1 },
});
```

***

## Props

| Prop      | Type                              | Required | Default   | Description                                                                       |
| --------- | --------------------------------- | -------- | --------- | --------------------------------------------------------------------------------- |
| `url`     | `string`                          | ✅        | —         | Full challenge URL from a payment frame's `"challenge"` event. Mount-time only.   |
| `onEvent` | `(event: ChallengeEvent) => void` |          | —         | Callback for challenge lifecycle events. See [`ChallengeEvent`](#challengeevent). |
| `style`   | `ViewStyle`                       |          | `flex: 1` | Container style.                                                                  |

### `ChallengeEvent`

Use `event.kind` to handle each event.

| kind          | Payload                             | When you receive it                                             |
| ------------- | ----------------------------------- | --------------------------------------------------------------- |
| `"ready"`     | —                                   | The challenge UI is rendered and ready.                         |
| `"complete"`  | `CompleteResult`                    | The challenge finished. See `CompleteResult` shape below.       |
| `"cancelled"` | `Cancellation`                      | The customer dismissed the challenge. See `Cancellation` below. |
| `"error"`     | `{ code: string; message: string }` | The challenge encountered an error.                             |

**`CompleteResult`** is a discriminated union on `flow`:

| `flow`       | Extra fields                    |
| ------------ | ------------------------------- |
| `"buy"`      | `transaction: FrameTransaction` |
| `"identity"` | `identityId: string`            |

**`Cancellation`** is a discriminated union on `flow`:

| `flow`       | Extra fields                                        |
| ------------ | --------------------------------------------------- |
| `"buy"`      | `transactionId?: string`, `challengeToken?: string` |
| `"identity"` | —                                                   |

On `"cancelled"`, carry `transactionId` and `challengeToken` to resume the
transaction if needed.
