PlexySDK DOCS

Manage Tokens

List, update, and delete stored payment methods for your customers

Manage Tokens

After creating tokens, you'll need to manage them throughout their lifecycle. This guide covers how to list, retrieve, update, and delete tokens for your shoppers.

List Tokens for a Shopper

Retrieve all stored payment methods for a specific customer. This is useful for displaying saved cards in your checkout or account settings.

curl -X GET "https://api.plexypay.com/v2/tokens?shopper_id=shopper_123456" \
  -H "x-api-key: Bearer YOUR_API_KEY"
import { Plexy } from '@plexy/plexy-web';

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

const tokens = await plexy.tokens.list({
  shopper_id: 'shopper_123456',
});

console.log(`Found ${tokens.data.length} saved payment methods`);

tokens.data.forEach(token => {
  console.log(`${token.card.brand} ending in ${token.card.last4}`);
});
import os
from plexy import Plexy

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

tokens = plexy.tokens.list(shopper_id='shopper_123456')

print(f'Found {len(tokens.data)} saved payment methods')

for token in tokens.data:
    print(f'{token.card.brand} ending in {token.card.last4}')

Response

{
  "data": [
    {
      "id": "tok_card_visa_4242",
      "type": "card",
      "shopper_id": "shopper_123456",
      "recurring_processing_model": "CardOnFile",
      "card": {
        "brand": "visa",
        "last4": "4242",
        "exp_month": 12,
        "exp_year": 2028,
        "funding": "credit",
        "issuer_country": "US"
      },
      "billing_address": {
        "line1": "123 Main St",
        "city": "San Francisco",
        "state": "CA",
        "postal_code": "94102",
        "country": "US"
      },
      "created_at": "2026-01-15T10:30:00Z",
      "updated_at": "2026-01-15T10:30:00Z"
    },
    {
      "id": "tok_card_mastercard_5678",
      "type": "card",
      "shopper_id": "shopper_123456",
      "recurring_processing_model": "Subscription",
      "card": {
        "brand": "mastercard",
        "last4": "5678",
        "exp_month": 6,
        "exp_year": 2027,
        "funding": "debit",
        "issuer_country": "KZ"
      },
      "created_at": "2026-02-20T14:45:00Z",
      "updated_at": "2026-02-20T14:45:00Z"
    }
  ],
  "has_more": false
}

Filtering Options

You can filter tokens by various criteria:

# Filter by recurring model
curl -X GET "https://api.plexypay.com/v2/tokens?shopper_id=shopper_123456&recurring_processing_model=Subscription" \
  -H "x-api-key: Bearer YOUR_API_KEY"

# Filter by card brand
curl -X GET "https://api.plexypay.com/v2/tokens?shopper_id=shopper_123456&card_brand=visa" \
  -H "x-api-key: Bearer YOUR_API_KEY"

# Pagination
curl -X GET "https://api.plexypay.com/v2/tokens?shopper_id=shopper_123456&limit=10&starting_after=tok_card_visa_4242" \
  -H "x-api-key: Bearer YOUR_API_KEY"
// Filter by recurring model
const subscriptionTokens = await plexy.tokens.list({
  shopper_id: 'shopper_123456',
  recurring_processing_model: 'Subscription',
});

// Filter by card brand
const visaTokens = await plexy.tokens.list({
  shopper_id: 'shopper_123456',
  card_brand: 'visa',
});

// Pagination
const paginatedTokens = await plexy.tokens.list({
  shopper_id: 'shopper_123456',
  limit: 10,
  starting_after: 'tok_card_visa_4242',
});
# Filter by recurring model
subscription_tokens = plexy.tokens.list(
    shopper_id='shopper_123456',
    recurring_processing_model='Subscription',
)

# Filter by card brand
visa_tokens = plexy.tokens.list(
    shopper_id='shopper_123456',
    card_brand='visa',
)

# Pagination
paginated_tokens = plexy.tokens.list(
    shopper_id='shopper_123456',
    limit=10,
    starting_after='tok_card_visa_4242',
)

Retrieve a Single Token

Get detailed information about a specific token.

curl -X GET https://api.plexypay.com/v2/tokens/tok_card_visa_4242 \
  -H "x-api-key: Bearer YOUR_API_KEY"
const token = await plexy.tokens.retrieve('tok_card_visa_4242');

console.log('Token ID:', token.id);
console.log('Card:', `${token.card.brand} **** ${token.card.last4}`);
console.log('Expires:', `${token.card.exp_month}/${token.card.exp_year}`);
token = plexy.tokens.retrieve('tok_card_visa_4242')

print(f'Token ID: {token.id}')
print(f'Card: {token.card.brand} **** {token.card.last4}')
print(f'Expires: {token.card.exp_month}/{token.card.exp_year}')

Response

{
  "id": "tok_card_visa_4242",
  "type": "card",
  "shopper_id": "shopper_123456",
  "recurring_processing_model": "CardOnFile",
  "card": {
    "brand": "visa",
    "last4": "4242",
    "exp_month": 12,
    "exp_year": 2028,
    "funding": "credit",
    "issuer_country": "US",
    "issuer_name": "Chase"
  },
  "billing_address": {
    "line1": "123 Main St",
    "city": "San Francisco",
    "state": "CA",
    "postal_code": "94102",
    "country": "US"
  },
  "metadata": {
    "nickname": "Personal Visa"
  },
  "created_at": "2026-01-15T10:30:00Z",
  "updated_at": "2026-01-15T10:30:00Z"
}

Update Token Details

You can update certain token attributes like billing address and metadata. Card details themselves cannot be modified - you would need to create a new token.

curl -X PATCH https://api.plexypay.com/v2/tokens/tok_card_visa_4242 \
  -H "x-api-key: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "billing_address": {
      "line1": "456 New Street",
      "line2": "Apt 7B",
      "city": "New York",
      "state": "NY",
      "postal_code": "10001",
      "country": "US"
    },
    "metadata": {
      "nickname": "Work Card",
      "is_default": true
    }
  }'
const updatedToken = await plexy.tokens.update('tok_card_visa_4242', {
  billing_address: {
    line1: '456 New Street',
    line2: 'Apt 7B',
    city: 'New York',
    state: 'NY',
    postal_code: '10001',
    country: 'US',
  },
  metadata: {
    nickname: 'Work Card',
    is_default: true,
  },
});

console.log('Token updated:', updatedToken.id);
console.log('New address:', updatedToken.billing_address.city);
updated_token = plexy.tokens.update(
    'tok_card_visa_4242',
    billing_address={
        'line1': '456 New Street',
        'line2': 'Apt 7B',
        'city': 'New York',
        'state': 'NY',
        'postal_code': '10001',
        'country': 'US',
    },
    metadata={
        'nickname': 'Work Card',
        'is_default': True,
    },
)

print(f'Token updated: {updated_token.id}')
print(f'New address: {updated_token.billing_address.city}')

Response

{
  "id": "tok_card_visa_4242",
  "type": "card",
  "shopper_id": "shopper_123456",
  "recurring_processing_model": "CardOnFile",
  "card": {
    "brand": "visa",
    "last4": "4242",
    "exp_month": 12,
    "exp_year": 2028,
    "funding": "credit"
  },
  "billing_address": {
    "line1": "456 New Street",
    "line2": "Apt 7B",
    "city": "New York",
    "state": "NY",
    "postal_code": "10001",
    "country": "US"
  },
  "metadata": {
    "nickname": "Work Card",
    "is_default": true
  },
  "updated_at": "2026-03-25T16:00:00Z"
}

Updatable Fields

FieldDescription
billing_addressCustomer's billing address
metadataCustom key-value pairs (up to 50 keys)

To update card details (number, expiry, CVC), create a new token and delete the old one. Card networks may automatically update expiry dates through Account Updater if enabled.

Delete a Token

Remove a stored payment method. This is typically done when a customer removes a card from their account.

curl -X DELETE https://api.plexypay.com/v2/tokens/tok_card_visa_4242 \
  -H "x-api-key: Bearer YOUR_API_KEY"
await plexy.tokens.delete('tok_card_visa_4242');

console.log('Token deleted successfully');
plexy.tokens.delete('tok_card_visa_4242')

print('Token deleted successfully')

Response

{
  "id": "tok_card_visa_4242",
  "deleted": true
}

Deleting a token is permanent and cannot be undone. Any active subscriptions or scheduled payments using this token will fail. Ensure you have confirmation flows in your application before deleting customer payment methods.

Disable a Token

Instead of permanently deleting a token, you can disable it. This prevents the token from being used for new payments while preserving the record.

curl -X POST https://api.plexypay.com/v2/tokens/tok_card_visa_4242/disable \
  -H "x-api-key: Bearer YOUR_API_KEY"
const disabledToken = await plexy.tokens.disable('tok_card_visa_4242');

console.log('Token disabled:', disabledToken.id);
console.log('Status:', disabledToken.status); // "disabled"
disabled_token = plexy.tokens.disable('tok_card_visa_4242')

print(f'Token disabled: {disabled_token.id}')
print(f'Status: {disabled_token.status}')  # "disabled"

Re-enable a Token

You can re-enable a disabled token if needed.

curl -X POST https://api.plexypay.com/v2/tokens/tok_card_visa_4242/enable \
  -H "x-api-key: Bearer YOUR_API_KEY"
const enabledToken = await plexy.tokens.enable('tok_card_visa_4242');

console.log('Token re-enabled:', enabledToken.id);
console.log('Status:', enabledToken.status); // "active"
enabled_token = plexy.tokens.enable('tok_card_visa_4242')

print(f'Token re-enabled: {enabled_token.id}')
print(f'Status: {enabled_token.status}')  # "active"

Managing Tokens in the Plexy Dashboard

You can also manage tokens directly in the Plexy Dashboard:

Go to Customers in the sidebar and search for the shopper.

Click on the customer to see their stored payment methods.

From here you can:

  • View token details and transaction history
  • Update billing address
  • Disable or delete tokens
  • See which subscriptions are linked to each token

Check Token Validity

Before attempting a payment, you can verify that a token is still valid.

curl -X POST https://api.plexypay.com/v2/tokens/tok_card_visa_4242/verify \
  -H "x-api-key: Bearer YOUR_API_KEY"
const verification = await plexy.tokens.verify('tok_card_visa_4242');

if (verification.valid) {
  console.log('Token is valid and can be charged');
} else {
  console.log('Token is invalid:', verification.reason);
  // Possible reasons: "expired", "card_declined", "account_closed"
}
verification = plexy.tokens.verify('tok_card_visa_4242')

if verification.valid:
    print('Token is valid and can be charged')
else:
    print(f'Token is invalid: {verification.reason}')
    # Possible reasons: "expired", "card_declined", "account_closed"

Response

{
  "token_id": "tok_card_visa_4242",
  "valid": true,
  "card": {
    "brand": "visa",
    "last4": "4242",
    "exp_month": 12,
    "exp_year": 2028
  },
  "verified_at": "2026-03-25T16:30:00Z"
}

Token verification performs a zero-amount authorization. Some card issuers may show a temporary pending charge to the cardholder. Use this sparingly and consider caching results.

Monitor Expiring Tokens

Proactively identify tokens that will expire soon to request updated payment methods from customers.

# Get tokens expiring in the next 30 days
curl -X GET "https://api.plexypay.com/v2/tokens?expires_before=2026-04-25" \
  -H "x-api-key: Bearer YOUR_API_KEY"
// Get tokens expiring in the next 30 days
const thirtyDaysFromNow = new Date();
thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);

const expiringTokens = await plexy.tokens.list({
  expires_before: thirtyDaysFromNow.toISOString().split('T')[0],
});

for (const token of expiringTokens.data) {
  console.log(`Token ${token.id} expires ${token.card.exp_month}/${token.card.exp_year}`);
  // Send reminder email to customer
  await sendExpirationReminder(token.shopper_id, token);
}
from datetime import datetime, timedelta

# Get tokens expiring in the next 30 days
thirty_days_from_now = datetime.now() + timedelta(days=30)

expiring_tokens = plexy.tokens.list(
    expires_before=thirty_days_from_now.strftime('%Y-%m-%d'),
)

for token in expiring_tokens.data:
    print(f'Token {token.id} expires {token.card.exp_month}/{token.card.exp_year}')
    # Send reminder email to customer
    send_expiration_reminder(token.shopper_id, token)

API Reference

List Tokens Parameters

ParameterTypeDescription
shopper_idstringFilter by customer (required)
recurring_processing_modelstringFilter by token type
card_brandstringFilter by card brand (visa, mastercard, etc.)
statusstringFilter by status (active, disabled)
expires_beforestringFilter tokens expiring before date (YYYY-MM-DD)
limitintegerNumber of results (1-100, default 10)
starting_afterstringCursor for pagination

Update Token Parameters

ParameterTypeDescription
billing_addressobjectCustomer billing address
billing_address.line1stringStreet address
billing_address.line2stringApartment, suite, etc.
billing_address.citystringCity
billing_address.statestringState or province
billing_address.postal_codestringZIP or postal code
billing_address.countrystringTwo-letter country code
metadataobjectCustom key-value pairs

Error Handling

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

try {
  const token = await plexy.tokens.retrieve('tok_invalid');
} catch (error) {
  if (error instanceof PlexyError) {
    switch (error.code) {
      case 'token_not_found':
        console.error('Token does not exist');
        break;
      case 'token_disabled':
        console.error('Token has been disabled');
        break;
      case 'unauthorized':
        console.error('Token belongs to a different merchant');
        break;
      default:
        console.error('Error:', error.message);
    }
  }
}
from plexy import PlexyError

try:
    token = plexy.tokens.retrieve('tok_invalid')
except PlexyError as error:
    if error.code == 'token_not_found':
        print('Token does not exist')
    elif error.code == 'token_disabled':
        print('Token has been disabled')
    elif error.code == 'unauthorized':
        print('Token belongs to a different merchant')
    else:
        print(f'Error: {error.message}')

Best Practices

  1. Display tokens clearly - Show card brand, last 4 digits, and expiry to help customers identify their cards
  2. Handle disabled tokens - Check token status before displaying in checkout
  3. Monitor expiration - Set up automated reminders for expiring cards
  4. Confirm deletion - Always confirm with the user before deleting a payment method
  5. Use metadata wisely - Store nicknames or default flags to improve UX
  6. Enable Account Updater - Automatically update card details when issuers reissue cards

Next Steps

On this page