Go to Hackademy website

Du e-commerce avec React & Stripe

Benoit Caccinolo

Posté par Benoit Caccinolo dans les catégories dev

Le e-commerce est un canal de vente qui a le vent en poupe. De plus en plus de personnes achètent en ligne sur des plateformes telles qu’Amazon ou CDiscount pour ne citer que celles-ci. Pour vous donner un ordre de grandeur, les Français ont acheté en 2016 pour 72 milliards d’euros sur Internet, on attend pour 2017 un montant de 80 milliards. Ce sont des chiffres qui donnent le tournis mais c’est la réalité. Nous pourrons bientôt acheter une baguette en ligne et se la faire livrer par un drone dans l’heure !

Bien que de nombreuses plateformes permettent aujourd’hui de vendre des produits en ligne, cet article vous propose une autre approche. L’idée est de vous montrer qu’il est assez simple de monter une page e-commerce from scratch. Pour réaliser ce projet, j’ai choisi deux technos : React & Stripe.

Les technos utilisées

Est-il nécessaire de présenter React ? Qui ne connaît pas encore React ? React n’est pas un framework mais plutôt une bibliothèque JavaScript pour créer des interfaces sous forme de composants. Sa grande force est qu’il est facile de l’intégrer dans une application existante. Grosso modo, une fois React chargé et votre composant défini, il suffit d’ajouter un tag dans la page et le tour est joué ! Pour les personnes qui souhaitent une introduction à React, je vous renvoie à l’article de Vincent sur le sujet.

J’entends déjà certains d’entre vous se demander pourquoi je n’ai pas utilisé le grand concurrent de React, j’ai nommé VueJS ? Cela semblerait d’autant plus naturel qu’en interne, chez Synbioz, nous utilisons Vue. À mon sens, il est intéressant, à travers de petits projets ou des articles, de prendre le pouls de technos alternatives à celles que l’on utilise habituellement. Cela permet d’avoir un regard plus avisé sur les outils que nous utilisons en interne.

Pour mettre en place une page e-commerce, il nous faut pouvoir facilement traiter les paiements. Il nous faut donc une solution de paiement avec un formulaire permettant de saisir les informations d’une carte de crédit. Je ne sais pas vous, mais quand je pense solution de paiement, je vois tout de suite une API complexe, mal documentée et souvent faite en .Net. Arrachage de cheveux en perspective !

C’est là que Stripe entre en scène. C’est une solution de paiement complète bien faite et surtout très bien documentée. Lorsque vous êtes authentifié sur la documentation en ligne de Stripe, tous les exemples fournis intègrent par défaut votre clef API de test. Ainsi il vous suffit de copier/coller le code d’exemple sans modification pour pouvoir le tester. Cela rend la documentation et leur API beaucoup plus abordables.

Sur Stripe, le traitement d’un paiement se fait en 2 étapes avec une action côté client et une autre côté serveur. Toutes les données sensibles de l’utilisateur transitent directement du navigateur de l’utilisateur vers Stripe pour retourner uniquement un token. Ce dernier représente le moyen de paiement de l’utilisateur. Le numéro de carte de crédit de l’utilisateur ne touche jamais votre serveur. Le token est ensuite utilisé côté serveur pour créer une Charge pour débiter le montant de l’achat.

Pour pouvoir tester le projet, un compte Stripe vous sera nécessaire. Vous devrez utiliser vos clefs d’API pour pouvoir communiquer avec la gateway de paiement.

stripe api keys

Une fois votre compte créé, vous pourrez utiliser votre paire de clefs d’API. La clef publique servira à la partie frontend et la clef privée servira à la partie backend de l’application. Ainsi chaque partie du projet pourra communiquer avec l’API Stripe.

Les étapes pour insérer les clefs d’API sont les suivantes :

  • ajouter la clef d’API publique dans le package.json à la racine du projet, la clef est stripePublicKey.
  • ajouter la clef d’API secrète dans le fichier backend/package.json, la clef est stripeSecretKey.

Une fois cela fait, nous sommes fin prêts pour attaquer !

Assez de blabla, place au code !

Le but de cet article est donc de mettre en place une page e-commerce pour vendre une peluche Pikachu. Je vous conseille de cloner le code de suite, cela rendra la compréhension plus facile. Le code est disponible sur Github.

Voici à quoi ressemble l’application :

screenshot application react stripe

La page est structurée en 3 blocs :

  • la partie présentation du produit
  • la partie informations client. Ici on a besoin que du nom du client
  • la partie paiement

Chez Stripe, ils ont pensé à tout pour faciliter l’intégration de Stripe avec React. Ils ont donc sorti une petite bibliothèque JavaScript qui encapsule les éléments d’un formulaire de paiement dans des composants React. L’avantage de cette solution est qu’elle fournit nativement une validation sur les données saisies. Par exemple, les numéros de carte incomplets sont mis en surbrillance.

Je vais vous présenter comment j’ai intégré ces éléments dans une page e-commerce React.

Définition des composants

Le composant qui nous intéresse ici est le composant de paiement :

<div className="App">
  <ProductView/>
  <UserInfo/>
  <Payment/>
</div>

Tous les composants de paiement doivent être encapsulés dans le composant parent <StripeProvider>. Ce composant va instancier l’objet Stripe principal en charge de l’envoi des données saisies. C’est pour cette raison que ce composant a besoin de la clef publique d’API.

<StripeProvider apiKey="pk_test_public_api_key">
  <Checkout/>
</StripeProvider>

Le formulaire de paiement doit aussi être encapsulé dans le composant <Elements>. C’est une façon de définir le groupe de composants à utiliser pour l’envoi des données pour la création du token de la carte de crédit.

<Elements>
  <CardForm/>
</Elements>

Enfin le composant <CardForm> contient le formulaire.

<form onSubmit={this.handleSubmit}>

  <Error msg={this.state.error} />
  <Success msg={this.state.success} />

  <div className="form-group">
    <label>Numéro de carte</label>
    <CardNumberElement { ...this.createCssOptions() } />
  </div>

  <div className="form-group">
    <label>Date d'expiration</label>
    <CardExpiryElement { ...this.createCssOptions() } />
  </div>

  <div className="form-group">
    <label>Code de sécurité</label>
    <CardCVCElement { ...this.createCssOptions() } />
  </div>

  <button type="submit" className="btn btn-primary">Pika Pay!</button>
</form>

Ici nous définissons les composants que nous souhaitons voir apparaître dans notre formulaire :

  • un champ numéro de carte de crédit
  • un champ date d’expiration
  • un champ code de sécurité

Communication

Une fois le formulaire mis en place, il ne reste plus qu’à envoyer les données pour recevoir le token de la carte de crédit qui servira à débiter la carte. Ce qu’il faut bien garder en tête, c’est que la transaction se fait en 2 étapes :

  1. tokenization de la carte de crédit
  2. demande de débit à l’aide du token reçu

Toute la communication est prise en charge par l’objet Stripe créé par le composant <StripeProvide>. Le côté pratique de cet élément est qu’il passe automatiquement l’objet Stripe dans les props aux enfants. Comme le montre le code ci-dessous, un simple this.props.stripe nous permet d’y accéder.

handleSubmit(ev) {
  ev.preventDefault();

  this.props.stripe.createToken({name: this.props.clientName})
    .then(result => {
      if(typeof(result.error) !== 'undefined') {
        this.setState({ error: result.error.message, success: ''});
      } else {
        this.stripeCreateCharge(result.token, this.props.totalPrice);
      }
    });
}

Nous n’avons pas besoin de nous soucier des données du formulaire, elles sont automatiquement sérialisées. La seule information manquante est le nom du client. Il est donc passé en paramètre lors de l’appel à stripe.createToken. En cas de succès, cet appel nous retourne le token de la carte de crédit qui nous permet d’appeler stripeCreateCharge pour débiter le montant de l’achat.

stripeCreateCharge(token, amount) {
  const params = { token: token.id, amount: amount };
  const qParams = queryString.stringify(params);
  const url = ['/api', qParams].join('?');

  fetch(url)
    .then(response => response.json())
    .then(val => {
      if (val.ok) {
        return val.message;
      }
      throw val.message;
    })
    .then(success => this.setState({alertMessage: success, alertStyle: 'success'}))
    .catch(error => this.setState({alertMessage: error, alertStyle: 'danger'}));
}

Ici nous faisons appel à notre serveur avec les informations nécessaires pour faire la demande de débit :

  • le token de la carte de crédit
  • le montant à débiter

Tester son formulaire de paiement

Sur un site e-commerce, un formulaire de paiement est une partie sensible, il faut donc le tester soigneusement. Pour ce faire, Stripe met à disposition un ensemble de numéros de carte de crédit de test. Par exemple :

4242 4242 4242 4242   Visa
5555 5555 5555 4444   Mastercard

En conclusion

Vous voici désormais en possession des cartes principales pour la mise en place d’un formulaire de paiement avec React & Stripe. Pour aller plus loin, n’hésitez pas à consulter la documentation sur le sujet :


L’équipe Synbioz.
Libres d’être ensemble.

Articles connexes

Résolution de bug — parlons méthodologie

15/06/2018

Véritable ascenseur émotionnel pour tout développeur, le faisant passer successivement du déni à la frustration, de l’incrédulité à la résignation, puis de l’espoir au soulagement, le débogage est un...

Un chatbot, une API et Recast.AI

22/03/2018

Les chatbots c’est un peu à la mode en ce moment, on en voit de plus en plus sur beaucoup de sites. Aujourd’hui je vous propose de nous intéresser à Recast.AI.

Implémentation d'une blockchain

18/01/2018

Nous avons tous entendu parlé des crypto-monnaies Bitcoin ou Ethereum. Et nous regrettons tous de ne pas avoir acheté des Bitcoins quand ces derniers valaient quelques centimes et non pas 15 000...

La magie de Rake

13/10/2017

Lecteur aguerri, vous devez savoir que nous sommes, chez Synbioz, une bande de Ruby Lovers comme tant d’autres ! Au cœur de notre activité quotidienne réside Ruby, aussi nous prenons un certain...