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

# Using Marqeta.js

> Marqeta.js is a PCI-compliant JavaScript library that enables your application to display sensitive card data in configurable iframes, while limiting your data security compliance burden.

<Warning>
  **Important**\
  We are pleased to announce that the Marqeta platform is transitioning away from the Marqeta.js library and its widgets in favor of [Marqeta UX Toolkit](/developer-guides/about-ux-toolkit/) for programs based in the United States. For this reason, we are no longer adding this functionality to new US programs.

  Existing US programs are not immediately impacted, but are encouraged to migrate over to UX Toolkit as soon as possible. Programs based outside the United States are not affected by this change, but may be eligible to use UX Toolkit. Contact your Marqeta representative for more information.
</Warning>

Marqeta provides a JavaScript library that enables you to display sensitive card data in your application or webpage while limiting your data security compliance burden.

Marqeta.js injects a set of configurable iframes into your HTML showing the cardholder’s card data. The iframes enable you to display a virtual card or PIN without handling sensitive card data on your servers. Instead, Marqeta hosts the data on secure, compliant servers. You can present a complete card—including the PAN, expiration date, and CVV2 elements—or individual elements such as the cardholder’s PIN. Marqeta.js can also add buttons to your application or webpage that copy a card’s PAN, expiration date, or CVV2 to the clipboard.

<Note>
  **Note**\
  While the Marqeta.js iframe feature reduces your burden of achieving data security compliance, it does not eliminate it entirely, and is only appropriate for certain use cases. Contact your Marqeta representative about using the Marqeta.js library.
</Note>

At the end of this guide, you should understand:

* How to integrate with Marqeta.js.

* How to obtain a client access token.

* How to inject the Marqeta.js iframes into your HTML.

<h2 id="_prerequisites">
  Prerequisites
</h2>

* Read the [Core API Quick Start](/developer-guides/core-api-quick-start/).

* Obtain a valid virtual card token.

<h2 id="_concepts">
  Concepts
</h2>

<h3 id="_data_security_compliance">
  Data security compliance
</h3>

Companies that store, transmit, or process sensitive card data, including the primary account number (PAN), card verification value (CVV2), expiration date, and personal identification number (PIN) must comply with the Payment Card Industry Data Security Standard (PCI DSS). Achieving PCI DSS certification is both time consuming and expensive.

Marqeta.js offloads some of the PCI compliance burden (for certain use cases) by enabling the encrypted transmission of sensitive card data. Marqeta is fully PCI-Service Provider Level 1 compliant and handles the unencrypted sensitive card data for you. Your servers never store, transmit, or process the card data.

<Danger>
  **Warning**\
  Card data is less secure when copied to the clipboard than when left in this PCI-compliant widget. Cardholders should adopt data security best practices and take precautions to keep their sensitive data safe.
</Danger>

<h3 id="_dynamic_card_data_iframes">
  Dynamic card data iframes
</h3>

The iframes injected by Marqeta.js enable you to control the styling and layout of the HTML pages you serve to client applications, while delegating secure handling of sensitive data to Marqeta servers. They also provide the transparent button UI elements used for copying sensitive data to the clipboard. These elements are transparent so you can overlay them over your custom user interface to intercept click events. They require no customization. You create and style pages in whatever manner you desire, and Marqeta.js inserts the card data and button UI elements into the page locations specified in the HTML.

<Tip>
  **Tip**\
  To display virtual cards within a mobile application, you can embed the iframes using a webview.
</Tip>

<h3 id="_encryption_and_card_data_flow">
  Encryption and card data flow
</h3>

The following process describes how Marqeta.js injects the iframes into your application. See the [tutorials](/developer-guides/using-marqeta-js/#_card_data_tutorial) on this page for more details.

<Frame>
  <img src="https://mintcdn.com/marqeta-b295cded/hYmh6YsXz54defql/images/docs/developer-guides/using-marqeta-js/pci_1.svg?fit=max&auto=format&n=hYmh6YsXz54defql&q=85&s=63a74972860c8693c778b3bfd20c33bf" alt="How Marqeta.js injects iframes into your application" width="1530" height="1070" data-path="images/docs/developer-guides/using-marqeta-js/pci_1.svg" />
</Frame>

<Steps>
  <Step>
    Your application’s backend requests a client access token.
  </Step>

  <Step>
    The Marqeta API creates a Base64-encoded client access token. This token enables access to the specified card and will expire after five minutes.
  </Step>

  <Step>
    Your backend passes the client access token to your JavaScript.
  </Step>

  <Step>
    Your JavaScript injects the client access token into the `marqeta.bootstrap()` method through a `configuration` object.
  </Step>

  <Step>
    Your JavaScript executes `marqeta.bootstrap()`, which initializes and configures Marqeta.js.
  </Step>

  <Step>
    Marqeta.js injects the card data and buttons into the HTML container:

    * If you are [displaying card data](/developer-guides/using-marqeta-js/#_card_data_tutorial), this action populates separate iframes for the card’s PAN, CVV2, and expiration date (as well as for their respective Copy to Clipboard buttons, if you decided to integrate the Copy to Clipboard functionality).

    * If you are [revealing the cardholder’s PIN](/developer-guides/using-marqeta-js/#_pin_reveal_tutorial), this action populates the iframe for the hidden PIN and button used to toggle displaying the PIN. The PIN is initially displayed as •••• until it is toggled.
  </Step>

  <Step>
    The HTML page displays the requested information.
  </Step>
</Steps>

<h3 id="_the_configuration_object">
  The configuration object
</h3>

The `.bootstrap()` method of Marqeta.js requires a `configuration` object, which defines the attributes and behaviors of the iframes. Nested under the `configuration` object is the `component` object, which accepts either a `showPan` or a `pinReveal` object, depending on the action you want to complete. In both cases, you must include the ID of the "div" element into which Marqeta.js injects the individual iframes of card data.

More information on the objects is given the section below.

**The configuration object**

| Fields                                                                                     | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| configuration.**clientAccessToken**<br /><br />string<br /><br />Required                  | Client access token obtained from the Marqeta API.<br /><br />**NOTE:** If you have migrated from a previous version of the Marqeta.js library and Marqeta has updated your program configuration, the next time you generate a new client access token the URL used to communicate with Marqeta.js will be refreshed to align with the new version you are using.<br /><br />For more information, see <a href="/developer-guides/release-notes-2023/#_deprecation_of_marqeta_js_v1_1_0">Deprecation of Marqeta.js v1.1.0</a>.<br /><br />**Allowable Values:**<br /><br />Client access token |
| configuration.**options**<br /><br />string<br /><br />Conditionally required              | You must set the `cardholderVerificationMethod` to `OTHER` when including the `pinReveal` component in your application.<br /><br />**Allowable Values:**<br /><br />`OTHER`                                                                                                                                                                                                                                                                                                                                                                                                                    |
| configuration.component.**showPan**<br /><br />object<br /><br />Required                  | Specifies the card data to display and applies typographical styling to the data.<br /><br />Include the `cardPan` object to display the PAN, the `cardCvv` object to display the CVV2 number, and the `cardExp` object to display the expiration date.<br /><br />**Allowable Values:**<br /><br />Any combination of `cardPan`, `cardCvv`, and `cardExp` objects                                                                                                                                                                                                                              |
| configuration.component.**pinReveal**<br /><br />object<br /><br />Optional                | Specifies how the cardholder’s PIN will be revealed/hidden and applies typographical styling to the data.<br /><br />Include the `cardPin` object to display the PIN.<br /><br />**Allowable Values:**<br /><br />`cardPin` object                                                                                                                                                                                                                                                                                                                                                              |
| configuration.component.pinReveal.**toggleCardPin**<br /><br />object<br /><br />Optional  | Your custom event handlers to reveal and hide the cardholder’s PIN.<br /><br />**Allowable Values:**<br /><br />The `domID` to associate the `toggleCardPin` element with its corresponding "div" element, the `mode` set to `transparent`, as well as existing objects to toggle the display of the cardholder’s PIN                                                                                                                                                                                                                                                                           |
| configuration.component.pinReveal.**hidePinTimeout**<br /><br />object<br /><br />Optional | Specifies when the cardholder’s PIN will time out on the cardholder’s screen and applies typographical styling to the PIN timer message.<br /><br />**Allowable Values:**<br /><br />The `domID` to associate the `hidePinTimeout` element with its corresponding "div" element, as well as a time value to cause the cardholder’s PIN to stop being displayed.                                                                                                                                                                                                                                 |
| configuration.**callbackEvents**<br /><br />object<br /><br />Optional                     | Defines customizable event handlers that are executed upon success or failure of iframe rendering.<br /><br />**Allowable Values:**<br /><br />Existing object                                                                                                                                                                                                                                                                                                                                                                                                                                  |

<h4 id="_the_showpan_object">
  The showPan object
</h4>

You must include the `showPan` object under the `component` object, which is itself nested under the `configuration` object. The `showPan` object specifies which card attributes to display. It can contain any of the following optional objects:

* `cardPan` — The card’s PAN.

* `cardCvv` — The card’s CVV2.

* `cardExp` — The card’s expiration date.

* `copyCardPan` — A transparent button used to copy the card’s PAN to the clipboard.

* `copyCardCvv` — A transparent button used to copy the card’s CVV2 to the clipboard.

* `copyCardExp` — A transparent button used to copy the card’s expiration date to the clipboard.

<Tip>
  **Tip**\
  If you include a `copyCard*` object, you should also include its associated `card*` object. For example, if you include the `copyCardPan` object in the `showPan` object, you should also include the `cardPan` object.
</Tip>

Any `cardPan`, `cardCvv`, or `cardExp` objects included within the `showPan` object have their associated values injected as iframes within the div container you specified in the `component` object.

For each included object, you must specify the div element that contains the iframe.

You can also configure the appearance of the card data using the `styles` object within each of the `cardPan`, `cardExp`, and `cardCvv` objects. The `showPan.copyCardPan`, `showPan.copyCardCvv`, and `showPan.copyCardExp` objects support `transparent` mode only, and do not contain a `styles` object or a `span`.

<Note>
  **Note**\
  Marqeta.js only supports web-safe/system fonts that can be displayed on modern web browsers without a specific download.
</Note>

| Object  | Supported Selectors | Supported Attributes                                                   |
| ------- | ------------------- | ---------------------------------------------------------------------- |
| cardPan | span, span:hover    | color, font-family, font-size, background, font-weight, letter-spacing |
| cardCvv | span, span:hover    | color, font-family, font-size, background                              |
| cardExp | span, span:hover    | color, font-family, font-size, background, font-weight, letter-spacing |

<h4 id="_the_showpan_cardpan_and_showpan_cardexp_objects">
  The showPan.cardPan and showPan.cardExp objects
</h4>

| Fields                                          | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| domId<br /><br />string<br /><br />Required     | Associates the `cardPan` and `cardExp` elements with their corresponding div elements.<br /><br />**Allowable Values:**<br /><br />Must match the DOM ID of the corresponding "div" element.<br /><br />For example, `cardPan.domId` must match the ID attribute of the div element that will contain the card PAN iframe.                                                                                                                                                                                                                       |
| format<br /><br />boolean<br /><br />Optional   | Set to `true` to format the element’s content.<br /><br />The content of `cardPan` is formatted as:<br />"XXXX XXXX XXXX XXXX"<br /><br />The content of `cardExp` is formatted as:<br />"XX/XX"<br /><br />**Allowable Values:**<br /><br />`true`, `false`<br /><br />**Default value:**<br />`false`                                                                                                                                                                                                                                          |
| styles<br /><br />object<br /><br />Optional    | A CSS-like style object applied to the iframe holding the card data.<br /><br />**Allowable Values:**<br /><br />Existing object                                                                                                                                                                                                                                                                                                                                                                                                                 |
| styles.\\<br /><br />object<br /><br />Optional | Replace `\\` with one of the supported selector values.<br /><br />**Supported selectors:**<br />`span`, `span:hover`<br /><br />**Supported CSS attributes:**<br />`color`, `font-family`, `font-size`, `background`, `font-weight`, `letter-spacing`<br /><br />**NOTE:** CSS importing schemes such as `@import` and `@url` are not supported. Marqeta.js only supports web-safe/system fonts that can be displayed on modern web browsers without a specific download.<br /><br />**Allowable Values:**<br /><br />Your custom styles object |

<h4 id="_the_showpan_cardcvv_object">
  The showPan.cardCvv object
</h4>

| Fields                                          | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| domId<br /><br />string<br /><br />Required     | Associates the `cardCvv` element with its corresponding div element.<br /><br />**Allowable Values:**<br /><br />Must match the DOM ID of the corresponding "div" element. That is, `cardCvv.domId` must match the ID attribute of the div element that will contain the card CVV2 iframe.                                                                                                                                                                                                            |
| styles<br /><br />object<br /><br />Optional    | A CSS-like style object applied to the iframe holding the card data.<br /><br />**Allowable Values:**<br /><br />Existing object                                                                                                                                                                                                                                                                                                                                                                      |
| styles.\\<br /><br />object<br /><br />Optional | Replace `\\` with one of the supported selector values.<br /><br />**Supported selectors:**<br />`span`, `span:hover`<br /><br />**Supported CSS attributes:**<br />`color`, `font-family`, `font-size`, `background`<br /><br />**NOTE:** CSS importing schemes such as `@import` and `@url` are not supported. Marqeta.js only supports web-safe/system fonts that can be displayed on modern web browsers without a specific download.<br /><br />**Allowable Values:**<br /><br />Existing object |

<h4 id="_the_showpan_copycardpan_showpan_copycardcvv_and_showpan_copycardexp_objects">
  The showPan.copyCardPan, showPan.copyCardCvv, and showPan.copyCardExp objects
</h4>

| Fields                                                     | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| domId<br /><br />string<br /><br />Required                | Associates the `copyCardPan`, `copyCardCvv`, and `copyCardExp` elements with their corresponding div elements.<br /><br />**Allowable Values:**<br /><br />Must match the DOM ID of the corresponding div element. That is, `copyCardPan.domId` must match the ID attribute of the div element that will contain the card PAN iframe’s Copy to Clipboard button.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| mode<br /><br />enum<br /><br />Required                   | With transparent mode, you can customize the look-and-feel of the Copy to Clipboard button within the parent div, and allow the transparent iframe to intercept click events. For example, you can provide your own button UI element inside the div, and the injected iframe will be positioned on top of the button to handle copying the text in a PCI-compliant manner.<br /><br />The iframe injected by Marqeta.js will be transparent, absolutely positioned to the bounds of the parent div element, and given a high z-ordering. The entire iframe region will handle clicks.<br /><br />The parent div element must have its CSS position set to `relative`, for example `style="position: relative;"` to ensure it remains tightly aligned with its iframe.<br /><br />**Allowable Values:**<br /><br />Only `transparent` is supported |
| onCopySuccess<br /><br />event handler<br /><br />Optional | Called when the element’s text is successfully copied to the clipboard.<br /><br />You can use this callback to update your user interface in response to a click.<br /><br />**Allowable Values:**<br /><br />A function with no parameters                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| onCopyFailure<br /><br />event handler<br /><br />Optional | Called when an error occurred while attempting to copy the element’s text to the clipboard.<br /><br />**Allowable Values:**<br /><br />A function with the `error` object as its parameter                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |

The [`callbackEvents` object](/developer-guides/using-marqeta-js/#_the_callbackevents_object) specifies the methods executed upon the success and failure events when rendering the iframes.

<h4 id="_the_pinreveal_object">
  The pinReveal object
</h4>

You must include the `pinReveal` object under the `component` object, which is itself nested under the `configuration` object. The `pinReveal` object specifies the attributes of the cardholder’s PIN to display. It must contain the following objects:

* `toggleCardPin` — A transparent button used to toggle the display of the cardholder’s PIN between its initial presentation as •••• and its literal value. There is no functionality available to copy the cardholder’s PIN to the clipboard.

* `hidePinTimeout` — A customizable timer that allows you to hide the cardholder’s PIN from view as a safety precaution after a preconfigured number of seconds have elapsed. If your cardholder clicks the toggle PIN button while the timer is running, the timer will end and Marqeta.js will hide the PIN from view. If the toggle PIN button is clicked again, the timer will start counting down from the beginning (and not resume the timer’s previous countdown position).

* `cardPin` — The cardholder’s PIN.

<Tip>
  **Tip**\
  If you include the `cardPin*` object, you should also include its associated `toggleCardPin*` object.
</Tip>

Any `cardPin` object included within the `pinReveal` object has its associated value injected as an iframe within the div container you specified in the `component` object.

For each included object, you must specify the "div" element that contains the iframe.

You can also configure the appearance of the cardholder’s PIN using the `styles` object within each of the `cardPin` objects. The `pinReveal.cardPin` object supports `transparent` mode only.

<Note>
  **Note**\
  Marqeta.js only supports web-safe/system fonts that can be displayed on modern web browsers without a specific download.
</Note>

| Object  | Supported Selectors | Supported Attributes                                                   |
| ------- | ------------------- | ---------------------------------------------------------------------- |
| cardPin | span, span:hover    | color, font-family, font-size, background, font-weight, letter-spacing |

With the `hidePinTimeout` object, you can restyle the timer message so it aligns with your application’s look and branding. This includes repositioning the timer message to your preferred location on the screen.

<h4 id="_the_pinreveal_cardpin_object">
  The pinReveal.cardPin object
</h4>

| Fields                                          | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| domId<br /><br />string<br /><br />Required     | Associates the `cardPin` element with its corresponding div element.<br /><br />**Allowable Values:**<br /><br />Must match the DOM ID of the corresponding "div" element.<br /><br />For example, `cardPin.domId` must match the `id` attribute of the "div" element that will contain the PIN’s iframe.                                                                                                                                                                                                                                        |
| format<br /><br />boolean<br /><br />Optional   | Set to `true` to format the element’s content.<br /><br />The content of `cardPin` is formatted as:<br />"XXXX"<br /><br />**Allowable Values:**<br /><br />`true`, `false`<br /><br />**Default value:**<br />`false`                                                                                                                                                                                                                                                                                                                           |
| styles<br /><br />object<br /><br />Optional    | A CSS-like style object applied to the iframe holding the cardholder’s PIN.<br /><br />**Allowable Values:**<br /><br />Existing object                                                                                                                                                                                                                                                                                                                                                                                                          |
| styles.\\<br /><br />object<br /><br />Optional | Replace `\\` with one of the supported selector values.<br /><br />**Supported selectors:**<br />`span`, `span:hover`<br /><br />**Supported CSS attributes:**<br />`color`, `font-family`, `font-size`, `background`, `font-weight`, `letter-spacing`<br /><br />**NOTE:** CSS importing schemes such as `@import` and `@url` are not supported. Marqeta.js only supports web-safe/system fonts that can be displayed on modern web browsers without a specific download.<br /><br />**Allowable Values:**<br /><br />Your custom styles object |

<h4 id="_the_pinreveal_togglecardpin_object">
  The pinReveal.toggleCardPin object
</h4>

| Fields                                                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| domId<br /><br />string<br /><br />Required                  | Associates the `toggleCardPin` element with its corresponding div element.<br /><br />**Allowable Values:**<br /><br />Must match the DOM ID of the corresponding "div" element.<br /><br />For example, `toggleCardPin.domId` must match the `id` attribute of the "div" element that will contain the PIN’s iframe.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| mode<br /><br />enum<br /><br />Required                     | With transparent mode, you can customize the look-and-feel of the Reveal PIN button within the parent div, and allow the transparent iframe to intercept click events. For example, you can provide your own button UI element inside the div, and the injected iframe will be positioned on top of the button to handle toggling the display of the cardholder’s PIN in a PCI-compliant manner.<br /><br />The iframe injected by Marqeta.js will be transparent, absolutely positioned to the bounds of the parent div element, and given a high z-ordering. The entire iframe region will handle clicks.<br /><br />The parent div element must have its CSS position set to `relative`, for example `style="position: relative;"` to ensure it remains tightly aligned with its iframe.<br /><br />**Allowable Values:**<br /><br />Only `transparent` is supported |
| onRevealSuccess<br /><br />event handler<br /><br />Optional | Executed upon success of iframe rendering.<br /><br />You can customize the method within this event handler to perform whatever action you want when the cardholder’s PIN has been successfully revealed.<br /><br />**Allowable Values:**<br /><br />A method                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| onHideSuccess<br /><br />event handler<br /><br />Optional   | Executed upon success of iframe rendering.<br /><br />You can customize the method within this event handler to perform whatever action you want when the cardholder’s PIN has been successfully hidden.<br /><br />**Allowable Values:**<br /><br />A method                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |

<h4 id="_the_pinreveal_hidepintimeout_object">
  The pinReveal.hidePinTimeout object
</h4>

| Fields                                             | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| domId<br /><br />string<br /><br />Required        | Associates the `hidePinTimeout` element with its corresponding div element.<br /><br />**Allowable Values:**<br /><br />Must match the DOM ID of the corresponding "div" element.<br /><br />For example, `hidePinTimeout.domId` must match the `id` attribute of the "div" element that will contain the PIN’s iframe.                                                                                                                                                                                                   |
| hideTimeout<br /><br />integer<br /><br />Required | Period of time after which the cardholder’s PIN will be automatically hidden from view on the cardholder’s screen as a security precaution. Expressed in seconds.<br /><br />**Allowable Values:**<br /><br />minimum: 5<br />maximum: 15                                                                                                                                                                                                                                                                                 |
| styles<br /><br />object<br /><br />Optional       | A CSS-like style object applied to the iframe holding the PIN timer message.<br /><br />**Allowable Values:**<br /><br />Existing object                                                                                                                                                                                                                                                                                                                                                                                  |
| styles.\\<br /><br />object<br /><br />Optional    | Replace `\\` with the supported selector value.<br /><br />**Supported selector:**<br />`span`<br /><br />**Supported CSS attributes:**<br />`color`, `font-family`, `font-size`, `background`, `font-weight`, `letter-spacing`<br /><br />**NOTE:** CSS importing schemes such as `@import` and `@url` are not supported. Marqeta.js only supports web-safe/system fonts that can be displayed on modern web browsers without a specific download.<br /><br />**Allowable Values:**<br /><br />Your custom styles object |

<h4 id="_the_callbackevents_object">
  The callbackEvents object
</h4>

| Fields                                                 | Description                                                                                                                                                                                            |
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| onSuccess<br /><br />event handler<br /><br />Optional | Executed upon success of iframe rendering.<br /><br />You can customize the method within this event handler to perform whatever action you want.<br /><br />**Allowable Values:**<br /><br />A method |
| onFailure<br /><br />event handler<br /><br />Optional | Executed upon failure of iframe rendering.<br /><br />You can customize the method within this event handler to perform whatever action you want.<br /><br />**Allowable Values:**<br /><br />A method |

<h3 id="_copying_card_data_to_the_clipboard">
  Copying card data to the clipboard
</h3>

You can add transparent iframes to your application or webpage that capture clicks to copy a card’s PAN, CVV2, or expiration date to the clipboard of the cardholder’s device. For example, in a POS financing scenario, your cardholders can click the buttons provided by the `.copyToClipboard()` method to help them avoid manually copying card data from a newly issued virtual card to the vendor’s application where they are making a purchase.

Each iframe is associated with a parent div element. Your application or webpage requires a separate parent div element for each card data element you want to copy to the clipboard.

The iframe containing the transparent Copy to Clipboard button is positioned precisely to the bounds of the parent div, so that it can intercept all click events. If your button is not responding to clicks, ensure that the iframe is positioned correctly. By handling the clicks within an iframe, your application avoids entering PCI scope.

You must supply your own visible button UI element inside each parent div that contains the card data to copy.

To respond to clicks within the parent div, you must specify a callback function for the `onCopySuccess` field. This event handler is triggered when data is successfully copied to the clipboard in response to a click event, enabling you to perform an action such as updating your application’s user interface or webpage.

The following HTML example displays a Copy PAN to Clipboard button as an icon:

```html HTML expandable lines wrap theme={null}
<div id='pan-container'></div>
<div id='copy-pan-container' style="position: relative;">
  <img src="myCopyPanIcon.jpg" alt="Copy PAN" id="mq-copy-card-pan">
</div>

<script>
marqeta.bootstrap({
   "clientAccessToken": "**CLIENT_ACCESS_TOKEN**",
   "component": {
     "showPan": {
       "cardPan": {
         "domId": "mq-card-pan",
         "format": true,
         "styles": styles.cardPan.styles // A custom styles object
       },
       "copyCardPan": {
         "domId": "mq-copy-card-pan",
         "mode": "transparent",
         "onCopySuccess": () => alert("Copied PAN!"),
         "onCopyFailure": error => {
           console.error(error);
         }
       }
     }
   },
   "callbackEvents": {
     "onSuccess": () => {
       console.log("Success!")
     },
     "onFailure": error => {
       console.error(error);
     }
   }
 });
</script>
```

When the cardholder clicks any of the transparent iframes, Marqeta.js displays a toast notification in the lower-left corner of the application window or webpage. The toast notification informs the cardholder of the implications of copying sensitive card data to the clipboard. After Marqeta.js displays the notification, it is not presented to the cardholder again on the same device for 90 days to optimize the user experience. Your site must allow access to `localStorage` because that is where Marqeta.js keeps track of the last time the notification was presented.

<Frame>
  <img src="https://mintcdn.com/marqeta-b295cded/hYmh6YsXz54defql/images/docs/developer-guides/using-marqeta-js/marqetajs_1.png?fit=max&auto=format&n=hYmh6YsXz54defql&q=85&s=21798e990be16084004e926a33ceacd0" alt="Example toast notification" width="456" height="150" data-path="images/docs/developer-guides/using-marqeta-js/marqetajs_1.png" />
</Frame>

The toast notification has default inline styles that you can override to match your application or webpage’s design by using the `!important` rule.

Displaying a toast notification on the implications of copying sensitive card data to the clipboard is not a PCI compliance requirement. If you do not want to display this toast notification to your cardholders, simply set the `clipboardWarning` key to undefined from localStorage.

```javascript JavaScript lines wrap theme={null}
localStorage.setItem('clipboardWarning',undefined)
```

<h3 id="_resetting_marqeta_js">
  Resetting Marqeta.js
</h3>

Marqeta.js also provides a `.destroy()` method. Run `marqeta.destroy()` to reset Marqeta.js and any existing configurations, by clearing all the listeners.

In some situations, you might prefer to call `marqeta.bootstrap()` instead of calling `marqeta.destroy()`. One example would be if you wanted to display the data from another card. If you use this approach, however, your client access token will expire. Don’t forget to obtain a new client access token first, as explained in [Step 6 of the card data tutorial](/developer-guides/using-marqeta-js/#_step_6_request_a_client_access_token).

<h2 id="_card_data_tutorial">
  Card data tutorial
</h2>

This tutorial shows you how to display a virtual card’s sensitive data using iframes on your application or webpage. In this scenario, you will display a virtual card’s PAN, expiration date, and CVV2 on an otherwise blank webpage, enabling you to display a virtual card’s data to your customer. You will also add three buttons to facilitate copying card data to the clipboard.

<Note>
  **Note**\
  This tutorial assumes you have already worked with Marqeta to enable Marqeta.js for your program. You cannot complete these steps in the public sandbox.
</Note>

When you are finished, your HTML code should look like the following:

```html HTML expandable lines wrap theme={null}
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Marqeta.js Card Data Tutorial</title>
    <style type="text/css">
      #copy-pan-container:hover > img /* styles */
      #copy-exp-container:hover > img /* styles */
      #copy-cvv-container:hover > img /* styles */
    </style>
  </head>
  <body>

    <!-- div elements for displaying and copying PAN, expiration date, and CVV -->
    <div>
      <div id='mq-card-pan'></div>
      <div id='mq-card-exp'></div>
      <div id='mq-card-cvv'></div>
      <div id='copy-pan-container' style="position: relative;">
        <img src="copyPanIcon.jpg" alt="Copy card number" id="mq-copy-card-pan">
      </div>
      <div id='copy-exp-container' style="position: relative;">
        <img src="copyExpIcon.jpg" alt="Copy expiration date" id="mq-copy-card-exp">
      </div>
      <div id='copy-cvv-container' style="position: relative;">
        <img src="copyCvvIcon.jpg" alt="Copy CVV" id="mq-copy-card-cvv">
      </div>
    </div>

    <!-- Reference Marqeta.js -->
    <script src="https://widgets.marqeta.com/marqetajs/2.0.0/marqeta.min.js" type="text/javascript"></script>
    <script>

    // Call the bootstrap method
     marqeta.bootstrap({
   "clientAccessToken": "**CLIENT ACCESS TOKEN**",
   "component": {
     "showPan": {
       "cardPan": {
         "domId": "mq-card-pan",
         "format": true,
         "styles": styles.cardPan.styles // A custom styles object
       },
       "copyCardPan": {
         "domId": "mq-copy-card-pan",
         "mode": "transparent",
         "onCopySuccess": () => alert("Copied PAN!"),
         "onCopyFailure": error => {
           console.error(error);
         }
       },
       "cardExp": {
         "domId": "mq-card-exp",
         "format": true,
         "styles": styles.cardExp.styles // A custom styles object
       },
       "copyCardExp": {
         "domId": "mq-copy-card-exp",
         "mode": "transparent",
         "onCopySuccess": () => alert("Copied expiration date!"),
         "onCopyFailure": error => {
           console.error(error);
         }
       },
       "cardCvv": {
         "domId": "mq-card-cvv",
         "styles": styles.cardCvv.styles // A custom styles object
       },
       "copyCardCvv": {
         "domId": "mq-copy-card-cvv",
         "mode": "transparent",
         "onCopySuccess": () => alert("Copied CVV2!"),
         "onCopyFailure": error => {
           console.error(error);
         }
       }
     }
   },
   "callbackEvents": {
     "onSuccess": () => {
       console.log("Success!")
     },
     "onFailure": error => {
       console.error(error);
     }
   }
 });
    </script>
  </body>
</html>
```

<h3 id="_step_1_prepare_a_blank_html_page">
  Step 1 — Prepare a blank HTML page
</h3>

Before integrating with Marqeta.js to display card data, prepare an otherwise blank HTML page.

Create a new HTML file and add the following code:

```html HTML lines wrap theme={null}
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Marqeta.js Card Data Tutorial</title>
  </head>
  <body>
  </body>
</html>
```

<h3 id="_step_2_reference_marqeta_js">
  Step 2 — Reference Marqeta.js
</h3>

If you are working in your private sandbox environment, add the following script tag to your HTML:

```html HTML lines wrap theme={null}
<script src="https://widgets-sandbox.marqeta.com/marqetajs/2.0.0/marqeta.min.js" type="text/javascript"></script>
```

If you are working in a production environment, add the following script tag to your HTML:

```html HTML lines wrap theme={null}
<script src="https://widgets.marqeta.com/marqetajs/2.0.0/marqeta.min.js" type="text/javascript"></script>
```

<h3 id="_step_3_add_a_marqeta_bootstrap_method_call">
  Step 3 — Add a marqeta.bootstrap() method call
</h3>

To inject the iframes into your HTML, call the `marqeta.bootstrap()` method of Marqeta.js from your HTML.

Add the following script tag to your HTML after the reference to Marqeta.js. You’ll need to pass an object to the method, but leave it empty for now.

```html HTML lines wrap theme={null}
<script>
  marqeta.bootstrap();
</script>
```

<h3 id="_step_4_add_target_div_elements">
  Step 4 — Add target div elements
</h3>

To present all three pieces of card data, create three div elements—one each for the PAN, expiration date, and CVV2. Assign a unique ID to each div; you will use these IDs in the `marqeta.bootstrap()` `configuration` object.

Add the following code to your HTML:

```html HTML lines wrap theme={null}
<div>
  <div id='mq-card-pan'></div>
  <div id='mq-card-exp'></div>
  <div id='mq-card-cvv'></div>
</div>
```

You can use CSS to define the width of the iframes created by Marqeta.js if you need to resize them. You have the option of setting the iframe’s width to a fixed value such as `300 px` or to a relative value such as `75%`.

If you set the iframe’s width to `100%`, it will expand to fill the size of the parent container. In terms of the span, its text will stop wrapping once it is wide enough. In many cases, it is recommended to set the iframe width to `100%`, and then style the parent container to the width you actually need.

<h3 id="_step_5_add_the_bootstrap_configuration_object">
  Step 5 — Add the bootstrap configuration object
</h3>

Use the `configuration` object to define how the iframes appear on your webpage. Make sure to include the required data. You can configure Marqeta.js to display any combination of the card’s PAN, CVV2, and expiration date.

In this scenario, you will display the PAN, CVV2, and expiration date, providing the necessary card data for your customer.

You have the option of supplying style-related information inline (see `mq-card-pan` below) or as a custom style object you create (see the `mq-card-exp` style object `styles.cardExp.styles` below).

Add the following object as an argument for the `bootstrap()` method. Later steps in this tutorial will explain how to retrieve the data that replaces the placeholder text.

```json JSON expandable lines wrap theme={null}
{
  "clientAccessToken": "**CLIENT ACCESS TOKEN**",
  "component": {
    "showPan": {
      "cardPan": {
        "domId": "mq-card-pan",
        "format": true,
        "styles": {
          "span": {
            "background": "green",
            "color": "white",
            "font-family": "monospace",
            "letter-spacing": "2px",
            "font-weight": "bold"
          }
        }
      },
     "cardExp": {
       "domId": "mq-card-exp",
       "format": true,
       "styles": styles.cardExp.styles // A custom styles object
     },
     "cardCvv": {
       "domId": "mq-card-cvv",
       "styles": styles.cardCvv.styles // A custom styles object
      }
    }
  },
  "callbackEvents": {
    "onSuccess": () => { console.log("Success!")
    },
    "onFailure": error => { console.error(error);
    }
  }
}
```

<h3 id="_step_6_request_a_client_access_token">
  Step 6 — Request a client access token
</h3>

Each time you want to display a virtual card’s sensitive data, you must request a new client access token. The client access token expires after five minutes.

Request a client access token from the Marqeta platform by sending a `POST` request to the `/users/auth/clientaccesstoken` endpoint.

Use the following cURL to request an access token. Replace the following placeholder text:

* **YOUR APPLICATION TOKEN**

* **YOUR ADMIN ACCESS TOKEN**

* **CARD TOKEN**

* **YOUR SUBDOMAIN**

```sh cURL lines wrap theme={null}
curl -i -X POST \
--user **YOUR APPLICATION TOKEN**:**YOUR ADMIN ACCESS TOKEN** \
-H 'Content-type: application/json' \
-d '{ "card_token": "**CARD TOKEN**" }' \
'https://**YOUR SUBDOMAIN**.marqeta.com/v3/users/auth/clientaccesstoken'
```

The following is a sample response to a request for a client access token:

```json JSON lines wrap theme={null}
{ "token":"ewogICJ0b2tlbiI6ICI5NzIwMDkwNS00ODc0LTRkMWEtODEzMS1jMWI3NDAwNzJjM2MmYXBwbGljYXRpb25fdG9rZW49eW91cl9hcHBsaWNhdGlvbl90b2tlbiIsCiAgImFwcGxpY2F0aW9uIjogewogICAgInRva2VuIjogInlvdXJfYXBwbGljYXRpb25fdG9rZW4iLAogICAgImFjdGl2ZSI6IHRydWUsCiAgICAiY2xpZW50X2FwaV9iYXNlX3VybCI6ICJodHRwOi8vd2lkZ2V0cy1lbnYubWFycWV0YS5jb20vY2xpZW50L2FwaS92MSIsCiAgICAiYXNzZXRzX3VybCI6ICJodHRwOi8vd2lkZ2V0cy1lbnYubWFycWV0YS5jb20vY2xpZW50L2Fzc2V0cy8xLjAuMCIsCiAgICAiY2xpZW50dG9rZW5hcHBsaWNhdGlvbklkIjogIjU3MDI2OTJhMGI4ZGNlOTg1YWVmNTExMiIKICB9LAogICJhcHBsaWNhdGlvbl90b2tlbiI6IG51bGwsCiAgImV4cGlyZXMiOiAiMjAxOC0xMi0zMVQyMzo1OTo1OSswMDAwIiwKICAiY2FyZF90b2tlbiI6ICJ0b2tlbl9vZl90aGVfY2FyZF95b3VfbmVlZF90b19wcmVzZW50IiwKICAiYWNjZXNzZWQiOiBudWxsLAogICJjbGllbnR0b2tlbklkIjogIjU5MTc2Y2JlMGI4ZGNlOTg1YWVmNTEzMCIsCiAgImNyZWF0ZWQiOiAiMjAxOC0wMS0wMVQwMDowMDowMCswMDAwIgp9"
}
```

After obtaining the client access token, embed it into your JavaScript code in place of the **CLIENT ACCESS TOKEN** placeholder text. For this tutorial, you can manually insert the token into your HTML code. In a production situation, however, you should programmatically insert the token before calling the `bootstrap()` method.

<Tip>
  **Tip**\
  The client access token is a string encoded as Base64. You can decode it to see client access token details, including the associated card token.
</Tip>

<h3 id="_step_7_add_copy_to_clipboard_buttons">
  Step 7 — Add "Copy to Clipboard" buttons
</h3>

Use the following set of HTML buttons to enable cardholders to copy card data elements to the clipboard of their device.

Add the following HTML to the page, at the top of the `<body>` tag, after the line `<div id='mq-card-cvv'></div>`:

```html HTML lines wrap theme={null}
<div id='copy-pan-container' style="position: relative;">
  <img src="copyPanIcon.jpg" alt="Copy card number" id="mq-copy-card-pan">
</div>
<div id='copy-exp-container' style="position: relative;">
  <img src="copyExpIcon.jpg" alt="Copy expiration date" id="mq-copy-card-exp">
</div>
<div id='copy-cvv-container' style="position: relative;">
  <img src="copyCvvIcon.jpg" alt="Copy CVV" id="mq-copy-card-cvv">
</div>
```

<Danger>
  **Warning**\
  The images referenced in the above example will not load because this is not an actual resource as-is.
</Danger>

Now modify the `marqeta.bootstrap()` method to configure these iframes:

```json JSON expandable lines wrap theme={null}
marqeta.bootstrap({
 "clientAccessToken": "**CLIENT ACCESS TOKEN**",
   "component": {
     "showPan": {
       "cardPan": {
         "domId": "mq-card-pan",
         "format": true,
         "styles": styles.cardPan.styles // A custom styles object
       },
       "copyCardPan": {
         "domId": "mq-copy-card-pan",
         "mode": "transparent",
         "onCopySuccess": () => alert("Copied PAN!"),
         "onCopyFailure": error => {
           console.error(error);
         }
       },
       "cardExp": {
         "domId": "mq-card-exp",
         "format": true,
         "styles": styles.cardExp.styles // A custom styles object
       },
       "copyCardExp": {
         "domId": "mq-copy-card-exp",
         "mode": "transparent",
         "onCopySuccess": () => alert("Copied expiration date!"),
         "onCopyFailure": error => {
           console.error(error);
         }
       },
       "cardCvv": {
         "domId": "mq-card-cvv",
         "styles": styles.cardCvv.styles // A custom styles object
       },
       "copyCardCvv": {
         "domId": "mq-copy-card-cvv",
         "mode": "transparent",
         "onCopySuccess": () => alert("Copied CVV2!"),
         "onCopyFailure": error => {
           console.error(error);
         }
       }
     }
   },
});
```

<h3 id="_step_8_add_a_hover_state">
  Step 8 — Add a hover state
</h3>

A hover state is a style configuration that you pass to the `marqeta.bootstrap()` method. The parent div receives hover events from its associated iframe.

To implement a hover state, add the following CSS statements to the HTML page inside the `<head>` tags:

```html HTML lines wrap theme={null}
<style type="text/css">
  #copy-pan-container:hover > img /* styles */
  #copy-exp-container:hover > img /* styles */
  #copy-cvv-container:hover > img /* styles */
</style>
```

<h3 id="_step_9_run_marqeta_bootstrap">
  Step 9 — Run marqeta.bootstrap()
</h3>

When the page loads, `marqeta.bootstrap()` injects the iframe populated with card data and styles into the inner container div elements `mq-card-pan`, `mq-card-exp`, and `mq-card-cvv`, as specified in the `configuration` object. The Copy to Clipboard iframes are also injected if you choose to integrate the Copy to Clipboard functionality.

<Tip>
  **Tip**\
  You can check the console of your browser for the success or failure message, as defined in the [callbackEvents](/developer-guides/using-marqeta-js/#_the_callbackevents_object) object.
</Tip>

<h2 id="_pin_reveal_tutorial">
  PIN reveal tutorial
</h2>

This tutorial shows you how to display a cardholder’s PIN using iframes on your application or webpage. In this scenario, you will display a cardholder’s PIN on an otherwise blank webpage. After the predetermined time limit has elapsed, the PIN is automatically hidden from view as a security precaution.

If your cardholder clicks the toggle PIN button while the timer is running, the timer will end and Marqeta.js will hide the PIN from view. If the toggle PIN button is clicked again, the timer will start counting down from the beginning (and not resume the timer’s previous countdown position).

<Note>
  **Note**\
  This tutorial assumes you have already worked with Marqeta to enable Marqeta.js for your program. You cannot complete these steps in the public sandbox.
</Note>

When you are finished, your HTML code should look like the following:

```html HTML expandable lines wrap theme={null}
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Marqeta.js PIN Reveal Tutorial</title>
    <style type="text/css">
        /* styles */
    </style>
  </head>
  <body>

  <!-- div elements for displaying the PIN -->
  <div>
    <div id='mq-card-pin' data-pin="hidden"></div>
    <button id='mq-toggle-card-pin'>Toggle</button>
    <div id='mq-pin-timeout'></div>
  </div>

  <!-- Reference Marqeta.js -->
  <script src="https://widgets.marqeta.com/marqetajs/2.0.0/marqeta.min.js" type="text/javascript"></script>
    <script>
    // Call the bootstrap method
      marqeta.bootstrap({
        "clientAccessToken": "**CLIENT ACCESS TOKEN**",
        "options": {
          "cardholderVerificationMethod": "OTHER"
        },
        "component": {
          "pinReveal": {
            "cardPin": {
              "domId": "mq-card-pin",
              "styles": {
                "span": {
                  "color": "black",
                  "font-family": "Sans-serif",
                  "font-size": "22px",
                  "letter-spacing": "2px",
                  "background": "transparent"
                },
                "span:hover": {
                  "color": "#60D4A8"
                }
              }
            },
            "toggleCardPin": {
              "domId": "mq-toggle-card-pin",
              "mode": "transparent",
              "onHideSuccess": () => alert("Hide Success!"),
              "onRevealSuccess": () => alert("Reveal Success!")
            },
            "hidePinTimeout": {
              "domId": "mq-pin-timeout",
              "hideTimeout": 10,
              "styles": {
                "color": "white",
                "font-family": "Arial",
                "font-size": "14px",
                "letter-spacing": "0.25px",
                "background": "transparent",
                "border": "0",
                "position": "absolute",
                "width": "180px",
                "height": "24px",
                "top": "150px",
                "left": "121px",
                "font-weight": "700",
                "line-height": "24px",
                "text-align": "center",
                "border-radius": "2px"
              }
            }
          }
        },
        "callbackEvents": {
          "onSuccess": () => {
            console.log("Success!")
          },
          "onFailure": error => {
            console.error(error.message);
          }
        }
      });
    </script>
  </body>
</html>
```

<h3 id="_step_1_prepare_a_blank_html_page_2">
  Step 1 — Prepare a blank HTML page
</h3>

Before integrating with Marqeta.js to display card data, prepare an otherwise blank HTML page.

Create a new HTML file and add the following code:

```html HTML lines wrap theme={null}
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Marqeta.js PIN Reveal Tutorial</title>
  </head>
  <body>
  </body>
</html>
```

<h3 id="_step_2_reference_marqeta_js_2">
  Step 2 — Reference Marqeta.js
</h3>

If you are working in your private sandbox environment, add the following script tag to your HTML:

```html HTML lines wrap theme={null}
<script src="https://widgets-sandbox.marqeta.com/marqetajs/2.0.0/marqeta.min.js" type="text/javascript"></script>
```

If you are working in a production environment, add the following script tag to your HTML:

```html HTML lines wrap theme={null}
<script src="https://widgets.marqeta.com/marqetajs/2.0.0/marqeta.min.js" type="text/javascript"></script>
```

<h3 id="_step_3_add_a_marqeta_bootstrap_method_call_2">
  Step 3 — Add a marqeta.bootstrap() method call
</h3>

To inject the iframes into your HTML, call the `marqeta.bootstrap()` method of Marqeta.js from your HTML.

Add the following script tag to your HTML after the reference to Marqeta.js. You’ll need to pass an object to the method, but leave it empty for now.

```html HTML lines wrap theme={null}
<script>
  marqeta.bootstrap();
</script>
```

<h3 id="_step_4_add_target_div_element">
  Step 4 — Add target div element
</h3>

To present the cardholder’s PIN, create a div element for it here. Assign a unique ID to the each div; you will use this ID in the `component` object of `marqeta.bootstrap()`.

Add the following code to your HTML:

```html HTML lines wrap theme={null}
<div>
  <div id='mq-card-pin' data-pin='hidden'></div>
  <div id='mq-toggle-card-pin'>Toggle</div>
  <div id='mq-pin-timeout'></div>
</div>
```

You can use CSS to define the width of the iframes created by Marqeta.js if you need to resize them. You have the option of setting the iframe’s width to a fixed value such as `300 px` or to a relative value such as `75%`.

If you set the iframe’s width to `100%`, it will expand to fill the size of the parent container. In terms of the span, its text will stop wrapping once it is wide enough. In many cases, it is recommended to set the iframe width to `100%`, and then style the parent container to the width you actually need.

<h3 id="_step_5_add_the_bootstrap_configuration_object_2">
  Step 5 — Add the bootstrap configuration object
</h3>

Use the `component` object to define how the iframes appear on your webpage. Make sure to include the required data. In this scenario, you will display the cardholder’s PIN.

You have the option of supplying style-related information inline (see `mq-card-pin` below) or as a custom style object you create (see the `mq-card-exp` style object `styles.cardExp.styles` in the [Card Data tutorial](/developer-guides/using-marqeta-js/#_step_5_add_the_bootstrap_configuration_object) above).

Add the following object as an argument for the `bootstrap()` method. Later steps in this tutorial will explain how to retrieve the data that replaces the placeholder text.

```json JSON expandable lines wrap theme={null}
{
  "clientAccessToken": "**CLIENT ACCESS TOKEN**",
  "options": {
    "cardholderVerificationMethod": "OTHER"
  },
  "component": {
    "pinReveal": {
      "cardPin": {
        "domId": "mq-card-pin",
        "styles": {
          "span": {
            "color": "black",
            "font-family": "Sans-serif",
            "font-size": "22px",
            "letter-spacing": "2px",
            "background": "transparent"
          },
          "span:hover": {
            "color": "#60D4A8"
          }
        }
      },
      "toggleCardPin": {
        "domId": "mq-toggle-card-pin",
        "mode": "transparent",
        "onHideSuccess": () => alert("Hide Success!"),
        "onRevealSuccess": () => alert("Reveal Success!")
      }
    }
  },
  "callbackEvents": {
    "onSuccess": () => {
      console.log("Success!")
    },
    "onFailure": error => {
      console.error(error.message);
    }
  }
}
```

<h3 id="_step_6_add_a_timeout_value">
  Step 6 — Add a timeout value
</h3>

The timeout value is the number of seconds after which Marqeta.js will hide the PIN from view as a safety precaution. In this step, you also add the styling information that will apply to the PIN timer’s message.

If your cardholder clicks the toggle PIN button while the timer is running, the timer will end and Marqeta.js will hide the PIN from view. If the toggle PIN button is clicked again, the timer will start counting down from the beginning (and not resume the timer’s previous countdown position).

Add the following code to your HTML:

```json JSON expandable lines wrap theme={null}
{
  "hidePinTimeout": {
    "domId": "mq-pin-timeout",
    "hideTimeout": 10,
    "styles": {
      "color": "white",
      "font-family": "Arial",
      "font-size": "14px",
      "letter-spacing": "0.25px",
      "background": "transparent",
      "border": "0",
      "position": "absolute",
      "width": "180px",
      "height": "24px",
      "top": "150px",
      "left": "121px",
      "font-weight": "700",
      "line-height": "24px",
      "text-align": "center",
      "border-radius": "2px"
    }
  }
}
```

<h3 id="_step_7_request_a_client_access_token">
  Step 7 — Request a client access token
</h3>

Each time you want to display a virtual card’s sensitive data, you must request a new client access token. The client access token expires after five minutes.

Request a client access token from the Marqeta platform by sending a `POST` request to the `/users/auth/clientaccesstoken` endpoint.

Use the following cURL to request an access token. Replace the following placeholder text:

* **YOUR APPLICATION TOKEN**

* **YOUR ADMIN ACCESS TOKEN**

* **CARD TOKEN**

* **YOUR SUBDOMAIN**

```sh cURL lines wrap theme={null}
curl -i -X POST \
--user **YOUR APPLICATION TOKEN**:**YOUR ADMIN ACCESS TOKEN** \
-H 'Content-type: application/json' \
-d '{ "card_token": "**CARD TOKEN**" }' \
'https://**YOUR SUBDOMAIN**.marqeta.com/v3/users/auth/clientaccesstoken'
```

The following is a sample response to a request for a client access token:

```json JSON lines wrap theme={null}
{ "token":"ewogICJ0b2tlbiI6ICI5NzIwMDkwNS00ODc0LTRkMWEtODEzMS1jMWI3NDAwNzJjM2MmYXBwbGljYXRpb25fdG9rZW49eW91cl9hcHBsaWNhdGlvbl90b2tlbiIsCiAgImFwcGxpY2F0aW9uIjogewogICAgInRva2VuIjogInlvdXJfYXBwbGljYXRpb25fdG9rZW4iLAogICAgImFjdGl2ZSI6IHRydWUsCiAgICAiY2xpZW50X2FwaV9iYXNlX3VybCI6ICJodHRwOi8vd2lkZ2V0cy1lbnYubWFycWV0YS5jb20vY2xpZW50L2FwaS92MSIsCiAgICAiYXNzZXRzX3VybCI6ICJodHRwOi8vd2lkZ2V0cy1lbnYubWFycWV0YS5jb20vY2xpZW50L2Fzc2V0cy8xLjAuMCIsCiAgICAiY2xpZW50dG9rZW5hcHBsaWNhdGlvbklkIjogIjU3MDI2OTJhMGI4ZGNlOTg1YWVmNTExMiIKICB9LAogICJhcHBsaWNhdGlvbl90b2tlbiI6IG51bGwsCiAgImV4cGlyZXMiOiAiMjAxOC0xMi0zMVQyMzo1OTo1OSswMDAwIiwKICAiY2FyZF90b2tlbiI6ICJ0b2tlbl9vZl90aGVfY2FyZF95b3VfbmVlZF90b19wcmVzZW50IiwKICAiYWNjZXNzZWQiOiBudWxsLAogICJjbGllbnR0b2tlbklkIjogIjU5MTc2Y2JlMGI4ZGNlOTg1YWVmNTEzMCIsCiAgImNyZWF0ZWQiOiAiMjAxOC0wMS0wMVQwMDowMDowMCswMDAwIgp9"
}
```

After obtaining the client access token, embed it into your JavaScript code in place of the **CLIENT ACCESS TOKEN** placeholder text. For this tutorial, you can manually insert the token into your HTML code. In a production situation, however, you should programmatically insert the token before calling the `bootstrap()` method.

<Tip>
  **Tip**\
  The client access token is a string encoded as Base64. You can decode it to see client access token details, including the associated card token.
</Tip>

<h3 id="_step_8_add_a_hover_state_2">
  Step 8 — Add a hover state
</h3>

A hover state is a style configuration that you pass to the `marqeta.bootstrap()` method. The parent div receives hover events from its associated iframe.

To implement a hover state, add the following CSS statements to the HTML page inside the `<head>` tags:

```html HTML lines wrap theme={null}
<style type="text/css">
  #mq-toggle-card-pin-container:hover /* styles */
  #mq-pin-timeout-container /* styles for the PIN timer message*/
</style>
```

<h3 id="_step_9_run_marqeta_bootstrap_2">
  Step 9 — Run marqeta.bootstrap()
</h3>

When the page loads, `marqeta.bootstrap()` injects the iframes populated with card data and styles into the inner container div elements of `mq-card-pin` and `mq-toggle-card-pin`. The `bootstrap()` method also injects a div element with the timeout message and styles into the inner container span element `mq-pin-timeout`.

<Tip>
  **Tip**\
  You can check the console of your browser for the success or failure message, as defined in the [callbackEvents](/developer-guides/using-marqeta-js/#_the_callbackevents_object) object.
</Tip>
