Using Marqeta.js

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 card holder's card data. The iframes enable you to display a virtual card 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. You can also add one or more buttons to your application or webpage that copy a card's PAN, expiration date, or CVV2 to the clipboard.

Note: While the Marqeta.js iframe feature reduces the burden to achieve data security compliance, it does not eliminate it entirely, and is only appropriate for certain use cases. Contact your Marqeta Customer Success Representative about using the Marqeta.js library.

At the end of the guide, you should understand:

  • How to integrate with Marqeta.js.
  • How to obtain a client access key.
  • How to inject the Marqeta.js iframes into your HTML.

Prerequisites


Concepts

Data security compliance

Companies that handle sensitive card data, including the primary account number (PAN), expiration date, and card verification value (CVV2), 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. The Marqeta servers are PCI DSS compliant and handle the unencrypted sensitive card data for you. Your servers never handle the card data.

Note: Card data is less secure when copied to the clipboard than when in the PCI-compliant widget. Card holders should adopt data security best practices and take precautions to keep their sensitive data safe.

Dynamic card data iframes

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 the sensitive data to Marqeta servers. You create and style pages in whatever manner you desire and Marqeta.js inserts the card data into the page locations specified in the HTML.

Note: To display virtual cards within a mobile application, you can embed the iframes using a web element.

Encryption and card data flow

The following process describes how Marqeta.js injects the iframes into your application. See the tutorial on this page for more details.

  1. Your application’s back end requests a client access token.
  2. The Marqeta API creates a base64-encoded client access token. This token enables access to the specified card and will expire after five minutes.

  3. Your back end passes the client access token to your JavaScript.

  4. Your JavaScript injects the client access token into the marqeta.bootstrap() method.

  5. Your JavaScript executes marqeta.bootstrap(), which initializes and configures Marqeta.js.

  6. Marqeta.js injects the card data into the HTML container using separate iframes for the card's PAN, CVV2, and expiration date.
 If configured, Marqeta.js includes “Copy to clipboard” buttons in the iframe.

  7. The HTML page displays the card data.


The configuration object

The .bootstrap() method of Marqeta.js requires a configuration object, which defines the attributes and behaviors of the iframes. You must include the ID of the div element into which Marqeta.js injects the individual iframes of card data.

The configuration object

Name Type Required? Description Allowable Values
clientAccessToken string Yes Client access token obtained from the Marqeta API. Client access token
integrationType string Yes Set to "custom". "custom"
containerId string Yes Identifies the outer div element whose child div elements will be injected with PAN, CVV2 and expiration date iframes. Must match the "id" of the outermost "div" element.
showPan object Yes Specifies the card data to display and applies typographical styling to the data.

Include the "cardPan" object to display the PAN, the "cardExp" object to display the expiration date, and the "cardCvv" object to display the CVV2 number.
Any combination of "cardPan", "cardExp", and "cardCvv" objects.
callbackEvents object No Defines customizable event handlers that are executed upon success or failure of iframe rendering.

Within the configuration object, you must include the showPan object. The showPan object specifies which card attributes to display. It can contain the following objects:

  • cardPan — The card's PAN
  • cardExp — The card's expiration date
  • cardCvv — The card's CVV2

You can include any combination of these objects within the showPan object. Objects included within the showPan object have their associated values injected as iframes within the div container you specified in the configuration 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.

Object Supported selectors Supported attributes
cardPan span, span:hover color, font-family, font-size, background, font-weight, letter-spacing
cardExp span, span:hover color, font-family, font-size, background, font-weight, letter-spacing
cardCvv span, span:hover color, font-family, font-size, background

The showPan.cardPan and showPan.cardExp objects

Name Type Required? Description Allowable Values
domId string Yes Associates the cardPan and cardExp elements with their corresponding div elements. Must match the DOM ID of the corresponding "div" element.

For example, showPan.domId must match the id attribute of the div element that will contain the card PAN iframe.
format boolean No Set to true to format the element's content.

The content of cardPan is formatted as:
"XXXX XXXX XXXX XXX"

The content of cardExp is formatted as:
"XX/XX".
true | false

Default: false
styles object No A CSS-like style object applied to the iframe holding the card data.
styles.<selector> object No Replace <selector> with one of the supported selector values.

Supported selectors:
span, span:hover

Supported CSS attributes:
color, font-family, font-size, background, font-weight, letter-spacing

Note: CSS importing schemes such as @import and @url are not supported.

The showPan.cardCvv object

Name Type Required? Description Allowable Values
domId string Yes Associates the cardCvv element with its corresponding div element. 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 object No A CSS-like style object applied to the iframe holding the card data.
styles.<selector> object No Replace <selector> with one of the supported selector values.

Supported selectors:
span, span:hover

Supported CSS attributes:
color, font-family, font-size, background

Note: CSS importing schemes such as @import and @url are not supported.

The callbackEvents object specifies the methods executed upon success and failure events when rendering the iframes.

The callbackEvents object

Name Type Required? Description Allowable Values
onSuccess event handler No Executed upon success of iframe rendering.

You can customize the method within this event handler to perform whatever action you want.
A method
onFailure event handler No Executed upon failure of iframe rendering.

You can customize the method within this event handler to perform whatever action you want.
A method

Copying card data to the clipboard

You can add the .copyToClipboard() method to your application or webpage to add buttons that copy a card's PAN, expiration date, or CVV2 to the clipboard of the card holder's device. For example, in a POS financing scenario, these buttons can help your card holders avoid manually copying card data from a newly-issued virtual card to the vendor’s application where they are making a purchase.

For each button, you must specify the ID of the div element that contains the card data to copy. The following HTML example adds a button that copies the contents of the "mq-card-pan" div element to the clipboard:

<button onclick="marqeta.copyToClipboard('mq-card-pan')">Copy card number</button>

When the card holder clicks any of the “Copy to clipboard” buttons, Marqeta.js displays a toast notification in the upper-right corner of the application window or webpage. The toast notification informs the card holder of the implications of copying sensitive card data to the clipboard. After Marqeta.js displays the notification, it is not presented to the card holder again on the same device for 90 days to optimize the user experience.

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

Resetting Marqeta.js

Marqeta.js also provides a .destroy() method. Run marqeta.destroy() to reset Marqeta.js and any existing configurations.


Tutorial

This tutorial shows you how to display a virtual card's sensitive data using iframes on your webpage or application. 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: This tutorial assumes you have already worked with Marqeta to enable Marqeta.js for your program.

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

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Virtual card presentment</title>
</head>
<body>
<div id="virtual-card-container" >
<div class="container-row" id="mq-card-pan"></div>
<div class="container-row" id="mq-card-exp"></div>
<div class="container-row" id="mq-card-cvv"></div>
</div>
<div>
<button onclick="marqeta.copyToClipboard('mq-card-pan')">Copy card number</button>
<button onclick="marqeta.copyToClipboard('mq-card-exp')">Copy expiration date</button>
<button onclick="marqeta.copyToClipboard('mq-card-cvv')">Copy CVV</button>
</div>
<script src="https://widgets.marqeta.com/client/assets/1.0.0/marqeta.min.js"></script>
<script> marqeta.bootstrap({
clientAccessToken: "**CLIENT ACCESS TOKEN**",
integrationType: "custom",
containerId: "virtual-card-container",
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: {
"span": {
"background": "green",
"color": "white",
"font-family": "monospace",
"letter-spacing": "2px",
"font-weight": "bold"
}
}
},
cardCvv: {
domId: "mq-card-cvv",
styles: {
"span": {
"background": "green",
"color": "white",
"font-family": "monospace"
}
}
}
},
callbackEvents: {
onSuccess:
successMethod() {
console.log("Success!");
},
onFailure:
failureMethod() {
console.log("Failure!");
}
}
}); </script>
</body>
</html>

Step One: Prepare a blank HTML page

Before integrating with Marqeta.js, prepare an otherwise blank HTML page.

Create a new HTML file and add the following code:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Virtual card presentment</title>
</head>
<body>
</body>
</html>

Step Two: Reference Marqeta.js

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

<script src="https://widgets.marqeta.com/client/assets/1.0.0/marqeta.min.js"></script>

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

<script src="https://widgets-sandbox.marqeta.com/client/assets/1.0.0/marqeta.min.js"></script>

Step Three: Add a marqeta.bootstrap() method call

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.

<script> marqeta.bootstrap(); </script>

Step Four: Add a target div

To present all three pieces of card data, create four divs—one each for the PAN, expiration date, and CVV2, and another to contain the other three divs. 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:

<div id="virtual-card-container" >
<div class="container-row" id="mq-card-pan"></div>
<div class="container-row" id="mq-card-exp"></div>
<div class="container-row" id="mq-card-cvv"></div>
</div>

Step Five: Add the bootstrap configuration object

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.

Add the following object as a parameter for the bootstrap() method. Later steps in this exercise will explain how to retrieve the data that replaces the placeholder text.

{
clientAccessToken: "**CLIENT ACCESS TOKEN**",
integrationType: "custom",
containerId: "virtual-card-container",
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: {
"span": {
"background": "green",
"color": "white",
"font-family": "monospace",
"letter-spacing": "2px",
"font-weight": "bold"
}
}
},
cardCvv: {
domId: "mq-card-cvv",
styles: {
"span": {
"background": "green",
"color": "white",
"font-family": "monospace"
}
}
}
},
callbackEvents: {
onSuccess: successMethod() {
console.log("Success!");
},
onFailure: failureMethod() {
console.log("Failure!");
}
}
}

Step Six: Request a client access token

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 MASTER ACCESS TOKEN**
  • **CARD TOKEN**
  • **YOUR SUBDOMAIN**

curl -i -X POST \
--user **YOUR APPLICATION TOKEN**:**YOUR MASTER 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:

{ "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 scenario, you can manually insert the token into your HTML code. In a production situation, you should programmatically insert the token before calling the bootstrap() method.

Note: 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.

Step Seven: Add "Copy to clipboard" buttons

Use the .copyToClipboard() method with a set of HTML buttons to enable card holders to copy card data elements to the clipboard.

Add the following HTML to the page, after the 'virtual-card-container' div:

<div>
<button onclick="marqeta.copyToClipboard('mq-card-pan')">Copy card number</button>
<button onclick="marqeta.copyToClipboard('mq-card-exp')">Copy expiration date</button>
<button onclick="marqeta.copyToClipboard('mq-card-cvv')">Copy CVV</button>
</div>

Step Eight: Run marqeta.bootstrap()

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.

Note: You can check the console of your browser for the success or failure message, as defined in the callbackEvents object.