Getting startedCard tokenization
Card tokenization
To ensure the security of sensitive card data, no card information should be transmitted or stored in plain text. In this flow, card data is tokenized on the client using asymmetric encryption, and only the encrypted token is sent to the API.
Tokenization uses the tokenization key, not the API key. You can find it under Finance → Integrations, in the API Credentials section, and it is safe to publish in the browser. The API key is secret and must never appear in the front-end.
Description
The platform supports two tokenization methods:
1. Via tokenization script (Front-end) — recommended for direct browser integrations such as web checkouts and client-side applications.
2. Via PaymentTokenizer class (API / Back-end) — recommended for server-to-server integrations, where encryption occurs on the integrator backend before sending data to the API.
1. How Tokenization Works
The tokenization process follows these steps:
1. Use the store tokenization key.
2. Card data is locally encrypted using this key.
3. The result is a token.
4. This token is sent to the payment API instead of the card data.
Method 1 - Front-end Tokenization (Script)
To perform credit card transactions, the card token must be included in the request.
Token generation is simple and must be performed on the front-end before sending data to the API.
Below is the first step, which consists of importing the official tokenization script.
Tokenization Script Inclusion
Add the script below to your HTML page or before using the tokenization function:
<script src="https://api.securitypag.com/v1/scripts"></script>Usage Example — Generating the Card Token
const pk = "CHAVE_DE_TOKENIZACAO"
try {
const card = {
number: "5555444433331111",
holderName: "John Doe",
expMonth: 8,
expYear: 2027,
cvv: "789",
};
await SecurityPag.init(pk);
const token = await SecurityPag.encrypt(card);
console.log(token);
} catch (err) {
console.error(err);
}Method 2 — API Tokenization (PaymentTokenizer Class)
This method is recommended for backend integrations (API, workers, or server-to-server) where the card must be tokenized before being sent to the payment API.
Tokenization continues to occur in your environment using asymmetric encryption. Only the token is sent to the platform.
Flow
1. Use the store tokenization key.
2. Your application initializes the PaymentTokenizer class with this key.
3. Card data is validated and encrypted locally.
4. The result is a token.
5. This token is sent to the payment API instead of the card data.
Dependency
The class uses libsodium for encryption:
import sodium from "https://cdn.jsdelivr.net/npm/libsodium-wrappers@0.8.0/+esmPaymentTokenizer Class
import sodium from "https://cdn.jsdelivr.net/npm/libsodium-wrappers@0.8.0/+esm";
type CardDTO = {
number: string;
holder: string;
expMonth: string;
expYear: string;
cvv: string;
};
class PaymentTokenizer {
tokenizationKey = "";
initialized = false;
async init(pk: string): Promise<void> {
this.assertValidTokenizationKey(pk);
await sodium.ready;
this.tokenizationKey = pk;
this.initialized = true;
}
async encrypt(card: CardDTO): Promise<string> {
if (!this.initialized || !this.tokenizationKey) {
throw new Error("TOKENIZER_NOT_INITIALIZED");
}
const payload = this.buildPayload(card);
const encrypted = sodium.crypto_box_seal(sodium.from_string(JSON.stringify(payload)), sodium.from_base64(this.tokenizationKey));
return sodium.to_base64(encrypted);
}
buildPayload(card: CardDTO): CardDTO {
return {
number: this.validateCardNumber(card.number),
holder: this.validateHolder(card.holder),
expMonth: this.validateMonth(card.expMonth),
expYear: this.validateYear(card.expYear),
cvv: this.validateCvv(card.cvv),
};
}
assertValidTokenizationKey(pk: string) {
if (!pk || typeof pk !== "string" || pk.trim() === "") {
throw new Error("INVALID_TOKENIZATION_KEY");
}
}
validateHolder(value: string): string {
if (!value?.trim()) {
throw new Error("INVALID_CARD_HOLDER");
}
return value.trim();
}
validateCardNumber(value: string): string {
const number = String(value ?? "").replace(/\D/g, "");
if (!/^\d{13,19}$/.test(number)) {
throw new Error("INVALID_CARD_NUMBER");
}
return number;
}
validateMonth(value: string): string {
const monthStr = String(value ?? "").replace(/\D/g, "");
if (!/^\d{2}$/.test(monthStr)) {
throw new Error("INVALID_EXP_MONTH");
}
const month = Number(monthStr);
if (month < 1 || month > 12) {
throw new Error("INVALID_EXP_MONTH");
}
return monthStr;
}
validateYear(value: string): string {
const yearStr = String(value ?? "").replace(/\D/g, "");
if (!/^\d{4}$/.test(yearStr)) {
throw new Error("INVALID_EXP_YEAR");
}
const year = Number(yearStr);
const currentYear = new Date().getFullYear();
if (year < currentYear) {
throw new Error("CARD_EXPIRED");
}
return yearStr;
}
validateCvv(value: string): string {
const cvv = String(value ?? "").replace(/\D/g, "");
if (!/^\d{3,4}$/.test(cvv)) {
throw new Error("INVALID_CVV");
}
return cvv;
}
}PaymentTokenizer Class
import { PaymentTokenizer } from "./PaymentTokenizer";
const pk = "SUA_CHAVE_DE_TOKENIZACAO";
async function tokenizeCard() {
const tokenizer = new PaymentTokenizer();
await tokenizer.init(pk);
const token = await tokenizer.encrypt({
number: "4111111111111111",
holder: "JOHN DOE",
expMonth: "12",
expYear: "2030",
cvv: "123"
});
console.log("Token do cartão:", token);
}
tokenizeCard();Something wrong on this page? Talk to us