Collect Card Data from User
Collect Card Data with VGS
In an agentic system, card data must be collected in a secure and compliant way without exposing raw PAN or CVC to your systems or AI agents. This page shows you how to use VGS Collect
to securely collect, tokenize, and store card data with full PCI compliance.
This method:
Uses customizable PCI-compliant hosted fields
Creates a Card Object along with VGS Aliases for the PAN and CVC fields
Authenticates via backend-generated JWT (using a minimally-scoped service account)
Step 1: Create a Client-Side Service Account
Navigate to the Service Accounts section of the VGS Dashboard: Vault > Organization > Service Accounts.
Click on the Create New button.
Select your Vault and add the following scopes:
cards:write
&network-tokens:write

Reference Documentation
Full Service Account Setup Guide
Step 2: Backend – Generate JWT to be used with Collect Form
Your backend must generate a short-lived JWT signed with your service account's private key. This token will be used by the frontend to authenticate to your account during form submission.
Below is a sample ExpressJS server that can be used to generate the JWT.
// sample-agentic-app
// `npm start` to run
const express = require('express');
const axios = require('axios');
const cors = require('cors');
require('dotenv').config();
const app = express();
const PORT = process.env.PORT || 3030;
app.use(cors());
app.use(express.static('public')); // serve frontend
const CLIENT_ID = process.env.VGS_CLIENT_ID;
const CLIENT_SECRET = process.env.VGS_CLIENT_SECRET;
const TOKEN_URL = 'https://auth.verygoodsecurity.com/auth/realms/vgs/protocol/openid-connect/token';
app.get('/get-collect-token', async (req, res) => {
try {
const params = new URLSearchParams();
params.append('client_id', CLIENT_ID);
params.append('client_secret', CLIENT_SECRET);
params.append('grant_type', 'client_credentials');
const response = await axios.post(TOKEN_URL, params);
res.json({ access_token: response.data.access_token });
} catch (error) {
console.error('Error getting VGS token:', error.response?.data || error.message);
res.status(500).json({ error: 'Failed to get token' });
}
});
app.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}`);
});
Step 3: Frontend – Instantiate the Form
Load the VGS Collect library and instantiate the form:
const VAULT_ID = "tntsample"; // replace with your Vault ID
const ENVIRONMENT = "sandbox";
const form = VGSCollect.create(VAULT_ID, ENVIRONMENT, () => { console.log("Form created") });
Reference Documentation
Step 4: Create Form Fields
Use the built-in card field types to render secure, styled input fields:
const VAULT_ID = "tntsample"; // replace with your Vault ID
const ENVIRONMENT = "sandbox";
const form = VGSCollect.create(VAULT_ID, ENVIRONMENT, () => { console.log("Form created") });
const css = {
"vertical-align": "middle",
"white-space": "normal",
"background": "none",
"font-family": "sofia, arial, sans-serif",
"font-size": "16px",
"color": "rgb(34, 25, 36)",
"line-height": "normal",
"padding": "0px 1em",
"box-sizing": "border-box",
"&::placeholder": {
"color": "#6A6A6A"
},
};
form.cardholderNameField('#cardholder-name', { placeholder: 'Jane Doe', css: css });
form.cardNumberField('#card-number', { placeholder: '4111 1111 1111 1111', css: css });
form.cardExpirationDateField('#card-expiration', { placeholder: 'MM / YY', css: css });
form.cardCVCField('#card-cvc', { placeholder: '123', css: css });
Reference Documentation
Step 5: Create a Card
When the user submits the form, call form.createCard(...)
and pass the backend-generated JWT from Step 2 into the createCard function.
document.getElementById('submit-btn').addEventListener('click', async () => {
try {
const res = await fetch('/get-collect-token');
const { access_token } = await res.json();
const response = await form.createCard({
auth: access_token,
data: {
"cardholder": {}
}
},
function (status, card_object) {
alert('Card created. Check your console for the details.');
console.log("Card ID: " + card_object.data.id);
console.log("PAN Alias: " + card_object.data.attributes.pan_alias);
console.log("CVC Alias: " + card_object.data.attributes.cvc_alias);
console.log('Card Object: ', card_object.data);
},
function (e) {
alert('Card creation failed. Check your console for the details.');
console.log("Error", e);
});
} catch (err) {
console.error('Error:', err);
alert('Card creation failed. Check console.');
}
});
Using the Card Object for Payments
The createCard
function will provide a card object to your front-end. Below are the key elements of the card object to use for payments and additional services.
Card ID
This is the main identifier forthe card object. It can be used to reference the card using the card GET endpoint as-needed in the future.
This value will remain constant even if the underlying card details change using card services.
card_object.data.id
PAN Alias
This is a unique token that represents the exact value of the card number (PAN). This value can change when VGS receives an update to the card number using the VGS Account Updater service.
This value can be used with the VGS Outbound Proxy when you wish to share the original PAN with a third-party.
`card_object.data.attributes.pan_alias
CVC Alias
This is a unique token that represents the exact value card number (PAN). This value can be used with the VGS Outbound Proxy when you wish to share the original PAN with a third-party PSP or other payment system. Because the CVC is considered "SAD" (Sensitive Authentication Data) according to PCI-DSS regulations, this value can only be used as a reference for 1 hour.
`card_object.data.attributes.cvc_alias
Expiration Date
The expiration date of the card. This value will be required for issuing PSP tokens and performing payments.
card_object.data.attributes.exp_month
card_object.data.attributes.exp_year
Last updated