> For the complete documentation index, see [llms.txt](https://docs.verygoodsecurity.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.verygoodsecurity.com/vault/developer-tools/vgs-collect/js/index.md).

# Getting Started

VGS Collect.js is a JavaScript library that allows you to securely collect data via any form. Instantly create custom forms that adhere to PCI, HIPAA, GDPR, or CCPA security requirements. VGS intercepts sensitive data before it hits your servers and replaces it with aliased versions while securing the original data in our vault. The form fields behave like traditional forms while preventing access to the unsecured data by injecting secure iframe components.

## Quick Start

The library is easy to integrate; you just need to designate the places where our fields will be inserted and initialize the Collect form in JS.

Let's start! First and foremost, include the JS file in your application.

{% tabs %}
{% tab title="CDN" %}

```
<script type="text/javascript" src="https://js.verygoodvault.com/vgs-collect/4.0.1/vgs-collect.js"></script>
```

{% endtab %}

{% tab title="NPM" %}

```bash
$ npm i @vgs/collect-js
```

{% endtab %}
{% endtabs %}

## Create Form Configuration

1. Navigate to the “Collect Forms” section in the [VGS Dashboard](https://dashboard.verygoodsecurity.com/cmp/o/ACb6FVp4cjGABHDGuEYPFP7U/a/ACTv9FcMEuKRhmK1iMLgV8W2f/collect-forms?env=live).
2. Create a new form and provide a name. The Form ID that is used to instantiate the form will be auto-generated based on this name.
3. [Specify which attributes you want this form to have access to and save the form.](#user-content-fn-1)[^1]

<figure><img src="https://2096104711-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUreALQAfVnRMQEz110rC%2Fuploads%2FKsc5AKbeZvZokOgE8LJM%2Fimage.png?alt=media&amp;token=f038560d-7e55-4f8f-b2ad-8f0f5b20776e" alt=""><figcaption></figcaption></figure>

Alternatively, you can create and manage form configuration using the VGS CLI. [See here.](https://docs.verygoodsecurity.com/vault/developer-tools/vgs-cli/commands#collect-forms)

## Instantiate the Collect Form

```javascript
// Get auth token for VGS with appropriate scopes for form actions
const getVGSAuthToken = async () => {
 const response = await fetch(`https://api.your-auth-server.com/get-vgs-auth`);
 const data = await response.json();
 return data.access_token;
}

const form = await VGSCollect.session({
  vaultId: 'tntYOUR_TENANT_ID',
  env: 'sandbox',
  formId: 'default', // form ID that is in your form configuration
  stateCallback: stateCallback.bind(state),
  authHandler: getVGSAuthToken,
  // error handler if config doesn't load
  onErrorCallback: (error) => {
    console.log(error);
  },
})
```

## Collect Authentication

VGS Collect requires a valid JWT to be provided in order to perform various actions, including creating cards and performing card attribute lookups during card entry.

```bash
vgs generate service-account \
--template public-credential-collect \
--var name=collect \
--tenant tntYOUR_TENANT_ID

vgs apply service-account -O YOUR_ORGANIZATION_ID -f public-credential-collect.yaml
```

## Attach Fields to Collect Form

Once the fields are initialized, VGS Collect.js communicates the state of the fields through a JavaScript callback. The callback returns the current form state as an argument, which contains a lot of useful information about the current field's condition. You can find more information about the form state [here](/vault/developer-tools/vgs-collect/js/reference-documentation.md#state-object).

Finally, create a field instance and configure the submit method.

In order to use our library, it's mandatory to establish an [Inbound connection](/vault/http-proxy/inbound-connection.md) first.

```javascript
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 });
```

## Create Cards

```javascript
document.getElementById('submit-btn').addEventListener('click', async () => {
  e.preventDefault();
  form.createCard(
    {},
    function (status, data) {
      console.log(“success!”)
      console.log(data)
    },
    function (error) {
      console.log(error, "error");
    }
  );
}, false);
```

## Card Collection Example

{% tabs %}
{% tab title="index.html" %}
HTML:

```html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/css/bootstrap.min.css"
    integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
  <link rel="stylesheet" href="./styles.css">
  <title>VGS Card Form</title>
</head>

<body>
  <div class="container pt-4">
    <div class="row">
      <div class="col-md">
        <div>
          <div id="cardholder-name" class="field-wrapper"></div>
        </div>
        <div>
          <div id="card-number" class="field-wrapper"></div>
        </div>
        <div>
          <div id="card-expiration" class="field-wrapper"></div>
        </div>
        <div>
          <div id="card-cvc" class="field-wrapper"></div>
        </div>
        <button id="submit-btn" class="submit-btn">Collect Card</button>
      </div>
    </div>
  </div>

  <script type="text/javascript" src="https://js.verygoodvault.com/vgs-collect/4.0.1/vgs-collect.js"></script>
  <script src="script.js"></script>
</body>

</html>
```

{% endtab %}

{% tab title="script.js" %}

```javascript
// Collect form state handling
const stateCallback = function (state) {
 document.getElementById('state').innerText = JSON.stringify(state, null, '  ');
};

// Get auth token for VGS
const getVGSAuthToken = async () => {
 const response = await fetch(`https://api.customer.com/get-vgs-auth`);
 const data = await response.json();
 return data.access_token;
}

(async () => {
   const form = await VGSCollect.session({
     vaultId: 'tntpguhb8vo',
     env: 'sandbox',
     formId: 'default',
     stateCallback: stateCallback.bind(state),
     authHandler: getVGSAuthToken,
     // error handler if config doesn't load
     onErrorCallback: (error) => {
       console.log(error);
     },
   });
  
   // Getting card attributes (success handler)
   form.on('getCardAttributesSuccess', (lookup) => {
     console.log('getCardAttributesSuccess', lookup)
     buildCardBrandList(lookup.data['card-attributes']['brands']);
   });

   // Getting card attributes (error handler)
   form.on('getCardAttributesError', (errors) => {
     console.log(errors)
   });

   // Fields
   form.cardholderNameField('#cc-name .fake-input', {});
   form.cardNumberField('#cc-number .fake-input', {});
   form.cardExpirationDateField('#cc-exp-date .fake-input', {});
   form.cardCVCField('#cc-cvc .fake-input', {});

   // Submit the form
   document.getElementById('cc-form').addEventListener('submit', function (e) {
     e.preventDefault();
     form.createCard(
       {},
       function (status, data) {
         console.log(“success!”)
         console.log(data)
       },
       function (error) {
         console.log(error, "error");
       }
     );
   }, false);
 })();
```

{% endtab %}

{% tab title="server.js" %}

```javascript
// `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-vgs-auth', 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}`);
});
```

{% endtab %}
{% endtabs %}

#### Using the Card Object for Payments <a href="#using-the-card-object-for-payments" id="using-the-card-object-for-payments"></a>

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.

<table><thead><tr><th width="123.08984375">Name</th><th width="354.1015625"></th><th>JSON Path</th></tr></thead><tbody><tr><td>Card ID</td><td><p>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.</p><p>This value will remain constant even if the underlying card details change using card services.</p></td><td><code>card_object.data.id</code></td></tr><tr><td>PAN Alias</td><td><p>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.</p><p></p><p>This value can be used with the VGS Outbound Proxy when you wish to share the original PAN with a third-party.</p></td><td><code>card_object.data.attributes.pan_alias</code></td></tr><tr><td>CVC Alias</td><td><p>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. </p><p></p><p>Because the CVC is considered "SAD" (Sensitive Authentication Data) according to PCI-DSS regulations, this value can only be used as a reference for 20 minutes.</p></td><td><code>card_object.data.attributes.cvc_alias</code></td></tr><tr><td>Expiration Date</td><td>The expiration date of the card. This value will be required for issuing PSP tokens and performing payments.</td><td><p><code>card_object.data.attributes.exp_month</code> </p><p></p><p><code>card_object.data.attributes.exp_year</code></p></td></tr></tbody></table>

### Browser compatibility

* IE 11, Edge
* Chrome latest
* Firefox latest
* Safari 10+

We're happy to help in case of any issues in a particular browser. Please contact us at <support@vgs.io> and describe your problem so we can investigate it and fix.

#### What's next?

* [Integration guide](/vault/developer-tools/vgs-collect/js/integration.md)
* [Customization](/vault/developer-tools/vgs-collect/js/customization.md)
* [Formatting](/vault/developer-tools/vgs-collect/js/formatting.md)
* [Samples](/vault/developer-tools/vgs-collect/js/samples.md)

[^1]:


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.verygoodsecurity.com/vault/developer-tools/vgs-collect/js/index.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
