Single-page web applications

The process of embedded form integration is different when it comes to websites whose logic is entirely based on JavaScript on the client side.

Simple integration

In case your website uses a n 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">
    </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> 
            

Remember to replace the ‘kr-public-key’ fields by your public key (go here for more information).

2. Initialize the payment form

When the user 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 a 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 the 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 client 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, registered in the KR.onSubmit method.

It is highly recommended to check the integrity of the message (see here for more information), and to launch the business processes on the server side (upon IPN reception). The JavaScript callback must only be used for taking back the control over the customer journey on the browser side and displaying the following message:

/** * Called when payment is finished * @param event */
function onPaid(event)
{
    if (event.clientAnswer.orderStatus === 'PAID')
    {
        // Hide payment form
        document.getElementById("paymentForm").style.display = 'none';

        // 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:

  • Preloading the library to allow for a faster display within slow networks
  • Configuration management 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, allowing to chain promises regardless 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 are 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.