Single-page web applications

Embedded form integration corresponds to a different process when it comes to websites entirely managed in JavaScript on the client side.

Simple integration

In case your website uses an uncompiled JavaScript framework (e.g., JQuery), the integration is relatively simple.

1. Load the payment form

The first step consists in loading the JavaScript library. Similarly to integration on the server side, all you need to do is include the JavaScript scripts and the style sheets of the embedded form.

<head>
    <!-- Javascript library. Should be loaded in head section -->
    <script type="text/javascript"
        src="https://api.lyra.com/static/js/krypton-client/V4.0/stable/kr-payment-form.min.js" 
        kr-public-key="69876357:testpublickey_DEMOPUBLICKEY95me92597fd28tGD4r5:testpublickey_DEMOPUBLICKEY95me92597fd28tGD4r5">
    </script>

    <!-- theme and plugins. should be loaded in the HEAD section -->
    <link rel="stylesheet" href="https://api.lyra.com/static/js/krypton-client/V4.0/ext/classic-reset.css">
    <script type="text/javascript" src="https://api.lyra.com/static/js/krypton-client/V4.0/ext/classic.js"></script>

</head>
<body>
    ...
        <!--Hidden payment form -->
        <div id="paymentForm" class="kr-embedded" style="display:none">

            <!-- payment form fields -->
            <div class="kr-pan"></div>
            <div class="kr-expiry"></div>
            <div class="kr-security-code"></div>
    
            <!-- payment form submit button -->
            <button class="kr-payment-button"></button>
    
            <!-- error zone -->
            <div class="kr-form-error"></div>
        </div>
    ...
</body> 

Make sure you replace the ''kr-public-key'' field with your public key (click here for more details).

2. Initialize the payment form

When the Buyer decides to make a payment, you can initialize the payment form. To do this, you must call your merchant server to check the Buyer’s purchases and generate a form identifier (called formToken) by calling the Charge/CreatePayment Web Service (also via your merchant server).

/**
* Called on 'checkout' click
*/
function onCheckout()
{
    // Create the order, based on your cart
    var order = {
        "amount":   1190,
        "currency": "EUR",
        "orderId":  "myOrderId-999999",
        "customer": {
            "email": "sample@example.com"
        }
    };

    // Call merchant server to get form token and then display payment form
    getFormToken(order, displayPaymentForm, alert);
}

/**
* Get form token from merchant server
* @param order
* @param resolve
* @param reject
*/
function getFormToken(order, resolve, reject) {
    var request = new XMLHttpRequest();

    // Open a new connection, using the POST request on the URL endpoint
    request.open('POST', 'YOUR_SERVER/payment/init', true);
    request.setRequestHeader('Content-Type', 'application/json');

    request.onload = function () {
        if (request.status >= 200 && request.status < 400) {
            resolve(this.response);
        }
        else
        {
            reject("Invalid server response. Code " + request.status);
        }
    };

    request.onerror = function (error) {
        reject(error);
    };

    // Send request
    request.send(JSON.stringify(order));
}

On the server side, your code must look like this (in Node JS):


/* Init payment form */
router.post('/init', function(req, res, next) {
  var order = req.body;

  // TO DO: check that order is valid  

  // Call CreatePayment web service to create the form token
  request.post({
    url: "https://api.lyra.com/api-payment/V4/Charge/CreatePayment",
    headers: {
      'Authorization': 'Basic Njk4NzYzNTc6dGVzdHBhc3N3b3JkX0RFTU9QUklWQVRFS0VZMjNHNDQ3NXpYWlEyVUE1eDdN',
      'Content-Type': 'application/json'
    },
    json: order
  }, function(error, response, body) {
    if (body.status === 'SUCCESS')
    {
      // Send back the form token to the client side
      res.send(body.answer.formToken);
    }
    else
    {
      // Do your own error handling  
      console.error(body);
      res.status(500).send('error');
    }
  });
});

Important - do not call the Charge/CreatePayment Web Service via the Buyer’s browser:

  • The step of shopping cart validation is crucial. You must also check on your servers that the amount matches the amount in the cart before transferring it to us.
  • Calling the Web Service via the Buyer’s browser would be equivalent to providing the Buyer (and potential hackers) your call keys, which violates the security rules.
  • The call will fail systematically, since our servers do not authorize calls via the browser (Cross Origin Policy).

3. Display the payment form

Once the Buyer has received the formToken generated on the server side, you can associate it with your form and proceed to display it.

/**
* Display the payment form with the argument form token
* @param formToken
*/
function displayPaymentForm(formToken)
{
    // Show the payment form
    document.getElementById('paymentForm').style.display = 'block';

    // Set form token
    KR.setFormToken(formToken);

    // Add listener for submit event
    KR.onSubmit(onPaid);
}

The last step consists in listening to the form events (KR.onSubmit) in order to be notified on the client side about the end of payment.

4. Verify the transaction status

Once the payment has been finalized, regardless of whether was accepted or rejected, you will be notified in two 2 ways:

  • Via a call (IPN) to your merchant server, if the Merchant is registered on our payment gateway,
  • Via a callback on the JavaScript side, recorded in the KR.onSubmit method.

It is strongly recommended to check the integrity of the message (click here for more details), and to launch the business processing on the server side (upon receiving the IPN). The JavaScript callback should only be used to regain control over the browser-side client path, and to display the right message:

/**
 * Called when payment is finished
 * @param event
 */
function onPaid(event) {
  if (event.clientAnswer.orderStatus === "PAID") {
    // Remove the payment form
    KR.removeForms();

    // Show success message
    document.getElementById("paymentSuccessful").style.display = "block";
  } else {
    // Show error message to the user
    alert("Payment failed !");
  }
}

Integration with Vue / React / Angular

Prerequisites

The integration of the embedded form into a website using JavaScript compiled frameworks (such as React or Angular) requires the use of the embedded-form-glue library.

Used in combination with the JavaScript code of the embedded form, this library facilitates the following operations:

  • Preload the library to allow for a faster display on slow networks.
  • Manageme the configuration when the application is not yet loaded.
  • Allows to easily add, delete and display the form once again.

The embedded-form-glue library is available on GitHub.

Working in asynchronous environment

In order to allow you to integrate the embedded form in an asynchronous environment, all the events and methods return promises.

Upon each resolution, the promise passes an object to the methodthen()that can contain two properties:

  • KR: the JavaScript library reference is always returned, which allows to chain the promises independently of the context.
  • result: the result of the operation can be undefined or absent from the object if not result is returned.
KR.validateForm().then( ({KR, result}) => {

    /* there is no errors */
    /* result == null */
    }

)
.catch( ({KR, result}) => {

    /* Get the error message */
    var code = result.errorCode;
    var message = result.errorMessage;
    var myMessage = code + ": " + message;
    console.log(myMessage);

    /* if you have defined a callback using      */
    /* result.onError(), you can trigger it calling: */
    return result.doOnError();
    }

);

Examples of integration

Depending on the JavaScript framework that you use on your merchant website, other examples of integration are available on the github website of the embedded-form-glue library.

Framework Description
Vue.js example of integration for Vue.js
React example of integration for React
Angular example of integration for Angular and TypeScript

You can integrate the embedded-form-glue library in any other framework by following the same principles.