Applications web monopages

L’intégration du formulaire embarqué répond à une cinématique différente lorsqu’il s’agit de sites web dont la logique est entièrement gérée en JavaScript coté client.

Intégration simple

Dans le cas où votre site utilise une framework JavaScript non compilé (JQuery par exemple), l’intégration est relativement simple.

1. Chargement du formulaire de paiement

La première étape consiste à charger la librairie JavaScript. Comme pour l’intégration coté serveur, il suffit d’inclure les scripts JavaScript et les feuilles de style du formulaire embarqué.

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

Bien entendu, n’oubliez pas de remplacer le champs ‘kr-public-key’ par votre clé publique (voir ici pour plus de détails).

2. Initialisation du formulaire de paiement

Lorsque l’utilisateur décide de payer, vous pouvez initialiser le formulaire de paiement. Pour cela, vous devez appeler votre serveur marchand, pour y vérifier les achats de l’utilisateur, puis générer un identifiant de formulaire (appelé formToken) en appelant le Web Service Charge/CreatePayment (toujours depuis votre serveur marchand).

/**
* 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));
}

Coté serveur, votre code devrait ressembler à ça (en 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 : n’appelez pas le Web Service Charge/CreatePayment depuis le navigateur de l’acheteur:

  • L’étape de validation du panier est une étape cruciale, et il vous revient de vérifier sur vos serveurs que le montant correspond bien au panier avant de nous le transmettre
  • Appeler le Web Service depuis le navigateur de l’acheteur revient à mettre à sa disposition (et à celle de pirates potentiels) vos clés d’appels, ce qui est contraire aux règles de sécurité,
  • L’appel échouera systématiquement, nos serveurs n’autorisant pas les appels depuis le navigateur (Cross Origin Policy).

3. Affichage du formulaire de paiement

Une fois que le client reçoit le formToken généré coté serveur, vous pouvez l’associer à votre formulaire, puis afficher ce dernier.

/**
* 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);
}

La dernière étape consiste à écouter les événements du formulaire (KR.onSubmit) afin d’être notifié coté client de la fin du paiement.

4. Vérification du statut de la transaction

Une fois le paiement terminé, qu’il soit accepté ou refusé, vous serez notifié de 2 manières :

  • par un appel (IPN) vers votre serveur marchand, si ce dernier est enregistré auprès de notre plateforme de paiement,
  • par un callback coté JavaScript, enregistré dans la méthode KR.onSubmit.

Il est fortement conseillé de vérifier l’intégrité du message (voir ici pour plus de détails), et de lancer les traitements métier coté serveur (lors de la réception de l’IPN). Le callback JavaScript ne devrait être utilisé que pour reprendre la main sur le parcours client coté navigateur, et lui afficher le bon 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 !");
  }
}

Intégration avec Vue / React / Angular

Prérequis

L’intégration du formulaire embarqué au sein d’un site utilisant des frameworks JavaScript compilés (type React ou Angular) nécessite l’utilisation de la librairie embedded-form-glue.

Associée au code JavaScript du formulaire embarqué, cette librairie facilite les opérations suivantes:

  • Préchargement de la librairie pour permettre un affichage plus rapide pour les réseaux lents
  • Gestion de la configuration lorsque l’application n’est pas encore chargée
  • Permet d’ajouter, de supprimer, et d’afficher à nouveau le formulaire facilement

La librairie embedded-form-glue est disponible sur github.

Travailler dans un environnement asynchrone

Pour vous permettre d’intégrer le formulaire embarqué dans un environnement asynchrone, tous les événements et méthodes retournent des promesses.

À chaque résolution, la promesse passe un objet à la méthode then() qui peut contenir deux propriétés:

  • KR: la référence de librarie JavaScript est toujours retournée permettant de chainer les promesses quel que soit le contexte
  • result: le résultat de l’opération, peut être non défini ou absent de l’objet si aucun résultat n’est renvoyé
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();
    }
);

Exemples d’intégration

En fonction du framework JavaScript que vous utilisez sur votre site marchand, d’autres exemples d’intégration sont disponibles sur le site github de la librairie embedded-form-glue.

Framework Description
Vue.js exemple d’intégration pour Vue.js
React exemple d’intégration pour React
Angular exemple d’intégration pour Angular et TypeScript

Vous pouvez intégrer la librairie embedded-form-glue dans n’importe quel autre framework en suivant les mêmes principes que les exemples précédents.