# @highnoteplatform/card-viewer

> **Note:** This library is in a pre-release phase. Prior to the release of
> version `1.0.0`, breaking changes may be introduced.

The Highnote Card Viewer library allows you to embed sensitive card data in your
UI seamlessly using iframes. This allows you to avoid PCI-scoped data flowing
through your servers or being accessible to scripts running on your page. You
can either render card data as individual fields or render a customized card
image (coming soon).

## Usage

### Card Viewer Fields

> **Note:** Read the full documentation [here](https://highnote.com/docs/basics/clientside-and-sdks/card-viewer-sdk).

#### Installation

With npm:

```sh
npm i @highnoteplatform/card-viewer
```

With yarn:

```sh
yarn add @highnoteplatform/card-viewer
```

#### Generate a client token

On your server, generate a client token using the GraphQL API.

<!-- markdownlint-disable MD013 -->

> See the [generatePaymentCardClientToken](https://highnote.com/docs/reference/mutation/generatePaymentCardClientToken) docs.

<!-- markdownlint-enable MD013 -->

<!-- markdownlint-disable MD036 -->

**GraphQL query**

```graphql
mutation GeneratePaymentCardClientToken(
  $input: GeneratePaymentCardClientTokenInput!
) {
  generatePaymentCardClientToken(input: $input) {
    ... on ClientToken {
      value
      expirationDate
    }
  }
}
```

**Input variables**

```json
{
  "input": {
    "paymentCardId": "MC43LjE=",
    "permissions": ["READ_RESTRICTED_DETAILS"]
  }
}
```

**Response**

```json
{
  "data": {
    "generatePaymentCardClientToken": {
      "value": "TOKEN",
      "expirationDate": "2022-02-07T20:04:50.633Z"
    }
  },
  "extensions": {
    "requestId": "example-request-id"
  }
}
```

#### Prepare your HTML

You will need to provide the Card Viewer with the elements you want to render
iframes into for each field.

- Card Number
- CVV
- Expiration date

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Payment Card</title>
  </head>
  <body>
    <p>Card Number</p>
    <div id="cardNumber">
      <!-- An iframe will be injected here -->
    </div>

    <p>CVV</p>
    <div id="cvv">
      <!-- An iframe will be injected here -->
    </div>

    <p>Expiration Date</p>
    <div id="expirationDate">
      <!-- An iframe will be injected here -->
    </div>
  </body>
</html>
```

#### Initialize the library

```typescript
import { renderFields } from "@highnoteplatform/card-viewer";

const { unmount } = await renderFields({
  clientToken: "client token from server",
  // This is the same paymentCardId used to generate the token
  paymentCardId: "MC43LjE=",
  // This allows a user to click and copy the value of a field. Enabled by default
  enableClipboard: true,
  // Only needed is clipboard is enabled
  onCopyToClipboardSuccess: ({ field }) => {
    console.log(`${field} value copied!`); // cardNumber value copied!
  },

  onError: (error) => {
    // Handle errors
  },

  // Specify the individual fields to render data into
  elements: {
    cardNumber: {
      selector: "#cardNumber",
    },

    cvv: {
      selector: "#cvv",
      // Example style payload allowing customization of the given field.
      styles: {
        color: "black",
        fontFamily: "monospace",
        cursor: "pointer",
        fontWeight: "medium",
        fontSize: "1rem",

        ":hover": {
          backgroundColor: "rgba(0, 0, 0, .2)",
      },
    },

    expirationDate: {
      selector: "#expirationDate",
    },
  },
});
```
