PlexySDK DOCS

Create Tokens

Learn how to securely store payment details as tokens for future payments, subscriptions, and card-on-file transactions

Create Tokens

Tokenization allows you to store your customer's payment details securely. When a customer pays for the first time, you can save their payment method as a token and use it for future transactions without requiring them to re-enter their card details.

Prerequisites

Before creating tokens, ensure you have:

  • A Plexy account with API keys from the Plexy Dashboard
  • A shopper_id to identify the customer whose payment method you're storing

The shopper_id is a unique identifier you create to link payment methods to a specific customer. This is required for all tokenization operations.

Token Types

Plexy supports three types of tokens based on how you intend to use them:

Token TypeUse CaseShopper PresentExample
CardOnFileCustomer-initiated payments with saved cardYesOne-click checkout
SubscriptionFixed-amount recurring chargesNoMonthly subscription
UnscheduledCardOnFileVariable-amount merchant-initiated chargesNoUsage-based billing, account top-ups

CardOnFile

Use this when the customer will be present and actively initiating the payment, such as:

  • One-click checkout on your website
  • Reordering previous purchases
  • Express checkout in mobile apps

Subscription

Use this for predictable, scheduled recurring payments where:

  • The amount is fixed or known in advance
  • Payments occur on a regular schedule
  • The customer has agreed to automatic billing

UnscheduledCardOnFile

Use this for merchant-initiated transactions where:

  • The payment amount varies
  • The timing is irregular or triggered by events
  • Examples include: usage charges, account top-ups, pay-as-you-go services

Creating a Token During Payment

The most common way to create a token is during the initial payment. Set store_payment_method to true and specify the token type.

curl -X POST https://api.plexypay.com/v2/payments \
  -H "x-api-key: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 10000,
    "currency": "KZT",
    "payment_method": {
      "type": "card",
      "card": {
        "number": "4111111111111111",
        "exp_month": 12,
        "exp_year": 2028,
        "cvc": "123"
      }
    },
    "shopper_id": "shopper_123456",
    "store_payment_method": true,
    "recurring_processing_model": "CardOnFile",
    "shopper_interaction": "Ecommerce",
    "return_url": "https://yoursite.com/checkout/complete",
    "metadata": {
      "order_id": "order_789"
    }
  }'
import { Plexy } from '@plexy/plexy-web';

const plexy = new Plexy({
  apiKey: process.env.PLEXY_SECRET_KEY,
});

const payment = await plexy.payments.create({
  amount: 10000,
  currency: 'KZT',
  payment_method: {
    type: 'card',
    card: {
      number: '4111111111111111',
      exp_month: 12,
      exp_year: 2028,
      cvc: '123',
    },
  },
  shopper_id: 'shopper_123456',
  store_payment_method: true,
  recurring_processing_model: 'CardOnFile',
  shopper_interaction: 'Ecommerce',
  return_url: 'https://yoursite.com/checkout/complete',
  metadata: {
    order_id: 'order_789',
  },
});

console.log('Payment ID:', payment.id);
console.log('Token ID:', payment.token_id);
import os
from plexy import Plexy

plexy = Plexy(api_key=os.environ['PLEXY_SECRET_KEY'])

payment = plexy.payments.create(
    amount=10000,
    currency='KZT',
    payment_method={
        'type': 'card',
        'card': {
            'number': '4111111111111111',
            'exp_month': 12,
            'exp_year': 2028,
            'cvc': '123',
        },
    },
    shopper_id='shopper_123456',
    store_payment_method=True,
    recurring_processing_model='CardOnFile',
    shopper_interaction='Ecommerce',
    return_url='https://yoursite.com/checkout/complete',
    metadata={
        'order_id': 'order_789',
    },
)

print(f'Payment ID: {payment.id}')
print(f'Token ID: {payment.token_id}')

Response

{
  "id": "pay_abc123def456",
  "status": "authorized",
  "amount": 10000,
  "currency": "KZT",
  "token_id": "tok_card_visa_4242",
  "shopper_id": "shopper_123456",
  "payment_method": {
    "type": "card",
    "card": {
      "brand": "visa",
      "last4": "1111",
      "exp_month": 12,
      "exp_year": 2028,
      "funding": "credit"
    }
  },
  "recurring_processing_model": "CardOnFile",
  "created_at": "2026-03-25T10:30:00Z"
}

The token_id in the response is what you'll use for future payments. Store this securely along with the shopper_id in your database.

Creating a Token Without Payment

You can also create a token without processing a payment. This is useful for:

  • Saving a card for future use before the customer makes a purchase
  • Validating a card before a subscription starts
  • Setting up a backup payment method
curl -X POST https://api.plexypay.com/v2/tokens \
  -H "x-api-key: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_method": {
      "type": "card",
      "card": {
        "number": "4111111111111111",
        "exp_month": 12,
        "exp_year": 2028,
        "cvc": "123"
      }
    },
    "shopper_id": "shopper_123456",
    "recurring_processing_model": "Subscription",
    "verify": true
  }'
import { Plexy } from '@plexy/plexy-web';

const plexy = new Plexy({
  apiKey: process.env.PLEXY_SECRET_KEY,
});

const token = await plexy.tokens.create({
  payment_method: {
    type: 'card',
    card: {
      number: '4111111111111111',
      exp_month: 12,
      exp_year: 2028,
      cvc: '123',
    },
  },
  shopper_id: 'shopper_123456',
  recurring_processing_model: 'Subscription',
  verify: true,
});

console.log('Token ID:', token.id);
console.log('Card brand:', token.card.brand);
import os
from plexy import Plexy

plexy = Plexy(api_key=os.environ['PLEXY_SECRET_KEY'])

token = plexy.tokens.create(
    payment_method={
        'type': 'card',
        'card': {
            'number': '4111111111111111',
            'exp_month': 12,
            'exp_year': 2028,
            'cvc': '123',
        },
    },
    shopper_id='shopper_123456',
    recurring_processing_model='Subscription',
    verify=True,
)

print(f'Token ID: {token.id}')
print(f'Card brand: {token.card.brand}')

Response

{
  "id": "tok_card_visa_5678",
  "type": "card",
  "shopper_id": "shopper_123456",
  "recurring_processing_model": "Subscription",
  "card": {
    "brand": "visa",
    "last4": "1111",
    "exp_month": 12,
    "exp_year": 2028,
    "funding": "credit"
  },
  "verified": true,
  "created_at": "2026-03-25T10:35:00Z"
}

Setting verify: true performs a zero-amount authorization to validate the card. This ensures the card is valid and can be charged, but some card issuers may show a temporary hold to the cardholder.

Using Plexy Checkout for Tokenization

For PCI compliance and a better user experience, use Plexy Checkout to collect card details securely.

Create a checkout session with tokenization enabled.

curl -X POST https://api.plexypay.com/v2/checkout/sessions \
  -H "x-api-key: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "setup",
    "shopper_id": "shopper_123456",
    "recurring_processing_model": "CardOnFile",
    "success_url": "https://yoursite.com/setup/success",
    "cancel_url": "https://yoursite.com/setup/cancel"
  }'
const session = await plexy.checkout.sessions.create({
  mode: 'setup',
  shopper_id: 'shopper_123456',
  recurring_processing_model: 'CardOnFile',
  success_url: 'https://yoursite.com/setup/success',
  cancel_url: 'https://yoursite.com/setup/cancel',
});

// Redirect customer to session.url
console.log('Redirect to:', session.url);
session = plexy.checkout.sessions.create(
    mode='setup',
    shopper_id='shopper_123456',
    recurring_processing_model='CardOnFile',
    success_url='https://yoursite.com/setup/success',
    cancel_url='https://yoursite.com/setup/cancel',
)

# Redirect customer to session.url
print(f'Redirect to: {session.url}')

Redirect the customer to the checkout URL returned in the response.

// On your frontend
window.location.href = session.url;

After the customer completes the checkout, Plexy sends a webhook with the token details.

// In your webhook handler
app.post('/webhooks/plexy', (req, res) => {
  const event = plexy.webhooks.constructEvent(
    req.body,
    req.headers['plexy-signature'],
    process.env.PLEXY_WEBHOOK_SECRET
  );

  if (event.type === 'checkout.session.completed') {
    const session = event.data;
    const tokenId = session.token_id;
    const shopperId = session.shopper_id;

    // Store the token_id for future payments
    await saveTokenToDatabase(shopperId, tokenId);
  }

  res.status(200).send('OK');
});

Request Parameters

ParameterTypeRequiredDescription
payment_methodobjectYesThe payment method details to tokenize
shopper_idstringYesYour unique identifier for the customer
store_payment_methodbooleanNoSet to true to create a token (default: false)
recurring_processing_modelstringYes*Token type: CardOnFile, Subscription, or UnscheduledCardOnFile
shopper_interactionstringNoEcommerce (online) or ContractPresent (in-person)
verifybooleanNoValidate the card with a zero-amount auth

*Required when store_payment_method is true

Choosing the Right Token Type

  • Customer initiates: Use CardOnFile
  • Merchant initiates: Use Subscription or UnscheduledCardOnFile
  • Fixed amount, regular schedule: Use Subscription
  • Variable amount or irregular timing: Use UnscheduledCardOnFile

Error Handling

import { Plexy, PlexyError } from '@plexy/plexy-web';

try {
  const token = await plexy.tokens.create({
    payment_method: { /* ... */ },
    shopper_id: 'shopper_123456',
    recurring_processing_model: 'CardOnFile',
  });
} catch (error) {
  if (error instanceof PlexyError) {
    switch (error.code) {
      case 'card_declined':
        console.error('Card was declined:', error.message);
        break;
      case 'invalid_card_number':
        console.error('Invalid card number');
        break;
      case 'expired_card':
        console.error('Card has expired');
        break;
      default:
        console.error('Tokenization failed:', error.message);
    }
  }
}
from plexy import Plexy, PlexyError

try:
    token = plexy.tokens.create(
        payment_method={ ... },
        shopper_id='shopper_123456',
        recurring_processing_model='CardOnFile',
    )
except PlexyError as error:
    if error.code == 'card_declined':
        print(f'Card was declined: {error.message}')
    elif error.code == 'invalid_card_number':
        print('Invalid card number')
    elif error.code == 'expired_card':
        print('Card has expired')
    else:
        print(f'Tokenization failed: {error.message}')

Testing

Use these test card numbers to verify your tokenization integration:

Card NumberScenario
4111 1111 1111 1111Successful tokenization
4000 0000 0000 0002Card declined
4000 0000 0000 0069Expired card
4000 0000 0000 0127Invalid CVC

Next Steps

Now that you can create tokens, learn how to use them:

On this page