Tokenization

How VINR replaces raw card numbers with tokens to reduce PCI scope and enable reuse.

View as MarkdownInstall skills

Tokenization is the process by which VINR replaces a raw card number (PAN) with a surrogate identifier — the pm_ token — that is safe to store, log, and transmit. The actual card credentials never transit your server after the initial collection, which collapses most integrations to the lightest PCI self-assessment tier and makes one-click checkout and recurring billing straightforward to build.

How tokenization worksAsk

When a customer enters card details on a VINR-hosted surface (Hosted Checkout, Elements, or the mobile SDK), the card data is encrypted and sent directly to VINR's vault. Your server receives only a pm_ identifier in return. Every subsequent operation — charging, saving for later, cancelling — references that token, never the underlying number.

Prop

Type

Tokens are not cards. A pm_ ID carries no sensitive cardholder data and is safe to store in your database, emit in logs, and reference in API calls. The PAN is held exclusively inside VINR's PCI DSS Level 1 vault.

Create a tokenAsk

The recommended path collects the card on a VINR-hosted surface and then saves the method to a customer record. The customer enters their details, VINR vaults them, and the resulting pm_ ID is attached to the customer automatically.

import { Vinr } from '@vinr/sdk';

const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });

const setup = await vinr.customers.setupMethod({
  customerId: 'cust_9Kp2v...',
  returnUrl: 'https://yoursite.com/wallet/saved',
});

// Redirect the customer to setup.checkoutUrl.
// On return, the new token is attached to the customer.
// setup.paymentMethod → "pm_7Xk4..."
curl -X POST https://api.vinr.com/v1/customers/cust_9Kp2v.../setup-method \
  -H "X-Api-Key: $VINR_SECRET_KEY" \
  -d "returnUrl=https://yoursite.com/wallet/saved"

You can also save the method used during a payment by passing savePaymentMethod: true when you create the payment. The token is created and attached to the customer as part of the same request.

const payment = await vinr.payments.create({
  amount: 4500,
  currency: 'EUR',
  customer: 'cust_9Kp2v...',
  description: 'Order #2084',
  savePaymentMethod: true,
  returnUrl: 'https://yoursite.com/checkout/complete',
});

// After the customer completes checkout:
// payment.paymentMethod → "pm_7Xk4..."

Pay with a tokenAsk

Pass the pm_ ID as paymentMethod on payments.create. For off-session charges — where the customer is not present — also set offSession: true so VINR sends the correct credential flags to the network.

const payment = await vinr.payments.create({
  amount: 4500,
  currency: 'EUR',
  customer: 'cust_9Kp2v...',
  paymentMethod: 'pm_7Xk4...',
  offSession: true,
  confirm: true,
  description: 'Order #2085',
  idempotencyKey: 'order-2085-charge-1',
});

// payment.status → "completed" | "requires_action" | "failed"
curl -X POST https://api.vinr.com/v1/payments \
  -H "X-Api-Key: $VINR_SECRET_KEY" \
  -d "amount=4500" \
  -d "currency=EUR" \
  -d "customer=cust_9Kp2v..." \
  -d "paymentMethod=pm_7Xk4..." \
  -d "offSession=true" \
  -d "confirm=true" \
  -d "description=Order #2085" \
  -d "idempotencyKey=order-2085-charge-1"

If the charge returns requires_action, the issuer is requesting step-up authentication. Bring the customer back on-session to complete it — do not silently retry. See SCA & 3D Secure for the handling pattern.

Manage tokensAsk

Use the following operations to list, retrieve, and remove stored methods.

List methods on a customer

const methods = await vinr.paymentMethods.list({
  customer: 'cust_9Kp2v...',
  type: 'card',
});

for (const pm of methods.data) {
  console.log(pm.id, pm.card.brand, pm.card.last4);
  // → "pm_7Xk4..." "visa" "4242"
}

Retrieve a single method

const pm = await vinr.paymentMethods.retrieve('pm_7Xk4...');

// pm.networkToken.status → "active"
// pm.card.expMonth       → 12
// pm.card.expYear        → 2028

Detach (delete) a method

Detaching is immediate and irreversible. The token can no longer be charged. Remove a method as soon as a buyer deletes a card from their wallet.

await vinr.paymentMethods.detach('pm_7Xk4...');

Detaching does not issue a refund or cancel any active subscriptions that reference the token. Update those to a new method before detaching, or they will fail on the next billing cycle.

Network tokenizationAsk

Beyond VINR's own vault tokens, VINR participates in Visa Token Service (VTS) and Mastercard Digital Enablement Service (MDES). When you store a card, VINR automatically requests a network token — a credential issued by the card scheme that is scoped to your merchant and replaces the underlying PAN on the network rail. This process is on by default and requires no flags or configuration changes from you.

Network tokens deliver two concrete benefits:

  • Higher authorization rates. Issuers treat network-tokenized credentials as lower risk than raw PAN-based credentials, particularly on off-session charges, resulting in fewer soft declines.
  • Automatic card renewal. When a cardholder's card is reissued — whether the physical card is lost, the number is refreshed, or the expiry rolls — the card scheme updates the network token automatically. Recurring charges keep working without the customer re-entering their details.

You can verify that a stored method is backed by an active network token by inspecting paymentMethod.networkToken.status:

const pm = await vinr.paymentMethods.retrieve('pm_7Xk4...');

if (pm.networkToken.status === 'active') {
  // this method benefits from network tokenization
}

Listen for the payment_method.updated webhook to be notified when a network token is refreshed or a card's details are updated by the scheme:

const event = vinr.webhooks.verify(payload, signature); // x-vinr-signature header

if (event.type === 'payment_method.updated') {
  const pm = event.data.object;
  console.log('Token refreshed for customer', pm.customer, '— method', pm.id);
}

Account updaterAsk

For cards where a network token is not available — for example, prepaid cards and certain regional issuers — VINR runs an account updater service. On a nightly batch schedule, VINR queries card network update feeds for any expiry date changes, card number replacements, or account closures and applies them to your stored methods silently.

When an update is applied, a payment_method.updated event fires with the same payload structure as a network token refresh. Your webhook handler does not need to distinguish between the two sources.

Account updater coverage depends on the issuer's participation in the relevant card network update programme. Network tokenization is always preferred where available because it is real-time rather than batch.

Next stepsAsk

Was this page helpful?
Edit on GitHub

Last updated on

On this page