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. Loading 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://static.systempay.fr/static/js/krypton-client/V4.0/stable/kr-payment-form.min.js" kr-public-key="73239078:testpublickey_Zr3fXIKKx0mLY9YNBQEan42ano2QsdrLuyb2W54QWmUJQ:testpublickey_DEMOPUBLICKEY95me92597fd28tGD4r5"> </script> <!-- theme and plugins. should be loaded in the HEAD section --> <link rel="stylesheet" href="https://static.systempay.fr/static/js/krypton-client/V4.0/ext/classic-reset.css"> <script type="text/javascript" src="https://static.systempay.fr/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. Initializing 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": 990,
"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.systempay.fr/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. Displaying 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. Verifying 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.
- Manage the configuration when the application is not yet loaded.
- 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.
At each resolution, the promise passes an object to the then()
method, which 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 error */ /* 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 |
require.js | example of integration with RequireJS |
You can integrate the embedded-form-glue library in any other framework by following the same principles.