Intégration des méthodes de paiement Stripe et PayPal dans Ruby on Rails

Publié: 2022-03-11

Une caractéristique clé pour les grandes entreprises de commerce électronique telles qu'AliExpress, Ebay et Amazon est un moyen sécurisé de gérer les paiements, ce qui est essentiel pour leur entreprise. Si cette fonctionnalité échoue, les conséquences seraient dévastatrices. Cela s'applique aux leaders de l'industrie et aux développeurs Ruby on Rails travaillant sur des applications de commerce électronique.

La cybersécurité est essentielle pour prévenir les attaques, et un moyen de rendre le processus de transaction plus sûr consiste à demander à un service tiers de le gérer. L'inclusion de passerelles de paiement dans votre application est un moyen d'atteindre cet objectif, car elles fournissent l'autorisation de l'utilisateur, le cryptage des données et un tableau de bord afin que vous puissiez suivre l'état de la transaction à la volée.

Il existe une variété de services de passerelle de paiement sur le Web, mais dans cet article, je me concentrerai sur l'intégration de Stripe et PayPal à une application Rails. Pour n'en citer que quelques-uns : Amazon Payments, Square, SecurePay, WorldPay, Authorize.Net, 2Checkout.com, Braintree, Amazon ou BlueSnap.

Comment fonctionne l'intégration de la passerelle de paiement

Représentation générale pour les transactions impliquant des passerelles de paiement
Représentation générale pour les transactions impliquant des passerelles de paiement

En général, il y aura un formulaire/bouton dans votre application où l'utilisateur pourra se connecter/insérer des données de carte de crédit. PayPal et Stripe rendent déjà cette première étape plus sûre en utilisant des formulaires iframe ou des popups qui empêchent votre application de stocker des informations sensibles sur la carte de crédit de l'utilisateur car ils renverront un jeton représentant cette transaction. Certains utilisateurs peuvent également se sentir plus en confiance pour traiter les paiements en sachant qu'un service tiers gère le processus de transaction, ce qui peut également être une attraction pour votre application.

Après avoir authentifié les informations de l'utilisateur, une passerelle de paiement confirmera le paiement en contactant un processeur de paiement qui communique avec les banques afin de régler les paiements. Cela garantit que la transaction est correctement débitée/créditée.

Stripe utilise un formulaire de carte de crédit demandant le numéro de carte de crédit, le cvv et la date d'expiration. L'utilisateur doit donc remplir les informations de carte de crédit dans les entrées sécurisées de Stripe. Après avoir fourni ces informations, le backend de votre application traite ce paiement via un jeton.

Contrairement à Stripe, PayPal redirige l'utilisateur vers la page de connexion PayPal. L'utilisateur autorise et sélectionne le mode de paiement via PayPal, et encore une fois, votre back-end gérera les jetons au lieu des données sensibles de l'utilisateur.

Il est important de mentionner que, pour ces deux passerelles de paiement, votre back-end doit demander la poursuite de l'exécution de la transaction via les API Stripe ou PayPal qui donneront une réponse OK/NOK, de sorte que votre application doit rediriger l'utilisateur vers une page de réussite ou d'erreur en conséquence.

Le but de cet article est de fournir un guide rapide pour intégrer ces deux passerelles de paiement dans une seule application. Pour tous les tests, nous utiliserons des bacs à sable et des comptes de test fournis par Stripe et PayPal afin de simuler les paiements.

Installer

Avant d'intégrer les passerelles de paiement, nous allons faire une configuration pour initialiser l'application en ajoutant des gemmes, des tables de base de données et une page d'index. Ce projet a été créé avec Rails version 5.2.3 et Ruby 2.6.3.

Remarque : vous pouvez découvrir les nouvelles fonctionnalités de Rails 6 dans notre récent article.

Étape 1 : Initialiser une application Rails.

Initialisez le projet en exécutant l'initialisation du projet avec la commande rails avec le nom de votre application :

 rails new YOUR_APP_NAME

Et cd dans votre dossier d'application.

Étape 2 : Installez les gemmes.

Outre les gemmes Stripe et PayPal, quelques autres gemmes ont été ajoutées :

  • devise : utilisé pour l'authentification et l'autorisation des utilisateurs
  • haml : outil de création de modèles pour le rendu des pages utilisateur
  • jquery-rails : pour jquery dans les scripts frontaux
  • money-rails : pour afficher les valeurs monétaires formatées

Ajoutez à votre Gemfile :

 gem "devise", ">= 4.7.1" gem "haml" gem "jquery-rails" gem "money-rails"

Après l'avoir ajouté, exécutez-le dans votre CLI :

 bundle install

Étape 3 : Initialisez les gemmes.

Certaines de ces gemmes nécessiteront une initialisation en plus de leur installation via bundle .

Dispositif d'installation :

 rails g devise:install

Initialisation money-rails :

 rails g money_rails:initializer

Initialisez jquery-rails en ajoutant au bas de app/assets/javascripts/application.js ce qui suit :

 //= require jquery //= require jquery_ujs

Étape 4 : Tables et migrations

Trois tables seront utilisées dans ce projet Users , Products et Orders .

  • Users : Seront générés par devis
  • Colonnes Products :
    • name
    • price_cents
    • Stripe_plan_name : un ID représentant un plan d'abonnement créé dans Stripe, afin que les utilisateurs puissent s'y abonner. Ce champ n'est requis que pour les produits associés à un plan Stripe.
    • paypal_plan_name : Identique à stripe_plan_name mais pour PayPal
  • Colonnes Orders :
    • product_id
    • user_id
    • status : Cela indiquera si la commande est en attente, échouée ou payée.
    • token : Il s'agit d'un token généré à partir des API (soit Stripe soit PayPal) afin d'initialiser une transaction.
    • price_cents : Similaire au produit, mais utilisé pour rendre cette valeur persistante dans l'enregistrement de la commande
    • payment_gateway : Enregistre la passerelle de paiement utilisée pour la commande PayPal ou Stripe
    • customer_id : Ceci sera utilisé pour Stripe afin de stocker le client Stripe pour un abonnement, et cela sera expliqué plus en détail dans une section ultérieure.

Pour générer ces tables, quelques migrations doivent être générées :

Pour créer la table Utilisateurs . Cours:

 rails g devise User

Pour créer la table Produits . Générez une migration en exécutant :

 rails generate migration CreateProducts name:string stripe_plan_name:string paypal_plan_name:string

Ouvrez votre fichier de migration créé, qui doit se trouver dans db/migrate/ , et apportez des modifications pour que votre migration ressemble à ceci :

 class CreateProducts < ActiveRecord::Migration[5.2] def change create_table :products do |t| t.string :name t.string :stripe_plan_name t.string :paypal_plan_name end add_money :products, :price, currency: { present: true } end end

Pour créer la table Commandes . Générez une migration en exécutant :

 rails generate migration CreateOrders product_id:integer user_id:integer status:integer token:string charge_id:string error_message:string customer_id:string payment_gateway:integer

Encore une fois, ouvrez votre fichier de migration créé qui devrait être situé dans db/migrate/ et apportez des modifications à ce fichier afin qu'il ressemble à ceci :

 class CreateOrders < ActiveRecord::Migration[5.2] def change create_table :orders do |t| t.integer :product_id t.integer :user_id t.integer :status, default: 0 t.string :token t.string :charge_id t.string :error_message t.string :customer_id t.integer :payment_gateway t.timestamps end add_money :orders, :price, currency: { present: false } end end

Exécutez les migrations de base de données en exécutant :

 rails db:migrate

Étape 5 : Créer des modèles.

Le modèle utilisateur est déjà créé à partir de l'installation de l'outil et aucune modification ne sera nécessaire. En plus de cela, deux modèles seront créés pour Product et Order .

Produit. Ajoutez un nouveau fichier, app/models/product.rb , avec :

 class Product < ActiveRecord::Base monetize :price_cents has_many :orders end

Commande. Ajoutez un nouveau fichier, app/models/order.rb , avec :

 class Order < ApplicationRecord enum status: { pending: 0, failed: 1, paid: 2, paypal_executed: 3} enum payment_gateway: { stripe: 0, paypal: 1 } belongs_to :product belongs_to :user scope :recently_created, -> { where(created_at: 1.minutes.ago..DateTime.now) } def set_paid self.status = Order.statuses[:paid] end def set_failed self.status = Order.statuses[:failed] end def set_paypal_executed self.status = Order.statuses[:paypal_executed] end end

Étape 6 : Remplissez la base de données.

Un utilisateur et deux produits seront créés dans la console. Les enregistrements de commande seront créés en fonction des tests de paiement.

  • Courir rails s
  • Dans votre navigateur, visitez http://localhost:3000
  • Vous serez redirigé vers une page d'inscription.
  • Inscrivez un utilisateur en renseignant son adresse e-mail et son mot de passe.
  • Dans votre terminal, les journaux suivants seront affichés indiquant qu'un utilisateur a été créé dans votre base de données :
 User Create (0.1ms) INSERT INTO "users" ("email", "encrypted_password", "created_at", "updated_at") VALUES (?, ?, ?, ?) …
  • Créez deux produits sans abonnement en exécutant les rails c et en ajoutant :
    • Product.create(name: "Awesome T-Shirt", price_cents: 3000)
    • Product.create(name: "Awesome Sneakers", price_cents: 5000)

Étape 7 : Créer une page d'index

La page principale du projet comprend une sélection de produits pour les achats ou les abonnements. De plus, il comporte également une section pour la sélection du mode de paiement (Stripe ou PayPal). Un bouton d'envoi est également utilisé pour chaque type de passerelle de paiement, car pour PayPal, nous ajouterons sa propre conception de bouton via sa bibliothèque JavaScript.

Tout d'abord, créez les routes pour index et submit -les dans config/routes.rb .

 Rails.application.routes.draw do devise_for :users get '/', to: 'orders#index' post '/orders/submit', to: 'orders#submit' end

Créez et ajoutez des actions index et submit dans le contrôleur de commandes app/controllers/orders_controller.rb . L'action orders#index stocke deux variables à consommer dans le front-end : @products_purchase qui a une liste de produits sans plans et @products_subscription qui a des produits avec des plans PayPal et Stripe.

 class OrdersController < ApplicationController before_action :authenticate_user! def index products = Product.all @products_purchase = products.where(stripe_plan_name:nil, paypal_plan_name:nil) @products_subscription = products - @products_purchase end def submit end end

Créez un fichier dans app/views/orders/index.html.haml . Ce fichier contient toutes les entrées que nous allons envoyer à notre serveur principal via la méthode de soumission, ainsi que l'interaction pour les passerelles de paiement et la sélection de produits. Voici quelques attributs de nom d'entrée :

  • Orders[product_id] stocke l'identifiant du produit.
  • Orders[payment_gateway] contient la passerelle de paiement avec les valeurs Stripe ou PayPal pour l'autre.
 %div %h1 List of products = form_tag({:controller => "orders", :action => "submit" }, {:id => 'order-details'}) do %input{id:'order-type', :type=>"hidden", :value=>"stripe", :name=>'orders[payment_gateway]'} .form_row %h4 Charges/Payments - @products_purchase.each do |product| %div{'data-charges-and-payments-section': true} = radio_button_tag 'orders[product_id]', product.id, @products_purchase.first == product %span{id: "radioButtonName#{product.id}"} #{product.name} %span{id: "radioButtonPrice#{product.id}", :'data-price' => "#{product.price_cents}"} #{humanized_money_with_symbol product.price} %br %h4 Subscriptions - @products_subscription.each do |product| %div = radio_button_tag 'orders[product_id]', product.id, false %span{id: "radioButtonName#{product.id}"} #{product.name} %span{id: "radioButtonPrice#{product.id}", :'data-price' => "#{product.price_cents}"} #{humanized_money_with_symbol product.price} %br %hr %h1 Payment Method .form_row %div = radio_button_tag 'payment-selection', 'stripe', true, onclick: "changeTab();" %span Stripe %br %div = radio_button_tag 'payment-selection', 'paypal', false, onclick: "changeTab();" %span Paypal %br %br %div{id:'tab-stripe', class:'paymentSelectionTab active'} %div{id:'card-element'} %div{id:'card-errors', role:"alert"} %br %br = submit_tag "Buy it!", id: "submit-stripe" %div{id:'tab-paypal', class:'paymentSelectionTab'} %div{id: "submit-paypal"} %br %br %hr :javascript function changeTab() { var newActiveTabID = $('input[name="payment-selection"]:checked').val(); $('.paymentSelectionTab').removeClass('active'); $('#tab-' + newActiveTabID).addClass('active'); } :css #card-element { width:500px; } .paymentSelectionTab { display: none; } .paymentSelectionTab.active { display: block !important; }

Si vous exécutez votre application avec des rails s et visitez votre page dans http://localhost:3000 . Vous devriez pouvoir voir la page comme suit :

Page d'index brute sans intégration Stripe et PayPal
Page d'index brute sans intégration Stripe et PayPal

Stockage des informations d'identification de la passerelle de paiement

Les clés PayPal et Stripe seront stockées dans un fichier non suivi par Git. Il existe deux types de clés stockées dans ce fichier pour chaque passerelle de paiement, et pour l'instant, nous utiliserons une valeur fictive pour elles. Des instructions supplémentaires pour la création de ces clés sont présentées dans les sections suivantes.

Étape 1 : Ajoutez ceci dans .gitignore .

 /config/application.yml

Étape 2 : Créez un fichier avec vos informations d'identification dans config/application.yml . Il doit contenir toutes vos clés de bac à sable/test PayPal et Stripe pour accéder à ces API.

 test: &default PAYPAL_ENV: sandbox PAYPAL_CLIENT_ID: YOUR_CREDENTIAL_HERE PAYPAL_CLIENT_SECRET: YOUR_CREDENTIAL_HERE STRIPE_PUBLISHABLE_KEY: YOUR_CREDENTIAL_HERE STRIPE_SECRET_KEY: YOUR_CREDENTIAL_HERE development: <<: *default

Étape 3 : Afin de stocker les variables du fichier config/application.yml au démarrage de l'application, ajoutez ces lignes dans config/application.rb à l'intérieur de la classe Application afin qu'elles soient disponibles dans ENV .

 config_file = Rails.application.config_for(:application) config_file.each do |key,value| ENV[key] = value end unless config_file.nil?

Configuration de bande

Nous ajouterons une gemme pour utiliser l'API Stripe : stripe-rails . La création d'un compte Stripe est également nécessaire pour que les frais et les abonnements puissent être traités. Si nécessaire, vous pouvez consulter les méthodes API pour l'API Stripe dans la documentation officielle.

Étape 1 : Ajoutez la gemme Stripe-Rails à votre projet.

La gemme stripe-rails fournira une interface pour toutes les requêtes API utilisées dans ce projet.

Ajoutez ceci dans le Gemfile :

 gem 'stripe-rails'

Cours:

 bundle install

Étape 2 : Générez vos clés API.

Afin d'avoir les clés API pour communiquer avec Stripe, vous devrez créer un compte dans Stripe. Pour tester l'application, il est possible d'utiliser le mode test, donc aucune véritable information commerciale ne doit être renseignée dans le processus de création de compte Stripe.

  • Créez un compte dans Stripe si vous n'en avez pas (https://dashboard.stripe.com/).
  • Toujours dans le tableau de bord Stripe, après vous être connecté, activez Afficher les données de test .
  • Sur https://dashboard.stripe.com/test/apikeys, remplacez YOUR_CREDENTIAL_HERE pour les valeurs STRIPE_PUBLISHABLE_KEY et STRIPE_SECRET_KEY dans /config/application.yml par le contenu de Publishable Key et Secret key .

Étape 3 : Initialiser le module Stripe

En plus de remplacer les clés, nous devons encore initialiser le module Stripe, afin qu'il utilise les clés déjà définies dans notre ENV .

Créez un fichier dans config/initializers/stripe.rb avec :

 Rails.application.configure do config.stripe.secret_key = ENV["STRIPE_SECRET_KEY"] config.stripe.publishable_key = ENV["STRIPE_PUBLISHABLE_KEY"] end

Étape 4 : Intégrez Stripe dans le front-end.

Nous ajouterons la bibliothèque Stripe JavaScript et la logique d'envoi d'un jeton qui représente les informations de carte de crédit de l'utilisateur et sera traité dans notre back-end.

Dans le fichier index.html.haml , ajoutez ceci en haut de votre fichier. Cela utilisera le module Stripe (fourni par la gemme) pour ajouter la bibliothèque javascript Stripe à la page de l'utilisateur.

 = stripe_javascript_tag

Stripe utilise des champs de saisie sécurisés créés via leur API. Comme ils sont créés dans un iframe créé via cette API, vous n'aurez pas à vous soucier des éventuelles vulnérabilités traitant les informations de carte de crédit de l'utilisateur. De plus, votre serveur principal ne sera pas en mesure de traiter/stocker les données sensibles de l'utilisateur, et il ne recevra qu'un jeton représentant ces informations.

Ces champs de saisie sont créés en appelant stripe.elements().create('card') . Après cela, il suffit d'appeler l'objet renvoyé avec mount() en passant comme argument l'élément HTML id/class où ces entrées doivent être montées. Plus d'informations peuvent être trouvées sur Stripe.

Lorsque l'utilisateur appuie sur le bouton d'envoi avec le mode de paiement Stripe, un autre appel d'API renvoyant une promesse est effectué sur l'élément de carte Stripe créé :

 stripe.createToken(card).then(function(result)

La variable de result de cette fonction, si aucune erreur de propriété n'est affectée, aura un jeton qui peut être récupéré en accédant à l'attribut result.token.id . Ce jeton sera envoyé au serveur principal.

Pour effectuer ces modifications, remplacez le code commenté // YOUR STRIPE AND PAYPAL CODE WILL BE HERE dans index.html.haml par :

 (function setupStripe() { //Initialize stripe with publishable key var stripe = Stripe("#{ENV['STRIPE_PUBLISHABLE_KEY']}"); //Create Stripe credit card elements. var elements = stripe.elements(); var card = elements.create('card'); //Add a listener in order to check if card.addEventListener('change', function(event) { //the div card-errors contains error details if any var displayError = document.getElementById('card-errors'); document.getElementById('submit-stripe').disabled = false; if (event.error) { // Display error displayError.textContent = event.error.message; } else { // Clear error displayError.textContent = ''; } }); // Mount Stripe card element in the #card-element div. card.mount('#card-element'); var form = document.getElementById('order-details'); // This will be called when the #submit-stripe button is clicked by the user. form.addEventListener('submit', function(event) { $('#submit-stripe').prop('disabled', true); event.preventDefault(); stripe.createToken(card).then(function(result) { if (result.error) { // Inform that there was an error. var errorElement = document.getElementById('card-errors'); errorElement.textContent = result.error.message; } else { // Now we submit the form. We also add a hidden input storing // the token. So our back-end can consume it. var $form = $("#order-details"); // Add a hidden input orders[token] $form.append($('<input type="hidden" name="orders[token]"/>').val(result.token.id)); // Set order type $('#order-type').val('stripe'); $form.submit(); } }); return false; }); }()); //YOUR PAYPAL CODE WILL BE HERE

Si vous visitez votre page, elle devrait ressembler à ceci avec les nouveaux champs de saisie sécurisés Stripe :

Page d'index intégrée aux champs de saisie sécurisés Stripe.
Page d'index intégrée aux champs de saisie sécurisés Stripe.

Étape 5 : Testez votre application.

Remplissez le formulaire de carte de crédit avec une carte de test (https://stripe.com/docs/testing) et soumettez la page. Vérifiez si l'action submit est appelée avec tous les paramètres ( product_id , payment_gateway et token ) dans la sortie de votre serveur.

Frais de bande

Les frais Stripe représentent des transactions uniques. Par conséquent, après une transaction de frais Stripe, vous recevrez directement de l'argent du client. C'est idéal pour vendre des produits qui ne sont pas associés à des plans. Dans une section ultérieure, je montrerai comment effectuer le même type de transaction avec PayPal, mais le nom de PayPal pour ce type de transaction est Payment .

Dans cette section, je fournirai également tout le squelette pour gérer et soumettre une commande. Nous créons une commande dans l'action de submit lorsque le formulaire Stripe est soumis. Cette commande aura initialement le statut en attente , donc si quelque chose ne va pas lors du traitement de cette commande, la commande sera toujours en attente .

Si une erreur survient lors des appels de l'API Stripe, nous définissons la commande dans un état d' échec , et si la charge est effectuée avec succès, elle sera dans l'état payé . L'utilisateur est également redirigé en fonction de la réponse de l'API Stripe comme indiqué dans le graphique suivant :

Transactions à rayures.
Transactions à rayures.

De plus, lorsqu'une charge Stripe est effectuée, un identifiant est renvoyé. Nous stockerons cet identifiant afin que vous puissiez le rechercher ultérieurement dans votre tableau de bord Stripe si nécessaire. Cet identifiant peut également être utilisé si la commande doit être remboursée. Une telle chose ne sera pas explorée dans cet article.

Étape 1 : Créez le service Stripe.

Nous utiliserons une classe singleton pour représenter les opérations Stripe à l'aide de l'API Stripe. Afin de créer une charge, la méthode Stripe::Charge.create est appelée et l'attribut d'ID d'objet renvoyé sera stocké dans l'enregistrement de commande charge_id . Cette fonction de create est appelée en transmettant le jeton créé dans le frontal, le prix de la commande et une description.

Créez donc un nouveau dossier app/services/orders , et ajoutez un service Stripe : app/services/orders/stripe.rb contenant la classe singleton Orders::Stripe , qui a une entrée dans la méthode execute .

 class Orders::Stripe INVALID_STRIPE_OPERATION = 'Invalid Stripe Operation' def self.execute(order:, user:) product = order.product # Check if the order is a plan if product.stripe_plan_name.blank? charge = self.execute_charge(price_cents: product.price_cents, description: product.name, card_token: order.token) else #SUBSCRIPTIONS WILL BE HANDLED HERE end unless charge&.id.blank? # If there is a charge with id, set order paid. order.charge_id = charge.id order.set_paid end rescue Stripe::StripeError => e # If a Stripe error is raised from the API, # set status failed and an error message order.error_message = INVALID_STRIPE_OPERATION order.set_failed end private def self.execute_charge(price_cents:, description:, card_token:) Stripe::Charge.create({ amount: price_cents.to_s, currency: "usd", description: description, source: card_token }) end end

Étape 2 : implémentez l'action de soumission et appelez le service Stripe.

Dans orders_controller.rb , ajoutez ce qui suit dans l'action submit , qui appellera essentiellement le service Orders::Stripe.execute . Notez que deux nouvelles fonctions privées ont également été ajoutées : prepare_new_order et order_params .

 def submit @order = nil #Check which type of order it is if order_params[:payment_gateway] == "stripe" prepare_new_order Orders::Stripe.execute(order: @order, user: current_user) elsif order_params[:payment_gateway] == "paypal" #PAYPAL WILL BE HANDLED HERE end ensure if @order&.save if @order.paid? # Success is rendered when order is paid and saved return render html: SUCCESS_MESSAGE elsif @order.failed? && [email protected]_message.blank? # Render error only if order failed and there is an error_message return render html: @order.error_message end end render html: FAILURE_MESSAGE end private # Initialize a new order and and set its user, product and price. def prepare_new_order @order = Order.new(order_params) @order.user_id = current_user.id @product = Product.find(@order.product_id) @order.price_cents = @product.price_cents end def order_params params.require(:orders).permit(:product_id, :token, :payment_gateway, :charge_id) end

Étape 3 : testez votre application.

Vérifiez si l'action submit, lorsqu'elle est appelée avec une carte de test valide, effectue une redirection vers un message réussi. De plus, vérifiez dans votre tableau de bord Stripe si la commande est également affichée.

Abonnements Stripe

Des abonnements ou des plans peuvent être créés pour des paiements récurrents. Avec ce type de produit, l'utilisateur est automatiquement facturé quotidiennement, hebdomadairement, mensuellement ou annuellement selon la configuration du plan. Dans cette section, nous utiliserons le champ pour le produit stripe_plan_name afin de stocker l'ID du plan - en fait, il nous est possible de choisir l'ID, et nous l'appellerons premium-plan - qui sera utilisé pour créer le relation customer <-> subscription .

Nous allons également créer une nouvelle colonne pour la table des utilisateurs appelée stripe_customer_id qui sera remplie avec la propriété id d'un objet client Stripe. Un client Stripe est créé lorsque la fonction Stripe::Customer.create est appelée, et vous pouvez également vérifier les clients créés et liés à votre compte dans (https://dashboard.stripe.com/test/customers). Les clients sont créés en passant un paramètre source qui, dans notre cas, est le jeton généré dans le frontal qui est envoyé lors de la soumission du formulaire.

L'objet client obtenu à partir du dernier appel d'API Stripe mentionné est également utilisé pour créer un abonnement, ce qui se fait en appelant customer.subscriptions.create et en transmettant l'ID du plan en tant que paramètre.

De plus, la gemme stripe-rails fournit l'interface pour récupérer et mettre à jour un client à partir de Stripe, ce qui se fait en appelant Stripe::Customer.retrieve et Stripe::Customer.update , respectivement.

Ainsi, lorsqu'un enregistrement d'utilisateur a déjà un stripe_customer_id , au lieu de créer un nouveau client en utilisant Stripe::Customer.create , nous appellerons Stripe::Customer.retrieve en passant le stripe_customer_id comme paramètre, suivi d'un Stripe::Customer.update , et dans ce cas, en passant le jeton en paramètre.

Tout d'abord, nous allons créer un plan à l'aide de l'API Stripe afin de pouvoir créer un nouveau produit d'abonnement en utilisant le champ stripe_plan_name . Ensuite, nous apporterons des modifications dans le service orders_controller et Stripe afin que la création et l'exécution des abonnements Stripe soient gérées.

Étape 1 : Créez un plan à l'aide de l'API Stripe.

Ouvrez votre console en utilisant les rails c . Créez un abonnement pour votre compte Stripe avec :

 Stripe::Plan.create({ amount: 10000, interval: 'month', product: { name: 'Premium plan', }, currency: 'usd', id: 'premium-plan', })

Si le résultat renvoyé à cette étape est vrai, cela signifie que le plan a été créé avec succès et que vous pouvez y accéder dans votre tableau de bord Stripe.

Étape 2 : Créez un produit dans la base de données avec le champ stripe_plan_name défini.

Maintenant, créez un produit avec le stripe_plan_name défini comme premium-plan dans la base de données :

 Product.create(price_cents: 10000, name: 'Premium Plan', stripe_plan_name: 'premium-plan')

Étape 3 : Générez une migration pour ajouter une colonne stripe_customer_id dans la table des users .

Exécutez ce qui suit dans le terminal :

 rails generate migration AddStripeCustomerIdToUser stripe_customer_id:string rails db:migrate

Étape 4 : implémentez la logique d'abonnement dans la classe de service Stripe.

Ajoutez deux fonctions supplémentaires dans les méthodes privées de app/services/orders/stripe.rb : execute_subscription est responsable de la création des abonnements dans l'objet du client. La fonction find_or_create_customer est chargée de retourner le client déjà créé ou en retournant un client nouvellement créé.

 def self.execute_subscription(plan:, token:, customer:) customer.subscriptions.create({ plan: plan }) end def self.find_or_create_customer(card_token:, customer_id:, email:) if customer_id stripe_customer = Stripe::Customer.retrieve({ id: customer_id }) if stripe_customer stripe_customer = Stripe::Customer.update(stripe_customer.id, { source: card_token}) end else stripe_customer = Stripe::Customer.create({ email: email, source: card_token }) end stripe_customer end

Enfin, dans la fonction execute du même fichier ( app/services/orders/stripe.rb ), nous allons d'abord appeler find_or_create_customer puis exécuter l'abonnement en appelant execute_subscription en passant le précédent client récupéré/créé. Remplacez donc le commentaire #SUBSCRIPTIONS WILL BE HANDLED HERE dans la méthode d' execute par le code suivant :

 customer = self.find_or_create_customer(card_token: order.token, customer_id: user.stripe_customer_id, email: user.email) if customer user.update(stripe_customer_id: customer.id) order.customer_id = customer.id charge = self.execute_subscription(plan: product.stripe_plan_name, customer: customer)

Étape 5 : Testez votre application.

Visitez votre site Web, sélectionnez le produit d'abonnement Premium Plan et remplissez une carte de test valide. Après la soumission, il devrait vous rediriger vers une page réussie. De plus, vérifiez dans votre tableau de bord Stripe si l'abonnement a été créé avec succès.

Configurer PayPal

Comme nous l'avons fait dans Stripe, nous ajouterons également un joyau pour l'utilisation de l'API PayPal : paypal-sdk-rest , et la création d'un compte PayPal est également requise. Un workflow descriptif pour PayPal utilisant cette gemme peut être consulté dans la documentation officielle de l'API PayPal.

Étape 1 : Ajoutez la gemme paypal-sdk-rest à votre projet.

Ajoutez ceci dans le Gemfile :

 gem 'paypal-sdk-rest'

Cours:

 bundle install

Étape 2 : Générez vos clés API.

Afin d'avoir les clés API pour communiquer avec PayPal, vous devrez créer un compte PayPal. Alors:

  • Créez un compte (ou utilisez votre compte PayPal) sur https://developer.paypal.com/.
  • Toujours connecté à votre compte, créez deux comptes sandbox sur https://developer.paypal.com/developer/accounts/ :
    • Personnel (compte acheteur) – Il sera utilisé dans vos tests pour effectuer des paiements et des abonnements.
    • Entreprise (compte marchand) - Ceci sera lié à l'application, qui aura les clés API que nous recherchons. De plus, toutes les transactions peuvent être suivies dans ce compte.
  • Créez une application sur https://developer.paypal.com/developer/applications en utilisant l'ancien compte sandbox professionnel.
  • Après cette étape, vous recevrez deux clés pour PayPal : Client ID et Secret .
  • Dans config/application.yml , remplacez YOUR_CREDENTIAL_HERE de PAYPAL_CLIENT_ID et PAYPAL_CLIENT_SECRET par les clés que vous venez de recevoir.

Étape 3 : Initialisez le module PayPal.

Semblable à Stripe, en plus de remplacer les clés dans application.yml , nous devons encore initialiser le module PayPal afin qu'il puisse utiliser les clés déjà définies dans notre variable ENV . Pour cela, créez un fichier dans config/initializers/paypal.rb avec :

 PayPal::SDK.configure( mode: ENV['PAYPAL_ENV'], client_id: ENV['PAYPAL_CLIENT_ID'], client_secret: ENV['PAYPAL_CLIENT_SECRET'], ) PayPal::SDK.logger.level = Logger::INFO

Étape 4 : Intégrez PayPal dans le front-end.

Dans index.html.haml , ajoutez ceci en haut du fichier :

 %script(src="https://www.paypal.com/sdk/js?client-id=#{ENV['PAYPAL_CLIENT_ID']}")

Contrairement à Stripe, PayPal utilise uniquement un bouton qui, lorsqu'il est cliqué, ouvre une fenêtre contextuelle sécurisée où l'utilisateur peut se connecter et procéder au paiement/à l'abonnement. Ce bouton peut être rendu en appelant la méthode paypal.Button(PARAM1).render(PARAM2) .

  • PARAM1 est un objet avec la configuration de l'environnement et deux fonctions de rappel comme propriétés : createOrder et onApprove .
  • PARAM2 indique l'identifiant de l'élément HTML auquel le bouton PayPal doit être attaché.

Ainsi, toujours dans le même fichier, remplacez le code commenté YOUR PAYPAL CODE WILL BE HERE par :

 (function setupPaypal() { function isPayment() { return $('[data-charges-and-payments-section] input[name="orders[product_id]"]:checked').length } function submitOrderPaypal(chargeID) { var $form = $("#order-details"); // Add a hidden input orders[charge_id] $form.append($('<input type="hidden" name="orders[charge_id]"/>').val(chargeID)); // Set order type $('#order-type').val('paypal'); $form.submit(); } paypal.Buttons({ env: "#{ENV['PAYPAL_ENV']}", createOrder: function() { }, onApprove: function(data) { } }).render('#submit-paypal'); }());

Étape 5 : Testez votre application.

Visitez votre page et vérifiez si le bouton PayPal s'affiche lorsque vous sélectionnez PayPal comme mode de paiement.

Opérations PayPal

La logique des transactions PayPal, contrairement à Stripe, est un peu plus complexe en impliquant davantage de demandes provenant du front-end vers le back-end. C'est pourquoi cette section existe. J'expliquerai plus ou moins (sans aucun code) comment les fonctions décrites dans les méthodes createOrder et onApprove vont être implémentées et ce qui est également attendu dans les processus back-end.

Étape 1 : Lorsque l'utilisateur clique sur le bouton d'envoi de PayPal, une fenêtre contextuelle PayPal demandant les informations d'identification de l'utilisateur s'ouvre mais est en cours de chargement. La fonction callback createOrder est appelée.

Popup PayPal, état de chargement
Popup PayPal, état de chargement

Étape 2 : Dans cette fonction, nous effectuerons une demande à notre back-end qui créera un paiement/abonnement. C'est le tout début d'une transaction, et aucun frais ne sera appliqué pour le moment, donc la transaction est en fait dans un état en attente . Notre serveur principal devrait nous renvoyer un jeton, qui sera généré à l'aide du module PayPal (fourni via le gem paypal-rest-sdk ).

Étape 3 : Toujours dans le rappel createOrder , nous renvoyons ce jeton généré dans notre back-end, et si tout va bien, la fenêtre contextuelle PayPal affichera ce qui suit, demandant les informations d'identification de l'utilisateur :

Popup PayPal, informations d'identification de l'utilisateur
Popup PayPal, informations d'identification de l'utilisateur

Étape 4 : Une fois que l'utilisateur s'est connecté et a sélectionné le mode de paiement, la fenêtre contextuelle changera son état comme suit :

Popup PayPal, transaction autorisée
Popup PayPal, transaction autorisée

Étape 5 : Le rappel de la fonction onApprove est maintenant appelé. Nous l'avons défini comme suit : onApprove: function(data) . L'objet data aura les informations de paiement afin de l'exécuter. Dans ce rappel, une autre demande à notre fonction back-end sera effectuée cette fois en passant l'objet de données afin d'exécuter la commande PayPal.

Étape 6 : Notre serveur principal exécute cette transaction et renvoie 200 (en cas de succès).

Étape 7 : Lorsque notre back-end revient, nous soumettons le formulaire. Il s'agit de la troisième requête que nous adressons à notre back-end.

Notez que, contrairement à Stripe, trois requêtes sont adressées à notre back-end dans ce processus. Et nous garderons l'état de notre dossier de commande synchronisé en conséquence :

  • createOrder : une transaction est créée et un enregistrement de commande est également créé ; par conséquent, il est dans un état en attente par défaut.
  • onApprove : la transaction est exécutée et notre commande sera définie comme paypal_executed .
  • La page de commande est soumise : La transaction a déjà été exécutée, donc rien ne change. L'enregistrement de la commande changera son état en payé .

Tout ce processus est décrit dans le graphique suivant :

Opérations PayPal
Opérations PayPal

Paiements PayPal

Les paiements PayPal suivent la même logique que Stripe Charges, ils représentent donc des transactions uniques, mais comme mentionné dans la section précédente, ils ont une logique de flux différente. Voici les changements qui devront être effectués pour gérer les paiements PayPal :

Étape 1 : Créez de nouveaux itinéraires pour PayPal et exécutez les paiements.

Add the following routes in config/routes.rb :

 post 'orders/paypal/create_payment' => 'orders#paypal_create_payment', as: :paypal_create_payment post 'orders/paypal/execute_payment' => 'orders#paypal_execute_payment', as: :paypal_execute_payment

This will create two new routes for creating and executing payments which will be handled in the paypal_create_payment and paypal_execute_payment orders controller methods.

Step 2: Create the PayPal service.

Add the singleton class Orders::Paypal at: app/services/orders/paypal.rb .

This service will initially have three responsibilities:

  • The create_payment method creates a payment by calling PayPal::SDK::REST::Payment.new . A token is generated and returned to the front-end.
  • The execute_payment method executes the payment by first finding the previous created payment object through PayPal::SDK::REST::Payment.find(payment_id) which uses the payment_id as an argument which has the same value as the charge_id stored in the previous step in the order object. After that, we call execute in the payment object with a given payer as the parameter. This payer is given by the front end after the user has provided credentials and selected a payment method in the popup.
  • The finish method finds an order by a specific charge_id querying for recently created orders in the paypal_executed state. If a record is found, it is marked as paid.
 class Orders::Paypal def self.finish(charge_id) order = Order.paypal_executed.recently_created.find_by(charge_id: charge_id) return nil if order.nil? order.set_paid order end def self.create_payment(order:, product:) payment_price = (product.price_cents/100.0).to_s currency = "USD" payment = PayPal::SDK::REST::Payment.new({ intent: "sale", payer: { payment_method: "paypal" }, redirect_urls: { return_url: "/", cancel_url: "/" }, transactions: [{ item_list: { items: [{ name: product.name, sku: product.name, price: payment_price, currency: currency, quantity: 1 } ] }, amount: { total: payment_price, currency: currency }, description: "Payment for: #{product.name}" }] }) if payment.create order.token = payment.token order.charge_id = payment.id return payment.token if order.save end end def self.execute_payment(payment_id:, payer_id:) order = Order.recently_created.find_by(charge_id: payment_id) return false unless order payment = PayPal::SDK::REST::Payment.find(payment_id) if payment.execute( payer_id: payer_id ) order.set_paypal_executed return order.save end end

Step 3: Call the PayPal service in the controller in the submit action.

Add a callback for prepare_new_order before the action paypal_create_payment (which will be added in the next step) is requested by adding the following in the file app/controllers/orders_controller.rb :

 class OrdersController < ApplicationController before_action :authenticate_user! before_action :prepare_new_order, only: [:paypal_create_payment] ...

Again, in the same file, call PayPal service in the submit action by replacing the commented code #PAYPAL WILL BE HANDLED HERE. avec ce qui suit :

 ... elsif order_params[:payment_gateway] == "paypal" @order = Orders::Paypal.finish(order_params[:token]) end ...

Step 4: Create the actions for handling requests.

Still, in the app/controllers/orders_controller.rb file, create two new actions (which should be public) for handling requests to paypal_create_payment and paypal_execute_payment routes:

  • The paypal_create_payment method: Will call our service method create_payment . If that returns successfully, it will return the order token created by Orders::Paypal.create_payment .
  • The paypal_execute_payment method: Will call our service method execute_payment (which executes our payments). If the payment is performed successfully, it returns 200.
 ... def paypal_create_payment result = Orders::Paypal.create_payment(order: @order, product: @product) if result render json: { token: result }, status: :ok else render json: {error: FAILURE_MESSAGE}, status: :unprocessable_entity end end def paypal_execute_payment if Orders::Paypal.execute_payment(payment_id: params[:paymentID], payer_id: params[:payerID]) render json: {}, status: :ok else render json: {error: FAILURE_MESSAGE}, status: :unprocessable_entity end end ...

Step 5: Implement the front-end callback functions for createOrder and onApprove .

Make your paypal.Button.render call look like this:

 paypal.Buttons({ env: "#{ENV['PAYPAL_ENV']}", createOrder: function() { $('#order-type').val("paypal"); if (isPayment()) { return $.post("#{paypal_create_payment_url}", $('#order-details').serialize()).then(function(data) { return data.token; }); } else { } }, onApprove: function(data) { if (isPayment()) { return $.post("#{paypal_execute_payment_url}", { paymentID: data.paymentID, payerID: data.payerID }).then(function() { submitOrderPaypal(data.paymentID) }); } else { } } }).render('#submit-paypal');

As mentioned in the previous section, we call paypal_create_payment_url for the createOrder callback and paypal_execute_payment_url for the onApprove callback. Notice that if the last request returns success, we submit the order, which is the third request made to the server.

In the createOrder function handler, we return a token (obtained from the back end). In the onApprove callback, we have two properties passed down to our back-end paymentID and payerID . These will be used in order to execute the payment.

Finally, notice that we have two empty else clauses as I'm leaving room for the next section where we will be adding PayPal subscriptions.

If you visit your page after integrating the front-end JavaScript section and select PayPal as the payment method, it should look like the following:

Index page after integration with PayPal
Index page after integration with PayPal

Step 6: Test your application.

  • Visitez la page d'accueil.
  • Sélectionnez un produit de paiement/charge et PayPal comme mode de paiement.
  • Cliquez sur le bouton Soumettre PayPal.
  • Dans la fenêtre contextuelle PayPal :
    • Utilisez les identifiants du compte acheteur que vous avez créé.
    • Connectez-vous et confirmez votre commande.
    • La popup devrait se fermer.
  • Vérifiez si vous êtes redirigé vers une page de réussite.
  • Enfin, vérifiez si la commande a été effectuée dans le compte PayPal en vous connectant avec votre compte professionnel sur https://www.sandbox.paypal.com/signin et en consultant le tableau de bord https://www.sandbox.paypal.com/listing /transactions.

Abonnements PayPal

Les plans/accords/abonnements PayPal suivent la même logique que les abonnements Stripe et sont créés pour les paiements récurrents. Avec ce type de produit, l'utilisateur est automatiquement facturé quotidiennement, hebdomadairement, mensuellement ou annuellement selon sa configuration.

Nous utiliserons le champ pour le produit paypal_plan_name , afin de stocker l'ID de plan fourni par PayPal. Dans ce cas, contrairement à Stripe, on ne choisit pas l'ID, et PayPal retourne cette valeur qui servira à mettre à jour le dernier produit créé dans notre base de données.

Pour créer un abonnement, aucune information customer n'est requise à aucune étape, car la méthode onApprove gère probablement ce lien dans son implémentation sous-jacente. Nos tables resteront donc les mêmes.

Étape 1 : Créez un forfait à l'aide de l'API PayPal.

Ouvrez votre console en utilisant les rails c . Créez un abonnement pour votre compte PayPal avec :

 plan = PayPal::SDK::REST::Plan.new({ name: 'Premium Plan', description: 'Premium Plan', type: 'fixed', payment_definitions: [{ name: 'Premium Plan', type: 'REGULAR', frequency_interval: '1', frequency: 'MONTH', cycles: '12', amount: { currency: 'USD', value: '100.00' } }], merchant_preferences: { cancel_url: 'http://localhost:3000/', return_url: 'http://localhost:3000/', max_fail_attempts: '0', auto_bill_amount: 'YES', initial_fail_amount_action: 'CONTINUE' } }) plan.create plan_update = { op: 'replace', path: '/', value: { state: 'ACTIVE' } } plan.update(plan_update)

Étape 2 : Mettez à jour le dernier produit dans la base de données paypal_plan_name avec le plan.id renvoyé.

Cours:

 Product.last.update(paypal_plan_name: plan.id)

Étape 3 : Ajoutez des itinéraires pour l'abonnement PayPal.

Ajoutez deux nouvelles routes dans config/routes.rb :

 post 'orders/paypal/create_subscription' => 'orders#paypal_create_subscription', as: :paypal_create_subscription post 'orders/paypal/execute_subscription' => 'orders#paypal_execute_subscription', as: :paypal_execute_subscription

Étape 4 : Gérez la création et l'exécution dans le service PayPal.

Ajoutez deux fonctions supplémentaires pour créer et exécuter des abonnements dans Orders::Paypal of app/services/orders/paypal.rb :

 def self.create_subscription(order:, product:) agreement = PayPal::SDK::REST::Agreement.new({ name: product.name, description: "Subscription for: #{product.name}", start_date: (Time.now.utc + 1.minute).iso8601, payer: { payment_method: "paypal" }, plan: { id: product.paypal_plan_name } }) if agreement.create order.token = agreement.token return agreement.token if order.save end end def self.execute_subscription(token:) order = Order.recently_created.find_by(token: token) return false unless order agreement = PayPal::SDK::REST::Agreement.new agreement.token = token if agreement.execute order.charge_id = agreement.id order.set_paypal_executed return order.charge_id if order.save end end

Dans create_subscription , nous initialisons un accord en appelant la méthode PayPal::SDK::REST::Agreement.new et en transmettant le product.paypal_plan_name comme l'un de ses attributs. Ensuite, nous le créons, et maintenant un jeton sera défini pour ce dernier objet. Nous renvoyons également le jeton au frontal.

Dans execute_subscription , nous retrouvons l'enregistrement de order créé lors de l'appel précédent. Après cela, nous initialisons un nouvel accord, nous définissons le jeton de cet objet précédent et l'exécutons. Si cette dernière étape est effectuée avec succès, le statut de la commande est défini sur paypal_executed . Et maintenant, nous retournons au front-end l'identifiant de l'accord qui est également stocké dans order.chager_id .

Étape 5 : Ajoutez des actions pour créer et exécuter des abonnements dans orders_controller .

Modifiez le app/controllers/orders_controller.rb . En haut de la classe, d'abord, puis mettez à jour le rappel prepare_new_order pour qu'il soit également exécuté avant que paypal_create_subscription ne soit appelé :

 class OrdersController < ApplicationController before_action :authenticate_user! before_action :prepare_new_order, only: [:paypal_create_payment, :paypal_create_subscription]

De plus, dans le même fichier, ajoutez les deux fonctions publiques afin qu'elles appellent le service Orders::Paypal avec un flux similaire à celui que nous avons déjà dans les paiements PayPal :

 ... def paypal_create_subscription result = Orders::Paypal.create_subscription(order: @order, product: @product) if result render json: { token: result }, status: :ok else render json: {error: FAILURE_MESSAGE}, status: :unprocessable_entity end end def paypal_execute_subscription result = Orders::Paypal.execute_subscription(token: params[:subscriptionToken]) if result render json: { id: result}, status: :ok else render json: {error: FAILURE_MESSAGE}, status: :unprocessable_entity end end ...

Étape 6 : Ajout de gestionnaires d'abonnement pour createOrder et onApprove dans le frontal.

Enfin, dans index.html.haml , remplacez la fonction paypal.Buttons par la suivante, qui remplira les deux else vides que nous avions auparavant :

 paypal.Buttons({ env: "#{ENV['PAYPAL_ENV']}", createOrder: function() { $('#order-type').val("paypal"); if (isPayment()) { return $.post("#{paypal_create_payment_url}", $('#order-details').serialize()).then(function(data) { return data.token; }); } else { return $.post("#{paypal_create_subscription_url}", $('#order-details').serialize()).then(function(data) { return data.token; }); } }, onApprove: function(data) { if (isPayment()) { return $.post("#{paypal_execute_payment_url}", { paymentID: data.paymentID, payerID: data.payerID }).then(function() { submitOrderPaypal(data.paymentID) }); } else { return $.post("#{paypal_execute_subscription_url}", { subscriptionToken: data.orderID }).then(function(executeData) { submitOrderPaypal(executeData.id) }); } } }).render('#submit-paypal');

La création et l'exécution des abonnements ont une logique similaire à celle utilisée pour les paiements. Une différence est que lors de l'exécution des paiements, les données de la fonction de rappel onApprove ont déjà un paymentID représentant le charge_id pour soumettre le formulaire via submitOrderPaypal(data.paymentID) . Pour les abonnements, nous obtenons le charge_id uniquement après l'avoir exécuté en demandant un POST sur paypal_execute_subscription_url , nous pouvons donc appeler submitOrderPaypal(executeData.id) .

Étape 7 : testez votre application.

  • Visitez la page d'accueil.
  • Sélectionnez un produit d'abonnement et PayPal comme mode de paiement.
  • Cliquez sur le bouton Soumettre PayPal.
  • Dans la fenêtre contextuelle PayPal :
    • Utilisez les identifiants du compte acheteur que vous avez créé.
    • Connectez-vous et confirmez votre commande.
    • La popup devrait se fermer.
  • Vérifiez si vous êtes redirigé vers une page de réussite.
  • Enfin, vérifiez si la commande a été effectuée sur le compte PayPal en vous connectant avec votre compte professionnel sur https://www.sandbox.paypal.com/signin et en consultant le tableau de bord https://www.sandbox.paypal.com/listing/ transactions.

Conclusion

Après avoir lu cet article, vous devriez être en mesure d'intégrer les paiements/charges ainsi que les transactions d'abonnements pour PayPal et Stripe dans votre application Rails. Il y a beaucoup de points qui pourraient être améliorés que je n'ai pas ajoutés dans cet article par souci de brièveté. J'ai tout organisé en partant d'une hypothèse de difficulté :

  • Plus facile:
    • Utilisez Transport Layer Security (TLS) pour que vos requêtes utilisent HTTPS.
    • Implémentez des configurations d'environnement de production pour PayPal et Stripe.
    • Ajoutez une nouvelle page afin que les utilisateurs puissent accéder à un historique des commandes précédentes.
  • Moyen:
    • Rembourser ou annuler des abonnements.
    • Fournir une solution pour les paiements des utilisateurs non enregistrés.
  • Plus fort:
    • Fournissez un moyen de supprimer des comptes et de conserver leur jeton et leur identifiant client si l'utilisateur souhaite revenir. Mais après un certain nombre de jours, supprimez ces données afin que votre application soit plus conforme à la norme PCI.
    • Passer à l'API PayPal version 2 côté serveur (https://developer.paypal.com/docs/api/payments/v2/) La gemme que nous avons utilisée dans ce tutoriel paypal-sdk-rest , n'a qu'une version bêta pour la version 2, donc cela pourrait être utilisé avec prudence (https://github.com/paypal/PayPal-Ruby-SDK/tree/2.0-beta).
    • Inclure les requêtes idempotentes.
      • Bande : https://stripe.com/docs/api/idempotent_requests
      • PayPal : https://developer.paypal.com/docs/api-basics/#api-idempotency

Je recommande également de lire sur l'élément Stripe Checkout, qui est une autre façon d'intégrer Stripe dans le front-end. Contrairement à Stripe Elements, que nous avons utilisé dans ce tutoriel, Stripe Checkout ouvre une fenêtre contextuelle après avoir cliqué sur un bouton (similaire à PayPal) où l'utilisateur remplit les informations de carte de crédit OU choisit de payer avec Google Pay/Apple Pay https://stripe.com /docs/web.

Une deuxième recommandation de lecture concerne les pages de sécurité pour les deux passerelles de paiement.

  • Pour Bande
  • Pour Paypal

Enfin, merci d'avoir lu cet article ! Vous pouvez également consulter mon projet GitHub utilisé pour cet exemple de projet. Là, j'ai également ajouté des tests rspec lors du développement.