Tokenization in Payments: The Future of Secure, Anonymous Transactions

By: Adeyinka Adegbenro

Since the 2010s, the gatekeepers of the payment industry—think Payment Card Industry Data Security Standard (PCI DSS), Mastercard, and Visa—have promoted tokenization as the industry standard for compliance and card-related fraud prevention.

Why? Because tokenization is extremely important for protecting the privacy of financial institutions. Instead of sharing a card’s actual sixteen-digit number, it swaps in a unique, randomly generated token so that a user’s raw card details are never shared.

In this article, you’ll learn more about tokenization and how to implement payment tokenization using the Rapyd API.

Understanding Tokenization

At its core, tokenization replaces sensitive payment details with nonsensitive, randomly generated tokens that can’t be reversed, unless you have access to the provider’s vault. These tokens are securely stored either by the merchant or in the tokenization provider’s vault.

Tokenizing payment data doesn’t use just a single algorithm—it uses a layered approach that combines techniques, like masking, cryptographic storage, obfuscation, and randomization, to create secure tokens:

In most cases, using a tokenization service is recommended over creating your own service because it’s PCI DSS–compliant out of the box, quicker to implement, and built to scale.

It’s important to note that tokenization does not replace due diligence. You still need to validate PCI DSS compliance, but it may simplify the process by reducing the number of components subject to PCI DSS requirements.

Benefits of Tokenization

The main benefit of tokenization is that it significantly reduces the impact of data breaches and the risk of fraud because the stolen tokens can’t be used to access the original card details. Tokenization also provides you with the following benefits:

  • Requires fewer resources than other privacy measures, like encryption, because it doesn’t involve complex mathematical operations and can be carried out by third-party providers like Rapyd.

  • Enables secure storage of credit card information for modern payment methods, including one-click payments, mobile wallets, and cryptocurrencies.

  • Enhances security and convenience while remaining invisible to customers, allowing businesses to offer a seamless payment experience without requiring user actions like signing up, logging in, or managing passwords.

  • Reduces fraud risk, increasing the likelihood of bank transactions.

Encryption vs. Tokenization

Tokenization is the process of replacing sensitive data with a token. Meanwhile, encryption is the process of converting data into an unreadable format using a decryption key. Encryption is ideal for securely transmitting and retrieving data, like encrypted emails, readable only by recipients with the cryptographic key. In contrast, tokenization is best for masking data that doesn’t need to be stored in its original form. Unlike encryption, tokenization is irreversible if you don’t have access to the token vault.

Encryption also differs from tokenization because encryption can be computationally intensive, especially for large-scale systems. Encryption is widely used for general data security and compliance with privacy laws like the Health Insurance Portability and Accountability Act (HIPAA) and the General Data Protection Regulation (GDPR).

In contrast, tokenization is lightweight, making it the primary choice for PCI DSS.

How to Implement a Tokenized Payment System with Rapyd

In this tutorial, you’ll learn how to use Rapyd for tokenization in a payment system by using a sample project on GitHub called [Rapyd_Ecommerce or rapyd-tokenization-example

](GitHub - Rapyd-Samples/rapyd-tokenization-example: In this tutorial, you'll learn how to use Rapyd for tokenization in a payment system by using a sample project.). Rapyd_Ecommerce is a simple Node.js app that uses Express as a server and EJS as a light template framework to render the UI.

Before you begin, you need to install the latest version of Git, Node.js, and npm (which comes with Node.js) on your computer.

Once you have the latest version of Git, clone the sample application from GitHub by running the following:


git clone https://github.com/Rapyd-Samples/rapyd-tokenization-example.git

cd Rapyd_Ecommerce

Create a Rapyd Account

If you don’t already have one, create a Rapyd account. Once you’re signed in, you will, by default, be in sandbox mode.

From the sidebar, navigate to Developers > API access control and note your sandbox credentials:

Next, create a .env file in the root folder. This holds your Rapyd credentials:


touch .env

In the .env file, add the following:


RAPYD_ACCESS_KEY=<YOUR_RAPYD_ACCESS_KEY>

RAPYD_SECRET_KEY=<YOUR_RAPYD_SECRET_KEY>

RAPYD_BASE_URL=https://sandboxapi.rapyd.net

Then, in the same file, replace <YOUR_RAPYD_ACCESS_KEY> and <YOUR_RAPYD_SECRET_KEY> with your access key and secret key. Install the dependencies:


npm install

Finally, start the server:


npm start

Since the Rapyd API doesn’t support localhost URLs for webhooks, this tutorial uses ngrok to create a secure, temporary public URL that tunnels requests to your local server. Use the following code to install ngrok:


npm install -g ngrok

Then, create an ngrok account and fetch your ngrok token by selecting Your Authtoken from the sidebar. Copy your authtoken, add it to ngrok in the terminal, and start the server:


ngrok config add-authtoken $YOUR_AUTHTOKEN

ngrok http 3000

In the output, you’ll see a public URL that looks like this—https://862e-102-89-82-24.ngrok-free.app:

Set Up Webhooks

Webhooks are sent by Rapyd after a payment request is completed—whether successful, failed, or canceled.

From your Rapyd Client Portal, navigate to Developer > Webhooks > Management. Go to the section named Define your callback URL and the events that will trigger it. On the blank, add your callback URL. It should look something like this:

For example, if your public URL is https://cb9d-102-89-83-16.ngrok-free.app, then the callback URL will be https://cb9d-102-89-83-16.ngrok-free.app/api/webhook.

In the Collect section, click Select all and save your changes. From now on, whenever a payment flow starts and the user completes payment, the server receives a webhook request at /api/webhook with an update on the original payment request.

Set Up the Payment Flow

To start the payment flow, enter your ngrok public URL in a browser and click Visit Site. You’ll see a page listing gadgets and their prices:

This page is being served by index.ejs and the product data from products.json. Clicking the Buy button sends a GET request to the server endpoint (/buy) along with the productId, amount, and currency.

In server.js, the /buy endpoint renders the Checkout page using views/checkout.ejs. This page collects the user’s card details and processes the payment. The Rapyd API securely tokenizes the card details and charges the card based on the specified currency, amount, and other transaction details.

When the Checkout page loads, the app sends a request to the /create-checkout endpoint to retrieve the Rapyd Checkout page URL. Handling this on the backend is more secure as it keeps sensitive API credentials like RAPYD_ACCESS_KEY and RAPYD_SECRET_KEY hidden.

In server.js, the /create-checkout route needs to call the Rapyd API /v1/checkout endpoint with the required headers and body attributes. For a list of possible attributes, see the Rapyd Create Checkout Page documentation.

For this tutorial, the body payload contains the required attributes as well as a few others. On line 75, the body payload contains the following:

  • amount refers to the price of the gadget converted to string format.

  • currency is the currency of the item being purchased.

  • country is the two-letter ISO 3166-1 code for the country.

  • complete_payment_url is the URL to which you want Rapyd to redirect the user after a successful checkout. It’s set to http://localhost:3000/success.

  • error_payment_url is the URL to which you want Rapyd to redirect the user after a failed checkout. In this case, it’s set to http://localhost:3000/fail.

Rapyd uses HMAC-SHA256 signature-based authentication to verify that every API request comes from an authorized source. This means that a request to /v1/checkout must include a digitally signed SHA-256 signature.

In server.js (line 88), the header object contains the following attributes:

  • content-type is set to application/json, indicating the request body is in JSON format.

  • access_key is retrieved from your .env file. This is the Rapyd access key found in the Developers section of your Rapyd Client Portal.

  • idempotency is a unique ID generated using the uuid library (UUID version 4) to prevent duplicate transactions. When retrying a failed request, reuse the same idempotency key to avoid processing it as a new request.

  • salt is an eight- to sixteen-digit random string required by Rapyd to generate a unique signature for each request, preventing replay attacks. It’s an extra layer of security to protect against malicious reuse of old requests. While the idempotency key can be reused for retries, the salt and signature must be regenerated for every request.

  • timestamp is the request timestamp in Unix format (seconds).

  • signature is generated in the generateSignature function by concatenating the request method (POST), URL path (/v1/checkout), salt, timestamp, access key, secret key, and the stringified JSON body. The string is then hashed using SHA-256 and encoded to Base64. For more details, check out the Rapyd documentation on Signatures.

Once the POST request is successfully sent to /v1/checkout, /create-checkout returns the checkout_url to checkout.ejs, which then redirects the page to the official Rapyd Checkout page. At this point, you should see a Checkout page with multiple payment options:

Since this tutorial focuses on card payment and tokenization, select the Card option.

Rapyd provides test card numbers for testing card payments. Use 4111111111111111 as the card number, any future date as the expiration date, and any three-digit number as the CVV number. Then select Place Your Order.

Once you’ve placed the order, you should see another authentication page that mimics 3-D Secure:

Enter 123456 and click Continue. Rapyd then handles payment tokenization and charges the card. All this is done on the Rapyd secure servers, which means you don’t need to worry about card number security, tokenization, or the details of charging the card.

If the payment fails, the error_payment_url endpoint /fail is called, and a PAYMENT_FAILED webhook is sent to the /api/webook endpoint.

On the flip side, if the payment is successful, the complete_payment_url endpoint /success is called. Then a PAYMENT_SUCCEEDED webhook is sent to the /api/webook endpoint:

Rapyd lets you save a user’s card details by initially creating a customer via the Create Customer endpoint, which returns a customer ID. This ID can be included in the /v1/checkout request, giving users the option to save their card for future purchases. For future transactions, simply reuse the customer ID to access saved cards—securely stored by Rapyd—so they never need to be saved on your server.

The beauty of this payment flow is that the tokenization process is completely abstracted away, leaving you time to focus on other things.

Conclusion

Without tokenization, unprotected data is a ticking time bomb. A data breach costs millions in damages and fines. Adding tokenization to your system design helps you build data breach–resilient systems.

Using the Rapyd API for tokenization, you can safeguard payment data for all your tokenization needs while ensuring compliance with global security best practices. Rapyd can also be used to receive, send, and manage funds globally. Learn more about Rapyd today.