Hosted-fields

Introduction

The hosted-fields mode is the best compromise between security, ease of customisation and payment form integration.

This integration mode aims to diminish your PCI-DSS constraints down to SAQ-A level requirements.

Here is a simple integration example of a payment form with hosted-fields:

See the Pen Basic Dalenys-Payment hosted-fields by Dalenys (@dalenys-payment) on CodePen.

Basic workflow

Here is a simple diagram illustrating the hosted-fields workflow.

Workflow

  1. You display a payment page including a payment form, except that the bankcard input fields are replaced by hosted-fields containers. These containers could be any HTML tag: div, p, span… the hosted-fields JavaScript library injects Dalenys-hosted iframes in these containers, each containing the card data input fields;
  2. At the submit process, you should call the createToken method of the hosted-fields library which will trigger the tokenization of the cardholder data (card number, expiry date and cryptogram);
  3. If the tokenization is successful, you must add the received token to your form submission request (e.g. by adding a hidden input);
  4. You can submit the payment form to your own server;
  5. You send a HTTPS POST request to our classical server to server endpoint: https://secure-test.be2bill.com/front/service/rest/process. The requests should contain the token instead of the cardholder data;
  6. The Dalenys platform sends a request to the bank network and waits for the result.
  7. You receive the result in the request response.
  8. In parallel, the transaction result is confirmed by a notification request sent to the merchant’s NOTIFICATION_URL containing the transaction’s parameters (among which EXECCODE and TRANSACTIONID).
info

The NOTIFICATION_URL can be configured through the Dalenys extranet, in the technical account configuration.

Authentication

The hosted-fields service uses the API Keys authentication mode with a Public key type.

Creation of a payment page

Step 1: Include hosted-fields library

First of all, you must include the Dalenys hosted-fields dedicated library, by adding the following code between the <head> and </head> tags in your HTML:

<script type="text/javascript" src="<https://js.sandbox.be2bill.com/hosted-fields/v1/hosted-fields.min.js>"></script>
security

You must own a TLS certificate to host a valid HTTPS payment page, otherwise the user’s browser will display security alerts and is likely to block it.

danger

The hosted-fields library must always be called online. Using a downloaded version hosted on your own server can cause serious malfunctions, especially in the case of an update of the API.

Step 2: Design your payment page

reminder

Remember to declare the encoding of your HTML page using a meta element with the value UTF-8.

<html>
<head>
    <meta charset="UTF-8">

Your payment page must contain a form, whose action attribute should point to your own server’s dedicated page for sending a payment request.

You also must imperatively provide 3 containers, to display the following bank card’s input fields:

  • Card code
  • Card expiry date
  • Cryptogram (CVV)

These containers could be any HTML tag and are intended to host the bank card input fields.

In the following example, we’re generating a payment form using 3 span tags as containers:

<form method="post" action="https://myshop.com/payment/process">
    <p><label for="cc-number">Card code</label> <span id="card-container"></span></p>
    <p><label>Card expiry</label> <span id="expiry-container"></span></p>
    <p><label>Card Validity Code (CVV)</label> <span id="cvv-container"></span></p>
    <p><input type="submit" value="Pay"></p>
</form>

Step 3: Configure the hosted-fields library

The next step is to designate the containers in which to create the secured hosted-fields, using JavaScript.

To do so, initialize the hosted-fields library with your Public API Key and your desired configuration:

<script type="text/javascript">
    // Initialize the hosted-fields library
    var hfields = dalenys.hostedFields({
        // Use your Public API Key
        key: {
            id : 'a1b2c3d4-e5f6-g7h8-i9j0-a1b2c3d4e5f6',
            value : 'uAr3s0133t#gLhF'
        },
        // Link and configure each hosted input field by providing the corresponding container ID
        fields: {
            'card': {
                id: 'card-container'
            },
            'expiry': {
                id: 'expiry-container'
            },
            'cryptogram': {
                id: 'cvv-container'
            }
        },
        // Choose the language for error messages
        location: "en"
    });
</script>

Step 4: Load the hosted-fields library

<script type="text/javascript">
    hfields.load();
</script>

At this point, your web browser may display the bank card input fields into their containers.

Configuration options

Due to safety cross domain restrictions, you cannot directly manage the events and the style of the hosted input fields hosted by Dalenys.

However, we provide CSS selectors and JS events / callbacks to manage them:

Available CSS selectors and properties

Since you can’t directly customize the inner iframe style from your own CSS, you can specify a style property in the hosted-fields initialization.

The selectors and css properties below are the only ones available to customization

Selectors
Properties:
fields: {
    'card': {
        id: 'card-container'
        style: {
             ':invalid':  {
                   "color": "red"
             }
        }
    },

Containers classes

Depending on the events occurring on the bank card input fields, some specific classes will be sent to your containers, live. These classes can be exploited in your CSS :

  • hosted-fields-valid-state
  • hosted-fields-invalid-state
  • hosted-fields-empty-state
  • hosted-fields-disabled-state
  • hosted-fields-focus-state

Callbacks and events

Available callbacks

You can customize some callbacks for receiving events happening on the hosted-fields inputs.

card: {
    id: "card-container",
    onInput: function (event) {
        alert(event['cardType']);
    },
    onInput: function (event) {
        if(event.type == 'invalid') {
            alert(event['message']);
        }
    },
}
Triggered events

Every callback will receive an event as a parameter. The structure of these events could differ depending on the event type:

  • invalid
  • valid
  • empty
  • focus
  • blur
  • input
  • disabled: The cryptogram field is disabled in the case where the card number entered corresponds to a card without crytogram (e.g. for Maestro and Bancontact cards).
  • enabled: The cryptogram field is enabled in case of using a card with cryptogram
Event types

An event could contain different properties (depending on its type):

  • type: the event type (see the previous list)
  • element: the concerned input
  • valueLength: the number of typed characters
  • execCode: the error code (only in case of invalid event) you can refer to full execcode list
  • message: the error message (only in case of invalid event)
  • cardType: the card type (only in case of blur or keyDown event)
    • unknown
    • visa
    • mastercard
    • american_express
    • maestro
    • bancontact

Language selection

The locale configuration key can have one of these values:

  • fr
  • en
  • de
  • es
  • it
  • nl
  • zh
  • ru
  • pt
  • cs

Placeholder

This property allows you to edit the placeholder of any input field.

tips

We have chosen to display hosted input fields without borders by default, however the style impacting the external aspect of the input fields, like the borders appearance for example, is easily simulable by applying it on the container

You can find more complex examples below

Generate a token

Once the user submits the form, you should call the createToken method to trigger the tokenization process.

This method expects a callback in parameter which will be triggered once the tokenization request is finished.

Your callback will receive a result object containing these properties:

  • execCode: The technical result code of the tokenization call. In case of success, 0000 will be sent
  • message: The description linked to the execCode
  • cardType: The card type
  • cardCode: The first 6 and last 4 digits of the cardholder’s card number
  • cardValidityDate: Card expiry date
  • hfToken: Of course the generated token

In case of success you have to add the received token to the form submit request (by adding an hidden input for example).

Here is an example:

<form action="https://myshop.com/payment/process" name="myForm" onsubmit="return tokenizeHandler()">
<!-- ... -->
    <input type="hidden" name="hf-token" id="hf-token">
<!-- ... -->
</form>

<script type="text/javascript">
    function tokenizeHandler() {
        hfields.createToken(function (result) {
            console.log(result); // Debug
            if (result.execCode == '0000') {
                // Set the token in an hidden input field to transmit it to the merchant submit page
                document.getElementById('hf-token').value = result.hfToken;
                // Send the form request
                document.myForm.submit();
            }
        });
        // Prevents the submit of the form in case of failed tokenization request
        return false;
    }
</script>

Sending a payment request

Once the token has been received by your server-side script, you have to initiate a server-to-server request except for all the bank card data (CARDCODE, CARDCVV, CARDVALIDITYDATE) which must be replaced by the token sent as a single HFTOKEN parameter.

Here is a server to server request example:

$> curl --request POST --url "https://secure-test.be2bill.com/front/service/rest/process" \
--data "method=payment" \
--data "params[IDENTIFIER]=YOUR_IDENTIFIER" \
--data "params[OPERATIONTYPE]=payment" \
--data "params[ORDERID]=1234" \
--data "params[AMOUNT]=1000" \
--data "params[CLIENTIDENT]=john.snow" \
--data "params[CLIENTEMAIL]=john.snow@example.com" \
--data "params[CLIENTREFERRER]=https://your_shop.com/order?id=1234" \
--data "params[CLIENTUSERAGENT]=Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" \
--data "params[CLIENTIP]=10.1.1.1" \
--data "params[CARDFULLNAME]=JOHN SNOW" \
--data "params[DESCRIPTION]=Knows nothing" \
--data "params[HFTOKEN]=17730892-b3f7-4411-bc81-557471ffcede" \
--data "params[HASH]=15477dcb8687adf90fa51e418f3c1a2d025f40b177a978c2734514734633b3c4" \
--data "params[VERSION]=3.0" \
info

The hosted-field token is only available for one transaction and cannot be reused.

info

The hosted-field token expires after 15 minutes.

Validating the transaction status

Please refer to the server to server integration mode dedicated chapter.

Requirements

The hosted-fields library is compatible with all recent desktop and mobile browsers (Edge, Chrome, Firefox, Safari…)

User experience on older browsers could be not optimal, some features may be disabled for technical or security motives.

SSL / TLS certificate

Please refer to the SSL / TLS certificate dedicated chapter.

Examples

More complex example

A more complex example that uses Javascript and CSS tricks:

See the Pen Dalenys-Payment hosted-fields custom complex payment template by Dalenys (@dalenys-payment) on CodePen.