Skip to main content

Collect Cards

When building an e-commerce application or subscription service, or enabling one-time purchases, one of the critical requirements is collecting and storing cardholder data securely. However, it can be challenging to navigate the complex regulatory landscape, particularly PCI DSS, and ensure that your application meets all the necessary security standards.

In this guide, we will set up SDKs to capture cards in the frontend, Web or Mobile, and securely store the cardholder data as tokens with the Basis Theory Platform. This will completely remove our user-facing applications and database from the compliance scope.

Getting Started

To get started, you will need a Basis Theory account and a Tenant.

Creating a Public Application

Next you will need you'll need a Public Application using our PCI-compliant template Collect PCI Data. Click here to create one.

This will create an application with the following Access Controls:

  • Permissions: token:create, token:update
  • Containers: /pci/
  • Transform: mask
Save the API Key from the created Public Application as it will be used later in this guide.

Configuring Basis Theory Elements

Basis Theory Elements is available for the following technologies. Click below for detailed instructions on how to install and configure it.

Javascript
React
iOS
Android

Adding Card Elements

Once properly installed and configured, add the Card Elements to your application. This will enable users to type in their card data in your form, while refraining from your systems to come in contact with it.

index.html
<div id="cardNumber"></div>
<div style="display: flex;">
<div id="cardExpirationDate" style="width: 100%;"></div>
<div id="cardVerificationCode" style="width: 100%;"></div>
</div>
index.js
import { BasisTheory } from '@basis-theory/basis-theory-js';

let bt;
let cardNumberElement;
let cardExpirationDateElement;
let cardVerificationCodeElement;

async function init() {
bt = await new BasisTheory().init('test_1234567890', { elements: true });

// Creates Elements instances
cardNumberElement = bt.createElement('cardNumber', {
targetId: 'myCardNumber' // (custom) used for tracking validation errors
});
cardExpirationDateElement = bt.createElement('cardExpirationDate', {
targetId: 'myCardExpiration'
});
cardVerificationCodeElement = bt.createElement('cardVerificationCode', {
targetId: 'myCardVerification'
});

// Mounts Elements in the DOM in parallel
await Promise.all([
cardNumberElement.mount('#cardNumber'),
cardExpirationDateElement.mount('#cardExpirationDate'),
cardVerificationCodeElement.mount('#cardVerificationCode'),
]);

// Binds card brand to verification code element
cardNumberElement.on('change', ({ cardBrand }) => {
cardVerificationCodeElement.update({ cardBrand });
});
}

init();

Using a single Card Element

Alternatively, you can declare a single Card Element that features all three basic cardholder data inputs in a single element.

index.html
<div id="card"></div>
index.js
import { BasisTheory } from '@basis-theory/basis-theory-js';

let bt;
let cardElement;

async function init () {
bt = await new BasisTheory().init('test_1234567890', { elements: true });
cardElement = bt.createElement('card');
await cardElement.mount('#card');
};

init();

Storing Cards

Now that you are securely capturing the cardholder data in your user-facing application(s), it is time to store it in your Basis Theory Tenant.

To do this, we will call the Create Token endpoint from the SDK, passing the Card Elements as data points in the payload. This way, the card information is securely transferred from the frontend Elements to the Basis Theory vault, where they will reside in the encrypted form.

Add a submit function along with a button to trigger it:

index.html
<div id="cardNumber"></div>
<div style="display: flex;">
<div id="cardExpirationDate" style="width: 100%;"></div>
<div id="cardVerificationCode" style="width: 100%;"></div>
</div>
<button onclick="submit();">Submit</button>
index.js
import { BasisTheory } from '@basis-theory/basis-theory-js';

let bt;
let cardNumberElement;
let cardExpirationDateElement;
let cardVerificationCodeElement;

async function init () { ... }

async function submit () {
try {
const token = await bt.tokens.create({
type: 'card',
data: {
number: cardNumberElement,
expiration_month: cardExpirationDateElement.month(),
expiration_year: cardExpirationDateElement.year(),
cvc: cardVerificationCodeElement,
}
});
// store token.id in your database
} catch (error) {
console.error(error);
}
}

init();

Customizing the Card Token

Deduplication

Aliasing

Masking

Conclusion