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_idto 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 Type | Use Case | Shopper Present | Example |
|---|---|---|---|
| CardOnFile | Customer-initiated payments with saved card | Yes | One-click checkout |
| Subscription | Fixed-amount recurring charges | No | Monthly subscription |
| UnscheduledCardOnFile | Variable-amount merchant-initiated charges | No | Usage-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
| Parameter | Type | Required | Description |
|---|---|---|---|
payment_method | object | Yes | The payment method details to tokenize |
shopper_id | string | Yes | Your unique identifier for the customer |
store_payment_method | boolean | No | Set to true to create a token (default: false) |
recurring_processing_model | string | Yes* | Token type: CardOnFile, Subscription, or UnscheduledCardOnFile |
shopper_interaction | string | No | Ecommerce (online) or ContractPresent (in-person) |
verify | boolean | No | Validate 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
SubscriptionorUnscheduledCardOnFile
- 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 Number | Scenario |
|---|---|
4111 1111 1111 1111 | Successful tokenization |
4000 0000 0000 0002 | Card declined |
4000 0000 0000 0069 | Expired card |
4000 0000 0000 0127 | Invalid CVC |
Next Steps
Now that you can create tokens, learn how to use them:
- Make Token Payments - Process payments using saved tokens
- Manage Tokens - List, update, and delete tokens