Fermer

décembre 17, 2021

Gestion de la facturation pour votre prochaine idée SaaS à l'aide des fonctions Stripe et Azure —


Résumé rapide ↬

Dans chaque solution de logiciel en tant que service, la facturation et les paiements des utilisateurs sont des aspects clés de la vente des services rendus. Découvrons Stripe et comment l'API REST peut être utilisée par programmation dans des fonctions sans serveur pour gérer la facturation d'une application.

Pour suivre les étapes de ce tutoriel, vous devez disposer des éléments suivants :

  • un compte Stripe (vous pouvez en créer un gratuitement et utiliser le mode test pour éviter de payer des frais en suivant les étapes dans cet article) ;
  • une compréhension de base de JavaScript et React ;
  • un compte Auth0 (vous pouvez vous inscrire pour un compte gratuit).

Introduction

Fournir une solution à utilisateurs via software as a service (Saas) implique souvent l'utilisation de fournisseurs de cloud pour héberger et fournir l'ensemble de votre infrastructure, comprenant généralement un client principal et un client frontal. Pour compenser les frais encourus par vos fournisseurs de cloud, un modèle de facturation approprié pour vos utilisateurs est nécessaire dans certains cas. Dans d'autres scénarios, vous pouvez avoir des produits ou des services que vous souhaitez vendre.

Les deux applications dans les scénarios susmentionnés partagent une exigence fonctionnelle, qui est la capacité à traiter le paiement de l'utilisateur. Pour y parvenir, le développeur pourrait tirer parti d'une infrastructure de paiement externe, telle que StripeSquare ou Amazon Payparmi beaucoup d'autres.

Dans ce cas. article, nous examinerons Stripe et utiliserons son API REST via le package Node.js de Stripe pour créer une couche API comprenant des applications Azure Functions pouvant être exécutées par un déclencheur HTTP à partir d'un client Web, mobile ou de bureau. La couche API et les points de terminaison accessibles via chacune des fonctions sont décrits dans le diagramme ci-dessous.

Remarque : Une application Azure Functions est une fonction sans serveur individuelle déployée et gérée à l'aide du service Azure Functions. Comme illustré dans le diagramme ci-dessous, un même projet peut comprendre plusieurs applications Azure Functions.

Diagramme de haut niveau de l'API comprenant Azure Functions

Diagramme de haut niveau de l'API comprenant Azure Functions. ( Grand aperçu)

Après avoir créé l'API, nous allons cloner une application Web existante, créée à l'aide de React pour afficher des peintures d'art à vendre. Les API ci-dessus seront utilisées pour récupérer les peintures en tant que produits individuels, et les autres points de terminaison seront utilisés pour gérer les paiements.

Remarque : Bien que cet article utilise Azure Functions en tant que fournisseur de fonctions sans serveur, vous pouvez réutiliser la logique dans votre fournisseur préféré, tel que Lambda d'AWS ou Google Cloud Functions.

Stripe Objects

Avant d'aller plus loin , nous devons comprendre les objets Stripe que nous allons créer dans cet article et ce qu'ils représentent. Vous trouverez ci-dessous une liste des cinq objets avec lesquels nous allons travailler :

  1. subscription
    Un objet subscription est créé pour facturer les utilisateurs à des intervalles spécifiés par la billing_period dans le prix objet attaché au produit. Dans ce tutoriel, nous aurons un produit avec un type de prix récurrent, et nous y abonnerons les utilisateurs à l'aide de l'objet subscription.

  2. product
    Un objet product est utilisé pour représenter un seul article ou service vendu, et le prix du produit est stocké dans l'objet price. Dans cet article, nous allons créer un produit à l'aide du tableau de bord d'administration de Stripe, puis le récupérer via l'API Stripe.

  3. price
    L'objet price est utilisé pour contenir les détails liés au prix d'un produit , comme la devise, le prix et le cycle de facturation. Dans cet article, nous allons à nouveau créer l'objet price à l'aide du tableau de bord d'administration de Stripe, puis le récupérer via l'API Stripe.

  4. mode de paiement
    Un objet payment_method sur Stripe est utilisé pour conserver les informations de paiement d'un client. Dans ce tutoriel, nous allons créer un mode de paiement sur chaque transaction et l'utiliser avec un objet payment_intent.

  5. payment intent
    Un objet payment_intent est créé pour suivre le le paiement d'un produit depuis sa création jusqu'au moment où le paiement est finalement reçu. Chaque objet payment_intent contient un champ status pour enregistrer l'étape du paiement. Dans cet article, nous utiliserons un payment_intent lorsqu'un utilisateur achète un produit avec un type de prix unique.

Plus après le saut ! Continuez à lire ci-dessous ↓

Création d'un profil Stripe pour votre idée d'entreprise

La première étape pour utiliser Stripe consiste à créer un compte avec votre adresse e-mail et un mot de passe, en utilisant le tableau de bord en ligne de Stripe.

La création d'un compte Stripe lancera la nouvelle entreprise en mode test. Nous pouvons comparer le mode test à votre mode de développement local, car il vous permet de créer des objets Stripe et de les tester à l'aide des cartes de crédit de test fournies par Stripe, sans encourir de frais.

Comme indiqué dans le tableau de bord Stripe pour l'exemple d'application ci-dessous, vous pouvez renseigner un nom de compte et d'autres détails pour personnaliser votre service. ( Grand aperçu)

L'image ci-dessus montre le tableau de bord de notre compte nouvellement créé. Notez la case en surbrillance dans l'image ci-dessus, car la section contient les clés que vous utiliseriez lorsque vous travailleriez par programmation avec le compte Stripe via l'API ou une bibliothèque cliente prise en charge.

Remarque : Stockez le secret dans un bloc-notes sécurisé, car nous les utiliserons lorsque nous travaillerons avec Stripe via un package Node.js à partir d'une fonction Azure dans la section suivante.

Créer des exemples de produits sur Stripe

Pour créer un produit dans Stripe, nous pouvons soit utiliser l'API REST, soit le tableau de bord de l'administrateur Web de Stripe. Dans notre cas, le propriétaire de l'application est le seul gestionnaire des produits vendus ; par conséquent, nous utiliserons le tableau de bord d'administration de Stripe pour créer des exemples de produits à afficher dans l'application de démonstration. La méthode product est utilisée pour effectuer des opérations CRUD sur un objet product.

À l'aide de la barre de navigation supérieure de la page d'accueil du tableau de bord Stripe, cliquez sur l'onglet « Produits » pour accéder au Page « Produits ». Sur la page « Produits », cliquez sur le bouton « Créer un produit » en haut pour créer votre premier produit dans ce compte professionnel Stripe.

Sur la page de création d'un produit, écrivez « Abonnement à la galerie » dans l'entrée « Nom » domaine. Écrivez un court texte dans le champ de saisie « Description », à utiliser comme information sur le produit. Et mettez « 150 » dans le champ de saisie « Prix », à utiliser comme prix du nouveau produit, comme indiqué ci-dessous.

Remarque : Vous pouvez également cliquer sur la case « Image » sur le Page « Créer un produit » pour sélectionner une image de votre appareil à utiliser comme image du produit.

L'image ci-dessous montre les champs de saisie de la page « Créer un produit » pour l'exemple de produit que nous créons.

 Stripe créera un produit avec un type de prix récurrent

Stripe créera un produit avec un type de prix récurrent. ( Grand aperçu)

À partir de l'image ci-dessus, nous pouvons voir que l'option « Périodique » dans les « Détails de la tarification » est sélectionnée. Cela signifie que lorsqu'un utilisateur est abonné à ce produit, Stripe tentera automatiquement de renouveler l'abonnement pour le produit à la fin de la « période de facturation » spécifiée dans la section « Détails des prix » ci-dessus. Cliquez sur le bouton « Enregistrer le produit » pour enregistrer et continuer.

Après avoir enregistré le produit, vous serez redirigé vers la page « Produits ». Cliquez à nouveau sur le bouton « Créer un produit » pour créer un produit, en spécifiant différentes informations pour le « Nom », la « Description » et les « Détails des prix ». Cette fois, cochez la case « Une fois » dans les « Détails des prix » pour permettre à un utilisateur d'acheter cet article une fois sans être facturé à nouveau.

 Stripe créera un produit avec un type de prix unique

Stripe créera un produit avec un type de prix unique. ( Grand aperçu)

L'image ci-dessus montre un nouveau produit en cours de création avec un type de prix « unique ». Notez que le menu déroulant "Période de facturation" est supprimé lorsque l'option "Une fois" est sélectionnée, contrairement au premier produit que nous avons créé avec un type de tarification "Récurrent".

Remarque : Vous pouvez continuer pour créer plus de produits avec des noms, des descriptions et des détails de tarification différents, pour remplir les produits dans votre compte professionnel Stripe.

Création de fonctions Azure

Les fonctions Azure sont des fonctions fournies par Azure pour gérer le code événementiel sans serveur qui peut être exécuté via un déclencheur d'événement défini. Toutes les fonctions Azure que nous allons créer dans cet article utiliseront le déclencheur HTTPqui permet de déclencher une fonction en effectuant une requête HTTP au point de terminaison d'URL de la fonction.

Toutes les opérations de programmation avec Stripe dans cet article sera réalisé à l'aide de la bibliothèque npm de Stripe pour un environnement Node.js. Les fonctions sans serveur sont utilisées dans cet article pour couvrir les cas d'utilisation des petites applications, en utilisant une architecture JAMstack sans service back-end.

Les fonctions Azure peuvent être développées via le portail Azure ou localement sur votre ordinateur. Toutes les fonctions Azure de cet article seront développées et exécutées localement à l'aide de l'interface de ligne de commande (CLI) Core Tools d'Azure. Exécutez la commande ci-dessous pour installer les outils de base d'Azure globalement sur votre ordinateur à l'aide de npm.

npm i -g azure-functions-core-tools@3 --unsafe-perm true

Ensuite, exécutez les commandes ci-dessous pour créer un nouveau répertoire de projet pour stocker les fichiers Azure Functions et amorcer le projet Azure Functions à l'aide de la CLI Core Tools.


# Créer un nouveau répertoire
mkdir stripe-serverless-api

# Changer dans un nouveau répertoire
cd stripe-serverless-api

# Projet Bootstrap Azure Functions
func new --language='javascript' --worker-runtime='node' --template="HTTP trigger"
--name="produits"

Les commandes ci-dessus créeront un répertoire de projet stripe-serverless-api sur votre ordinateur. En outre, à l'aide des paramètres transmis à la CLI Core Tools, nous avons créé une application Azure Functions avec un modèle de déclencheur HTTP à l'aide d'un runtime Node.js avec JavaScript.

Nous pouvons démarrer notre nouvelle fonction Azure à partir de la CLI pour écouter les requêtes HTTP. via localhost sur le port 5050.

Remarque : lorsque vous utilisez le déclencheur HTTP pour une application Azure Functions, la fonction peut être appelée via le nom de l'application de fonction ajouté au point de terminaison. Un exemple de l'application de fonction de produits créée ci-dessus est /products.

func start -p 5050

Avant de commencer à implémenter les fonctions Azure, installons les deux dépendances ci-dessous, à utiliser dans le Fonctions Azure.

yarn add stripe dotenv

Le package Node.js de Stripe, installé ci-dessus, sera utilisé pour interagir avec l'API Stripe. Et dotenv sera utilisé pour charger les informations d'identification secrètes de Stripe, utilisées dans les fonctions Azure qui seront créées ensuite.

Créez un fichier .env pour stocker les informations d'identification Stripe copiées à partir du Tableau de bord à rayures au format ci-dessous, en remplaçant l'espace réservé entre crochets angulaires par la valeur appropriée.

// .env

STRIPE_SECRET_KEY=

Les informations d'identification Stripe stockées ci-dessus seront utilisées pour authentifier le package Stripe avec l'API Stripe. Ces informations d'identification sont sensibles et doivent être stockées de manière privée. Pour éviter qu'ils ne soient poussés lorsque l'ensemble du projet est poussé vers un référentiel GitHub, créez un fichier .gitignore et ajoutez le nom de fichier .env.

// .gitignore
.env

À ce stade, le projet Azure Functions est entièrement configuré et nous pouvons maintenant procéder à la création des applications individuelles au sein du projet. Nous allons procéder à l'implémentation de la logique dans les applications Azure Functions, en commençant par l'application de fonction de produits.

Fonction de produits

Le but de cette fonction Azure est d'accepter une requête HTTP GETpuis répondez avec des données JSON contenant tous les produits du compte Stripe.

À l'aide de votre éditeur de code, ouvrez le fichier index.js dans le répertoire products créé lorsque vous avez créé Azure Projet de fonctions. Ajoutez le bloc de code ci-dessous au fichier index.js pour récupérer tous les produits créés dans Stripe.

require("dotenv").config();

const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
en-têtes const = {
  "Access-Control-Allow-Methods": "*",
  "Contrôle-Accès-Autoriser-Origine": "*",
  "Access-Control-Allow-Headers": "Content-Type",
  "Content-Type": "application/json",
} ;

module.exports = fonction async (contexte, req) {
  essayer {
    const { data } = wait stripe.products.list({});
    context.res = {
      en-têtes,
      corps: {
        Les données,
      },
    } ;
  } capture (e) {
    context.res = {
      en-têtes,
      corps : e,
    } ;
  }
} ;

La fonction exportée dans le bloc de code ci-dessus utilise la méthode list pour répertorier tous les produits créés dans le compte appartenant à la variable STRIPE_SECRET_KEY utilisée.

Une fois la promesse de la méthode asynchrone list est résolue, le tableau de données est déstructuré et renvoyé (avec certains en-têtes de requête) en tant que réponse à la requête, en définissant le corps dans l'objet context .[19659008]Pour tester la fonction implémentée ci-dessus, ouvrez une nouvelle CLI et exécutez la commande ci-dessous, qui envoie une requête HTTP GETà l'aide de cURLaux fonctions Azure exécutées dans un terminal séparé .

curl http://localhost:4040/api/customer

Après avoir exécuté la commande ci-dessus, une réponse JSON sera renvoyée à votre console contenant les produits précédemment créés.

La réponse de données JSON imprime la console d'une requête HTTP à la fonction produits n

La réponse de données JSON imprime la console à partir d'une requête HTTP vers la fonction produits. ( Grand aperçu)

Fonction de prix

Comme indiqué dans les champs renvoyés par la fonction de produits ci-dessus, les détails du prix d'un produit ne sont pas inclus dans l'objet product. Pour obtenir les détails du prix d'un produit, nous devons récupérer l'objet price associé au produit. Ce sera le travail de la fonction de prix, car à chaque exécution, elle renverra l'objet price associé à un produit.

Pour créer une nouvelle application Azure Functions, copiez le

existant. products et collez-le dans le même répertoire qu'un doublon. Ensuite, renommez le dossier dupliqué en price.

À l'aide de votre éditeur de code, ouvrez le fichier index.js dans le nouveau répertoire priceet remplacez le fonction existante avec le contenu du bloc de code ci-dessous, qui implémente la fonction prix :

require("dotenv").config();

const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
en-têtes const = {
  "Access-Control-Allow-Methods": "*",
  "Contrôle-Accès-Autoriser-Origine": "*",
  "Access-Control-Allow-Headers": "Content-Type",
  "Content-Type": "application/json",
} ;

module.exports = fonction async (contexte, req) {
  const { produit } = req.query;

  essayer {
    const { data } = wait stripe.prices.list({
      produit,
    });
    context.res = {
      en-têtes,
      corps: {
        données : données[0],
      },
    } ;
  } capture (e) {
    context.res = {
      en-têtes,
      corps : e,
    } ;
  }
} ;

L'application de fonction price ci-dessus accepte une requête HTTP GET qui contient un produit dans le paramètre query avec la valeur d'un ID de produit. La méthode list sur l'objet price est utilisée pour récupérer les prix dans un compte Stripe. Le paramètre product passé à la méthode list restreint les prix récupérés à ceux associés à l'objet product dont l'ID a été passé à la list.

Une fois la promesse de la méthode list résolue, le tableau de données de la méthode list est déstructuré et seul le premier objet du tableau de données est envoyé comme réponse à la demande.

Remarque : Seul le premier objet du tableau de données est renvoyé car nous souhaitons afficher une seule entité de prix. Un produit peut avoir plusieurs objets price attachés, mais pour cette application, nous n'en utiliserons qu'un.

Pour tester la fonction implémentée ci-dessus, exécutez la commande ci-dessous, qui envoie un GET Requête HTTP contenant un ID de produit dans un paramètre request aux fonctions Azure exécutées dans un terminal distinct.

Remarque : Vous pouvez trouver l'ID d'un produit dans Stripe. tableau de bord. Accédez à la page « Produits » et cliquez sur un produit pour afficher ses détails. Dans les détails affichés, vous trouverez l'ID du produit.

curl http://localhost:4040/api/price?product="prod_JudY3VFuma4zj7"

Une fois la commande ci-dessus exécutée, une réponse JSON sera renvoyé à votre console avec un objet contenant l'objet price d'un produit.

La réponse de données JSON imprime la console à partir d'une requête HTTP vers la fonction de prix

La réponse de données JSON imprime la console à partir de une requête HTTP à la fonction prix. ( Grand aperçu)

À partir de la réponse indiquée dans l'exemple ci-dessus, nous pouvons voir les détails du prix du produit, y compris la devise, le type et les données récurrentes.

Fonction d'achat

L'application de fonction d'achat sera utilisée soit pour faire un achat unique d'un produit ou pour abonner un utilisateur à un produit. L'une ou l'autre de ces deux opérations consiste à facturer un utilisateur via sa carte bancaire.

Pour créer une nouvelle application de fonction dans le projet Azure Functions, copiez soit les produits existants, soit le dossier price et collez-le dans le dossier même répertoire qu'un doublon. Ensuite, renommez le dossier dupliqué en purchase.

Dans votre éditeur de code, ajoutez le contenu du bloc de code ci-dessous dans le fichier index.jsqui gérera un ]POST demande de créer un abonnement ou un achat unique pour un utilisateur.

// ./purchase/index.js
require("dotenv").config();

const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
en-têtes const = {
  "Access-Control-Allow-Methods": "*",
  "Contrôle-Accès-Autoriser-Origine": "*",
  "Access-Control-Allow-Headers": "Content-Type",
  "Content-Type": "application/json",
} ;

module.exports = fonction async (contexte, req) {
  const {
    numéro,
    acheterDevise,
    cvc,
    exp_mois,
    exp_année,
    montant des achats,
    e-mail,
    type d'achat,
    prixEntityId,
  } = corps de requête;

  essayer {
    // Créer un mode de paiement pour l'utilisateur en utilisant les détails de la carte
    const { id: paymentID } = wait stripe.paymentMethods.create({
      tapez : "carte",
      carte: {
        numéro,
        cvc,
        exp_année,
        exp_mois,
      },
    });

    const { id: customerID } = wait stripe.customers.create({
      e-mail,
      description: "Client de la galerie d'art",
      payment_method : ID de paiement,
    });

    wait stripe.paymentMethods.attach(paymentID, { client: customerID });
    if (purchaseType === "récurrent") {
      const subscriptionData = wait stripe.subscriptions.create({
        client : ID client,
        default_payment_method : ID de paiement,
        éléments : [
          {
            price: priceEntityId,
          },
        ],
      });
      context.res = {
        en-têtes,
        corps: {
          message : "ABONNEMENT CREE",
          userStripeId : ID client,
          userSubscriptionId : subscriptionData.id,
        },
      } ;
    } autre {
      const { id: paymentIntentId } = wait stripe.paymentIntents.create({
        montant : montant de l'achat,
        devise : achatDevise || "USD",
        client : ID client,
        payment_method : ID de paiement,
      });
      const {mount_received } = wait stripe.paymentIntents.confirm(
        PaymentIntentId,
        {
          payment_method : ID de paiement,
        }
      );
      context.res = {
        en-têtes,
        corps: {
          message : `PAIEMENT DE ${amount_received} REÇU`,
        },
      } ;
    }
  } capture (e) {
    context.res = {
      statut : 500,
      corps : e,
    } ;
  }
} ;

L'application de fonction dans le bloc de code ci-dessus utilise le package Stripe pour créer un paiement unique ou un abonnement pour un utilisateur en fonction de la valeur purchaseType obtenue à partir du corps de la demande. Voici un aperçu de ce qui s'est passé ci-dessus :

  • Tout d'abord, une entité payment_method est créée à l'aide du numéro de carte de crédit, du nom, du CVC et des détails d'expiration, déstructurés à partir des données envoyées dans le corps de la demande de la fonction .
  • Ensuite, un client est créé dans Stripe à l'aide de la valeur email envoyée dans le corps de la demande, d'une description et du mode de paiement précédemment créé. L'objet customer est également attaché à l'entité payment_method en utilisant la méthode attach et en spécifiant la chaîne d'ID payment_method qui a été renvoyée lorsque le mode de paiement a été créé et en spécifiant une option customer avec l'ID client qui a été renvoyé lorsque l'entité customer a été créée.
  • La dernière partie du gestionnaire de fonction a un if condition qui évalue la valeur purchaseType envoyée dans le corps de la requête. Si la valeur purchaseType est récurrente, l'entité subscription contiendra l'ID client renvoyé par l'entité customerune default_payment_method avec le valeur de l'ID payment_method renvoyé par l'entité paymentet un tableau items avec un seul objet item contenant l'ID d'un price.

Extension de l'application Web de démonstration

Une application Web créée à l'aide de React servira de client Web qui accède directement aux applications Azure Functions que nous avons créées. jusqu'à maintenant. Comme expliqué précédemment, l'interface a déjà été créée et les données ont été récupérées à partir d'un fichier JSON fictif. Nous n'apporterons que quelques modifications minimes et ajouterons les requêtes HTTP pour utiliser le point de terminaison Azure Functions.

Clonez l'application Web à partir du référentiel GitHub en exécutant la commande Git ci-dessous à partir de votre CLI locale :

 git clone https://github.com/vickywane/stripe-art-app.git

Ensuite, accédez au répertoire de l'application clonée et installez les dépendances répertoriées dans le fichier package.json.

 ]# changer de répertoire
cd stripe-art-app

# installer les dépendances
wire install

Une fois les dépendances installées, exécutez la commande yarn start à partir de votre CLI pour afficher la page d'accueil de l'application Web à partir de votre navigateur Web à l'adresse http://localhost:3000 .

Page d'accueil de l'application de galerie affichant les illustrations du fichier mock.json local.

Page d'accueil de l'application de galerie affichant les illustrations du fichier mock.json local. ( Grand aperçu)

Avant de plonger dans la base de code de l'application Web, notons quelques points sur la structure existante de l'application.

Premièrement, la gestion des utilisateurs, y compris l'authentification et le stockage des données personnelles d'un utilisateur à partir de l'application, a été implémenté à l'aide de Auth0 via l'utilisation du auth0-react SDK pour les applications React.

Pour utiliser Auth0 dans l'application clonée, nous devons fournir les informations d'identification d'un Auth0 application à page unique saisissez le fichier .env dans le dossier de l'application Web au format indiqué ci-dessous.

Remarque : consultez le guide de démarrage rapide Auth0 pour plus de détails sur la façon de démarrer avec une application d'une seule page.

# ./env

REACT_APP_AUTHO_DOMAIN=
REACT_APP_AUTHO_SECRET_KEY=
REACT_APP_FUNCTION_ENDPOINT="http://localhost:5050/api"

Le REACT_APP_FUNCTION_ENDPOINT défini dans le fichier .env ci-dessus sera accessible avec les composants de l'application pour faire des requêtes HTTP au exécuter des applications de fonction. Actuellement, les applications Azure Functions sont servies localement sur l'hôte local de votre ordinateur, mais cela deviendra une URL en direct lorsque les applications de fonction seront déployées sur Azure Functions.

La deuxième chose à noter est que les données des produits artistiques affichées sur la page d'accueil est statique, récupérée à partir d'un fichier JSON dans le répertoire data.

Dans cette partie de cet article, nous allons étendre les fonctionnalités ci-dessus comme suit :

  • Page d'accueil[19659132]Nous allons refactoriser la page d'accueil pour récupérer et afficher les produits créés dans Stripe à l'aide de la fonction Azure des produits GET créée précédemment, et nous supprimerons le fichier mock.json contenant l'art du prototype produits.
  • Page de paiement
    Nous allons créer une nouvelle page de paiement pour les utilisateurs qui souhaitent acheter une reproduction d'art ou un abonnement avec leur carte de crédit.

Page d'accueil

La page d'accueil est affiché pour tous les utilisateurs, qu'ils soient authentiques ted ou non authentifié, et il affiche une liste de tous les produits d'art disponibles, en utilisant un composant enfant artworkCard exporté à partir du fichier artworkCard.js.

Nous devons apporter quelques modifications. à ce composant, car nous voulons que le bouton du composant artworkCard invite l'utilisateur à acheter une œuvre d'art. Modifiez le fichier artworkCard.js existant dans le répertoire components avec les parties en surbrillance du bloc de code ci-dessous.

// ./src/components/artworkCard.js

importer { naviguer } depuis "@reach/router" ;
import React, { useState, useEffect } de "react" ;

const ArtworkCard = ({ nom, description, img_uri, productId }) => {
  const [priceData, setPriceData] = useState({});

  useEffect(() => {
    (async () => wait fetchPrice())();
  }, []);

  const fetchPrice = async () => {
    const res = wait fetch(
      '${process.env.REACT_APP_FUNCTION_ENDPOINT}/price?product=${productId}'
    );
    const { data } = wait res.json();
    setPriceData(données);
  } ;

  retourner (
    
{name}

{'$${priceData.unit_amount}'}


{description}

); } ; export default ArtworkCard;

Dans les parties en surbrillance du fichier ci-dessus, nous avons introduit un useEffect hook pour faire une requête HTTP à l'application de fonction de prix pour récupérer l'objet price attaché à le produit affiché dans la carte. Une fois la promesse de la méthode fetch résolue, le flux de données est ensuite converti en JSON et stocké dans l'état local du composant.

Un bouton intitulé Acheter a également été ajouté à la Composant artworkCard. Lorsque vous cliquez dessus, l'utilisateur accède à la page de paiement, où l'utilisateur peut saisir les détails de sa carte bancaire pour acheter le produit.

Dans votre éditeur de code, ouvrez le fichier Home.js dans le ]pages et modifiez-le avec les parties en surbrillance du bloc de code ci-dessous, qui récupérera tous les produits disponibles dans Stripe via l'application de fonction de produits, puis les affichera.

# ./src/pages/home. js

import React, { useState, useEffect } de "react" ;
importer l'en-tête de "../components/header" ;
importer "../App.css" ;
importer la bannière de "../components/banner" ;
importer ArtworkCard depuis "../components/artworkCard" ;

const Accueil = () => {

  const [artworks, setArtworks] = useState([]);
  useEffect(() => {
    (async () => wait fetchArtworks())();
  }, []);

  const fetchArtworks = async () => {
    const res = wait fetch(`${process.env.REACT_APP_FUNCTION_ENDPOINT}/products`);
    const { data } = wait res.json();
    setArtworks(données);
  } ;

  retourner (
    


Mes peintures d'art notées

Chaque artiste plonge son pinceau dans sa propre âme,
et peint sa propre nature dans ses tableaux.


    {artworks.map(({ id, name, img_uri, images, description }) => (
  • ))}
); } ; exporter la page d'accueil par défaut ;

Dans le bloc de code ci-dessus, une requête GET est effectuée dès que le composant est chargé dans un hook useEffect à l'aide de l'API fetch du navigateur. La réponse de flux de la demande effectuée est ensuite convertie au format JSON et les données sont stockées dans l'état du composant local pour une utilisation ultérieure.

Avec cette modification, le fichier data.json n'est plus utilisé. De plus, lorsque vous affichez l'application Web dans votre navigateur, vous trouverez les produits créés dans Stripe affichés dans une grille, comme illustré ci-dessous :

Page d'accueil dans l'application de la galerie affichant tous les produits récupérés à partir de Stripe.

Page d'accueil dans application de galerie affichant tous les produits récupérés à partir de Stripe. ( Grand aperçu)

À partir des détails affichés dans l'image ci-dessus, vous remarquerez que les produits affichés sur la page d'accueil étaient ceux créés au début de cet article.

Page de paiement

Créez un checkout.js dans le répertoire pages. Ce nouveau fichier contiendra le composant qui sera affiché pour collecter les détails de la carte de crédit de l'utilisateur, une fois qu'ils seront acheminés vers /checkout en cliquant sur le bouton « Acheter » pour acheter une copie d'art.

Ajoutez le contenu du bloc de code ci-dessous pour créer le composant de paiement qui contient les éléments de formulaire pour collecter les détails de la carte de crédit :

# ./src/pages/checkout.js

import React, { useState } from "react";
import { useAuth0 } from "@auth0/auth0-react";
import Header from "../components/header";
import "../App.css";

const Checkout = (props) => {
  const { purchaseType, productId, priceEntityId, name, price } =
    props.location.state;

  const [cardNumber, setCardNumber] = useState("");
  const [cardName, setCardName] = useState("");
  const [cvc, setcvc] = useState("");
  const [cardExpiryMonth, setCardExpiryMonth] = useState("");
  const [cardExpiryYear, setCardExpiryYear] = useState("");
  const [loading, setLoading] = useState(false);
  const [paymentSuccess, setPaymentSuccess] = useState(false);
  const { user } = useAuth0();

  const makePayment = async () => {
    setLoading(true);
    try {
      const res = await fetch(
        `${process.env.REACT_APP_FUNCTION_ENDPOINT}/purchase`,
        {
          method: "POST",
          body: JSON.stringify({
            number: cardNumber,
            exp_month: cardExpiryMonth,
            exp_year: cardExpiryYear,
            purchaseAmount: price,
            purchaseType,
            priceEntityId,
            cvc,
            email: user.email,
          }),
        }
      );

      if (res.status === 200) {
        const { paymentId } = await res.json();
        await fetch(`${process.env.REACT_APP_FUNCTION_ENDPOINT}/billing-data`, {
          method: "POST",
          body: JSON.stringify({
            productId,
            userId: user.sub,
            paymentId,
          }),
        });
        setPaymentSuccess(true);
      }
    } catch (e) {
      console.log(e);
    } finally {
      setLoading(false);
    }
  };

  return (
    
{name} Checkout

Total Price: {`$${price}`}

Payment Type: {purchaseType.toUpperCase()}


{!paymentSuccess ? (
{ e.preventDefault(); makePayment(); }} >
Payment Details

setCardName(e.target.value)} className="payment-input" placeholder="Bank Cardholder Name" type="text" />

setCardNumber(e.target.value)} className="payment-input" placeholder="Bank Card Numbers" type="number" />

setcvc(e.target.value)} className="payment-input" placeholder="Bank Card CVC" type="text" />

setCardExpiryMonth(e.target.value)} className="payment-input" placeholder="Bank Card Expiry Month" type="text" />

setCardExpiryYear(e.target.value)} className="payment-input" placeholder="Bank Card Expiry Year" type="text" />

) : (

Your {`$${price}`} purchase of {name} was successfull{" "}

)}
); }; export default Checkout;

As described earlier, the form component above contains four input fields for the user to type in their name, number, expiration and CVC details. These details are further stored in the component’s local state, and, upon a click of the “Confirm my payment” button, the stored credit card details are used to purchase the product.

Of particular interest in the checkout component above is the makePayment function, because it handles the functionality of the checkout page. When executed, the makePayment function sends a POST request containing the credit card details in its request body using fetch to the /purchase cloud function. Once the first POST request is resolved successfully, with a 200 status code indicating a successful payment, a new POST request is made to the /billing-data cloud function to store the details of the purchased product.

Note: As explained when we were designing the productCard component, the purchased product details stored in Auth0 will be used to identify products purchased by the user from the home page.

To test this component, we will fill the input fields with the details of one of the basic test cards provided by Stripe for applications still in test mode, and then click the “Confirm payment” button, as shown below:

Checkout page in the gallery application displaying fields for inputting a credit card to purchase the selected product.

Checkout page in the gallery application displaying fields for inputting a credit card to purchase the selected product. (Large preview)

Note: The credit card used in the image above is one of the basic test cards provided by Stripe and not a real credit card. Stripe accounts in test mode must use one of the basic test cards.

Once the “Confirm my payment” button in the checkout card is clicked, a payment for the product is made from the credit card provided, and the checkout card interface is changed to reflect the successful response.

Checkout page in the gallery application displaying a successful payment response.

Checkout page in the gallery application displaying a successful payment response. (Large preview)

Going to the “Reports” section of your Stripe admin dashboard, you will see a reflection of the last payment made when the gallery subscription was created on the checkout page above.

Home page in Stripe admin dashboard displays $150 as gross volume for the day from last transaction.

Home page in Stripe admin dashboard displays $150 as gross volume for the day from last transaction. (Large preview)

From the charts shown in the image above, taken from the test Stripe card used in this tutorial, you will see that a gross volume of $150.00 was attained once the gallery subscription was created.

Note: The image also shows statistics from test operations that were made on the Stripe account while this article was being developed.

At this point, we have fully set up the entire payment flow. You can repeat the process of creating a product through the Stripe dashboard and purchasing it using the React application or any other client that consumes Azure Functions.

Summary

Congratulations on completing this hands-on tutorial.

By going through the steps in this tutorial, we have worked with Stripe, Azure Functions, and React. We started by building an API layer that uses the Stripe API through a Node.js package. Then, we moved on to consuming the Azure Functions app endpoints from a web application, using the function app to retrieve products and make payments for the products.

References

Smashing Editorial" width="35" height="46" loading="lazy" decoding="async(ks, vf, yk, al, il)




Source link