# React

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

## Getting Started

Our React SDK is distributed via npm and can be installed using your preferred package manager.

Once installed, Initialize the SDK by wrapping your application with the `EvervaultProvider` component.

```jsx
import { EvervaultProvider } from "@evervault/react";

export default function App() {
  return (
    <EvervaultProvider teamId="<TEAM_ID>" appId="<APP_ID>">
      ...
    </EvervaultProvider>
  );
}
```

## Encrypting Data

Once you've added the `<EvervaultProvider>`, you can access the `useEvervault()` hook in its children. The `useEvervault()` hook returns an initialized instance of the [JavaScript SDK](/sdks/javascript), which includes the `encrypt()` function. The `encrypt()` function can be used to encrypt plaintext data in your application.

```jsx
import { useState } from "react";
import { useEvervault } from "@evervault/react";

export default function ChildComponent() {
  const evervault = useEvervault();
  const [message, setMessage] = useState("");

  const handleSubmit = async (e) => {
    e.preventDefault();
    const encryptedMessage = await evervault.encrypt(message);
    alert(encryptedMessage);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input value={message} onChange={(e) => setMessage(e.target.value)} />
      <button>Submit</button>
    </form>
  );
}
```

## Components

### EvervaultProvider

Sets up a client for interacting with Evervault. You must provide a `teamId` and `appId` to the provider.

```jsx
<EvervaultProvider teamId={String} appId={String}>
  {children}
</EvervaultProvider>
```

**Props**

- `teamId` `String` _(required)_ — The unique identifier for your Team.
- `appId` `String` _(required)_ — The unique identifier for your App.
- `onLoadError` `Function` — A callback function that is called if the SDK fails to load.

The `EvervaultProvider` accepts a `ref` that exposes a `reload()` method that you can use to reload the script if it fails.

**Ref Methods**

- `reload` `() => void` — Attempts to reload the Evervault script. Typically called in response to an `onLoadError` event.

### Card

The Card Component allows you to collect and encrypt card data in a completely PCI-compliant environment. See [Card Collection](/cards/card-collection) for more information.

```jsx
import { Card, themes } from "@evervault/react";
const theme = themes.clean();

export function Checkout() {
  const handleChange = (details) => {
    console.log(details);
  };

  return (
    <div>
      <Card theme={theme} onChange={handleChange} />
    </div>
  );
}
```

**Props**

- `theme` `Object` — The theme to use for the Card. See the [styling section](/cards/card-collection#styling) for more information.
- `colorScheme` `string` — Allows you to set the root [color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/color-scheme) for the iframe document. For a seamless transparent background, use the same color scheme as the parent document.
- `icons` `Boolean | Record<brand, string>` — If set to true, the component will display icons for the detected card brand. You can customize icons by passing an object with the brand as the key and src URL as the value.
- `autoFocus` `Boolean` — If set to true, the component will automatically focus the first field when the component is mounted.
- `autoProgress` `Boolean` — If set to true, the component automatically moves focus to the next field when the current field is complete.
- `autoComplete` `Object` — Controls browser autocomplete behavior per field.
  - `autoComplete.name` `Boolean` — Enable browser autocomplete for the name field.
  - `autoComplete.number` `Boolean` — Enable browser autocomplete for the card number field.
  - `autoComplete.expiry` `Boolean` — Enable browser autocomplete for the expiry field.
  - `autoComplete.cvc` `Boolean` — Enable browser autocomplete for the CVC field.
- `acceptedBrands` `string[]` — Restricts the component to only accept the specified card brands. If not provided, all brands are accepted. Possible values are `visa`, `mastercard`, `american-express`, `diners-club`, `discover`, `jcb`, `unionpay`, `maestro`, `elo`, `mir`, `hiper`, `hipercard`, `szep`, `uatp`, `rupay`. Custom brands defined using `customBrands` are accepted regardless of this list.
- `customBrands` `CustomBrand[]` — An array of custom card brand definitions. Use `evervault.brands.create` from the browser SDK to create them. Custom brands are always accepted, even when `acceptedBrands` is set. See the [custom card brands](/cards/card-collection?client=react#custom-card-brands) section for usage examples.
- `fields` `String[]` — Allows you to configure the fields displayed in the component. Possible values are `name`, `number`, `expiry`, and `cvc`. By default only number, expiry and cvc will be shown.
- `defaultValues` `Object` — Sets default values for card fields on mount.
  - `defaultValues.name` `String` — Default value for the cardholder name field.
- `redactCVC` `Boolean` — Sets the `type` attribute of the CVC field to `password` in order to visually redact the CVC field..
- `allow3DigitAmexCVC` `Boolean` — If set to false, rejects 3-digit CVCs for American Express cards and requires a 4-digit CVC. Defaults to `true`.
- `translations` `Object` — Allows you to customize the translations of the component.
  - `translations.name.label` — Customize the label for the name field.
  - `translations.name.placeholder` — Customize the placeholder for the name field.
  - `translations.name.errors.invalid` — Customize the error message for the name field when the value is invalid.
  - `translations.number.label` — Customize the label for the number field.
  - `translations.number.placeholder` — Customize the placeholder for the number field.
  - `translations.number.errors.invalid` — Customize the error message for the number field when the value is invalid.
  - `translations.expiry.label` — Customize the label for the expiry field.
  - `translations.expiry.placeholder` — Customize the placeholder for the expiry field.
  - `translations.expiry.errors.invalid` — Customize the error message for the expiry field when the value is invalid.
  - `translations.cvc.label` — Customize the label for the cvc field.
  - `translations.cvc.placeholder` — Customize the placeholder for the cvc field.
  - `translations.cvc.errors.invalid` — Customize the error message for the cvc field when the value is invalid.
- `validation` `Object` — Allows you to customize the validation logic of the component.
  - `validation.name.regex` `RegExp` — A regex pattern that the name must match in order to be considered valid. You can use this option to only allow certain characters.
  - `validation.cvc.optional` `Boolean` — When set to `true`, the CVC field is treated as optional. The card is considered valid even if no CVC is entered. If a CVC is entered, it is validated as normal. Defaults to `false`.
- `onChange` `(payload: Object) => void` — Triggered whenever the component's state is updated. **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.
- `onComplete` `(payload: Object) => void` — Triggered when the component is complete. **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.
- `onValidate` `(payload: Object) => void` — Triggered when the component is programmatically validated with the `validate()` ref method. **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.
- `onSwipe` `(payload: Object) => void` — Triggered when the component is swiped.
  - `brand` `String` — The brand that issued the card.
  - `localBrands` `String[]` — The brands that are supported by the component.
  - `number` `String` — The card number.
  - `expiry` `Object` — The expiry date of the card.
  - `firstName` `String` — The first name of the card holder.
  - `lastName` `String` — The last name of the card holder.
  - `lastFour` `String` — The last 4 digits of the card.
  - `bin` `String` — The bin for the card.
- `onFocus` `(event: { field: string, data: Object }) => void` — Triggered when a card field receives focus. The `field` property identifies which field received focus (`name`, `number`, `expiry`, or `cvc`).
- `onBlur` `(event: { field: string, data: Object }) => void` — Triggered when a card field loses focus. The `field` property identifies which field lost focus (`name`, `number`, `expiry`, or `cvc`).
- `onKeyUp` `(event: { field: string, data: Object }) => void` — Triggered on a key-up event within a card field. The `field` property identifies the active field.
- `onKeyDown` `(event: { field: string, data: Object }) => void` — Triggered on a key-down event within a card field. The `field` property identifies the active field.
- `onReady` `() => void` — Triggered when the component has loaded and is ready to be used.
- `onError` `() => void` — Triggered when the component encounters an error and fails to load.

The `Card` component accepts a `ref` that exposes the following methods:

**Ref methods**

- `validate` `() => void` — Programmatically triggers validation on all card fields and emits a `validate` event with the current payload. Use this with the `onValidate` callback to implement submit-time validation.

### ThreeDSecure

The ThreeDSecure component can be used instead of the [useThreeDSecure](/sdks/react#useThreeDSecure) hook when you want more control over how and where the 3D Secure iframe is displayed. In order to use the component you must first [create a 3D Secure session](/api#createThreeDSSession) on your backend.

```jsx
import { ThreeDSecure } from "@evervault/react";

export function MyComponent() {
  const handleSuccess = () => {
    console.log("3D Secure authentication complete");
  };

  return (
    <ThreeDSecure session="tds_visa_123456789" onSuccess={handleSuccess} />
  );
}
```

**Props**

- `session` `String` _(required)_ — The 3D Secure session ID. A 3D Secure session can be created using the [API](/api#createThreeDSSession).
- `theme` `Object` — Allows you to customize the appearance of the component. Note: You can't customize the appearance of the iframe content itself. This is controlled by the card issuer.
- `colorScheme` `string` — Allows you to set the root [color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/color-scheme) for the iframe document. For a seamless transparent background, use the same color scheme as the parent document.
- `size` `{ width: string, height: string }` — This size of the 3D Secure iframe. Card issuers are required to support content at 250x400, 390x400, 500x600, 600x400. The default size is 500x600.
- `failOnChallenge` `Boolean | () => Boolean | () => Promise<Boolean>` — If set to true, the component will fail 3DS authentication when a challenge is requested and no challenge will be shown. Alternatively, you can provide a function which will be called when a challenge is requested. If the function returns true 3DS authentication will fail, if it returns false the challenge will be shown.
- `onSuccess` `Function` — The 'success' event will be fired once the 3D Secure 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](/api#retrieveThreeDSSession) endpoint to retrieve the cryptogram for the session and complete the payment.
- `onFailure` `Function` — The 'failure' event will be fired if the 3D Secure authentication process fails. You should use this event to handle the failure and inform the user and prompt them to try again.
- `onError` `Function` — The error event will be fired if the component fails to load.
- `onReady` `Function` — The ready event will be fired once the component has fully loaded and is ready to be displayed. This is often used to show a loading state while the component loads.

### Reveal

The Reveal component allows you to display previously encrypted card data to your users in plaintext in a secure iframe hosted by Evervault. See [Card Reveal](/cards/reveal) for more information.

```jsx
import { useMemo } from "react";
import { Reveal } from "@evervault/react";

export function MyComponent() {
  const request = useMemo(() => {
    return new Request("<YOUR_ENDPOINT>");
  }, []);

  return (
    <Reveal request={request}>
      <Reveal.Text path="$.card.number" />
      <Reveal.CopyButton path="$.card.number" text="Copy Number" />
    </Reveal>
  );
}
```

**Props**

- `request` `Request` _(required)_ — The request to use to fetch the encrypted data.
- `onReady` `Function` — Triggered when the component has fully loaded and is ready to be shown.
- `onError` `Function` — Triggered when the component fails to load.

### Reveal.Text

Creates a Reveal Text consumer component. The Reveal Text consumer allows you to render a selected field from the request response. This component must be rendered as a child of the Reveal component.

```jsx
import { useMemo } from "react";
import { Reveal } from "@evervault/react";

export function MyComponent() {
  const request = useMemo(() => {
    return new Request("<YOUR_ENDPOINT>");
  }, []);

  return (
    <Reveal request={request}>
      <Reveal.Text path="$.user.pin" />
    </Reveal>
  );
}
```

**Props**

- `theme` `Object` — Allows you to completely customize the appearance of the component.
- `colorScheme` `string` — Allows you to set the root [color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/color-scheme) for the iframe document. For a seamless transparent background, use the same color scheme as the parent document.
- `path` `String` _(required)_ — A [JSON path](https://jsonpath.com/) selector for the response field you want to display.
- `format` `Object` — Allows you to use regex matching to format the field value.
  - `regex` `String` — The regex statement to match against the value.
  - `replace` `String` — The text to replace the value with. You can use $ to reference matched regex groups.

### Reveal.CopyButton

Creates a Reveal Copy Button consumer component. This renders a button which when clicked will copy a response field to the users clipboard. This component must be rendered as a child of the Reveal component.

```jsx
import { useMemo } from "react";
import { Reveal } from "@evervault/react";

export function MyComponent() {
  const request = useMemo(() => {
    return new Request("<YOUR_ENDPOINT>");
  }, []);

  return (
    <Reveal request={request}>
      <Reveal.CopyButton path="$.card.number" />
    </Reveal>
  );
}
```

**Props**

- `path` `String` _(required)_ — A [JSON path](https://jsonpath.com/) selector for the response field you want to copy.
- `theme` `Object` — Allows you to completely customize the appearance of the component.
- `colorScheme` `string` — Allows you to set the root [color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/color-scheme) for the iframe document. For a seamless transparent background, use the same color scheme as the parent document.
- `format` `Object` — Allows you to use regex matching to format the field value.
  - `regex` `String` — The regex statement to match against the value.
  - `replace` `String` — The text to replace the value with. You can use $ to reference matched regex groups.
- `onCopy` `() => void` — A callback function that is called when the button is clicked.

### Pin

Creates a Pin component which allows you to collect and encrypt pin numbers in a completely PCI-compliant environment.

```jsx
import { Pin, themes } from "@evervault/react";
const theme = themes.clean();

export function MyComponent() {
  const handleChange = (details) => {
    console.log(details);
  };

  return (
    <div>
      <Pin theme={theme} onChange={handleChange} />
    </div>
  );
}
```

**Props**

- `theme` `Object` — The theme to use for the Pin.
- `colorScheme` `string` — Allows you to set the root [color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/color-scheme) for the iframe document. For a seamless transparent background, use the same color scheme as the parent document.
- `autoFocus` `Boolean` — If set to true, the component will automatically steal focus when it mounts.
- `length` `Number` — Change the length of the pin number.
- `mode` `numeric | alphanumeric` — If set to 'alphanumeric' the pin number will also accept letters as input.
- `inputType` `"number" | "text" | "password"` — Sets the `type` attribute of the underlying input elements used to capture the pin. Defaults to `"number"`.
- `onChange` `(payload: Object) => void` — Triggered whenever the component's state is updated.
  - Payload
  - `value` `String` — The encrypted pin number.
  - `isComplete` `Boolean` — Whether or not the pin number field is complete.
- `onComplete` `(payload: Object) => void` — Triggered when the pin number field has been fully filled out by the user.
  - Payload
  - `value` `String` — The encrypted pin number.
  - `isCompleteBoolean` `Boolean` — Whether or not the pin number field is complete.
- `onReady` `Function` — Triggered when the component has fully loaded and is ready to be shown.
- `onError` `Function` — Triggered when the component fails to load. If you want to respond to validation errors you should use the change event instead.

## Hooks

### useEvervault

The `useEvervault` hook is accessible in children of the EvervaultProvider, and returns an initialized instance of the Evervault [JavaScript SDK](/sdks/javascript). One of the functions included in the returned object is `encrypt()`, which can be passed any plaintext data structure.

```jsx
const evervault = useEvervault();
```

#### .encrypt()

Encrypts data using Evervault Encryption. Evervault Strings can be used across all of our products. It is accessible on the returned value from the `useEvervault()` hook. To encrypt data using the React.js SDK, simply pass a String or an Object into the `evervault.encrypt()` function.

The encrypted data can be passed to your server and stored in your database as normal. It can also be used with any of Evervault's other services.

```jsx
function MyComponent() {
  const evervault = useEvervault();

  const handleEncrypt = async () => {
    const encrypted = await evervault.encrypt("Hello, world!");
    console.log(encrypted);
  };

  return <button onClick={handleEncrypt}>Encrypt</button>;
}
```

**Parameters**

- `data` `String | Object | Array | File | Blob` _(required)_ — The data to encrypt.

#### .decrypt()

Allows you to decrypt a previously encrypted piece of data using a client side token. The token is a time bound token for decrypting data. The token can be generated using our [backend SDKs](/sdks) or through our [REST API](/api).

The payload must be the same payload that was used to create the token and expires in a maximum of 10 minutes depending on the expiry set when creating the token.

The payload can be any `String` or `Object` and it will be returned, decrypted, in the same form.

```jsx
const evervault = useEvervault();
const data = await evervault.encrypt("Hello, world!");
const decrypted = await evervault.decrypt("[client-side-token]", data);
```

**Parameters**

- `token` `String` _(required)_ — A valid [client-side token](/api#client-side-tokens) with permissions to decrypt the data.
- `data` `String | Object` _(required)_ — The encrypted data to decrypt.

#### .brands.create()

Creates a custom card brand definition that can be passed to the `customBrands` prop on [`Card`](#card). Use this to add support for card networks that aren't included in Evervault's built-in brand list.

```javascript
const acmeBrand = evervault.brands.create("acme-card", {
  numberValidationRules: {
    ranges: [9900, [88000, 88999]],
    lengths: [16],
  },
  securityCodeValidationRules: {
    lengths: [3],
  },
})
```

**Parameters**

- `name` `string` _(required)_ — A unique identifier for the brand. This value is returned in the `localBrands` array of the card change payload.
- `options` `Object` _(required)_ — Configuration for the custom brand.
  - `options.numberValidationRules` `Object` _(required)_ — Rules used to validate card numbers for this brand.
    - `options.numberValidationRules.ranges` `Array<number | [number, number]>` _(required)_ — Bank identification number (BIN) prefixes or ranges that identify cards belonging to this brand. A single number matches cards starting with that prefix (e.g., `9900`). A two-element tuple defines an inclusive range of BIN prefixes (e.g., `[88000, 88999]`).
    - `options.numberValidationRules.lengths` `number[]` _(required)_ — The valid card number lengths for this brand.
    - `options.numberValidationRules.luhnCheck` `Boolean` — Whether to validate the card number using the Luhn algorithm. Defaults to `true`.
  - `options.securityCodeValidationRules` `Object` _(required)_ — Rules used to validate the CVC for this brand.
    - `options.securityCodeValidationRules.lengths` `Array<3 | 4>` _(required)_ — The valid CVC lengths for this brand. Accepts 3, 4 or both.
  - `options.iconSrc` `string` — A URL for the brand's icon. Displayed in the card component when a matching card number is entered.

### useThreeDSecure

The useThreeDSecure hook can be used in combination with the Evervault API to perform 3D Secure authentication. In order to use the hook you must first [create a 3D Secure session](/api#createThreeDSSession) on your backend and pass it to your frontend. The hook will manage displaying the 3D Secure iframe inside of a modal window and handle the authentication process.

Note: If you want more control over how and where the 3D Secure iframe is displayed you can use the [ThreeDSecure](/sdks/react#three-d-secure) component instead.

See [3D Secure](/cards/3d-secure) for more information.

```jsx
import { Card, useThreeDSecure } from "@evervault/react";
import { createThreeDSSession, finalizePayment } from "./api";

function Checkout() {
  const threeDSecure = useThreeDSecure();

  const handlePay = async () => {
    const session = await createThreeDSSession();
    threeDSecure.start(session, {
      onSuccess: () => {
        finalizePayment(session);
      },
    });
  };

  return (
    <>
      <Card />
      <button onClick={handlePay}>Pay</button>
    </>
  );
}
```

**Options**

- `theme` `Object` — Allows you to customize the appearance of the component. Note: You can't customize the appearance of the iframe content itself. This is controlled by the card issuer.
- `colorScheme` `string` — Allows you to set the root [color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/color-scheme) for the iframe document. For a seamless transparent background, use the same color scheme as the parent document.
- `size` `{ width: string, height: string }` — This size of the 3D Secure iframe. Card issuers are required to support content at 250x400, 390x400, 500x600, 600x400. The default size is 500x600.
- `failOnChallenge` `Boolean | () => Boolean | () => Promise<Boolean>` — If set to true, the component will fail 3DS authentication when a challenge is requested and no challenge will be shown. Alternatively, you can provide a function which will be called when a challenge is requested. If the function returns true 3DS authentication will fail, if it returns false the challenge will be shown.

#### threeDSecure.start()

The start function is used to begin the 3D Secure authentication process.

**Parameters**

- `session` `String` _(required)_ — The 3D Secure session ID. A 3D Secure session can be created using the [API](/api#createThreeDSSession).
- `options.onSuccess` `Function` — The 'success' event will be fired once the 3D Secure 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](/api#retrieveThreeDSSession) endpoint to retrieve the cryptogram for the session and complete the payment.
- `options.onFailure` `Function` — The 'failure' event will be fired if the 3D Secure authentication process fails. You should use this event to handle the failure and inform the user and prompt them to try again.
- `options.onError` `Function` — The error event will be fired if the component fails to load.
- `options.onReady` `Function` — The ready event will be fired once the component has fully loaded and is ready to be displayed. This is often used to show a loading state while the component loads.

#### threeDSecure.update()

The update function updates the options passed to the active 3D Secure instance without restarting the authentication flow.

**Parameters**

- `options.theme` `Object` — Allows you to customize the appearance of the component. Note: You can't customize the appearance of the iframe content itself. This is controlled by the card issuer.
- `options.colorScheme` `string` — Allows you to set the root [color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/color-scheme) for the iframe document. For a seamless transparent background, use the same color scheme as the parent document.
- `options.size` `{ width: string, height: string }` — This size of the 3D Secure iframe. Card issuers are required to support content at 250x400, 390x400, 500x600, 600x400. The default size is 500x600.
- `options.failOnChallenge` `Boolean | () => Boolean | () => Promise<Boolean>` — If set to true, the component will fail 3DS authentication when a challenge is requested and no challenge will be shown. Alternatively, you can provide a function which will be called when a challenge is requested. If the function returns true 3DS authentication will fail, if it returns false the challenge will be shown.

## Content Security Policy (CSP)

If you are using a Content Security Policy (CSP), you will need to add the following directives to allow the Evervault SDK to function correctly.

```text
script-src https://js.evervault.com;
connect-src https://keys.evervault.com https://api.evervault.com;
frame-src https://ui-components.evervault.com;
```

