# React Native

_Encrypt data client-side, collect card details & perform 3D Secure authentication._

## Installation

Our React Native SDK is distributed via [npm](https://www.npmjs.com/), and can be installed using your preferred package manager.
The [react-native-webview](https://www.npmjs.com/package/react-native-webview) package is a peer dependency and will need to be installed as well.

> **Compatibility**
>
> Our React Native SDK requires [React Native 0.76](https://reactnative-archive-august-2025.netlify.app/docs/0.76/getting-started) or higher. We recommend upgrading if possible.
>
> If you are unable to upgrade, you will need to use our [legacy React Native SDK](/sdks/react-native-legacy).

### Linking

This package supports [autolinking](https://github.com/react-native-community/cli/blob/master/docs/autolinking.md).

### Expo

This library has native code, so it does not work with [Expo Go](https://expo.dev/go). However, you can install it using a [custom development build](https://docs.expo.dev/develop/development-builds/create-a-build/).

### Proguard Rules

If you are using code shrinking with ProGuard for Android, you will need to specify exclusion rules for several Evervault dependencies. The required ProGuard rules can be found in our [Android SDK docs](/sdks/android#proguard-rules).

## Quickstart

### Add the EvervaultProvider

Wrap your app with the [{'<EvervaultProvider />'}](#evervault-provider) component and pass your Team and App ID as props.

Your Team and App ID can be found in the [Evervault Dashboard](https://app.evervault.com).

```tsx
import { EvervaultProvider } from "@evervault/react-native";

function App() {
  return (
    <EvervaultProvider teamId="team_id" appId="app_id">
      <YourApp />
    </EvervaultProvider>
  );
}
```

### Collect Card Data

You can use the [{'<Card />'}](#card) component to collect card data securely.

```tsx
import { Card, type CardPayload } from "@evervault/react-native";
import { Button, Form } from "@your/ui";

function CardForm({ onSubmit }: CardFormProps) {
  const [data, setData] = useState<CardPayload | null>(null);

  return (
    <Form>
      <Card onChange={setData}>
        <Card.Number />
        <Card.Expiry />
        <Card.Cvc />
        <Card.Holder />
      </Card>

      <Button disabled={!data?.isValid || !data?.isComplete} onPress={onSubmit}>
        Pay
      </Button>
    </Form>
  );
}
```

If you don't need to collect all four types of supported Card Data, you can omit the relevant components.

However, the components cannot be used individually outside of the `<Card />` component.

### Perform 3D Secure Authentication

You can use the [{'<ThreeDSecure />'}](#three-d-secure) component in combination with the Evervault API to perform 3DS authentications.

In order to use the 3DS component you must first [create a 3DS session on your backend](/api#createThreeDSSession) and pass it to your frontend. You can then use the [{'<ThreeDSecure.Frame />'}](#three-d-secure-frame) component to display the 3DS webview.

```tsx
import { ThreeDSecure, useThreeDSecure } from "@evervault/react-native";
import { createThreeDSecureSession } from "@your/api";
import { Button, Form, Modal } from "@your/ui";

function Checkout({ onSuccess, onFailure, onError }: CheckoutProps) {
  const tds = useThreeDSecure();

  async function handlePayment() {
    // Create a 3DS session on your backend
    const sessionId = await createThreeDSecureSession();

    tds.start(sessionId, {
      onSuccess,
      onFailure,
      onError,
    });
  }

  return (
    <Form>
      <Button onPress={handlePayment}>Pay</Button>

      <ThreeDSecure state={tds}>
        <Modal onRequestClose={() => tds.cancel()}>
          <ThreeDSecure.Frame />
        </Modal>
      </ThreeDSecure>
    </Form>
  );
}
```

## Components

### {'<EvervaultProvider />'}

Wraps your app in a new Evervault context, scoped to a specific team and app.

```tsx
import { EvervaultProvider } from "@evervault/react-native";

function App() {
  return (
    <EvervaultProvider teamId="team_123" appId="app_123">
      <YourApp />
    </EvervaultProvider>
  );
}
```

**Props**

- `teamId` _(required)_ — The Team ID found in the [Evervault Dashboard](https://app.evervault.com).
- `appId` _(required)_ — The App ID found in the [Evervault Dashboard](https://app.evervault.com).

### {'<Card />'}

The Card component is used to securely collect cardholder data from your users.

```tsx
import { Card, type CardPayload } from "@evervault/react-native";

function CardForm() {
  const [data, setData] = useState<CardPayload | null>(null);

  return (
    <Card onChange={setData}>
      <Card.Number />
    </Card>
  );
}
```

It is a wrapper component that manages the state of the child input components:

- [{'<Card.Holder />'}](#card-holder)
- [{'<Card.Number />'}](#card-number)
- [{'<Card.Expiry />'}](#card-expiry)
- [{'<Card.Cvc />'}](#card-cvc)

You do not have to render all of the available child input components as children. For example, if you only need to collect a card number and expiry, you can omit the Card.Cvc and Card.Holder components.

The `onComplete` field will be `true` once all **rendered** fields are filled out successfully with valid values.

**Props**

- `acceptedBrands` `CardBrandName[]` — An array of card brands that are accepted. If not provided, all brands are accepted. Possible values are 'american-express', 'visa', 'mastercard', 'discover', 'jcb', 'diners-club', 'unionpay', 'maestro', 'mir', 'elo', 'hipercard', 'hiper', 'szep', 'uatp', 'rupay'.
- `defaultValues` `CardForm` — Default values for the card fields.
  - `name` `string` — The card holder name.
  - `number` `string` — The unencrypted card number field.
  - `expiry` `string` — The expiry date for the card. Takes the format MMYY
  - `cvc` `string` — The unencrypted three (or four) digit CVC code for the card.
- `validationMode` `'onChange' | 'onBlur' | 'onTouched' | 'all'` — The validation mode for the card fields. Defaults to `all`.
- `onChange` `(payload: CardPayload) => void` — A callback function that is called whenever the card data changes. **Payload** - `card.name` `String` — The card holder name. - `card.number` `String` — The encrypted card number. This will only be present if the number is valid. - `card.brand` `String` — The brand that issued the card. - `card.lastFour` `String` — The last 4 digits of the card. This will only be present if the number is valid. - `card.bin` `String` — The bin for the card. This will only be present if the number id valid. - `card.expiry.month` `String` — The month for the card expiry field. - `card.expiry.year` `String` — The year for the card expiry field. - `card.cvc` `String` — The encrypted card CVC. - `card.errors` `Object` — Validation errors related to the card details. - `card.isValid` `Boolean` — Whether or not there are any errors shown in the component. - `card.isComplete` `Boolean` — Whether or not all of the fields have been filled out successfully with valid values.
- `onError` `(error: Error) => void` — A callback function that is called when a native error occurs.

#### Ref

The `Card` component exposes an imperative handle using `ref`.

```tsx
import { useRef } from "react";
import { Card } from "@evervault/react-native";

function CardForm() {
  const cardRef = useRef<Card>(null);

  return (
    <Card ref={cardRef}>
      <Card.Number />
    </Card>
  );
}
```

**Methods**

- `reset()` `() => void` — Resets the form to its default values and state.

### {'<Card.Holder />'}

Used as a child of [{'<Card />'}](#card) to collect the name of a card holder.

```tsx
import { Card } from "@evervault/react-native";

function CardForm() {
  return (
    <Card>
      <Card.Holder placeholder="Johnny Appleseed" />
    </Card>
  );
}
```

**Props**

- `placeholder` `string` — The placeholder text to display in the input field.

### {'<Card.Number />'}

Used as a child of [{'<Card />'}](#card) to collect the card number.

```tsx
import { Card } from "@evervault/react-native";

function CardForm() {
  return (
    <Card>
      <Card.Number placeholder="1234 1234 1234 1234" />
    </Card>
  );
}
```

**Props**

- `placeholder` `string` — The placeholder text to display in the input field.
- `obfuscateValue` `boolean | string` — If `true`, all but the first 6 characters of the card number will be obfuscated. If a string is provided, it will be used as the obfuscation character (defaults to `•`).

### {'<Card.Expiry />'}

Used as a child of [{'<Card />'}](#card) to collect the expiry date of a card.

```tsx
import { Card } from "@evervault/react-native";

function CardForm() {
  return (
    <Card>
      <Card.Number />
      <Card.Expiry placeholder="MM / YY" />
    </Card>
  );
}
```

**Props**

- `placeholder` `string` — The placeholder text to display in the input field.

### {'<Card.Cvc />'}

Used as a child of [{'<Card />'}](#card) to collect the CVC code of a card.

```tsx
import { Card } from "@evervault/react-native";

function CardForm() {
  return (
    <Card>
      <Card.Number />
      <Card.Cvc placeholder="CVC" />
    </Card>
  );
}
```

**Props**

- `placeholder` `string` — The placeholder text to display in the input field.
- `obfuscateValue` `boolean | string` — If `true`, all of the CVC will be obfuscated. If a string is provided, it will be used as the obfuscation character (defaults to `•`).

### {'<ThreeDSecure />'}

The ThreeDSecure component is used to provide access to the 3DS authentication process.

This component allows you to use the [{'<ThreeDSecure.Frame />'}](#three-d-secure-frame) component to display the 3DS webview. Any custom components you want to display alongside the 3DS webview should be wrapped in the ThreeDSecure component.

It should be used in combination with the [useThreeDSecure](#use-three-d-secure) hook.

**Props**

- `state` `ThreeDSecureState` _(required)_ — The 3DS state object returned by the [useThreeDSecure](#use-three-d-secure) hook.

### {'<ThreeDSecure.Frame />'}

The ThreeDSecure.Frame component is used to display the 3DS webview, which will handle the authentication process.

If the user closes the frame before completion, you will need to use the `cancel()` method (from the [useThreeDSecure](#usethreedsecure) hook) to properly close the webview and clean up the session.

```tsx
import { ThreeDSecure, useThreeDSecure } from "@evervault/react-native";
import { createThreeDSSession } from "@your/api";
import { Button, Form, Modal } from "@your/ui";

function CustomCheckout() {
  const tds = useThreeDSecure();

  async function handlePayment() {
    // Create a 3DS session on your backend
    const sessionId = await create3DSecureSession();

    tds.start(sessionId, {
      onSuccess: () => {
        console.log("3DS successful");
      },
      onFailure: (error: Error) => {
        console.error("3DS failed", error);
      },
      onError: (error: Error) => {
        console.warn("3DS errored", error);
      },
    });
  }

  return (
    <Form>
      <Button onPress={handlePayment}>Pay</Button>

      <ThreeDSecure state={tds}>
        <Modal onRequestClose={tds.cancel}>
          <ThreeDSecure.Frame />
        </Modal>
      </ThreeDSecure>
    </Form>
  );
}
```

**Props**

- `style` `StyleProp<ViewStyle>` — Style applied to the WebView container.

**Parameters**

- `session` `string` _(required)_ — The 3D Secure session ID.
- `options` `ThreeDSSessionOptions` — The options for the 3DS authentication process.
  - `failOnChallenge` `boolean | () => Promise<boolean>` — If set to true (or a function that returns true), the authentication will fail if a challenge is required.
  - `onRequestChallenge` `(event: ThreeDSecureEvent) => void` — The `requestChallenge` event will be fired if the 3DS authentication process requires a challenge. If you'd like to fail the authentication, you should call `preventDefault` on the passed event.
  - `onSuccess` `() => void` — The 'success' event will be fired once the 3DS authentication process has been completed successfully. You should use this event to trigger your backend to finalize the payment. Your backend can use the [Retrieve 3DS Session endpoint](/api#retrieveThreeDSSession) to retrieve the cryptogram for the session and complete the payment.
  - `onFailure` `(error: Error) => void` — The 'failure' event will be fired if the 3DS authentication process fails. You should use this event to handle the failure and inform the user and prompt them to try again. If the user cancels the 3DS authentication process this event will be fired.
  - `onError` `(error: Error) => void` — The error event will be fired if the component fails to load.

## Hooks

### useEvervault

The `useEvervault` hook is used to access the current Evervault scope in context.

Any component that uses this hook must be wrapped in the [{'<EvervaultProvider />'}](#evervault-provider) component.

```tsx
import { useEvervault } from "@evervault/react-native";
import { Button, Text, TextInput, View } from "react-native";

function YourApp() {
  const { teamId, appId, encrypt } = useEvervault();

  const [data, setData] = useState("");
  const [encryptedData, setEncryptedData] = useState("");

  async function handleEncrypt() {
    const encrypted = await encrypt(data);
    setEncryptedData(encrypted);
  }

  return (
    <View>
      <Text>
        Encrypting data for team {teamId} and app {appId}
      </Text>

      <TextInput value={data} onChangeText={setData} />
      <Button title="Encrypt" onPress={handleEncrypt} />

      <Text>Encrypted Data: {encryptedData}</Text>
    </View>
  );
}
```

#### Returns

##### encrypt

Encrypts the provided data using native encryption modules and the Evervault API.

**Parameters**

- `data` `string | number | boolean | object | array` _(required)_ — The data to encrypt.

### useThreeDSecure

The `useThreeDSecure` hook is used to manage the 3DS authentication process.

The hook returns an object with `start()` and `cancel()` methods. The returned object should be used with the [{'<ThreeDSecure />'}](#three-d-secure) component.

**Options**

- `failOnChallenge` `boolean | () => Promise<boolean>` — If set to true (or a function that returns true), the authentication will fail if any sessions require a challenge. Can be overridden on a per-session basis by the failOnChallenge option passed to the `start()` method.

#### Returns

##### start

The start function is used to kick off the 3DS authentication process.

**Parameters**

- `sessionId` `string` _(required)_ — The 3DS session ID. A 3DS session can be created using the [Evervault API](/api#createThreeDSSession).
- `options` `ThreeDSSessionOptions` — The options for the 3DS authentication process.
  - `failOnChallenge` `boolean | () => Promise<boolean>` — If set to true (or a function that returns true), the authentication will fail if a challenge is required.
  - `onRequestChallenge` `(event: ThreeDSecureEvent) => void` — The `requestChallenge` event will be fired if the 3DS authentication process requires a challenge. If you'd like to fail the authentication, you should call `preventDefault` on the passed event.
  - `onSuccess` `() => void` — The 'success' event will be fired once the 3DS authentication process has been completed successfully. You should use this event to trigger your backend to finalize the payment. Your backend can use the [Retrieve 3DS Session endpoint](/api#retrieveThreeDSSession) to retrieve the cryptogram for the session and complete the payment.
  - `onFailure` `(error: Error) => void` — The 'failure' event will be fired if the 3DS authentication process fails. You should use this event to handle the failure and inform the user and prompt them to try again. If the user cancels the 3DS authentication process this event will be fired.
  - `onError` `(error: Error) => void` — The error event will be fired if the component fails to load.

##### cancel

The `cancel()` function is used to cancel the ongoing 3DS authentication process. This can be particularly useful for canceling a session when a custom cancel button is triggered.

##### session

The current `ThreeDSecureSession` object, or `null` if no session was created.

##### isVisible

A boolean indicating whether the 3DS webview should currently be rendered. Use this to conditionally display the `ThreeDSecure` component and its children.

## V2 Migration Guide

If your app currently uses the older `@evervault/evervault-react-native` package, you can follow [our migration guide](/sdks/react-native/v2-migration) to upgrade to the new package.

