# SecureFields JS

## SecureFields JS Overview

SecureFields JS is a hosted field (payment, PII) solution that helps developers provide additional security to a merchant’s website. They are plug-in fields in your platform's "end-user" interface that provide an easy way to securely implement data collection without needing to pass through your systems. SecureFields JS fields are customizable, secure, input elements. When a user enters secure data in these fields, the data is converted into a token/s. The token/s can be used to send the sensitive data to the specified destination.

{% hint style="info" %}
If you are looking for specific commands or options, please see the reference to the developer API specs provided from within your partner portal
{% endhint %}

![](https://2556322805-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MRlN2yYeruyG-6M2wZN%2F-MWgRFU1tTs81hOjqsug%2F-MWgVUG55MgkDWT3ULi-%2FScreen%20Shot%202021-03-25%20at%208.08.49%20PM.png?alt=media\&token=3b713904-4d0c-48ac-ab79-1b8b7b043cbe)

### Advantages of using SecureFields JS

Instantly create customized forms that adhere to PCI and other PII requirements. Our servers intercept the sensitive data before it hits your servers and replaces it with aliased version, while securing the original data in our vault.

The following example shows a rendered payments form using the SecureFields JS to serve the card holder name, card number, expiration date and CVV fields.&#x20;

![](https://2556322805-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MRlN2yYeruyG-6M2wZN%2F-MWh0mvZNi4S71ljbH3k%2F-MWh2ZrKwYYMeRvBqHsc%2FScreen%20Shot%202021-03-25%20at%2010.42.26%20PM.png?alt=media\&token=a3877766-29f5-4806-8493-113db024aa30)

{% hint style="info" %}
**Before you begin**\
You will need your public and private keys from your partner console account.
{% endhint %}

## Implementing SecureField JS

### 1. Add SecureFields JS to your checkout page&#x20;

There are two ways to load SecureFields JS

a. **Option #1** - To add SecureFields JS to your checkout page, include our JavaScript library in your host page:

```markup
<head>
  <script src="https://<payengine-partner-server>/js/wc/js/payengine.min.js?key=<your-public-api-key>"></script>
</head>
```

b. **Option #2** - Alternatively, to load only the SecureField JS library without the web components, include the following JavaScript library in your host page:

```markup
<head>
  <script src="https://<payengine-partner-server>/js/1.0.0/securefields.min.js?key=<your-public-api-key>"></script>
</head>
```

Then copy the following checkout form into the checkout page:

<pre class="language-markup"><code class="lang-markup">&#x3C;form id="cc-form">
  &#x3C;div>
    &#x3C;label>Card Name&#x3C;/label>
    &#x3C;div id="card-name">&#x3C;/div>
  &#x3C;/div>
  &#x3C;div>
    &#x3C;label>Card Number&#x3C;/label>
    &#x3C;div id="card-number">&#x3C;/div>
  &#x3C;/div>
  &#x3C;div>
    &#x3C;label>Expire Date&#x3C;/label>
    &#x3C;div id="card-expiry">&#x3C;/div>
  &#x3C;/div>
  &#x3C;div>
    &#x3C;label>CVC&#x3C;/label>
    &#x3C;div id="card-cvc">&#x3C;/div>
  &#x3C;/div>
  &#x3C;div>
    &#x3C;label>Address Line 1&#x3C;/label>
    &#x3C;div id="address-line1">&#x3C;/div>
  &#x3C;/div>
  &#x3C;div>
    &#x3C;label>Address Line 2&#x3C;/label>
    &#x3C;div id="address-line2">&#x3C;/div>
  &#x3C;/div>
  &#x3C;div>
    &#x3C;label>City&#x3C;/label>
    &#x3C;div id="address-city">&#x3C;/div>
<strong> &#x3C;/div>
</strong>  &#x3C;div>
    &#x3C;label>State&#x3C;/label>
    &#x3C;div id="address-state">&#x3C;/div>
  &#x3C;/div>
   &#x3C;div>
    &#x3C;label>Country&#x3C;/label>
    &#x3C;div id="address-country">&#x3C;/div>
  &#x3C;/div>
  &#x3C;div>
    &#x3C;label>Zip&#x3C;/label>
    &#x3C;div id="cc-zip">&#x3C;/div>
  &#x3C;/div>
  &#x3C;div>
    &#x3C;label>Email&#x3C;/label>
    &#x3C;div id="cc-email">&#x3C;/div>
  &#x3C;/div>
  &#x3C;div>
    &#x3C;label>Country Code&#x3C;/label>
    &#x3C;div id="cc-phonecountrycode">&#x3C;/div>
  &#x3C;/div>
  &#x3C;div>
    &#x3C;label>Phone&#x3C;/label>
    &#x3C;div id="cc-phonenumber">&#x3C;/div>
  &#x3C;/div>
  &#x3C;div>
    &#x3C;button id="btn-create-card">Create Card&#x3C;/button>
  &#x3C;/div>
  &#x3C;pre id="result">Submit to see result.&#x3C;/pre>
&#x3C;/form>
</code></pre>

This will create a very simple (and unstyled) payment form. However, the payment form will not yet contain the fields nor will it be functional. It must first be configured before it can successfully tokenize your payment methods.

{% hint style="warning" %}
**Important:** &#x20;

1. For credit card form, the field ids must match exactly the pre-defined field ids by our system in order for us to tokenize the appropriate data. **`card-name`, `card-number`, `card-expiry`, `card-cvc`**\
   `For general PII data any IDs can be utilized.`
2. Cardholder's address fields - **`address_line1` , `address_line2` , `address_state`, `address_country` , `address_zip`** if you are planning to capture address fields as part of secure fields. \
   \
   But these fields can be captured outside of secure fields too and in that case, these fields should not be included in the above form. Refer to this [section](https://docs.payengine.co/developer-docs/processing-payments/secure-fields#capture-address-outside-secure-fields) on more details
   {% endhint %}

### 2. Initialization

Once the host form is on the page, the fields are initialized with the SecureFields JS module.&#x20;

Place the below snippet in a new script tag on the bottom of your checkout page, swapping out the example environment key with your own:

Note:&#x20;

{% hint style="warning" %}
Note

1. If the merchant enters the credit card information, set the parameter manuallyEntered to true. And on the other hand, if you enter the credit card information, set the parameter manuallyEntered to false
2. To link the created card to a specific merchant, pass the corresponding Platform `merchant_id` in the `merchant_id` parameter. The card will then be restricted to that merchant's use only.
   {% endhint %}

#### Capturing cardholder's billing address fields

There are two ways to capture address fields and send to Platform

1. Capture address fields within the secure fields
2. Capture address fields outside of the secure fields, in your own form and  pass these address fields via createCard

#### 2a. Capture address fields within the secure fields

```javascript
Platform.SecureFields.create().then((form) => {

  // define styles for the fields
  const css = {
    '@font-face': {
      'font-family': 'PT Mono',
      'font-style': 'normal',
      'font-weight': '400',
      'font-display': 'swap',
      'src': 'local("PT Mono"), local("PTMono-Regular") url(https://fonts.gstatic.com/s/ptmono/v7/9oRONYoBnWILk-9AnCszM_HxEcn7Hg.woff2) format("woff2")',
      'unicode-range': 'U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116'
    },
    'font-family': '"PT Mono", monospace',
    boxSizing: "border-box",
    lineHeight: "1.5em",
    border: "#CCC 1px solid",
    color: "#31325F",
    width: "100%",
    height: "36px",
    padding: "0 10px",
    "&::placeholder": {
      color: "#CFD7E0",
    },
  };

  // initialize the iframe fields
  form.field("#card-name", {
    type: "text",
    fontSize: "14px",
    fontWeight: "200",
    name: "card_holder",
    placeholder: "Card holder",
    validations: ["required"],
    css,
  });
  form.field("#card-number", {
    type: "card-number",
    name: "card_number",
    successColor: "#4F8A10",
    errorColor: "#D8000C",
    placeholder: "Card number",
    showCardIcon: true,
    validations: ["required", "validCardNumber"],
    validCardBrands: [{type:'visa'}, {type:'mastercard'}, {type:'discover'}],//Optional field
    validCardTypes: ["credit"], // Optional field - Supported values - credit, debit, prepaid, gift
    cardTypeErrorMessage: "Only credit cards are accepted", 
    css,
  });
  form.field("#card-cvc", {
    type: "card-security-code",
    name: "card_cvc",
    successColor: "#4F8A10",
    errorColor: "#D8000C",
    placeholder: "CVC",
    maxLength: 3,
    validations: ["required", "validCardSecurityCode"],
    css,
  });
  form.field("#card-expiry", {
    type: "card-expiration-date",
    name: "card_exp",
    successColor: "#4F8A10",
    errorColor: "#D8000C",
    placeholder: "MM / YY",
    validations: ["required", "validCardExpirationDate"],
    css,
  });
 form.field("#address-line1", {
    type: "text",
    name: "address_line1",
    successColor: "#4F8A10",
    errorColor: "#D8000C",
    placeholder: "Address Line1",
    validations: ["required"],
    css,
  });
  form.field("#address-line2", {
    type: "text",
    name: "address_line2",
    placeholder: "Address Line2",
    css,
  });
 form.field("#address-city", {
    type: "text",
    name: "address_city",
    placeholder: "City",
    validations: ["required"],
    css,
  });
  form.field("#address-state", {
    type: "text",
    name: "address_state",
    placeholder: "State",
    validations: ["required"],
    css,
  });
  form.field("#address-country", {
    type: "text",
    name: "address_country",
    placeholder: "Country",
    validations: ["required"],
    css,
  });
  form.field("#cc-zip", {
    type: "zip-code",
    name: "address_zip",
    successColor: "#4F8A10",
    errorColor: "#D8000C",
    placeholder: "Zip Code",
    validations: ["postal_code/us,ca"],
    css,
  });
  
  // Email or Phone number is required only for Visa 3DS
 
  // Cardholder Email
  form.field("#cc-email", {
    type: "email",
    name: "email",
    successColor: "#4F8A10",
    errorColor: "#D8000C",
    placeholder: "Email",
    css,
  });
  // Country Code for Phone Number
  form.field("#cc-phonecountrycode", {
    type: "phone-number-cc",
    name: "phone_number.cc",
    successColor: "#4F8A10",
    errorColor: "#D8000C",
    placeholder: "CC",
    css,
  });
  // Phone Number
  form.field("#cc-phonenumber", {
    type: "phone-number-subscriber",
    name: "phone_number.subscriber",
    successColor: "#4F8A10",
    errorColor: "#D8000C",
    placeholder: "Subscriber",
    css,
  });

  // attach a listener to the action button
  document.getElementById('btn-create-card').addEventListener("click", async (e) => {
    e.preventDefault();
    try {
      const cardObj = await form.createCard({
        merchant_id: <merchant_id>, // if the token created need to linked to a specific merchant
        manuallyEntered: true,
        store_payment_method: false // this is optional field and set it to false only if the created token should not be stored
      });
      console.log("data", cardObj);
      // for general purpose tokenization call await form.secureFields();
      document.getElementById("result").innerHTML = JSON.stringify(cardObj, null, 4);
    } catch (e) {
      console.log("error", e);
      document.getElementById("result").innerHTML = JSON.stringify(e);
    }
  });
  
});
```

{% hint style="warning" %}
**Note:**&#x20;

1. If the token is intended for use with a **specific merchant**, include `merchant_id` when creating the token. If `merchant_id` is not provided, the card token can be used across merchants in your portfolio.
2. When creating a card, set `store_payment_method` to `false` only if the card should **not** be stored for future use. If `store_payment_method` is not provided, it defaults to `true`.
3. **validCardBrands** *(**optional**)*: accepted values are **visa, mastercard, discover, amex**. Use this to block specific card brands from being accepted. Default is to accept all card brands if this field is not provided
   1. **Default behavior:** if `validCardBrands` is **not provided**, the system **accepts all card brands**.
4. **validCardTypes** *(**optional**)*: accepted values are **credit, debit, gift, prepaid**. Use this to block specific card types from being accepted.&#x20;
   1. **Default behavior:** if `validCardtypes` is **not provided**, the system **accepts all card types**
   2. **Custom error messaging** (two options):
      * **One fallback message:** `cardTypeErrorMessage` *(singular)* applies to all blocked card types.
        * **Type-specific messages:** `cardTypeErrorMessages` *(plural)* provides per-card-type messages when that type isn’t accepted.
      1. ```
             cardTypeErrorMessages: {
                     debit: "Debit cards are not allowed",
                     prepaid: "Prepaid cards are not allowed",
                     gift: "Gift cards are not allowed",
                     default: "This card type is not accepted"
                 }
         ```

{% endhint %}

#### 2b. Capture address fields outside of secure fields, in your own form and you can pass the address info via createCard <a href="#capture-address-outside-secure-fields" id="capture-address-outside-secure-fields"></a>

In this scenario, you will capture the address fields in your own form and provide those values in the form.createCard function as shown below

```javascript
Platform.SecureFields.create().then((form) => {

  // define styles for the fields
  const css = {
    '@font-face': {
      'font-family': 'PT Mono',
      'font-style': 'normal',
      'font-weight': '400',
      'font-display': 'swap',
      'src': 'local("PT Mono"), local("PTMono-Regular") url(https://fonts.gstatic.com/s/ptmono/v7/9oRONYoBnWILk-9AnCszM_HxEcn7Hg.woff2) format("woff2")',
      'unicode-range': 'U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116'
    },
    'font-family': '"PT Mono", monospace',
    boxSizing: "border-box",
    lineHeight: "1.5em",
    border: "#CCC 1px solid",
    color: "#31325F",
    width: "100%",
    height: "36px",
    padding: "0 10px",
    "&::placeholder": {
      color: "#CFD7E0",
    },
  };

  // initialize the iframe fields
  form.field("#card-name", {
    type: "text",
    fontSize: "14px",
    fontWeight: "200",
    name: "card_holder",
    placeholder: "Card holder",
    validations: ["required"],
    css,
  });
  form.field("#card-number", {
    type: "card-number",
    name: "card_number",
    successColor: "#4F8A10",
    errorColor: "#D8000C",
    placeholder: "Card number",
    showCardIcon: true,
    validations: ["required", "validCardNumber"],
    validCardBrands: [{type:'visa'}, {type:'mastercard'}, {type:'discover'}],//Optional field
    validCardTypes: ["credit"], // Optional field - Supported values - credit, debit, prepaid, gift
    cardTypeErrorMessage: "Only credit cards are accepted", 
    css,
  });
  form.field("#card-cvc", {
    type: "card-security-code",
    name: "card_cvc",
    successColor: "#4F8A10",
    errorColor: "#D8000C",
    placeholder: "CVC",
    maxLength: 3,
    validations: ["required", "validCardSecurityCode"],
    css,
  });
  form.field("#card-expiry", {
    type: "card-expiration-date",
    name: "card_exp",
    successColor: "#4F8A10",
    errorColor: "#D8000C",
    placeholder: "MM / YY",
    validations: ["required", "validCardExpirationDate"],
    css,
  });
  
  // Email or Phone number is required only for Visa 3DS
  // Cardholder Email
  form.field("#cc-email", {
    type: "email",
    name: "email",
    successColor: "#4F8A10",
    errorColor: "#D8000C",
    placeholder: "Email",
    css,
  });
  // Country Code for Phone Number
  form.field("#cc-phonecountrycode", {
    type: "phone-number-cc",
    name: "phone_number.cc",
    successColor: "#4F8A10",
    errorColor: "#D8000C",
    placeholder: "CC",
    css,
  });
  // Phone Number
  form.field("#cc-phonenumber", {
    type: "phone-number-subscriber",
    name: "phone_number.subscriber",
    successColor: "#4F8A10",
    errorColor: "#D8000C",
    placeholder: "Subscriber",
    css,
  });

  // attach a listener to the action button
  document.getElementById('btn-create-card').addEventListener("click", async (e) => {
    e.preventDefault();
    try {
      const cardObj = await form.createCard({
        merchant_id: <merchant_id>, // if the created card need to linked to a specific merchant
        manuallyEntered: true,
        address_line1: "line1",
        address_line2: "line2",
        address_city: "city",
        address_state: "CA",
        address_zip: "91205",
        address_country: "US"
      });
      console.log("data", cardObj);
      // for general purpose tokenization call await form.secureFields();
      document.getElementById("result").innerHTML = JSON.stringify(cardObj, null, 4);
    } catch (e) {
      console.log("error", e);
      document.getElementById("result").innerHTML = JSON.stringify(e);
    }
  });
  
});
```

{% hint style="info" %}
Following sections are only applicable if you're tokenizing card data for payments. For general PII information, please refer to [using-tokens](https://docs.payengine.co/developer-docs/processing-payments/secure-fields/using-tokens "mention") .
{% endhint %}

{% hint style="warning" %}
**Visa 3D Secure Update: Action Required**\
Partners must collect cardholder's mobile number OR email address during payment processing by January 20, 2025. Update existing tokens with this information before use (refer step 3 below for tokenizing payment details)\
See [Visa Secure Program Guide Updates](https://support.visaacceptance.com/knowledgebase/knowledgearticle/?code=KA-04583) for details. Contact Platform support with any questions you have.
{% endhint %}

### 3. Tokenize payment details&#x20;

{% hint style="info" %}
Depending on your account configuration, your tokenized card info can be made available as global or merchant specific.
{% endhint %}

Note from the example code above that SecureFields JS doesn’t automatically hook into any form events. Instead, you must explicitly tell it when you want to send the collected card data for tokenization.

As shown in the example above, the most straightforward approach is to create a form onSubmit handler or an element `eventListener` that serves as a trigger to delegate to SecureFields JS `createCard()` method.  This method will in turn return the tokenized card object that you can safely store within your system.

{% hint style="info" %}
When automatic [Network Tokenization](https://docs.payengine.co/developer-docs/tokenization/automatic-network-tokenization) is activated on your account, any PAN data associated with it will automatically use a token provided by the card brand network.
{% endhint %}

### 4. Executing an auth transaction

After the SecureFields JS tokenizes your payment method, it is up to you to execute the actual transaction from your backend server environment. This is necessary because the browser is not a secure environment and should never contain your access secret (which is required to invoke the transactional portion of our API).

When the checkout form is submitted, extract the `token` parameter and use it to execute an auth and capture using the direct APIs:

```bash
curl https://<payengine-partner-server>/api/payment/auth \
  -H 'Authorization: Basic <partner_private_token>' \
  -H 'Content-Type: application/json' \
  -d '{
      "merchant_id": "YOUR_MERCHANT_ID",
      "data": {
              "transactionAmount": "109",
              "cardToken": "token_sanbox_2ljk534jh5v3h456klj245",
              "currency_code": "USD"
              }
      }'
```

The above call will authorize a payment method to be charged a specific amount and return an authorization id. No funds are taken with an auth – a follow-up capture transaction is required to actually move the funds.

### 5. Executing a capture transaction&#x20;

To capture the amount, you must next call the capture API endpoint

```bash
curl https://<payengine-partner-server>/api/payment/capture \
  -H 'Authorization: Basic <partner_private_token>' \
  -H 'Content-Type: application/json' \
  -d '{
      "id": "<authorization_id>",
      "data": {
              "transactionAmount": "109",
              "tip": "1"
              }
      }'
```

{% hint style="info" %}
the `amount` and `currency_code` are optional fields within the capture call if a partial capture is desired.
{% endhint %}

At this point, you should be able to see the posted transactions via the merchant's transactions page available via your partner portal.

### 6. Refund the transaction&#x20;

To refund the amount, void or reverse the transaction you must make next call

```bash
curl https://<payengine-partner-server>/api/payment/return\
  -H 'Authorization: Basic <partner_private_token>' \
  -H 'Content-Type: application/json' \
  -d '{
      "id": "<authorization_id>",
      "data": {
              "transactionAmount": "109",
              "tip": "1"
              }
      }'
```

### Implementing CSS for secure fields

To customize the appearance of secure fields in your payment form, you can add CSS to style them according to your needs. Here's a sample CSS snippet:

<pre class="language-html"><code class="lang-html">&#x3C;html>

&#x3C;head>
    &#x3C;script
        src="https://console.payengine.co/js/1.0.0/securefields.min.js?key=pk_test_6tMrSVLiijTsqCQm3Xv6vZB91mbzQEGy">&#x3C;/script>
    &#x3C;style>
        #cc-form .field {
            display: block;
            box-sizing: border-box;
            width: 100%;
            height: 2.25rem;
            padding: 0.375rem 0.75rem;
            font-size: 1rem;
            line-height: 1.5;
            color: #495057;
            background-color: #fff;
            background-clip: padding-box;
            border: 1px solid #ced4da;
            border-radius: 0.25rem;
            transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
        }
        #cc-form .field iframe {
            border: 0 none transparent;
            height: 100%;
            vertical-align: middle;
            width: 100%;
        }
    &#x3C;/style>
&#x3C;/head>

&#x3C;body>
    &#x3C;form id="cc-form">
        &#x3C;div>
            &#x3C;label>Card Name&#x3C;/label>
            &#x3C;div id="card-name" class="field">&#x3C;/div>
        &#x3C;/div>
        &#x3C;div>
            &#x3C;label>Card Number&#x3C;/label>
            &#x3C;div id="card-number" class="field">&#x3C;/div>
        &#x3C;/div>
        &#x3C;div>
            &#x3C;label>Expire Date&#x3C;/label>
            &#x3C;div id="card-expiry" class="field">&#x3C;/div>
        &#x3C;/div>
        &#x3C;div>
            &#x3C;label>CVC&#x3C;/label>
            &#x3C;div id="card-cvc" class="field">&#x3C;/div>
        &#x3C;/div>
        &#x3C;div>
            &#x3C;label>ZIP&#x3C;/label>
            &#x3C;div id="cc-zip" class="field">&#x3C;/div>
        &#x3C;/div>
        &#x3C;div>
            &#x3C;label>Email&#x3C;/label>
            &#x3C;div id="cc-email" class="field">&#x3C;/div>
        &#x3C;/div>
        &#x3C;div>
            &#x3C;label>Country Code&#x3C;/label>
            &#x3C;div id="cc-phonecountrycode" class="field">&#x3C;/div>
        &#x3C;/div>
        &#x3C;div>
            &#x3C;label>Phone&#x3C;/label>
            &#x3C;div id="cc-phonenumber" class="field">&#x3C;/div>
        &#x3C;/div>
        &#x3C;div>
            &#x3C;button id="btn-create-card">Create Card&#x3C;/button>
        &#x3C;/div>
        &#x3C;pre id="result">Submit to see result.&#x3C;/pre>
    &#x3C;/form>
    &#x3C;script>
        Platform.SecureFields.create().then((form) => {

            // define styles for the fields
            const css = {
                '@font-face': {
                    'font-family': 'PT Mono',
                    'font-style': 'normal',
                    'font-weight': '400',
                    'font-display': 'swap',
                    'src': 'local("PT Mono"), local("PTMono-Regular") url(https://fonts.gstatic.com/s/ptmono/v7/9oRONYoBnWILk-9AnCszM_HxEcn7Hg.woff2) format("woff2")',
                    'unicode-range': 'U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116'
                },
                'font-family': '"PT Mono", monospace',
                boxSizing: "border-box",
                color: "#31325F",
                "&#x26;::placeholder": {
                    color: "#CFD7E0",
                },
            };

            // initialize the iframe fields
            form.field("#card-name", {
                type: "text",
                fontSize: "14px",
                fontWeight: "200",
                name: "card_holder",
                placeholder: "Card holder",
                validations: ["required"],
                css,
            });
<strong>            form.field("#card-number", {
</strong>                type: "card-number",
                name: "card_number",
                successColor: "#4F8A10",
                errorColor: "#D8000C",
                placeholder: "Card number",
                showCardIcon: true,
                validations: ["required", "validCardNumber"],
                css,
            });
            form.field("#card-cvc", {
                type: "card-security-code",
                name: "card_cvc",
                successColor: "#4F8A10",
                errorColor: "#D8000C",
                placeholder: "CVC",
                maxLength: 3,
                validations: ["required", "validCardSecurityCode"],
                css,
            });
            form.field("#card-expiry", {
                type: "card-expiration-date",
                name: "card_exp",
                successColor: "#4F8A10",
                errorColor: "#D8000C",
                placeholder: "MM / YY",
                validations: ["required", "validCardExpirationDate"],
                css,
            });
            form.field("#cc-zip", {
                type: "zip-code",
                name: "address_zip",
                successColor: "#4F8A10",
                errorColor: "#D8000C",
                placeholder: "Zip Code",
                validations: ["postal_code/us,ca"],
                css,
            });
            
          // Email or Phone number is required only for Visa 3DS
             
          // Cardholder Email
            form.field("#cc-email", {
                type: "email",
                name: "email",
                successColor: "#4F8A10",
                errorColor: "#D8000C",
                placeholder: "Email",
                css,
            });
          // Country Code for Phone Number
            form.field("#cc-phonecountrycode", {
                type: "phone-number-cc",
                name: "phone_number.cc",
                successColor: "#4F8A10",
                errorColor: "#D8000C",
                placeholder: "CC",
                css,
             });
          // Phone Number
              form.field("#cc-phonenumber", {
                type: "phone-number-subscriber",
                name: "phone_number.subscriber",
                successColor: "#4F8A10",
                errorColor: "#D8000C",
                placeholder: "Subscriber",
                css,
              });

         
     // attach a listener to the action button
            document.getElementById('btn-create-card').addEventListener("click", async (e) => {
                e.preventDefault();
                try {
                    console.log("form.createCard",form)
                    console.log("form.createCard",form.createCard)
                    const cardObj = await form.createCard({
                        manuallyEntered: true
                    });
                    console.log("data", cardObj);
                    // for general purpose tokenization call await form.secureFields();
                    document.getElementById("result").innerHTML = JSON.stringify(cardObj, null, 4);
                } catch (e) {
                    console.log("error", e);
                    document.getElementById("result").innerHTML = JSON.stringify(e);
                }
            });

        });
    &#x3C;/script>
&#x3C;/body>

&#x3C;/html>
</code></pre>

### SecureFields' API

#### **form.on(event, callback)**

Listen to events that's related to the whole form state

| Parameter | Type     | Description                                              |
| --------- | -------- | -------------------------------------------------------- |
| event     | string   | Event type. Supported events are `ready`and `enterPress` |
| callback  | function | A function to execute each time the event is triggered   |

{% tabs %}
{% tab title="Example code" %}

```javascript
function onEnterPress() {
    // submit form
}

form.on("ready", function() {
    // hide loading state
});

form.on("enterPress", onEnterPress);
```

{% endtab %}
{% endtabs %}

#### form.off(event, callback)

Unsubscribe from the form event listeners

| Parameter | Type     | Description                                              |
| --------- | -------- | -------------------------------------------------------- |
| event     | string   | Event type. Supported events are `ready`and `enterPress` |
| callback  | function | A function to execute each time the event is triggered   |

{% tabs %}
{% tab title="Example code" %}

```javascript
form.off("enterPress", onEnterPress);
```

{% endtab %}
{% endtabs %}

#### form.reset()

Reset the form state and its values

{% tabs %}
{% tab title="Example code" %}

```
form.reset()
```

{% endtab %}
{% endtabs %}
