Secure Inputs SDK for Tokenization
Overview
The Secure Inputs SDK for tokenization is a customizable checkout solution. For a simpler, drop-in solution, use the Checkout SDK.
The Highnote Secure Inputs SDK can be used to tokenize payment method details so you can process payments in your application or website. This prevents PCI-scoped data from flowing through your servers or being accessible to scripts running on your page.
This guide explains how to install and use the Secure Inputs (Tokenization) SDK.
Prerequisites
- A Highnote account
- A server-side integration using an API key
- Payment card ID
Installation
The Highnote Secure Inputs SDK follows semver and can be installed using the following:
- JavaScript package manager:
npm,yarn, orpnpm - Content Delivery Network (CDN) via traditional
<script>tag or ECMAScript module.
Install by package manager
The Secure Inputs SDK supports the following JavaScript package managers: npm, yarn, and pnpm.
npm i @highnoteplatform/secure-inputs
yarn add @highnoteplatform/secure-inputs
pnpm add @highnoteplatform/secure-inputs
Install by CDN
To ensure stability and avoid potential issues caused by updates, replace @latest with a specific version number such as @1.0.0.
You can install Secure Inputs SDK directly from a content delivery network (CDN) such as JSDelivr.
The SDK supports both traditional script tags and ECMAScript module imports. ESM imports require modern browsers. To support older browsers, use the traditional script tag approach with appropriate polyfills.
Script tag
To install the Secure Inputs SDK by <script> tag, add the following to your HTML file:
<script src="https://cdn.jsdelivr.net/npm/@highnoteplatform/secure-inputs@latest/lib/index.js"></script>
ESM import
To install the Secure Inputs SDK by ESM module, add the following to your HTML file:
<script type="module">
import { SecureInputs } from "https://cdn.jsdelivr.net/npm/@highnoteplatform/secure-inputs@latest/lib/index.js";
// Initialize the Secure Inputs
const secureInputs = new SecureInputs({
// configuration options
});
</script>
Usage
To render secure input fields in your UI, configure elements to hold each field as follows:
- Prepare your HTML
- Fetch a client token
- Initialize secure inputs.
Prepare your HTML
To use the Secure Inputs SDK, you must provide elements for the payment details fields.
The following fields are supported for the Secure Inputs SDK for tokenization:
cardNumberexpirationDateorexpirationMonthandexpirationYearsecurityCode
<!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 Form</title>
</head>
<body>
<div id="card-number">
<!-- An iframe will be injected here -->
</div>
<div id="expiration-date">
<!-- An iframe will be injected here -->
</div>
<div id="security-code">
<!-- An iframe will be injected here -->
</div>
</body>
</html>
Fetch a client token
To obtain a client token from your server for the Secure Inputs SDK, use the generatePaymentMethodTokenizationClientToken mutation.
Refer to the following guidelines when generating a payment method tokenization client token:
- The client token is only valid for 10 minutes but can be used multiple times.
- Once a token expires, you must generate a new one.
Use the following mutation to generate a payment method tokenization client token:
GeneratePaymentMethodTokenizationClientToken
Query
mutation GeneratePaymentMethodTokenizationClientToken(
$input: GeneratePaymentMethodTokenizationClientTokenInput!
) {
generatePaymentMethodTokenizationClientToken(input: $input) {
__typename
... on ClientToken {
expirationDate
usage
value
}
}
}
Variables
{ "input": { "permissions": [ "TOKENIZE_PAYMENT_METHOD" ] } }
Result
{
"data": {
"generatePaymentMethodTokenizationClientToken": {
"__typename": "ClientToken",
"expirationDate": "2024-01-01T00:00:00.000Z",
"usage": "UNTIL_EXPIRATION",
"value": "TOKEN"
}
},
"extensions": {
"requestId": "REQUEST_ID",
"rateLimit": {
"cost": 10,
"limit": 60060,
"remaining": 60049
}
}
}
Initialize secure inputs
The secure inputs library works by injecting an iframe into the payment element to render the appropriate data. You can style the content inside each iframe by passing any combination of styling options.
You can initialize the card viewer by using a renderFieldsForTokenization function.
This returns a Promise that contains a reference to the secureInputs instance.
This is useful for lifecycle management and interactions such as field submission.
The onSuccess method passes a payload object that contains a token field.
This field is the PaymentMethodToken object.
You can call your server endpoint with the payload.token to create an authorization using the chargePaymentMethodToken mutation.
The following example shows how to initialize the Secure Inputs SDK for tokenization:
import { renderFieldsForTokenization } from "@highnoteplatform/secure-inputs";
const secureInputs = await renderFieldsForTokenization({
clientToken: "client token from server",
// Optionally exclude card brands from being accepted
excludedCardBrands: ["brand1", "brand2"],
// Specify the individual fields to render data into
elements: {
cardNumber: {
selector: "#card-number",
},
expirationDate: {
selector: "#expiration-date",
},
securityCode: {
selector: "#security-code",
},
},
onReady: () => {
// Callback to indicate that the secure inputs have loaded
// and are ready for entry.
},
onSuccess: (token) => {
// The payment card was successfully tokenized.
// Send this to your server for authorization/charge
},
onError: (error) => {
// Handle errors
},
});
Additional cardholder data
The secure input fields capture PCI-scoped card details (cardNumber, expirationDate, securityCode).
When calling submit to tokenize, you can also pass non-PCI cardholder data such as fullName and billingAddress via the additionalData parameter, typed as TokenizeCardPaymentMethodInput.
When tokenizing for Instant Network Transfers (INT), fullName and billingAddress are required for OFAC and AVS compliance checks.
const { submit, unmount } = await renderFieldsForTokenization({
// ...config
});
// Collected from your UI
const fullName = "Jane Doe";
const billingAddress = {
streetAddress: "123 Main St",
locality: "San Francisco",
region: "CA",
postalCode: "94111",
countryCodeAlpha3: "USA",
};
// Submit with additional data
submit({
additionalData: {
cardHolder: {
fullName,
billingAddress,
},
},
});
The cardHolder object accepts the following fields:
| Field | Type | Description |
|---|---|---|
fullName | String | The full name as represented on the card. Must be between 1 and 255 characters. |
billingAddress | TokenizeAddressInput | The billing address associated with the card. postalCode is required. |
Error handling
The Secure Inputs SDK doesn't render error messages or update your UI inside iframes when errors occur. You must introspect and handle errors accordingly.
You can pass an onError handler to the renderFieldsForTokenization call. This callback will be invoked whenever an error is raised from the integration.
Error types
The following error types are supported for the Secure Inputs SDK for tokenization:
| Error | Description |
|---|---|
| InvalidCredentialError | The provided client token is invalid or expired. The payload will contain the requestId which can be used for support and debugging. |
| SecureInputsRequestError | Represents errors encountered when communicating with the Highnote API, such as an incorrect payment card ID. The payload will contain the requestId which can be used for support and debugging. |
| SecureInputsFieldsInputError | Raised when an invalid configuration is provided at runtime. |
| GenericError | A generic catchall error. |
Error examples
The following code samples provides examples of secure inputs errors:
import {
type SecureInputsTokenizationError,
renderFieldsForTokenization,
} from "@highnoteplatform/secure-inputs";
const handleError = (error: SecureInputsTokenizationError) => {
switch (error.name) {
case "SecureInputsRequestError":
// Handle errors from tokenization
// related to fields or additional data
// passed in for tokenization.
// See "Error codes" below for all possible codes.
console.error(error);
break;
case "InvalidCredentialError":
// Handle invalid/expired credential
// Unmount fields, fetch new client token, re-initialize
break;
default:
// Handle generic errors
// Try unmount fields, fetch new client token, re-initialize
console.error(error);
}
};
const { unmount, submit } = await renderFieldsForTokenization({
// ...
onError: handleError,
// ...
});
Error codes
When tokenization fails, the SecureInputsRequestError contains a code field with one of the following values.
The response also includes an errorPath array that identifies the specific field that caused the error. Use these codes and paths to surface helpful messages to your users.
{
"__typename": "UserError",
"errors": [
{
"code": "INVALID_SECURITY_CODE",
"description": "The security code provided does not match the card type",
"errorPath": ["input", "paymentCard", "securityCode"]
}
]
}
Card fields
| Code | Description | Field | Action |
|---|---|---|---|
INVALID_SECURITY_CODE | Security code does not match card type. Must be 3 digits. | card/securityCode | Prompt the cardholder to re-enter the security code. |
CARD_EXPIRATION_DATE_ALREADY_PAST | Expiration date is in the past. Format: MM/YY. | card/expiry | Prompt the cardholder to enter a valid expiration date. |
INVALID_NUMBER_LENGTH | Card number has an invalid length. Must be 15–19 digits. | card/number | Prompt the cardholder to re-enter the card number. |
CARD_BRAND_NOT_SUPPORTED | Card brand is not currently supported. Supported brands: Visa and Mastercard. | card/brand | Prompt the cardholder to use a Visa or Mastercard. |
Token and payment method
| Code | Description | Field | Action |
|---|---|---|---|
INVALID_TOKEN_INPUT | Token ID cannot be null. | tokenId | Provide a valid token ID in the request. |
INVALID_TOKEN_ID_FORMAT | Token ID has an invalid format. Must use the tkpmc_ prefix. | tokenId | Use a token ID with the tkpmc_ prefix. |
INVALID_PAYMENT_METHOD_INPUT | Payment method cannot be null. | paymentMethod | Provide a payment method in the request. |
INVALID_PAYMENT_METHOD_TYPE | Payment method type is invalid or not provided. Valid types: CARD, BANK, PASS. | paymentMethodType | Set the payment method type to a supported value. |
PAYMENT_METHOD_UNSUPPORTED | Payment method is not currently supported. Only CARD is supported for tokenization. | paymentMethod | Use CARD as the payment method type. |
General input
Address fields are validated for presence and length only. Invalid address data returns NON_NULL_INPUT_REQUIRED, NON_EMPTY_INPUT_REQUIRED, or MAX_LENGTH_REACHED with the specific field identified in errorPath.
| Code | Description | Field | Action |
|---|---|---|---|
NON_NULL_INPUT_REQUIRED | Input cannot be null. | input | Provide a value for the required field indicated in errorPath. |
NON_EMPTY_INPUT_REQUIRED | Input cannot be empty. | input | Provide a non-empty value for the field indicated in errorPath. |
MAX_LENGTH_REACHED | Input exceeds maximum character length. Limits: name 255, address lines 512, city 255, title/suffix 10. | input | Shorten the input to within the allowed character limit. |
INVALID_NAME_FORMAT | Name format is invalid. Must be 1–255 characters. | name | Enter a name between 1 and 255 characters. |
Styling options
The following styling options are available for use in elements for your secure inputs fields:
| 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 |
iframe defaults
Highnote injects card viewer iframes with the following defaults. Your CSS styling can override each of these:
border: nonewidth: 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
Custom fonts
The Secure Inputs SDK only supports system fonts.
Layout
The layout of payment card fields in the card viewer is customizable. Highnote injects iframes into the provided container elements, which will inherit the width of the container. You can customize the width and height of the container to accommodate your UI as needed.
The following code sample provides an example of custom layout styling:
#card-number { margin: 1em; } /* You can target the iframe with a child
combinator. */ #card-number > iframe { height: 140px; }
Using the Live environment
By default, the card viewer library will make requests against the Test environment. When you are ready to switch to the Live environment, set the environment configuration option using the following function call:
const { unmount } = await renderFieldsForTokenization({
// Set this to `live`
environment: "live",
// ...
});
Lifecycle
The Secure Inputs SDK's lifecycle consists of unmounting fields.
If you need to unmount 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.
The following code sample provides an example function to unmount fields:
import { renderFieldsForTokenization } from "@highnoteplatform/secure-inputs";
const { submit, unmount } = await renderFieldsForTokenization({
onSuccess: async (token) => {
// The payment card was successfully tokenized.
// Send this to your server for authorization/charge
await unmount();
},
// ...config
});
// ...
submit();
Content security policy
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://cdn.highnote.com