Secure iframes are valuable tools that online merchants can use to protect credit card data, and provide a safe and convenient payment experience for customers. Radial JS offers a method to create and implement a secure iframe to collect payment data on behalf of the webstore. The iframe secure fields are hosted by Radial.When a customer submits payment information through the secure iframes, Radial sends the encrypted Payment information to the webstore to continue the order process. This provides a safe and isolated environment for sensitive data, protecting it from potential vulnerabilities and attacks.

How Secure iframes Work

Radial Secure iframes use two techniques:

  • Isolation: When using the Radial JS Secure iframe feature to collect payment information from checkout pages, Radial creates a separate iframe for each secure field needed for the webstore. These iframes are a separate browsing context within the webstore checkout pages. This context avoids directly accessing the iframe's content or data from the main page via Java Script and other scripts running on main page.

  • Data Encryption: Once webstore customers enter credit card information into the secure iframe, Radial JS validates the content and provides the encrypted payment data using secure encryption algorithms. This ensures data is transmitted securely between the webstore and the Radial Payment APIs.

Secure iframe Integration

Prepare the Webstore Payment Page

Based on your checkout flow, you can use Radial Secure iframes to collect both credit card and CVV info or just the needed field. Radial JS also supports saved wallet functionality. In this case Radial only adds the CVV field to capture input from the webstore user and communicate the user-entered value in an encrypted format with the parent webstore .

Ensure that the required DIV tags are present in the checkout pages to accommodate the iframe secure fields. The webstore can use provided customizations for all the secure fields to have the same look and feel as the existing checkout/payment form fields. Radial JS emits success and failure events based on customer inputs in these fields. The webstore listens to those events to handle error scenarios (for example, invalid card or cvv). If successful (valid card and cvv), Radial JS provides the webstore with encrypted payment details that the webstore can use to make further order flow scenarios like the submit payment authorization call for Radial Payment APIs.

Implement iframe Code

Once you invoke the initial Radial JS with a valid access token, you can use the Radial JS provided createSecureForm() method to create a secure iframe(s) for collecting payment data from the end user. The createSecureForm() method requires the Radial Options parameter, which is defined for the secure elements iframe options and styles.

Method

Copy
radial.createSecureForm(customConfig); 

Radial Secure iframe Options High-Level Structure

Copy

    "card" : { SecureFieldOptions}, 
    "code" : { SecureFieldOptions }, 
    "savedWallet": {boolean} //default false 

The Radial Option Object consists of two properties: “card” and “code”. These properties describe the secure credit card and secure code fields configurations. The Radial object also contains The optional property “savedWallet”. This property takes a Boolean argument to determine the saved wallet payment scenarios. If savedWallet is true, the end user wants to use existing saved payment information without re-entering the card number but reconfirming the card secure code. In this scenario, the card property is optional.

Copy
{
  "code": { SecureFieldOptions },
  "savedWallet": true,
  "tenderType": "VC" //allowed values are AM, VC, MC, DC,

 

The "SecureFieldOptions" object consists of “iframeConfig”, “style”, ”attributes”, and ”config” properties. The following table describes each property.

Property  Description Child properties
iframeConfig Along with the style property, describes the about secure field iframe div container info. containerId, style (see next row for style)
style Represents an object that used to define the style of the secure field element. Follow the “CSSStyleDeclaration” object specification. Color, fontSize, fontFamily, padding, border, ::placeholder (pseudo-element), invalid (only web safe fonts are allowed)
attributes Secure field html element attributes Any valid html element attributes; for example, placeholder
config Handles Radial custom functional config on secure field. displayCardLogo (Available on card secure field only)

The "IframeConfig" object consists of containerId and style. The following table describes each property.

iframeConfig Object properties Description Example Required
containerId Id of <div> tag where iframe needs to be added . containerId: “cardContainer” Yes
iframeId Sets Id for IFrame “cc1Id” Optional/required for muti-card
name Sets name for IFrame "cc1Name” Optional /required for muti-card
style Represents an object that defines height and width for iframe

style: {       "width": "100%",       "height": "100%"     } 

Optional

Customize iframe and Secure Element inside iframe:

To customize the secure field iframe, use the "style" element to match the existing checkout page designs. The "style" object allows SSStyleDeclations interface elements, but Radial recommends using a minimum number of styles properties to match the existing page.

The "style" object consists of all CSS styles to match existing layout. The following table describes a few of the basic properties.

Note: All styles passed inside the ":: placeholder" must be in CSS style format.

style Object properties Description Example Required
color Represent color of that font

color: "grey" 

Optional
fontSize Represent size of that font

fontSize": "16px"

Optional
fontFamily Represent style of that font

fontFamily: "Arial, sans-serif", 

Optional
padding Represent spacing

padding: "12px", 

Optional
border Represent outline around iframe

border: "1px solid #ccc", 

Optional
borderRadius Represent curve outline corner around iframe

borderRadius: "4px", 

Optional
letterSpacing Represent spacing between each letters

letterSpacing: "5", 

Optional
":: placeholder": { “ color ” : “ font-family":            "font-size":  " font -weight":          "letter-spacing":   }, Add styling to placeholder if any

::placeholder: {       "color": "green",       "fontFamily": "sans-serif",       "fontSize": "13px",       "fontWeight": "unset",        "letterSpacing": "0px"     }, 

Optional
invalid: {    color:   }, It will that color passed when card number is invalid

invalid: {       "color": "blue"     } 

Optional

The "attributes" object consists of value that is displayed on iframe. The following table describes each property.

attributes Object properties Description Example Required
placeholder Represents value that needs to be displayed in iframe

placeholder: "Card Number"   

Optional

The "config" object consists of value that is displayed on iframe. The following table describes each property.

config Object properties Description Example Required
displayCardLogo Represents logo of the card typed, by default it is false displayCardLogo: true 

Optional

Sample Style Options for Card and CVV

Copy
{
    "card": {
        "iframeConfig": {
            "containerId": "ccNumber",
            "iframeId": "cc1Id",
            "name": "cc1Name",
            "style": {
                "width": "100%",
                "height": "100%"
            }
        },
        "style": {
            "color": "#581845",
            "padding": "12px",
            "border": "1px solid #ccc",
            "borderRadius": "4px",
            "::placeholder": {
                "color": "#D2D8D0",
                "font-family": "sans-serif",
                "font-size": "13px",
                "font-weight": "unset",
                "letter-spacing": "0px",
                "line-height": "22px"
            },
            "invalid": {
                "color": "red"
            }
        },
        "attributes": {
            "placeholder": "Card Number",
            "id": "ccCard"
        },
        "config": {
            "displayCardLogo": true
        }
    },
    "code": {
        "iframeConfig": {
            "containerId": "cvv",
            "iframeId": "code1Id",
            "name": "code1Name",
            "style": {
                "width": "100%",
                "height": "100%"
            }
        },
        "style": {
            "color": "#581845",
            "padding": "12px",
            "border": "1px solid #ccc",
            "borderRadius": "3px",
            "::placeholder": {
                "color": "#D2D8D0",
                "font-family": "sans-serif",
                "font-size": "13px",
                "font-weight": "unset",
                "letter-spacing": "0px",
                "line-height": "22px"
            },
            "invalid": {
                "color": "red"
            }
        },
        "attributes": {
            "placeholder": "cvv"
        }
    }
}

Sample Style Options for saved Wallet

Copy
{
    "code": {
        "iframeConfig": {
            "containerId": "savedccNumber1",
            "iframeId": "code1Id2",
            "name": "code1Name",
            "style": {
                "width": "100%",
                "height": "100%"
            }
        },
        "style": {
            "color": "#581845",
            "padding": "12px",
            "border": "1px solid #ccc",
            "borderRadius": "3px",
            "::placeholder": {
                "color": "#D2D8D0",
                "font-family": "sans-serif",
                "font-size": "13px",
                "font-weight": "unset",
                "letter-spacing": "0px",
                "line-height": "22px"
            },
            "invalid": {
                "color": "red"
            }
        },
        "attributes": {
            "placeholder": "cvv02"
        }
    },
    "savedWallet": true,
    "tenderType": "VC"
}

Sample UI for the Secure Radial iframe Fields

SecureForm Creation Errors

If errors occur during the secure form creation, Radial JS returns the following errors.

Scenario errorCode Message Description
accessToken expired 40001 Invalid Authentication Error provided JWT is either invalid or expired, please try with valid Access Token
Insufficient Radial Options 40006 Radial Secure Form Error No Options provided for secure card or code fields
Client specific HPS JS load error 40007 Radial HPS Module Load Error Error Loading Radial Hosted Payment JS Module. Reach Radial PTF Support team
card/code options missing 40006 Radial Secure Form Error No Options provided for secure card field

 

Copy

  errorCode: "40006"
  errorMessage: "Radial Secure Form Error"
  errorDescription: "No Options provided for secure card or code fields",
  "success": false

In case of token expiry please try fetching new jwt token, for any other error please provide valid configuration

 

Sample UI for the Secure Radial IFrame Fields for Multi-card

Webstore can invoke radial.createSecureForm multiple times for any additional radial secure forms to accept multi card payment. Make sure radial options are appropriate for additional IFrames as per requirements.

Note: For multi-card payment processing implementation, it is recommended to provide a unique ‘iframeId’ or ‘name’ for each card and code IFrame in the ‘iframeConfig’ when passing ‘customConfig’ to radial.createSecureForm method

This is useful when webstore needs to identify and retrieve payment information for a specific card when user is presented with multi-card payments UI. Radial will assign a unique identifier as ‘cardPairId’ to each Secure card payment (which includes secure iframe for card and code) this will be generated based on a combination of these values (ex., cardIframeId-codeIframeId or cardIframeName-codeIframeName). If no ‘iframeId’ or ‘name’ is provided in custom config, Radial will generate a random cardPairId value for each multi-card instance. Radial will provide this cardPairId value when calling radial.getEncryptedData method or in the events emitted by Radial via RadialSecureFormEvents

Use the Radial Custom Window Event ‘RadialSecureFormEvent‘ on credit card number and code (CVV) input text fields to handle styling error and success messages or user input. The following table lists the event types emitted under ‘RadialSecureFormEvent’ message.

Code snippet to listen events for ‘RadialSecureFormEvent’:

Copy
window.addEventListener('RadialSecureFormEvent', function (e) { 
console.log(e.detail);  
}, false);  

The event sub type determines how to show error messages on the webstore payment page.

Handle Scenarios (success/failure):

Once createSecureiframe() has successfully added iframes for the secure fields in the webstore, the customer can use them as regular payment form fields. Radial JS performs real-time validations on these secure fields; for example, when a customer enters a credit card number, Radial JS validates and detects card type. (The ‘onblur’ and ‘input’ event listeners fire to validate data.) If the customer enters an invalid card number or code/CVV, Radial JS triggers the Invalid validation event. (Note: The CVV length is validated based on tender type). For all validation events, Radial emits a ‘RadialSecureFormEvent’. The webstore should listen for those events and style the parent fields of the iframe for error messages/styles.

Once the customer enters valid credit card numbers and valid CVV and clicks the webstore Submit button, call the getEncryptedPaymentData() method. This method gets the encrypted payment data entered by the customer.

Radial Custom Window Event Message for secureForm

Use the Radial Custom Window Event ‘RadialSecureFormEvent‘ on credit card number and code (CVV) input text fields to handle styling error and success messages or user input. The following table lists the event types emitted under ‘RadialSecureFormEvent’ message.

Sample code to listen events for ‘RadialSecureFormEvent’:

Copy
window.addEventListener('RadialSecureFormEvent', function (e) { console.log(e.detail); }, false);
Event sub type Validation /event type
cardEncrypted success
cardValidationSuccess success
cardValidationFailed fail
cardEncryptedFailed fail
secureCodeEncrypted success
secureCodeValidationSuccess success
secureCodeValidationFailed fail
secureCodeEncryptionFailed fail

The event sub type determines how to show error messages on the webstore payment page.

Sample ‘RadialSecureFormEvent’ type cardValidationSucces Event

Copy
{
    "message": {
        "tenderType": "VC",
        "cvvLength": 3,
        "issuingNetwork": "visa",
        "binPrefix": "41111",
        "panSuffix": "1111",
        "encryptedCardNumber": "/09MAt3aUh3x+HvfXwmF9G03r93wBGzPMoSAjR0pJ3I="
    },
    "success": true,
    "type": "cardValidationSuccess",    
    "elementInfo": {
        "containerId": "ccNumber",
        "id": "cc1Id",
        "pairId": "cc1Id-code1Id"
    }
}

 

Sample cardValidationFailed Event

Copy
{
    "message": {
        "errorMessage": "Invalid Card: Card Luhn Check Failed",
        "errorCode": "40004"
    },
    "success": false,
    "type": "cardValidationFailed",
    "elementInfo": {
        "containerId": "ccNumber",
        "id": "cc1Id",
        "pairId": "cc1Id-code1Id"
    }
}

 

Copy
{
    "message": {
        "errorMessage": "Invalid Secure Code",
        "errorCode": "40004"
    },
    "success": false,
    "type": "secureCodeValidationFailed",
    "elementInfo": {
        "containerId": "cvv",
        "id": "code1Id",
        "pairId": "cc1Id-code1Id"
    }
}

 

Copy
{
    "message": {
        "errorMessage": "Invalid Card: Empty Card Number",
        "errorCode": "40003"
    },
    "success": false,
    "type": "cardValidationFailed",
    "elementInfo": {
        "containerId": "ccNumber",
        "id": "cc1Id",
        "pairId": "cc1Id-code1Id"
    }
}

 

Copy
{
    "message": {
        "errorMessage": "Invalid Card: Card Type Not Supported",
        "errorCode": "40000"
    },
    "success": false,
    "type": "cardValidationFailed",
    "elementInfo": {
        "containerId": "ccNumber",
        "id": "cc1Id",
        "pairId": "cc1Id-code1Id"
    }
}

Test the Integration

After you configure iframe with the required options and styles, create a ‘Submit’ button to simulate the payment submit form. During this submit button call, use the getEncryptedPaymentData method to fetch encrypted payment that the customer entered in the Radial-provided secure iframe fields.While calling encryption method specify saved wallet option as true if webstore is processing saved wallet flow

Method and Parameter

Copy
radial.getEncryptedPaymentData(isSavedWallet, cardPairId);

Default value is false for isSavedWallet

  • true: if webstore is processing saved wallet payment (returns only the encrypted security code)

  • false: if webstore is not processing Saved wallet payment (returns both the encrypted card number and the encrypted security code).

  • For multi card - cardPairId is the combination of card iframe id and code iframe id

Field Description Required
isSavedWallet false: for not processing saved wallet true: for processing saved Wallet (returns only the encrypted security code) Yes
cardPairId When using multi card payment options use this option (cardPairId) to fetch the specific multi card payment details. If this option is not provided it will fetch all multi-card details. Optional – used for multi-Card Payment only

Responses (in below responses all encrypted fields are trimmed for readability)

If isSavedWallet = false ( i.e not Saved Wallet Flow) and single card

Copy
{
    "success": true,
    "cardDetails": {
        "encryptedCardNumber": "0umyKjCub8BPWQgW7Yxf8zxkeo7yk3VZw=",
        "binPrefix": "491761",
        "panSuffix": "0000",
        "encryptedSecurityCode": "bOZCDYakq/xfcT8kBJIkpWeiJm9PwpoI="
    },
    "tenderType": "VC"
}

 

If isSavedWallet = false ( i.e not Saved Wallet Flow) and multi-card without passing cardPairId

Copy
[
    {
        "cardDetails": {
            "encryptedCardNumber": "Yaq5Y9eZ5NabKtftwxg9AaVtEwxLDhxFHohwrVMw34=",
            "binPrefix": "491761",
            "panSuffix": "0000",
            "encryptedSecurityCode": "IkZhkMvSJirC1mIclh8gh/zoTj+M7k7wa9JWk="
        },
        "tenderType": "VC",
        "cardPairId": "cc1Id-code1Id"
    },
    {
        "cardDetails": {
            "encryptedCardNumber": "fGLBIXV8C77Sl2EwwiD7hkBhjNzFmz6EMgzn8VRg=",
            "binPrefix": "520128",
            "panSuffix": "9736",
            "encryptedSecurityCode": " ODsS1c3I0y2WKoS8tTxgrNy5XgO6EZfsDYMS5ZU"
        },
        "tenderType": "MC",
        "cardPairId": "cc1Id2-code1Id2"
    }
]

 

If isSavedWallet = true ( i.e Saved Wallet Flow) and single card:

Copy
{
    "success": true,
    "cardDetails": {
        "encryptedSecurityCode": "GXSFSpNMzsZxq7M8="
    }
}

 

If isSavedWallet = true ( i.e Saved Wallet Flow) and multi-card without passing pairId:

Copy
[
    {
        "success": true,
        "cardDetails": {
            "encryptedSecurityCode": "JfzLkMM="
        },
        "cardPairId": "cc1Id"
    },
    {
        "success": true,
        "cardDetails": {
            "encryptedSecurityCode": "1JCs="
        },
        "cardPairId": "code1Id2"
    }
]

Error Response

If invalid card is provided

Copy
{
    "success": false,
    "cardDetails": {
        "encryptedSecurityCode": "jx5HTa4KfSdnzek9ZPvbTBN2eiad8n5D1eq2qfpPL/6NbeVKg="
    },
    "errorMessage": "Invalid Card Number"
}

 

If invalid CVV is provided

Copy
{
    "success": false,
    "cardDetails": {
        "encryptedCardNumber": "oiJsZhq4XFTKw=",
        "binPrefix": "520128",
        "panSuffix": "9736"
    },
    "tenderType": "MC",
    "errorMessage": "Invalid Secure Code"
}

 

If one valid and one invalid card are provided in Multi-Card Scenarios

Copy
[
    {
        "cardDetails": {
            "encryptedSecurityCode": "RX6IehiQhCWPtwcs="
        },
        "errorMessage": "Invalid Card Number",
        "cardPairId": "cc1Id-code1Id"
    },
    {
        "cardDetails": {
            "encryptedCardNumber": "K/ZTN7HgvqavaxAKKR04CNjk/IBQ=",
            "binPrefix": "491761",
            "panSuffix": "0000",
            "encryptedSecurityCode": "UAIzwPUdpscTSI="
        },
        "tenderType": "VC",
        "cardPairId": "cc1Id2-code1Id2"
    }
]

 

No card details are provided for single card

Copy
{
    "success": false,
"errorMessage": "Invalid Card Number and Invalid Secure Code"
}

 

No card details are provided for 2 cards

Copy
[
    {
        "success": false,
        "cardPairId": "cc1Name-code1Name",
        "errorMessage": "Invalid Card Number and Invalid Secure Code"
    },
    {
        "success": false,
        "cardPairId": "cc2Name-code2Name",
        "errorMessage": "Invalid Card Number and Invalid Secure Code"
    }
]

 

If two invalid cvv is provided

Copy
[
    {
        "success": false,
        "cardDetails": {
            "encryptedCardNumber": "UKfKGM=",
            "binPrefix": "491761",
            "panSuffix": "0000"
        },
        "tenderType": "VC",
        "cardPairId": "CARD1-CODE1",
        "errorMessage": "Invalid Secure Code"
    },
    {
        "success": false,
        "cardDetails": {
            "encryptedCardNumber": "LdzoMmPQw5OBmE=",
            "binPrefix": "520128",
            "panSuffix": "9736"
        },
        "tenderType": "MC",
        "cardPairId": "cc1Id2-code1Id2",
        "errorMessage": "Invalid Secure Code"
    }
]

 

If two invalid card details are provided

Copy
[
    {
        "success": false,
        "cardDetails": {
            "encryptedSecurityCode": "WWdNyIHSGa/alNxMR8dM="
        },
        "errorMessage": "Invalid Card Number",
        "cardPairId": "CARD1-CODE1"
    },
    {
        "success": false,
        "cardDetails": {
            "encryptedSecurityCode": "ajJJADuThzZsN9dFYa4eMdF09wUI="
        },
        "errorMessage": "Invalid Card Number",
        "cardPairId": "cc1Id2-code1Id2"
    }
]

 

For saved wallet single card error

Copy
{
    "success": false,
    "errorMessage": "Invalid Secure Code"
}

 

For saved wallet multi card error

Copy
[
    {
        "success": false,
        "errorMessage": "Invalid Secure Code",
        "cardPairId": "cc1Id"
    },
    {
        "success": false,
        "errorMessage": "Invalid Secure Code",
        "cardPairId": "code1Id2"
    }
]
Property   description    
Success Boolean Indicates getEncryptedPaymentData is success or failed to fetch payment info    
cardDetails Object Contains below properties encryptedCardNumber, encryptedSecurityCode    
tenderType String Determine which tenderType of card used VC, DC, MC  

Sample Response from the getEncryptedPaymentData Method

Copy

"success": true
"cardDetails": { 
"encryptedCardNumber": "aigAafIZgL+...Fjxb/z8qtZ+I2P7YNdmzs2evnWufiG1Ug="
"encryptedSecurityCode": "ZVfjO5AX....KX1h07CAKICafPrGMPD7KytRPwS1pkj3bGU=" 
}, 
"tenderType": "VC"