# iFields

## Overview <a href="#overview" id="overview"></a>

iFields is a Sola technology that integrates into your payment forms, giving you the ability to design and customize the look and feel of your payment and checkout flows without having to worry about PCI compliance.

Payment forms that leverage iFields technology keep sensitive card data away from merchant servers,  keeping you outside of PCI compliance territory. Information that's entered into the standard card number and CVV input fields are sent directly to the Sola gateway via iframes. The gateway immediately returns SUTs (single-use tokens,  also referred to as payment nonces) in place of the card and CVV numbers, that are used by the server-side code for processing the transaction.\
\
Here is an example of how the iframes work, and the SUTs they return.

## Workflow <a href="#workflow" id="workflow"></a>

Let's get started by understanding the difference between how card information flows through an API-only integration versus one that utilizes iFields.

### API-Only <a href="#api-only" id="api-only"></a>

* The customer enters the credit card information into an `<input>` field on the website checkout page, submitting the data to the website server.
* The server sends an HTTP POST request with the transaction information to the Sola gateway for processing using the Sola API.
* Sola sends the response back through the server, which forwards it and displays it on the website.

See [Transaction API - Request Method](https://docs.cardknox.com/api/transaction) for more information about request methods.

![](https://2242410501-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbdKiWuld-TceAgWrgh%2F-Mguu6poV5raOHzD-nV9%2F-MguuczhtODXlwfBHQuJ%2FIllustration-flow-0620-1.png?alt=media\&token=1b789267-3c6f-4010-95aa-ddce8a166fec)

### API and iFields <a href="#api-and-ifields" id="api-and-ifields"></a>

* The customer enters the credit card information into an `<iframe>` field on the website checkout page, submitting the data to Cardknox CDN.
* Sola CDN returns the single-use token (SUT) into a hidden `<input>` field of the website checkout page, which submits the data to the website server.
* The server sends an HTTP POST request with the transaction information to the Sola gateway for processing using the Sola API with the SUT as xCardNum.
* Sola sends the response back through the server, which forwards and displays it on the website. Sola gateway includes an xToken in the response, enabling the merchant to use the xToken to send in any future transactions for that customer.

See [Transaction API - Tokenization](https://docs.cardknox.com/api/transaction#tokenization) for more information about tokenization.

![](https://2242410501-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbdKiWuld-TceAgWrgh%2F-Mguu6poV5raOHzD-nV9%2F-MguvUJ938cGqpwqdcnf%2FIllustration-flow2-0620-1.png?alt=media\&token=24445194-9c6a-4d78-9cd3-64c052e630df)

## Getting Started <a href="#overview" id="overview"></a>

To use iFields, you’ll need two Sola keys:\
1\. Your iFields key, which is the public-facing key used in the Javascript\
2\. Your private Sola merchant key

**The Sola iFields key (public-facing key) is for the client-side transaction.**\
**The Sola transaction key is for the server-side transaction.**

**Important note**\
The iFields solution accomplishes the goal of generating a SUT in place of the card number that will then be sent to your server.  A transaction cannot be processed with iFields alone. Once your server obtains the SUT, you'll need to use our Transaction API to send a server-side command to process a transaction. The card number SUT should be sent as `"xCardNum"` and the CVV SUT should be sent as `"xCVV"`.\
See [Transaction API](https://docs.solapayments.com/api/transaction) for the server-side commands.

## Frameworks <a href="#initiate-ifields" id="initiate-ifields"></a>

If you use one of the following frameworks, you can set up the iFields integration more easily:

[Npm: React](https://www.npmjs.com/package/@cardknox/react-ifields)\
[Npm: Angular](https://www.npmjs.com/package/@cardknox/angular-ifields)\
[Npm: Vue](https://www.npmjs.com/package/@cardknox/vue-cardknox-ifields)

## Initiate iFields <a href="#initiate-ifields" id="initiate-ifields"></a>

[See Full Working Example](https://codepen.io/cardknox/pen/Bajdzvv)

### Step 1 <a href="#step-1" id="step-1"></a>

Find the latest version of iFields at: <https://cdn.cardknox.com/ifields/versions.htm>

Add the Cardknox JS file after the \<head> tag on your payment page:

```markup
<script src="https://cdn.cardknox.com/ifields/**ifields-version-number**/ifields.min.js" />
```

Then, add the `setAccount()` function with the three required parameters which should be called on page load:

| **Parameter**    | **Description**                                                                                                                                                                                                                                                                            |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| iFields key      | <p>Your iFields key<br>Use the iFields key that matches the account that you will submit the transaction to. Ensure you are using the correct key as this does not get validated on the front end.<br><strong>Attention:</strong> Do NOT use your API key here, as it will be exposed.</p> |
| Software name    | Name of your software                                                                                                                                                                                                                                                                      |
| Software version | Version number of your software                                                                                                                                                                                                                                                            |

```
setAccount("iFields key", "Software name", "Software version")
```

### Step &#x32;**:** HTML <a href="#step-2-html" id="step-2-html"></a>

In addition to the standard fields necessary for non-sensitive card data, the html should include four additional fields for the form; two fields for the credit card number; and two for the CVV. The first set of fields are iFrame fields to collect the sensitive information, and the second set are hidden input fields that are populated with the SUTs once they are returned by the gateway.

Adding the fields:

First, add these three fields to your form to collect the sensitive card data:

```markup
<iframe data-ifields-id="ach" data-ifields-placeholder="Checking Account Number" src="https://cdn.cardknox.com/ifields/**ifields-version-number**/ifield.htm"></iframe> 
<iframe data-ifields-id="card-number" data-ifields-placeholder="Card Number" src="https://cdn.cardknox.com/ifields/**ifields-version-number**/ifield.htm"></iframe> 
<iframe data-ifields-id="cvv" data-ifields-placeholder="CVV" src="https://cdn.cardknox.com/ifields/**ifields-version-number**/ifield.htm" ></iframe>
```

**Attention: Be sure to replace the \*\*ifields-version-number\*\* text with the appropriate iFields version number. Get the latest version of iFields at** [**https://cdn.cardknox.com/ifields/versions.htm**](https://cdn.cardknox.com/ifields/versions.htm)**.**

Next, add the following two fields that will be populated with the SUTs once the gateway returns them:

```markup
<input name="xACH" data-ifields-id="ach-token" type="hidden" /> 
<input name="xCVV" type="hidden" data-ifields-id="cvv-token" /> 
<input name="xCardNum" type="hidden" data-ifields-id="card-number-token" />
```

Finally, add this field for error handling:

```markup
<label data-ifields-id="card-data-error" style="color: red;"></label>
```

Full Sample HTML:

```javascript
<head>
    <script src="https://cdn.cardknox.com/ifields/**ifields-version-number**/ifields.min.js" />
</head>
<body>
     
<form id=”payment-form”>
        <iframe data-ifields-id="ach" data-ifields-placeholder="Checking Account Number" src="https://cdn.cardknox.com/ifields/**ifields-version-number**/ifield.htm"></iframe>
        <input data-ifields-id="ach-token" name="xACH" type="hidden" />
        <iframe data-ifields-id="card-number" data-ifields-placeholder="Card Number" src="https://cdn.cardknox.com/ifields/**ifields-version-number**/ifield.htm"></iframe>
        <input data-ifields-id="card-number-token" name="xCardNum" type="hidden" >
        <iframe data-ifields-id="cvv" data-ifields-placeholder="CVV" src="https://cdn.cardknox.com/ifields/**ifields-version-number**/ifield.htm" ></iframe>
        <input data-ifields-id="cvv-token" name="xCVV" type="hidden" >
 
        <!--And a field for all errors from the iFields-->
        <label id="transaction-status"></label>
        <label data-ifields-id="card-data-error" style="color: red;"></label>
 
        <!--Submit button-->
        <input id="submit-btn" type="submit" value="Submit">
    </form>
 
</body>
```

### Step 3: JavaScript <a href="#step-3-js" id="step-3-js"></a>

Attach an event listener to submit event of the form (in our example #payment-form) that contains the following:

A call to the `getTokens()` function that will pass in a callback to receive the SUTs and populate the hidden fields with them, and then submit the form with all the transaction details to your server-side code for processing. For a full list of server-side calls, see our [API docs](https://kb.cardknox.com/api).

```javascript
setAccount("your-public-facing-key", "your-software-name", "0.1.2");
document.getElementById('payment-form').addEventListener('submit', function(e){
    e.preventDefault();
    var submitBtn = document.getElementById('submit-btn');
    submitBtn.disabled = true;
    getTokens(
        function() { 
            document.getElementById('payment-form').submit();
        },
        function() { //onError
            submitBtn.disabled = false;
        },
        30000, //30 second timeout
    );
});
```

### 3D Secure Authentication with iFields <a href="#ifields-with-3d-secure-authentication" id="ifields-with-3d-secure-authentication"></a>

(Available starting in version 2.14)

Enhance your payment security and protect against fraud by enabling **3D Secure Authentication (3DS)** in your iFields integration. This requires both **client-side** and [**server-side**](https://docs.solapayments.com/api/transaction/3ds) handling.

#### Step 1: Enable 3D Secure on the Client Side <a href="#step-1-enable-3d-secure-on-the-client-side" id="step-1-enable-3d-secure-on-the-client-side"></a>

Call the `enable3DS()` function during page load to initialize 3DS. This function takes two required parameters:

**Function**: `enable3DS(environment, verifyHandler)`

**Parameters:**

| **Parameter** | **Type** | **Description**                                                                                                                                                                                                                                | **Required?** |
| ------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| environment   | String   | Use staging for testing or production for live implementations.                                                                                                                                                                                | Y             |
| verifyHandler | Function | Callback function that handles the 3DS result and sends it to your server. Your server should finalize the transaction by submitting the 3DS result to our API. See [**server-side**](https://docs.solapayments.com/api/transaction/3ds) code. | Y             |

**`verifyHandler` Callback**

When the 3DS challenge popup completes, the `verifyHandler` function is triggered with these parameters:

| **Parameter**                   | **Description**                               |
| ------------------------------- | --------------------------------------------- |
| x3dsActionCode                  | The 3DS action code result.                   |
| xCavv                           | Cardholder Authentication Verification Value. |
| xEci                            | Electronic Commerce Indicator.                |
| xRefNum                         | Transaction reference number.                 |
| x3dsAuthenticationStatus        | Status of the authentication attempt.         |
| x3dsSignatureVerificationStatus | Result of the digital signature verification. |

**Sample code:**

{% code lineNumbers="true" %}

```javascript
// Enable 3D Secure (3DS)
enable3DS('staging', verifyHandler); // or 'production'

function verifyHandler(x3dsActionCode, xCavv, xEci, xRefNum, x3dsAuthenticationStatus, x3dsSignatureVerificationStatus) {
    // Prepare authentication result data
    const postData = {
        x3dsActionCode,
        xCavv,
        xEci,
        xRefNum,
        x3dsAuthenticationStatus,
        x3dsSignatureVerificationStatus
    };

    // Send to your server and finalize the transaction
}
```

{% endcode %}

See [**server-side**](https://docs.solapayments.com/api/transaction/3ds) code how to finalize the transaction.

#### Step 2: Check Server Response for 3DS Challenge <a href="#step-2-check-server-response-for-3ds-challenge" id="step-2-check-server-response-for-3ds-challenge"></a>

After submitting a payment to the [transaction API](https://docs.solapayments.com/api/transaction), the response will include an `xResult` value that indicates the status:

`A`**,** `E`**, or** `D` — Transaction complete. No further 3DS action is needed.

`V` — A 3DS challenge is required. You must initiate the challenge step by calling `verify3DS()`.

In a case where the **xResult** is **V**, 3D Secure authentication must be completed through a challenge popup. To proceed, call the `verify3DS()` function and pass the entire transaction response object.

#### `verify3DS(transactionResponse)` <a href="#verify3ds-transactionresponse" id="verify3ds-transactionresponse"></a>

| Parameter           | Type   | Description                                                          |
| ------------------- | ------ | -------------------------------------------------------------------- |
| transactionResponse | Object | The full transaction response from your initial server-side request. |

**Sample Code**:

```
if (transactionResponse.xResult === 'V') {
    // Triggers the 3DS challenge popup
    verify3DS(transactionResponse);
} else {
    // No additional 3DS action needed
    console.log("Transaction complete.");
}
```

## iFields Features <a href="#ifield-features" id="ifield-features"></a>

### Setting iFields Styles <a href="#setting-ifield-styles" id="setting-ifield-styles"></a>

Added in version 2.2\
A style can be set for each iFields by calling the `setIfieldStyle()` function and passing in the `data-ifields-id` value (card-number or cvv) and the JSON with the styles to set.<br>

Each field can be given its own style or use a shared variable to set them all to look the same.

\
**Parameters:**

| **Parameter** | **Description**                                                            | **Required?** |
| ------------- | -------------------------------------------------------------------------- | ------------- |
| iFieldName    | The name of the iFields to style (valid names are ‘card-number’ or ‘cvv’). | Y             |

\
**Sample Code:**

```markup
let style = {
    border: '1px solid black',
    font-size: '14px',
    padding: '3px',
    width: '250px'
};
setIfieldStyle('card-number', style);
setIfieldStyle('cvv', style);
```

### Clear iFields <a href="#clear-ifield" id="clear-ifield"></a>

Added in version 2.2\
You can clear the data inside an iFields by calling clearIfield(ifieldName).

\
**Parameters:**

| **Parameter** | **Description**                                                            | **Required?** |
| ------------- | -------------------------------------------------------------------------- | ------------- |
| ifieldName    | The name of the iFields to style (valid names are ‘card-number’ or ‘cvv’). | Y             |

\
**Sample Code:**

```markup
cleariField(‘cvv’);
```

### Auto Format iFields Data <a href="#auto-format-ifield-data" id="auto-format-ifield-data"></a>

Added in version 2.3\
You can allow auto-formatting of the data in the card number field by calling `enableAutoFormat(separator)`.

\
**Parameters:**

| **Parameter** | **Description**                                                                                                                                                  | **Required?** |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| Separator     | This is the separation character to place between number groups. The default separator is a space. Only a single character should be passed in as the separator. | N             |

\
**Sample Code:**

```javascript
enableAutoFormatting(‘-‘); will show 4444-3333-2222-1111
```

### Focus iFields <a href="#focus-ifield" id="focus-ifield"></a>

Added in version 2.3\
You can set focus on an iFields. A common use case for this is if you want the iframes to be focused after page load.<br>

**Paramaters:**

| **Parameter** | **Description**                                                            | **Required?** |
| ------------- | -------------------------------------------------------------------------- | ------------- |
| iFieldName    | The name of the iFields to style (valid names are ‘card-number’ or ‘cvv’). | Y             |

\
**Sample Code:**

```javascript
focusIfield(‘card-number’);
```

### iFields Key Pressed Callback <a href="#ifield-key-pressed-callback" id="ifield-key-pressed-callback"></a>

*Added in version 2.3*<br>

You can create a reaction to the changing of data in the iFields as the user types by registering a callback using `addiFieldKeyPressCallback(callbackFunction)`. The callback function can accept a parameter that passes in a JSON object. That object contains non-sensitive information about the data contained in the iFields, such as the validity of the card number/CVV; the length of the data entered; the issuer of the entered card number; and which iFields last had text entered into it. This function can be called multiple times to add multiple callbacks.

\
**Parameters:**

| **Parameter**    | **Description**                                               | **Required?** |
| ---------------- | ------------------------------------------------------------- | ------------- |
| callbackFunction | The function to call after the text in an iFields is changed. | Y             |

\
**Sample Code:**

```javascript
addIfieldKeyPressCallback(function(data) {
    console.log('card number is ' + (data.cardNumberIsValid ? 'valid' : 'invalid');
});
```

```javascript
addIfieldKeyPressCallback(function(data) {
                    setIfieldStyle('card-number', data.cardNumberFormattedLength <= 0 ? defaultStyle : data.cardNumberIsValid ? validStyle : invalidStyle);
                    if (data.lastIfieldChanged === 'cvv'){
                        setIfieldStyle('cvv', data.issuer === 'unknown' || data.cvvLength <= 0 ? defaultStyle : data.cvvIsValid ? validStyle : invalidStyle);
                    } else if (data.lastIfieldChanged === 'card-number') {
                        if (data.issuer === 'unknown' || data.cvvLength <= 0) {
                            setIfieldStyle('cvv', defaultStyle);
                        } else if (data.issuer === 'amex'){
                            setIfieldStyle('cvv', data.cvvLength === 4 ? validStyle : invalidStyle);
                        } else {
                            setIfieldStyle('cvv', data.cvvLength === 3 ? validStyle : invalidStyle);
                        }
                    } else if (data.lastIfieldChanged === 'ach') {
                        setIfieldStyle('ach',  data.achLength === 0 ? defaultStyle : data.achIsValid ? validStyle : invalidStyle);
                    }
                });
```

### Global iFields Key <a href="#global-ifields-key" id="global-ifields-key"></a>

Developers who use multiple keys in their software can eliminate the need to collect a new iFields key from each merchant by using the Vendor ID feature.

Once this feature is enabled by a Sola Support team, the developer is free to use the same iFields key for all transactions. They just need to add an extra parameter to all transactions using the SUTs that were generated with the global iFields key.

The Vendor ID can also be configured to supply a default Software Name.

| **Parameter** | **Description**                                                                                                                                                                                                                                           | **Sample** |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| xVendorId     | The parameter that tells the gateway which developer is performing the transaction. If the value matches the account of the iFields key, the gateway will allow the transaction to work even though the API and iFields keys are from different accounts. | 123456     |

**Sample Code:**

```json
{
  "xCommand": "cc:sale",
  "xSoftwareVersion": "1.0.0",
  "xVersion": "5.0.0",
  "xSoftwareName": "Cardknox Test",
  "xKey": "test1",
  "xAmount": "1",
  "xCardnum": "4000000000001111;sut_02_1_cc_visa_keyed_01_20230417T134931Z_7200_hf-jrfg-2_e949b687b122457da8513f81d175ced2_e9b71c6bf1125748a6362ae90f28ed9f5024bedf438a7c3046ec1a1ccd226958",
  "xCvv": "xxx;sut_xx_x_cvv_xx_xxxxxxxxTxxxxxxZ_xxxx_hf-jrfg-x_xxcxbfxaxxxxxxxcxxxxaxexxxxefxac_bbxxfxdxecaxxcxxexxxxxxxxaxdxxxxcdxxxfxxxfaxxfxxxxxxdcaxxxaxxbax",
  "xExp": "1234",
  "xVendorId": "123456"
}
```

<br>
