Home / Clientside and SDKs
The Highnote Card Viewer SDK allows you to embed sensitive card data into your UI using iframes seamlessly. This allows you to avoid PCI-scoped data flowing through your servers or being accessible to scripts running on your page.
The Card Viewer SDK uses client tokens to request the Highnote GraphQL API on your behalf. You can generate client tokens using the generatePaymentCardClientToken
mutation.
The Card Viewer library follows semver and can be installed from npm or a cdn.
You can install the Card Viewer library with the following
npm i @highnoteplatform/card-viewer
yarn add @highnoteplatform/card-viewer
pnpm add @highnoteplatform/card-viewer
This package ships with TypeScript definitions installed.
You can install the Card Viewer library for use on your page directly from a CDN such as JSDelivr. This is helpful when exploring the SDK or for use in tools such as CodeSandbox.
It is recommended you select a specific version of the library to use. You can replace @latest
with your chosen version, for example, @1.0.0
.
To render card details in your UI, you must set up elements to hold each field. You can then initialize the JavaScript library to populate those fields with the proper values via iframes.
First, you must obtain a client token from your server using the generatePaymentCardClientToken
mutation. When generating the client token, you must provide the Payment Card ID of the card you will render.
The resulting token can be safely provided to your client and passed to the Highnote JavaScript SDK. It is only valid for 10 minutes but can be used multiple times. Once the token has expired, you must generate a new one to re-render the payment card details.
You must provide the Card Viewer with the elements you want to render iframes for each field. For this example, the following elements are used:
<!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>
The library will inject an iframe into each element to render the appropriate data. You can style the content inside each iframe by passing any combination of allowed styles.
You can initialize the Card Viewer by calling renderFields
. This returns a Promise that contains a reference to the cardViewer
instance. This is useful for lifecycle management and interactions such as Card Number Masking.
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: "PAYMENT_CARD_ID", onError: (error) => { // Handle errors }, // Specify the individual fields to render data into elements: { cardNumber: { selector: "#cardNumber", }, cvv: { selector: "#cvv", }, expirationDate: { selector: "#expirationDate", }, }, });
You can pass an onError
handler to the renderFields
call. This callback is invoked whenever an error is raised from the integration.
The Card Viewer doesn’t render error messages or update the UI inside iframes when errors occur. You must introspect and handle errors accordingly.
Error | Description |
---|---|
InvalidCredentialError | Occurs when the provided Client Token is invalid or expired. The payload will contain the requestId which can be used for support and debugging. |
CardViewerRequestError | Represents errors encountered when communicating with the Highnote GraphQL API. The payload will contain the requestId which can be used for support and debugging. |
CardViewerFieldsInputError | Raised when an invalid configuration is provided at runtime. |
CopyToClipboardError | Raised when an issue copying a field value to a users clipboard. |
CardViewerError | A generic catchall error. |
import { renderFields } from "@highnoteplatform/card-viewer"; const handleError = ( error: HighnoteRequestError | HighnoteConfigError | Error ) => { switch (error.name) { case "InvalidCredential": // Handle invalid/expired credential // Unmount fields, fetch new client token, re-initialize console.error(error.context.requestId); // "some-request-id" break; case "CardViewerRequestError": console.error(error.context.requestId); // some-request-id break; case "CardViewerFieldsInputError": console.error(error.message); // "Invalid Payment Card ID" break; default: console.error(error); } }; const { unmount } = await renderFields({ clientToken: "client token from server", // This is the same paymentCardId used to generate the token paymentCardId: "PAYMENT_CARD_ID", onError: handleError, // Specify the individual fields to render data into elements: { cardNumber: { selector: "#cardNumber", }, cvv: { selector: "#cvv", }, expirationDate: { selector: "#expirationDate", }, }, });
Property | Examples | Docs |
---|---|---|
color | #55f5a3 , rgba(85,245,163,1) , #springgreen | MDN Docs |
cursor | pointer , none | MDN Docs |
fontFamily | sans-serif , serif , monospace System fonts only | MDN Docs |
fontSize | 12px , 1em , 1.1rem | MDN Docs |
fontWeight | bold , normal | MDN Docs |
letterSpacing | normal , .2rem | MDN Docs |
lineHeight | normal , 150% | MDN Docs |
userSelect | none , auto , inherit | MDN Docs |
Highnote will inject iframes with the following defaults. Your CSS styling can override each of these:
border: none
width: 300px
(browser default)height: 150px
(browser default)The document and body inside the frame will have transparent backgrounds and default to margin: 0
, padding: 0
.
Only system fonts are supported.
The layout of payment card fields is up to you. Highnote will inject iframes into the provided container elements. The iframes will inherit the width of the container. You can also set the height to accommodate your UI as needed.
#cardNumber { margin: 1em; } /* You can target the iframe with a child combinator. */ #cardNumber > iframe { height: 140px; }
By default, the library will make requests against the Test Environment. When you are ready to switch to the Live Environment, set the environment
configuration option:
const { unmount } = await renderFields({ clientToken: "client token from server", paymentCardId: "PAYMENT_CARD_ID", // Set this to `live` environemnt: 'live', onError: handleError, elements })
When rendering card viewer fields, the Highnote library writes the required iframes into your UI and renders them in a loading state. While in the loading state, the fields will be populated with placeholder characters:
•••• •••• •••• ••••
•••
••/••
Currently, these values cannot be changed.
Once the configuration has been validated and the fields rendered, the library will request the card details from the Highnote API and replace the loading values with the data.
If you need to unmount the payment card fields, use the unmount
method on the returned reference. This is useful when you need to “restart” the integration, or navigate to a new view client-side. Using this will ensure the cleanup of any DOM and event handlers.
import { renderFields } from "@highnoteplatform/card-viewer"; const { unmount } = await renderFields({ // ...config }); // Later...unmount await unmount()
The Highnote Card Viewer SDK allows your Account Holders to toggle sensitive data and copy data to their clipboard to complete payments.
By default, the payment card number will be masked (•••• •••• •••• ••••
). Only the last four digits will be shown when the card number is available.
You can toggle the masking on and off using the toggleCardNumberMask
method on the returned card viewer reference.
By default, users can select and copy values to their clipboard.
The enableClipboard
configuration property allows toggling the copy to the clipboard feature on and off. By default, Account Holders can select and copy values to their clipboard on all fields.
When enabled, clicking the card number, expiration date, or CVV field will copy the underlying value to the Account Holder's clipboard. In addition to the copy event, two callback functions allow customization when a user copies or fails to copy a value.
callback | description |
---|---|
onCopyToClipboardSuccess | Invoked when an Account Holder successfully copies a value to their clipboard. This function will also receive an object with the property field and a property __typename of COPY_TO_CLIPBOARD_SUCCESS |
onError | invoked with an error of type COPY_TO_CLIPBOARD_ERROR in the event this functionality fails. |
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: "PAYMENT_CARD_ID", // 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", }, expirationDate: { selector: "#expirationDate", }, }, });
If your application enforces a Content Security Policy, you must set the frame-src
header to allow iframes from the Highnote domain:
Content-Security-Policy: frame-src https://sdk.highnoteplatform.com/