Hosted Fields

This provides a way for the merchant ( channels: Regular or Value Financing ) to securely collect card details for customers paying with debit or credit card to complete the loan application on their channels. It enables the merchant to control the experience; look and feel (that is, the merchant is in complete control of their UI/UX).

The following fields are hosted securely in iframes which the merchant can embed in their checkout page:

PAN
Expiry Date
PIN
CVV
OTP

Steps to implement hosted fields
The customer has to add this html code into their webpage body
The checkout button should contain the id name (id="hf-create-fields-button"), this is the id that triggers the hosted field when clicked

Lending Service Hosted Fields
This provides a way for merchant channel providers to securely collect card details from customers paying with credit on their channels. It enables the merchant to control the experience, look and feel.

  • Expiry Date
  • PIN
  • CVV

Process Flow

Step-by-step guide

For the duration of this guide, we will be using the form below.

<div>
        <div class="create-payment-container">
            <div style="display: none;">
                ISW Hosted Fields Parameters
            </div>
            <div>
                <label>amount (in minor currency)</label>
                <input id="hf-amount" value="1234" />
            </div>
            <div style="display: none;">
                <label>currencyCode</label>
                <input id="hf-currencyCode" value="123" />
            </div>
            <div style="display: none;">
                <label>merchantCode</label>
                <input id="hf-merchantCode" value="AB12345" />
            </div>
            <div style="display: none;">
                <label>payableCode</label>
                <input id="hf-payableCode" value="123456" />
            </div>
            <div>
                <label>merchantCustomerName</label>
                <input id="hf-merchantCustomerName" value="ABCD" />
            </div>
            <div>
                <label>transactionReference</label>
                <input id="hf-transactionReference" />
            </div>
        </div>
   
        <div class="payment-form-container" style="display: none">
            <div class="notification-box">
                <div class="content"></div>
            </div>
            <div class="form-header">
                <img src="./logo.png">
                <div class="info">
                    <div class="title">ISW Hosted Fields</div>
                    <div id="amount-placeholder" class="amount"></div>
                </div>
            </div>
            <div class="form-page card-details show">
                <div class="form-control">
                    <label>Card Number</label>
                    <div id="cardNumber-container" class="payment-field"></div>
                </div>
                <div class="form-group">
                    <div class="form-control">
                        <label>EXP</label>
                        <div id="expirationDate-container" class="payment-field"></div>
                    </div>
                    <div class="form-control">
                        <label>CVV</label>
                        <div id="cvv-container" class="payment-field"></div>
                    </div>
                </div>
                <div class="button-container">
                    <button id="pay-button" class="blue">Pay</button>
                </div>
            </div>



            <div class="form-page pin">
                <div class="back-control" id="pin-back-button">
                    <img src="./back-icon.png" />
                    <label>Back</label>
                </div>
                <div class="form-text">Please provide your PIN</div>
                <div class="form-control">
                    <label></label>
                    <div id="pin-container" class="payment-field"></div>
                </div>
                <div class="button-container">
                    <button id="continue-button" class="green">Continue</button>
                </div>
            </div>
   
            <div class="form-page otp">
                <div class="back-control" id="otp-back-button">
                    <img src="./back-icon.png" />
                    <label>Back</label>
                </div>
                <div class="form-text">Please input the OTP sent to your mobile number</div>
                <div class="form-control">
                    <label></label>
                    <div id="otp-container" class="payment-field"></div>
                </div>
                <div class="button-container">
                    <button id="validate-button" class="orange">Validate</button>
                </div>
            </div>
            <div class="form-page cardinal">
                <div class="cardinal-container"></div>
            </div>
        </div>
   
    </div>

Load the SDK

Loading the SDK will make available global lending service hosted fields variable available.

Copy and paste the sdk.js and index.js scripts before the closing body tag of the customers html page

n/b: The path/location below does not indicate the actual path of the SDK

πŸ“˜

Load JavaScript SDK

Loading the SDK will make available a global interswitch.hostedFields variable available.

<script src="https://mufasa-qa.interswitchng.com/p/lending-service/build.js"></script>

<body>
        <script src="https://mufasa-qa.interswitchng.com/p/lending-service/sdk.js"></script>
        <script src="https://mufasa-qa.interswitchng.com/p/lending-service/index.js"></script>

</body>

As soon as the customer submits, initiate a submit request on the hostedFieldInstance returned in 2.

// Submit Loan Application
var submit = document.querySelector('button[type="submit"]');

submit.addEventListener('click', function (evt) {
  evt.preventDefault();
  evt.stopPropagation();
  hostedFieldInstance.submit(function (err, payload) {
    if (err) {
      alert("Loan application failed");
      return;
    }
    else {
      console.log(payload);
      var payref = payload.body.loanId;
      console.log(payref);
      alert("Loan application was successful with loan Id of " + payref);
      return;
    }
  });
}, false)

Tokenization Using Hosted Fields

This provides a way for merchant channels to securely collect card details for customers paying with credit on their channels. It enables the merchant to control the experience and look and feel.

The following fields are hosted securely in iframes which the merchant can embed in their checkout page;

PAN
Expiry Date
PIN
CVV
Step-by-step guide
For the duration of this guide, we will be using the form below.

<!-- Card form -->
<body>
  <form id="cardForm">
    <div class="panel">
      <header class="panel__header">
        <h2>Submit Card Details</h2>
      </header>
      <div class="panel__content">
        <div class="textfield--float-label">
          <label class="hosted-field--label" for="card-pan">
            <span class="icon"> </span> Card Number
          </label>
          <div id="card-pan" class="hosted-field"></div>
        </div>
        <div class="textfield--float-label">
          <label class="hosted-field--label" for="expiration-date">Expiration Date</label>
          <div id="expiration-date" class="hosted-field"></div>
        </div>
        <div class="textfield--float-label">
          <label class="hosted-field--label" for="card-cvv"> CVV</label>
          <div id="card-cvv" class="hosted-field"></div>
        </div>
        <div class="textfield--float-label">
          <label class="hosted-field--label" for="card-pin">Pin</label>
          <div id="card-pin" class="hosted-field"></div>
        </div>
      </div>
      <footer class="panel__footer">
        <button class="pay-button" type="submit">Submit</button>
      </footer>
    </div>
  </form>
  <script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
  <script src="https://mufasa-qa.interswitchng.com/p/lending-service/tokenize/sandbox/build.js"></script>
</body>

πŸ“˜

Load JavaScript SDK

Loading the SDK will make available a global interswitch.hostedFields variable available.

<script src="https://mufasa-qa.interswitchng.com/p/lending-service/tokenize/sandbox/build.js"></script>

Create a hosted field instance calling the newInstance method on the interswitch.hostedFields variable. The method takes options and a callback. An hosted field instance which can be used to register events listeners and finally submit the customer’s request when the customer clicks on a the submit button will be returned to the callback

// Create Hosted Fields Instance
interswitch.hostedFields.newInstance(options,
  function (err, hostedFieldInstance) {
    if (err) {
      // something is wrong,
      return;
    }
    function findLabel(field) {
      return $('.hosted-field--label[for="' + field.container.id + '"]');
    }
    hostedFieldInstance.on('focus', function (event) {
      var field = event.fields[event.emittedBy];
      findLabel(field).addClass('label-float').removeClass('filled');
    })
  })
The options include authorization, accept offer request, fields and styles as shown below.

Available Options
var options = {
  authorization: "eyJhbGciOiJSUzI1NiJ9.eyJhdWQiOlsiY2FyZGxlc3Mtc2VydmljZSIsImZpbmdlcnByaW50LWFwaSIsImlzdy1sZW5kaW5nLXNlcnZpY2UiLCJwYXNzcG9ydCIsInJlZmVycmFsLXNlcnZpY2UtYXBpIiwic2NwIl0sInNjb3BlIjpbInByb2ZpbGUiXSwianRpIjoiODcwYmZiNDAtNWQyMS00MDVkLTkzMTQtMWFmM2IwOGZmNjY0IiwiY2xpZW50X2lkIjoicG9zdG1hbiJ9.fXPGEz4nuo2FW0M9Qi1cIeZxm0xGsJKQRK5D4jdo8pMALU4JNbCSQGugB7xjpBNcGPR13_i7Y_0y0awljrOtsp-dIyrQ9cBSRGjuDCPDXXEkOX0xVBt0IGZa8DyGmFfNFLsv15R3ZUBLmg2OAJRtJ95DXoKAs16Kd07eKJsDCcWBLlk-sHg1HyXtcYm9XiAAbqWHJTWhCDueDZtz68tLoErxusLVbd_CL4Ec06CacJdJDUy9__HZMrHCiz9lSkx3PCg2GRNZhDw-u90sizpVzVNCE92cFcmSpXkF4j_vhlSvGqJN4Qi4_XQJ-3qFT5uP5Pg4jLdsvLzGGRm1T6lA8A"
  request: {
    customerId: "2348030583962",
    providerCode: "MKT"
  },
  styles: {
    'input': {
      'font-size': '16px',
      'font-family': 'roboto, verdana, sans-serif',
      'color': 'black'
    },
    ':focus': {
      'color': 'blue'
    },
    '.valid': {
      'color': 'black'
    },
    '.invalid': {
      'color': 'red'
    }
  },
  fields: {
    pan: {
      selector: '#card-pan',
      placeholder: '1111 1111 1111 1111'
    },
    cvv: {
      selector: '#card-cvv',
      placeholder: '111'
    },
    exp: {
      selector: '#expiration-date',
      placeholder: 'MM/YY'
    },
    pin: {
      selector: '#card-pin',
      placeholder: 'PIN'
    }
  }
}

As soon as the customer submits, initiate a submit request on the hostedFieldInstance returned in 2.

// Submit Loan Application
var submit = document.querySelector('button[type="submit"]');
submit.addEventListener('click', function (evt) {
  evt.preventDefault();
  evt.stopPropagation();
  hostedFieldInstance.submit(function (err, payload) {
    if (err) {
      alert("Loan application failed");
      return;
    }
    else {
      console.log(payload);
      var token = payload.body.token;
      var tokenExpiry = payload.body.tokenExpiryDate;
      return;
    }
  });
}, false)

Tokenization Event

There are available events emitted by the hosted field instance that you can subscribe to. This can be done on the hostedField instance.

These events include:

NameEvent Description
focusThis event is emitted when a field gains focus
blurThis is emitted when a field loses focus
validityChangeThis is emitted when the validity of a field changes
emptyThis is emitted when the field becomes empty

Register the events using the on method on the hostedFieldInstance returned.
See below an example using the focus and blur event:

// Events
function findLabel(field){
  return $('.hosted-field--label[for="' + field.container.id + '"]');
}

hostedFieldInstance.on('focus', function (event) {
   var field = event.fields[event.emittedBy];
   findLabel(field).addClass('label-float').removeClass('filled');
});
                        
hostedFieldInstance.on('blur', function (event) {
   var field = event.fields[event.emittedBy];
   var label = findLabel(field);
   if (field.isEmpty) {
      label.removeClass('label-float');
    } else if (field.isValid) {
      label.addClass('filled');
    } else {
      label.addClass('invalid');
    }
});