NAV
Javascript

Get Started

Reference

Other Docs

More

Introduction

Basis Theory Elements are simple, secure, developer-friendly inputs that empower consumers to collect sensitive data from their users directly to Basis Theory certified vault.

Think about it as a portal that we open within your site that allows users to seamlessly tokenize information and never notice they are interacting with our technology. Here is how we make it possible:

Getting started

Before You Begin

If you don't have an account

To begin taking advantage of the Basis Theory platform, you’ll need to create an account and Tenant through our Portal.

If you have an account

Check out our API Reference documentation below, or go to our Getting Started section if you’re unsure of where to go next.

Install SDK

NPM

npm install --save @basis-theory/basis-theory-js

Yarn

yarn add @basis-theory/basis-theory-js

CDN

<!-- Including this tag will export a global/window "BasisTheory" variable -->
<script src="https://js.basistheory.com"></script> 

You don't have to install Elements as a separate module or include additional script tags besides BasisTheory.js. It will dynamically load them from our secure domain, which enables us to keep the highest compliance standards (e.g. PCI compliance).

To install BasisTheory.js you can choose either our NPM module or CDN hosted bundle through a script tag.

Content Security Policy

CSP

<head>
  <meta
    http-equiv="Content-Security-Policy"
    content="frame-src https://elements.basistheory.com; script-src https://js.basistheory.com"
  />
</head>

Trusted Types


trustedTypes.createPolicy("default", {
  createScriptURL: (input) => {
    if (new URL(input).origin === "https://js.basistheory.com") {
      return input;
    }
    return undefined;
  }
});

If you have a CSP deployed in your website, you must include the following directives:

If you are using Trusted Types, you must allow dynamic script loading from the https://js.basistheory.com origin. This should be done BEFORE initialization.

Common CSP Errors

The setup above is recommended to avoid errors similar to these:

Usage with TypeScript

Starting at 1.14.0, BasisTheory.js bundles all TypeScript definitions for Elements features. You don't have to take any extra steps in order to use it.

If you can't upgrade past 1.13.1, Basis Theory Elements offers unmaintained definitions for deprecated Elements features.

Permissions

Permissions offer fine-grained control over your Application's access to different aspects of your token infrastructure. We suggest limiting the scope of your Application to the least amount possible, and to not share them across your internal services.

Permissions are associated with every Application and can be configured when you create an Application or update an Application.

Elements Applications only allow create permissions, removing any risk that your API keys are stolen and used to access data.

Permission Types

Permission Description
token:general:create Create tokens in the vault
token:pci:create Create Atomic Card tokens
token:bank:create Create Atomic Bank tokens

Authentication

Elements use a specific type of Application key to allow access to the API. To create one, login into our Portal and create a new "Elements" Application with the permissions you require.

Limits

The Basis Theory API has rate limits applied to ensure the speed and consistency of our systems.

Error Codes

Error Code Meaning
429 Request has been rate limited

Initialize

CDN

<script>
  // you can initialize it wherever it suits your workflow best
  // here we are waiting for the window to load, to make sure BasisTheory instance
  // has been injected in the window variable
  window.addEventListener('load', async () => {
    try {
      // global/window variable BasisTheory is an instance, but requires initialization
      await BasisTheory.init('test_1234567890', { elements: true });      
      // use Elements
    } catch (e) {
      // handle errors that could happen while loading elements script
    } 
  });  
</script>

Module

import { BasisTheory } from '@basis-theory/basis-theory-js';

// In this context BasisTheory is a class
const bt = await new BasisTheory().init('test_1234567890', { elements: true });
// use Elements

After installing BasisTheory.js, simply initialize it with elements: true so it dynamically loads Elements module.

Element Types

Card Element

The "card" element type features a full credit card collector containing the following inputs:

Text Element

The "text" element type features a regular text input for collecting any input data.

Elements Instance

After initialization, Elements are available through BasisTheory instance.

Create Element

var cardElement = BasisTheory.createElement('card', options);

var textElement = BasisTheory.createElement('text', { targetId: 'myInputId' });

This method returns a new instance of an element type.

Parameter Required Type Description
type true string Type of the element you want to create
options false CreateElementOptions Options for customizing the element

Create Element Options

CreateElementOptions provide a quick way to customize an Element before mounting it to your website.

Attribute Required Type Eligible Elements Description
style false ElementStyle All Object used to customize the element appearance
disabled false boolean All Boolean used to set the disabled attribute of the input(s)
targetId true string TextElement String used to identify your element
mask false ElementMask TextElement Array used to restrict and fill user input using regex and static strings
transform false ElementTransform TextElement RegExp object or array used to modify user input before sending input to any services
placeholder false string TextElement String used to customize the placeholder attribute of the input
aria-label false string TextElement String used to customize the aria-label attribute of the input
password false boolean TextElement Boolean used to set the text element input type as password

Mount Element

<div id="my-card"></div>

<script>
  cardElement.mount('#my-card')
</script>

This method attaches the element to the DOM, under a specific container.

Parameter Required Type Description
selector true string CSS selector that matches the container where your element will be mounted

Update Element

cardElement.update(options);

Updates the element options the element was initialized with. The values are merged into the previous options.

Parameter Required Type Description
options false UpdateElementOptions Options for customizing the element

UpdateElementOptions

UpdateElementOptions provide a quick way to change an existing (mounted) Element's appearance and functionality.

Attribute Required Type Eligible elements Description
style false ElementStyle All Object used to customize the element appearance
disabled false boolean All Boolean used to set the disabled attribute of the input(s)
transform false ElementTransform TextElement RegExp object or array used to modify user input before sending input to any services
placeholder false string TextElement String used to customize the placeholder attribute of the input
aria-label false string TextElement String used to customize the aria-label attribute of the input
password false boolean TextElement Boolean used to set the text element input type as password

Clear Element

cardElement.clear();

Clears the element input values.

Unmount Element

cardElement.unmount();

Safely removes the element from the DOM, stopping any further communication with it.

Element Events

var subscription = cardElement.on('event-type', (event) => {
  // handle event  
});

subscription.unsubscribe(); // stops listening to the event type

You can communicate with Elements by listening to events. When you subscribe to an event, you'll get back a Subscription that you can unsubscribe if/when it fits your workflow.

On Ready

cardElement.on('ready', () => {
  // handle ready event 
})

This event is triggered when the element has rendered and user is able to start interacting with it.

On Change

cardElement.on('change', (changeEvent) => {
  if (changeEvent.complete) {
    // enable submit button  
  } else {
    // disable submit button
    // present validation message
  }
})

This event is triggered whenever element's value(s) change. For example, if the user types data that doesn't change the state of a field between valid/invalid or empty/filled, you shouldn't expect the event to trigger.

Parameter Required Type Description
event true "change" The event type to listen to.
handler true function Callback function to be called when the event is fired. Takes in a ChangeEvent.

ChangeEvent

{
  "complete": false,
  "empty": false,
  "errors": [
    {...},
    {...}
  ]
}
Attribute Type Description
complete boolean If the element value is well-formed and is ready to be submitted.
empty boolean Whether the element is empty. Multi-input Elements will be empty only if all inputs are.
errors array Array of FieldError.

FieldError

{
  "targetId": "cardNumber",
  "type": "invalid"
}
Attribute Type Description
targetId string Input id that triggered the error. Values vary per element type.
type "invalid" or "incomplete" Type of the error.

On Focus

cardElement.on('focus', (focusEvent) => {

})

Triggered when an element input is focused.

Parameter Required Type Description
event true "focus" The event type to listen to.
handler true function Callback function to be called when the event is fired. Takes in a FocusEvent.

FocusEvent

{
  "targetId": "cardNumber"  
}
Attribute Type Description
targetId string Input id that triggered the event. Values vary per element type.

On Blur

cardElement.on('blur', (blurEvent) => {

})

Triggered when an element input focus is lost.

Parameter Required Type Description
event true "blur" The event type to listen to.
handler true function Callback function to be called when the event is fired. Takes in a BlurEvent.

BlurEvent

{
  "targetId": "cardNumber"  
}
Attribute Type Description
targetId string Input id that triggered the event. Values vary per element type.

On Keydown

cardElement.on('keydown', (keydownEvent) => {

})

Triggered when user hits a special key inside an element input.

Parameter Required Type Description
event true "keydown" The event type to listen to.
handler true function Callback function to be called when the event is fired. Takes in a KeydownEvent.

KeydownEvent

{
  "targetId": "cardNumber",
  "key": "Enter",
  "ctrlKey": false,
  "altKey": false,
  "shiftKey": false,
  "metaKey": false
}
Attribute Type Description
targetId string Input targetId that triggered the event. Values vary per element type.
key Escape or Enter Key pressed by the user.
ctrlKey boolean Flag indicating control key was pressed when the event occurred.
altKey boolean Flag indicating alt key was pressed when the event occurred.
shiftKey boolean Flag indicating shift key was pressed when the event occurred.
metaKey boolean Flag indicating meta key was pressed when the event occurred.

Element Style

var cardElement = BasisTheory.createElement('card', {
  style: {
    fonts: [
      "https://fonts.googleapis.com/css2?family=Source+Sans+Pro:ital,[email protected],200;0,300;0,400;0,600;0,700;0,900;1,200;1,300;1,400;1,600;1,700;1,900&display=swap"
    ],
    base: {
      color: "#fff",
      fontWeight: 500,
      fontFamily: "'Source Sans Pro'",
      fontSize: "16px",
      fontSmooth: "antialiased",
      "::placeholder": {
        color: "#6b7294"
      },
      ":disabled": {
        backgroundColor: "#f0f0f4"
      },
    },
    invalid: {
      color: "#ffc7ee"
    },
    complete: {
      color: "#1ad1db"
    }    
  }
})

Elements are styled through the ElementStyle object, which maps state variants and miscellaneous.

Attribute Required Type Description
fonts false array Array of Google Fonts URLs
base false object Base variant style - all other variant styles inherit from this one
complete false object Variant style applied when the element input has valid value
empty false object Variant style applied when the element input has no value
invalid false object Variant style applied when the element input has invalid value

You can customize the following pseudo-classes and pseudo-elements inside each variant using a nested object:

Here is a complete list of the supported CSS properties:

Element Mask

var phoneNumberElement = BasisTheory.createElement('text', {
  targetId: 'myPhoneNumberElement',
  mask: ['(', /\d/, /\d/, /\d/, ')', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/]
})

Text elements can restrict and fill user input by using the mask attribute. It consists of an array of RegExp objects and strings, used to restrict and fill input, respectively. The position of each item in the mask array corresponds to the restriction or fill used for that input's position. The length of the array determines how long an input is allowed to be. For example, the mask for a US based phone number shown on the right will have the following rules:

The mask will be displayed as the user is typing, and will be used as the value for any services used with that text element. The transform attribute can be used to modify this value before any requests to any services. If the value does not satisfy the mask in its entirety, the field is considered incomplete. This is reflected in the on change events and will fail validation before tokenizing data with any services.

Element Transform

var phoneNumberElement = BasisTheory.createElement('text', {
  targetId: 'myPhoneNumberElement',
  mask: ['(', /\d/, /\d/, /\d/, ')', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/],
  transform: /[()-]/,
})

Text elements allow you to modify user input before sending it to any services through the transform attribute. It can be set as a RegExp object, an array with a RegExp object, or an array with a RegExp object at the first index and a string at the second. It works by making use of the String replace function. The RegExp object and string defined will be used as the first and second argument for the replace function, respectively. If no string is defined, an empty string will be used as the second argument. For instance, the mask for a US based phone number shown on the right will modify user input to look like this: (123)456-7890. The transform attribute, in this case, will modify the user input to remove (, ), and - from the input. The resulting value is 1234567890 which will be what gets sent to any services.

Elements Services

The following BasisTheory.js services are capable of recognizing Elements instances in the payload and securely tokenizing their data directly to Basis Theory vault.

Atomic Cards

BasisTheory.atomicCards.create({
  card: cardElement
}).then((token) => {
  console.log(token.id); // token to store
  console.log(JSON.stringify(token.card)); // redacted card data
});

Allows secure submission and tokenization of a card element. Returns a Promise that resolves to the tokenized card data. See CardModel for the resolved value type. The Promise will reject with an error if the response status is not in the 2xx range.

You can fetch this same data later with Get an Atomic Card API.

Atomic Banks

BasisTheory.atomicBanks.create({
  bank: {
    routingNumber: routingNumberElement | 'plainText',  // values can be either a TextElement or plain text (see warning).
    accountNumber: accountNumberElement | 'plainText',
  },
}).then((token) => {
  console.log(token.id); // token to store
  console.log(JSON.stringify(token.bank)); // redacted bank data
});

Allows secure submission and tokenization of a bank element. Returns a Promise that resolves to the tokenized bank data. The Promise will reject with an error if the response status is not in the 2xx range.

You can fetch this same data later with Get an Atomic Bank API.

Tokens

BasisTheory.tokens.create({
  type: 'token',
  data: {
    sensitiveData: sensitiveDataElement,
    nonSensitiveData: 'plainText', // see warning on plain text data
    otherData: {
      someInteger: 20,
      someBoolean: false,
    },
    someOtherData: ['plainText1', 'plainText2'],
  },
  metadata: {
    nonSensitiveField: 'nonSensitiveValue'
  }
}).then((token) => {
  console.log(JSON.stringify(token)); // encrypted token data
});

Allows secure submission and tokenization of string data. Returns a Promise that resolves to the created token. The Promise will reject with an error if the response status is not in the 2xx range.

You can fetch this same data later with Get a Token API or Get a Decrypted Token API

Tokenize

BasisTheory.tokenize({
  sensitiveData: sensitiveDataElement,
  nonSensitiveData: 'plainText', // see warning on plain text data
  otherData: {
    someInteger: 20,
    someBoolean: false,
  },
  someOtherData: ['plainText1', 'plainText2'],
}).then((token) => {
  console.log(JSON.stringify(token)); // encrypted token data
});

Allows secure submission and tokenization of string data. Returns a Promise that resolves to the created tokens. The Promise will reject with an error if the response status is not in the 2xx range.

You can fetch this same data later with Get a Token API or Get a Decrypted Token API.

Errors

BasisTheory.tokens.create(...).catch(error => {
  // handle error
});

In case any Elements service throws an error, that could be related to client-side validation or an unaccepted request from the server.

Attribute Type Scope Description
validation array client Array of FieldError, in case of client-side error.
data object server Response body sent from the server.
status number both Response HTTP status or -1 if the request never left the client (i.e. connection issues)

Store Credit Card DEPRECATED

BasisTheory.elements.storeCreditCard({
  card: cardElement,
}).then((token) => {
  console.log(token.id); // token to store
  console.log(JSON.stringify(token.card)); // redacted card data
});

Allows secure submission and tokenization of a card element. Returns a Promise that resolves to the tokenized card data. See CardModel for the resolved value type. The Promise will reject with an error if the response status is not in the 2xx range.

Internally, BasisTheory.elements.storeCreditCard calls Create Atomic Card API.

You can fetch this same data later with Get an Atomic Card API.