Integrarea metodelor de plată Stripe și PayPal în Ruby on Rails
Publicat: 2022-03-11O caracteristică cheie pentru marile companii de comerț electronic, cum ar fi AliExpress, Ebay și Amazon, este o modalitate sigură de a gestiona plățile, care este esențială pentru afacerea lor. Dacă această caracteristică eșuează, consecințele ar fi devastatoare. Acest lucru se aplică liderilor din industrie și dezvoltatorilor Ruby on Rails care lucrează la aplicații de comerț electronic.
Securitatea cibernetică este esențială pentru prevenirea atacurilor, iar o modalitate de a face procesul de tranzacție mai sigur este să ceri unui serviciu terță parte să o gestioneze. Includerea gateway-urilor de plată în aplicația dvs. este o modalitate de a atinge acest obiectiv, deoarece acestea oferă autorizarea utilizatorului, criptarea datelor și un tablou de bord, astfel încât să puteți urmări starea tranzacției din mers.
Există o varietate de servicii de gateway de plată pe web, dar în acest articol mă voi concentra pe integrarea Stripe și PayPal într-o aplicație Rails. Ca să menționăm câteva altele: Amazon Payments, Square, SecurePay, WorldPay, Authorize.Net, 2Checkout.com, Braintree, Amazon sau BlueSnap.
Cum funcționează integrarea Gateway-ului de plată

În general, va exista un formular/buton în aplicația dvs. în care utilizatorul se poate autentifica/introduce datele cărții de credit. PayPal și Stripe fac deja acest prim pas mai sigur utilizând formulare iframe
sau popups
-up care împiedică aplicația dvs. să stocheze informații sensibile ale cardului de credit al utilizatorului, deoarece vor returna un simbol care reprezintă această tranzacție. De asemenea, unii utilizatori s-ar putea să se simtă deja mai încrezători în procesarea plăților, știind că un serviciu terț se ocupă de procesul de tranzacție, așa că acesta poate fi, de asemenea, o atracție pentru aplicația dvs.
După autentificarea informațiilor despre utilizator, un gateway de plată va confirma plata contactând un procesator de plăți care comunică cu băncile în vederea decontării plăților. Acest lucru asigură că tranzacția este debitată/creditată corespunzător.
Stripe folosește un formular de card de credit care solicită numărul cardului de credit, CVV și data de expirare. Deci, utilizatorul trebuie să completeze informațiile cardului de credit în intrările securizate Stripe. După furnizarea acestor informații, back-end-ul aplicației dvs. procesează această plată printr-un simbol.
Spre deosebire de Stripe, PayPal redirecționează utilizatorul către pagina de conectare PayPal. Utilizatorul autorizează și selectează metoda de plată prin PayPal și, din nou, back-end-ul tău va gestiona jetoanele în loc de datele sensibile ale utilizatorului.
Este important de menționat că, pentru aceste două gateway-uri de plată, back-end-ul dvs. ar trebui să solicite continuarea execuției tranzacției prin Stripe sau API-urile PayPal, care vor da un răspuns OK/NOK, astfel încât aplicația dvs. ar trebui să redirecționeze utilizatorul către o pagină de succes sau de eroare în consecință.
Intenția acestui articol este de a oferi un ghid rapid pentru integrarea acestor două gateway-uri de plată într-o singură aplicație. Pentru toate testele, vom folosi sandbox-uri și conturi de test furnizate de Stripe și PayPal pentru a simula plățile.
Înființat
Înainte de a integra gateway-uri de plată, vom face o configurare pentru inițializarea aplicației prin adăugarea de pietre prețioase, tabele de baze de date și o pagină de index. Acest proiect a fost creat folosind versiunea Rails 5.2.3 și Ruby 2.6.3.
Notă: puteți verifica noile funcții Rails 6 în articolul nostru recent.
Pasul 1: Inițializați o aplicație Rails.
Inițializați proiectul rulând inițializarea proiectului cu comanda rails
cu numele aplicației dvs.:
rails new YOUR_APP_NAME
Și cd
în folderul aplicației dvs.
Pasul 2: Instalați pietre prețioase.
Pe lângă pietrele Stripe și PayPal, au fost adăugate alte câteva pietre:
-
devise
: utilizat pentru autentificarea și autorizarea utilizatorului -
haml
: instrument de modelare pentru randarea paginilor utilizatorului -
jquery-rails
: pentrujquery
în scripturile front-end -
money-rails
: pentru afișarea valorilor monetare formatate
Adăugați la fișierul dvs. Gemfile
:
gem "devise", ">= 4.7.1" gem "haml" gem "jquery-rails" gem "money-rails"
După ce l-ai adăugat, rulează în CLI:
bundle install
Pasul 3: Inițializați pietrele prețioase.
Unele dintre aceste pietre prețioase vor necesita inițializare pe lângă instalarea lor prin bundle
.
Dispozitiv de instalare:
rails g devise:install
Inițializarea money-rails
:
rails g money_rails:initializer
Inițializați jquery-rails
adăugând în partea de jos a app/assets/javascripts/application.js
următoarele:
//= require jquery //= require jquery_ujs
Pasul 4: Tabele și migrații
Trei tabele vor fi utilizate în acest proiect Utilizatori , Produse și Comenzi .
-
Users
: vor fi generați prin devise - Coloane
Products
:-
name
-
price_cents
-
Stripe_plan_name
: un ID care reprezintă un plan de abonament creat în Stripe, astfel încât utilizatorii să se poată abona la acesta. Acest câmp este obligatoriu numai pentru produsele asociate unui plan Stripe. -
paypal_plan_name
: La fel castripe_plan_name
, dar pentru PayPal
-
- Coloane
Orders
:-
product_id
-
user_id
-
status
: Aceasta va informa dacă comanda este în așteptare, eșuată sau plătită. -
token
: Acesta este un token generat din API-uri (fie Stripe, fie PayPal) pentru a inițializa o tranzacție. -
price_cents
: Similar cu produsul, dar folosit pentru ca această valoare să fie persistentă în înregistrarea comenzii -
payment_gateway
: Stochează care gateway de plată este utilizat pentru comanda PayPal sau Stripe -
customer_id
: Acesta va fi folosit pentru Stripe pentru a stoca clientul Stripe pentru un abonament și va fi explicat cu mai multe detalii într-o secțiune ulterioară.
-
Pentru generarea acestor tabele, trebuie generate câteva migrări:
Pentru crearea tabelului Users . Alerga:
rails g devise User
Pentru crearea tabelului Produse . Generați o migrare rulând:
rails generate migration CreateProducts name:string stripe_plan_name:string paypal_plan_name:string
Deschideți fișierul dvs. de migrare creat, care ar trebui să fie localizat la db/migrate/
și faceți modificări pentru ca migrarea să arate similar cu acesta:
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
Pentru crearea tabelului Comenzi . Generați o migrare rulând:
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
Din nou, deschideți fișierul de migrare creat, care ar trebui să fie localizat la db/migrate/
și faceți modificări la acel fișier pentru a-l face să arate similar cu acesta:
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
Rulați migrarea bazei de date executând:
rails db:migrate
Pasul 5: Creați modele.
Modelul utilizatorului este deja creat din instalarea proiectării și nu vor fi necesare modificări asupra acestuia. În plus, vor fi create două modele pentru Produs și Comandă .
Produs. Adăugați un fișier nou, app/models/product.rb
, cu:
class Product < ActiveRecord::Base monetize :price_cents has_many :orders end
Ordin. Adăugați un fișier nou, app/models/order.rb
, cu:
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
Pasul 6: Populați baza de date.
Un utilizator și două produse vor fi create în consolă. Înregistrările comenzilor vor fi create conform testelor de plată.
-
rails s
- În browser, accesați
http://localhost:3000
- Veți fi redirecționat către o pagină de înscriere.
- Înregistrați un utilizator completând adresa de e-mail și parola acestuia.
- În terminalul dvs., vor fi solicitate următoarele jurnale care arată că a fost creat un utilizator în baza de date:
User Create (0.1ms) INSERT INTO "users" ("email", "encrypted_password", "created_at", "updated_at") VALUES (?, ?, ?, ?) …
- Creați două produse fără abonamente rulând
rails c
și adăugând:-
Product.create(name: "Awesome T-Shirt", price_cents: 3000)
-
Product.create(name: "Awesome Sneakers", price_cents: 5000)
-
Pasul 7: Creați o pagină de index
Pagina principală a proiectului include selecția de produse pentru achiziții sau abonamente. În plus, are și o secțiune pentru selectarea metodei de plată (Stripe sau PayPal). Un buton de trimitere este, de asemenea, utilizat pentru fiecare tip de gateway de plată, deoarece pentru PayPal vom adăuga propriul design de buton prin biblioteca sa JavaScript.
Mai întâi, creați rutele pentru index
și submit
în config/routes.rb
.
Rails.application.routes.draw do devise_for :users get '/', to: 'orders#index' post '/orders/submit', to: 'orders#submit' end
Creați și adăugați index
acțiuni și submit
în app/controllers/orders_controller.rb
. Acțiunea orders#index
stochează două variabile pentru a fi consumate în front-end: @products_purchase
care are o listă de produse fără planuri și @products_subscription
care are produse atât cu planuri PayPal, cât și 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
Creați un fișier în app/views/orders/index.html.haml
. Acest fișier conține toate intrările pe care le vom trimite către backend prin metoda de trimitere și interacțiunea pentru gateway-uri de plată și selecția produselor. Iată câteva atribute ale numelui de intrare:
-
Orders[product_id]
stochează ID-ul produsului. -
Orders[payment_gateway]
conține gateway-ul de plată cu valori Stripe sau PayPal pentru celălalt.
%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; }
Dacă rulați aplicația cu rails s
și vă vizitați pagina în http://localhost:3000
. Ar trebui să puteți vedea pagina după cum urmează:

Stocarea acreditărilor pentru Gateway de plată
Cheile PayPal și Stripe vor fi stocate într-un fișier care nu este urmărit de Git. Există două tipuri de chei stocate în acest fișier pentru fiecare gateway de plată și, deocamdată, vom folosi o valoare inactivă pentru ele. Indicații suplimentare pentru crearea acestor chei sunt prezentate în secțiunile ulterioare.
Pasul 1: Adăugați acest lucru în .gitignore
.
/config/application.yml
Pasul 2: creați un fișier cu acreditările dvs. în config/application.yml
. Ar trebui să conțină toate cheile de testare/sandbox PayPal și Stripe pentru accesarea acestor API-uri.
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
Pasul 3: Pentru a stoca variabilele din fișierul config/application.yml
când pornește aplicația, adăugați aceste linii în config/application.rb
în interiorul clasei Application
, astfel încât să fie disponibile în ENV
.
config_file = Rails.application.config_for(:application) config_file.each do |key,value| ENV[key] = value end unless config_file.nil?
Configurație Stripe
Vom adăuga o bijuterie pentru utilizarea API-ului Stripe: stripe-rails
. Crearea unui cont Stripe este, de asemenea, necesară pentru ca taxele și abonamentele să poată fi procesate. Dacă este necesar, puteți consulta metodele API pentru Stripe API în documentația oficială.
Pasul 1: Adăugați bijuteria cu șinele dungi la proiectul dvs.
Bijuteria stripe-rails va oferi o interfață pentru toate solicitările API utilizate în acest proiect.
Adăugați asta în Gemfile
:
gem 'stripe-rails'
Alerga:
bundle install
Pasul 2: generați cheile API.
Pentru a avea cheile API pentru comunicarea cu Stripe, va trebui să vă creați un cont în Stripe. Pentru a testa aplicația, este posibil să utilizați modul de testare, astfel încât nu trebuie să completați informații despre afaceri reale în procesul de creare a contului Stripe.
- Creați un cont în Stripe dacă nu aveți unul (https://dashboard.stripe.com/).
- În timp ce vă aflați încă în tabloul de bord Stripe, după ce vă conectați, activați Vizualizarea datelor de testare .
- La https://dashboard.stripe.com/test/apikeys, înlocuiți
YOUR_CREDENTIAL_HERE
pentru valorileSTRIPE_PUBLISHABLE_KEY
șiSTRIPE_SECRET_KEY
din/config/application.yml
cu conținutul dinPublishable Key
și CheiaSecret key
.
Pasul 3: Inițializați modulul Stripe
Pe lângă înlocuirea cheilor, mai trebuie să inițializam modulul Stripe, astfel încât să folosească cheile deja setate în ENV
-ul nostru.
Creați un fișier în config/initializers/stripe.rb
cu:
Rails.application.configure do config.stripe.secret_key = ENV["STRIPE_SECRET_KEY"] config.stripe.publishable_key = ENV["STRIPE_PUBLISHABLE_KEY"] end
Pasul 4: Integrați Stripe în partea din față.
Vom adăuga biblioteca Stripe JavaScript și logica pentru trimiterea unui token care reprezintă informațiile despre cardul de credit al utilizatorului și va fi procesat în back-end-ul nostru.
În fișierul index.html.haml
, adăugați-l în partea de sus a fișierului. Aceasta va folosi modulul Stripe (furnizat de bijuterie) pentru a adăuga biblioteca javascript Stripe la pagina utilizatorului.
= stripe_javascript_tag
Stripe utilizează câmpuri de intrare securizate care sunt create prin intermediul API-ului lor. Deoarece sunt create într-un iframe
creat prin acest API, nu va trebui să vă faceți griji cu privire la posibilele vulnerabilități care manipulează informațiile despre cardul de credit al utilizatorului. În plus, back-end-ul dvs. nu va putea procesa/stoca date sensibile ale utilizatorului și va primi doar un simbol care reprezintă aceste informații.
Aceste câmpuri de intrare sunt create prin apelarea stripe.elements().create('card')
. După aceea, este necesar doar să apelați obiectul returnat cu mount()
trecând ca argument id-ul/clasa elementului HTML în care ar trebui să fie montate aceste intrări. Mai multe informații pot fi găsite la Stripe.
Când utilizatorul apasă butonul de trimitere cu metoda de plată Stripe, un alt apel API care returnează o promisiune este efectuat pe elementul de card Stripe creat:
stripe.createToken(card).then(function(result)
Variabila result
a acestei funcții, dacă nu are o eroare de proprietate atribuită, va avea un token care poate fi preluat accesând atributul result.token.id
. Acest token va fi trimis la back-end.
Pentru a face aceste modificări, înlocuiți codul comentat // YOUR STRIPE AND PAYPAL CODE WILL BE HERE
în index.html.haml
cu:
(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
Dacă vizitați pagina dvs., ar trebui să arate așa cu noile câmpuri de introducere securizate Stripe:

Pasul 5: Testează-ți aplicația.
Completați formularul de card de credit cu un card de testare (https://stripe.com/docs/testing) și trimiteți pagina. Verificați dacă acțiunea de submit
este apelată cu toți parametrii ( product_id , payment_gateway și token ) din ieșirea serverului dvs.
Stripe Charges
Taxele Stripe reprezintă tranzacții unice. Prin urmare, după o tranzacție de taxare Stripe, veți primi bani direct de la client. Acesta este ideal pentru vânzarea de produse care nu sunt asociate cu planuri. Într-o secțiune ulterioară, voi arăta cum să faci același tip de tranzacție cu PayPal, dar numele PayPal pentru acest tip de tranzacție este Plată .
În această secțiune voi furniza și tot scheletul pentru manipularea și trimiterea unei comenzi. Creăm o comandă în acțiunea de submit
când este trimis formularul Stripe. Această comandă va avea inițial starea în așteptare , așa că dacă ceva nu merge bine în timpul procesării acestei comenzi, comanda va fi în continuare în așteptare .
Dacă apare vreo eroare din apelurile Stripe API, setăm comanda într-o stare eșuată , iar dacă taxa este finalizată cu succes, aceasta va fi în starea plătită . Utilizatorul este, de asemenea, redirecționat în funcție de răspunsul Stripe API, așa cum se arată în graficul următor:

În plus, atunci când se efectuează o taxă Stripe, se returnează un ID. Vom stoca acest ID, astfel încât să îl puteți căuta ulterior în tabloul de bord Stripe, dacă este necesar. Acest ID poate fi folosit și în cazul în care comanda trebuie rambursată. Așa ceva nu va fi explorat în acest articol.
Pasul 1: Creați serviciul Stripe.
Vom folosi o clasă singleton pentru a reprezenta operațiunile Stripe folosind API-ul Stripe. Pentru a crea o taxă, este apelată metoda Stripe::Charge.create
, iar atributul ID obiect returnat va fi stocat în înregistrarea comenzii charge_id
. Această funcție de create
este apelată prin transmiterea simbolului originat în front-end, prețul comenzii și o descriere.
Deci, creați un nou folder app/services/orders
și adăugați un serviciu Stripe: app/services/orders/stripe.rb
care conține clasa singleton Orders::Stripe
, care are o intrare în metoda 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
Pasul 2: implementați acțiunea de trimitere și apelați serviciul Stripe.
În orders_controller.rb
, adăugați următoarele în acțiunea de submit
, care practic va apela serviciul Orders::Stripe.execute
. Rețineți că au fost adăugate și două noi funcții private: prepare_new_order
și 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
Pasul 3: Testați aplicația.
Verificați dacă acțiunea de trimitere, atunci când este apelată cu un card de testare valid, efectuează o redirecționare către un mesaj de succes. În plus, verificați în tabloul de bord Stripe dacă comanda este afișată și.
Abonamente Stripe
Pot fi create abonamente sau planuri pentru plăți recurente. Cu acest tip de produs, utilizatorul este taxat zilnic, săptămânal, lunar sau anual automat conform configurației planului. În această secțiune, vom folosi câmpul pentru produs stripe_plan_name
pentru a stoca ID-ul planului - de fapt, este posibil să alegem ID-ul și îl vom numi premium-plan
- care va fi folosit pentru a crea relație customer <-> subscription
.
De asemenea, vom crea o nouă coloană pentru tabelul utilizatori numit stripe_customer_id
, care va fi completată cu proprietatea id a unui obiect client Stripe. Un client Stripe este creat atunci când este apelată funcția Stripe::Customer.create
și, de asemenea, puteți verifica clienții creați și conectați la contul dvs. în (https://dashboard.stripe.com/test/customers). Clienții sunt creați prin trecerea unui parametru source
care, în cazul nostru, este tokenul generat în front end care este trimis la trimiterea formularului.
Obiectul client obținut din ultimul apel Stripe API menționat, este folosit și pentru crearea unui abonament care se face prin apelarea customer.subscriptions.create
și transmiterea ID-ului planului ca parametru.
În plus, bijuteria stripe-rails
oferă interfața pentru a prelua și actualiza un client din Stripe, care se face apelând Stripe::Customer.retrieve
și, respectiv, Stripe::Customer.update
.
Deci, atunci când o înregistrare de utilizator are deja un stripe_customer_id
, în loc să creăm un nou client folosind Stripe::Customer.create
, vom apela Stripe::Customer.retrieve
trecând stripe_customer_id
ca parametru, urmat de un Stripe::Customer.update
, iar în acest caz, trecerea jetonului un parametru.

În primul rând, vom crea un plan folosind Stripe API, astfel încât să putem crea un nou produs de abonament folosind câmpul stripe_plan_name
. Ulterior, vom face modificări în orders_controller
și serviciul Stripe, astfel încât crearea și execuția abonamentelor Stripe să fie gestionată.
Pasul 1: Creați un plan utilizând API-ul Stripe.
Deschideți consola folosind rails c
. Creați un abonament pentru contul Stripe cu:
Stripe::Plan.create({ amount: 10000, interval: 'month', product: { name: 'Premium plan', }, currency: 'usd', id: 'premium-plan', })
Dacă rezultatul returnat în acest pas este adevărat, înseamnă că planul a fost creat cu succes și îl puteți accesa în tabloul dvs. Stripe.
Pasul 2: Creați un produs în baza de date cu câmpul stripe_plan_name
setat.
Acum, creați un produs cu stripe_plan_name
setat ca premium-plan
în baza de date:
Product.create(price_cents: 10000, name: 'Premium Plan', stripe_plan_name: 'premium-plan')
Pasul 3: Generați o migrare pentru adăugarea unei coloane stripe_customer_id
în tabelul users
.
Rulați următoarele în terminal:
rails generate migration AddStripeCustomerIdToUser stripe_customer_id:string rails db:migrate
Pasul 4: Implementați logica abonamentului în clasa de serviciu Stripe.
Adăugați încă două funcții în metodele private ale app/services/orders/stripe.rb
: execute_subscription
este responsabil pentru crearea abonamentelor în obiectul clientului. Funcția find_or_create_customer
este responsabilă să returneze clientul deja creat sau prin returnarea unui client nou creat.
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
În cele din urmă, în funcția execute
din același fișier ( app/services/orders/stripe.rb
), vom apela mai întâi find_or_create_customer
și apoi vom executa abonamentul apelând execute_subscription
trecând clientul anterior recuperat/creat. Așadar, înlocuiți comentariul #SUBSCRIPTIONS WILL BE HANDLED HERE
în metoda execute
cu următorul cod:
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)
Pasul 5: Testează-ți aplicația.
Vizitați site-ul dvs. web, selectați produsul cu abonament Premium Plan
și completați un card de testare valid. După trimitere, ar trebui să vă redirecționeze către o pagină de succes. În plus, verificați în tabloul de bord Stripe dacă abonamentul a fost creat cu succes.
Configurare PayPal
Așa cum am făcut în Stripe, vom adăuga și o bijuterie pentru utilizarea API-ului PayPal: paypal-sdk-rest
și este, de asemenea, necesară crearea unui cont PayPal. Un flux de lucru descriptiv pentru PayPal folosind această bijuterie poate fi consultat în documentația oficială PayPal API.
Pasul 1: Adăugați bijuteria paypal-sdk-rest
la proiectul dvs.
Adăugați asta în Gemfile
:
gem 'paypal-sdk-rest'
Alerga:
bundle install
Pasul 2: generați cheile API.
Pentru a avea cheile API pentru comunicarea cu PayPal, va trebui să vă creați un cont PayPal. Asa de:
- Creați un cont (sau utilizați contul dvs. PayPal) la https://developer.paypal.com/.
- Încă sunteți conectat la contul dvs., creați două conturi sandbox la https://developer.paypal.com/developer/accounts/:
- Personal (Cont de cumpărător) – Acesta va fi folosit în testele dumneavoastră pentru efectuarea plăților și abonamentelor.
- Business (Cont de comerciant) – Acesta va fi legat de aplicație, care va avea cheile API pe care le căutăm. În plus, toate tranzacțiile pot fi urmărite în acest cont.
- Creați o aplicație la https://developer.paypal.com/developer/applications folosind contul anterior de business sandbox.
- După acest pas, veți primi două chei pentru PayPal:
Client ID
șiSecret
. - În
config/application.yml
, înlocuițiYOUR_CREDENTIAL_HERE
dinPAYPAL_CLIENT_ID
șiPAYPAL_CLIENT_SECRET
cu cheile pe care tocmai le-ați primit.
Pasul 3: Inițializați modulul PayPal.
Similar cu Stripe, pe lângă înlocuirea cheilor în application.yml
, mai trebuie să inițializam modulul PayPal, astfel încât să poată folosi cheile deja setate în variabila ENV
. În acest scop, creați un fișier în config/initializers/paypal.rb
cu:
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
Pasul 4: Integrați PayPal în front-end.
În index.html.haml
adăugați acest lucru în partea de sus a fișierului:
%script(src="https://www.paypal.com/sdk/js?client-id=#{ENV['PAYPAL_CLIENT_ID']}")
Spre deosebire de Stripe, PayPal folosește doar un buton care, atunci când este apăsat, deschide o fereastră pop-up securizată în care utilizatorul se poate autentifica și trece la plata/abonament. Acest buton poate fi redat apelând metoda paypal.Button(PARAM1).render(PARAM2)
.
-
PARAM1
este un obiect cu configurația mediului și două funcții de apel invers ca proprietăți:createOrder
șionApprove
. -
PARAM2
indică identificatorul elementului HTML la care trebuie atașat butonul PayPal.
Deci, tot în același fișier, înlocuiți codul comentat YOUR PAYPAL CODE WILL BE HERE
cu:
(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'); }());
Pasul 5: Testează-ți aplicația.
Vizitați pagina dvs. și verificați dacă butonul PayPal este redat atunci când selectați PayPal ca metodă de plată.
Tranzacții PayPal
Logica pentru tranzacțiile PayPal, spre deosebire de Stripe, este puțin mai complexă, implicând mai multe solicitări provenite de la front-end la back-end. De aceea există această secțiune. Voi explica mai mult sau mai puțin (fără niciun cod) cum vor fi implementate funcțiile descrise în metodele createOrder
și onApprove
și ce se așteaptă și în procesele back-end.
Pasul 1: Când utilizatorul face clic pe butonul de trimitere PayPal, o fereastră pop-up PayPal care solicită acreditările utilizatorului este deschisă, dar în stare de încărcare. Este apelată funcția callback createOrder
.

Pasul 2: În această funcție, vom efectua o solicitare către back-end-ul nostru, care va crea o plată/abonament. Acesta este chiar începutul unei tranzacții și încă nu vor fi aplicate taxe, așa că tranzacția este de fapt într-o stare în așteptare . Back-end-ul nostru ar trebui să ne returneze un token, care va fi generat folosind modulul PayPal (furnizat prin bijuteria paypal-rest-sdk
).
Pasul 3: Încă în callback createOrder
, returnăm acest token generat în back-end-ul nostru și, dacă totul este în regulă, fereastra pop-up PayPal va afișa următoarele, solicitând acreditările utilizatorului:

Pasul 4: După ce utilizatorul s-a autentificat și a selectat metoda de plată, fereastra pop-up își va schimba starea în următoarea:

Pasul 5: Funcția onApprove
callback este acum apelată. L-am definit astfel: onApprove: function(data)
. Obiectul data
va avea informațiile de plată pentru a-l executa. În acest callback, o altă solicitare către funcția noastră de back-end va fi efectuată de data aceasta trecând obiectul de date pentru a executa comanda PayPal.
Pasul 6: Back-end-ul nostru execută această tranzacție și returnează 200 (dacă are succes).
Pasul 7: Când back-end-ul nostru revine, trimitem formularul. Aceasta este a treia cerere pe care o facem back-end-ului nostru.
Rețineți că, spre deosebire de Stripe, există trei solicitări adresate back-end-ului nostru în acest proces. Și vom păstra starea comenzii sincronizată în consecință:
-
createOrder
callback: este creată o tranzacție și este creată și o înregistrare a comenzii; prin urmare, este într-o stare în așteptare ca implicită. -
onApprove
callback: tranzacția este executată și comanda noastră va fi setată ca paypal_executed . - Pagina de comandă este trimisă: Tranzacția a fost deja executată, așa că nu se schimbă nimic. Înregistrarea comenzii își va schimba starea în plătit .
Întregul proces este descris în graficul următor:

Plăți PayPal
Plățile PayPal urmează aceeași logică ca și taxele Stripe, deci reprezintă tranzacții unice, dar, așa cum sa menționat în secțiunea anterioară, au o logică de flux diferită. Acestea sunt modificările care vor trebui efectuate pentru gestionarea plăților PayPal:
Pasul 1: Creați noi rute pentru PayPal și executați plăți.
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 callingPayPal::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 throughPayPal::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 callexecute
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.
cu urmatoarele:
... 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 methodcreate_payment
. If that returns successfully, it will return the order token created byOrders::Paypal.create_payment
. - The
paypal_execute_payment
method: Will call our service methodexecute_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:

Step 6: Test your application.
- Vizitați pagina de index.
- Selectați un produs de plată/debit și PayPal ca metodă de plată.
- Faceți clic pe butonul de trimitere PayPal.
- În fereastra pop-up PayPal:
- Utilizați acreditările pentru contul de cumpărător pe care l-ați creat.
- Conectați-vă și confirmați comanda.
- Fereastra pop-up ar trebui să se închidă.
- Verificați dacă sunteți redirecționat către o pagină de succes.
- În cele din urmă, verificați dacă comanda a fost efectuată în contul PayPal, conectându-vă cu contul dvs. de afaceri la https://www.sandbox.paypal.com/signin și verificând tabloul de bord https://www.sandbox.paypal.com/listing /tranzacții.
Abonamente PayPal
Planurile/acordurile/abonamentele PayPal urmează aceeași logică ca și abonamentele Stripe și sunt create pentru plăți recurente. Cu acest tip de produs utilizatorul este taxat zilnic, săptămânal, lunar sau anual automat în funcție de configurația sa.
Vom folosi câmpul pentru produsul paypal_plan_name
, pentru a stoca ID-ul planului furnizat de PayPal. În acest caz, altfel decât Stripe, nu alegem ID-ul, iar PayPal returnează această valoare la care va fi folosită pentru a actualiza ultimul produs creat în baza noastră de date.
Pentru crearea unui abonament, nu sunt necesare informații despre customer
în niciun pas, deoarece metoda onApprove
se ocupă probabil de această legătură în implementarea sa de bază. Deci mesele noastre vor rămâne aceleași.
Pasul 1: Creați un plan utilizând API-ul PayPal.
Deschideți consola folosind rails c
. Creați un abonament pentru contul dvs. PayPal cu:
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)
Pasul 2: Actualizați ultimul produs din baza de date paypal_plan_name
cu plan.id
returnat.
Alerga:
Product.last.update(paypal_plan_name: plan.id)
Pasul 3: Adăugați rute pentru abonamentul PayPal.
Adăugați două rute noi în 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
Pasul 4: Gestionați crearea și execuția în serviciul PayPal.
Adăugați încă două funcții pentru crearea și executarea abonamentelor în 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
În create_subscription
, inițializam un acord apelând metoda PayPal::SDK::REST::Agreement.new
și trecând product.paypal_plan_name
ca unul dintre atributele sale. După aceea, îl creăm, iar acum va fi setat un token pentru acest ultim obiect. De asemenea, returnăm jetonul în partea din față.
În execute_subscription
, găsim înregistrarea order
creată în apelul anterior. După aceea, inițializam un nou acord, setăm simbolul acestui obiect anterior și îl executăm. Dacă acest ultim pas este efectuat cu succes, starea comenzii este setată la paypal_executed . Și acum revenim la front-end ID-ul acordului care este, de asemenea, stocat în order.chager_id
.
Pasul 5: Adăugați acțiuni pentru crearea și executarea abonamentelor în orders_controller
.
Schimbați app/controllers/orders_controller.rb
. În partea de sus a clasei, în primul rând, și apoi actualizați callback prepare_new_order
pentru a fi executat și înainte ca paypal_create_subscription
să fie apelat:
class OrdersController < ApplicationController before_action :authenticate_user! before_action :prepare_new_order, only: [:paypal_create_payment, :paypal_create_subscription]
De asemenea, în același fișier adăugați cele două funcții publice astfel încât acestea să apeleze serviciul Orders::Paypal
cu un flux similar cu cel pe care îl avem deja în plățile 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 ...
Pasul 6: Adăugarea de gestionare a abonamentelor pentru createOrder
și onApprove
în front-end.
În cele din urmă, în index.html.haml
, înlocuiți funcția paypal.Buttons
cu următoarea, care va umple cele două else
goale pe care le aveam înainte:
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');
Crearea și execuția pentru abonamente au o logică similară cu cea folosită pentru plăți. O diferență este că, atunci când se execută plăți, datele din funcția de apel invers onApprove
au deja un paymentID
de plată care reprezintă codul de charge_id
pentru a trimite formularul prin submitOrderPaypal(data.paymentID)
. Pentru abonamente, obținem charge_id
numai după ce îl executăm prin solicitarea unui POST
pe paypal_execute_subscription_url
, așa că putem apela submitOrderPaypal(executeData.id)
.
Pasul 7: Testați aplicația.
- Vizitați pagina de index.
- Selectați un produs cu abonament și PayPal ca metodă de plată.
- Faceți clic pe butonul de trimitere PayPal.
- În fereastra pop-up PayPal:
- Utilizați acreditările pentru contul de cumpărător pe care l-ați creat.
- Conectați-vă și confirmați comanda.
- Fereastra pop-up ar trebui să se închidă.
- Verificați dacă sunteți redirecționat către o pagină de succes.
- În cele din urmă, verificați dacă comanda a fost efectuată în contul PayPal, conectându-vă cu contul dvs. de afaceri la https://www.sandbox.paypal.com/signin și verificând tabloul de bord https://www.sandbox.paypal.com/listing/ tranzactii.
Concluzie
După ce ați citit acest articol, ar trebui să puteți integra plăți/taxări, precum și tranzacțiile de abonamente pentru PayPal și Stripe în aplicația dvs. Rails. Există o mulțime de puncte care ar putea fi îmbunătățite pe care nu le-am adăugat în acest articol de dragul conciziei. Am organizat totul pe baza unei presupuneri de dificultate:
- Mai ușor:
- Utilizați Transport Layer Security (TLS) pentru ca cererile dvs. să utilizeze HTTPS.
- Implementați configurații ale mediului de producție atât pentru PayPal, cât și pentru Stripe.
- Adăugați o pagină nouă, astfel încât utilizatorii să poată accesa un istoric al comenzilor anterioare.
- Mediu:
- Rambursați sau anulați abonamentele.
- Oferiți o soluție pentru plățile utilizatorilor neînregistrați.
- Mai tare:
- Furnizați o modalitate de a elimina conturile și de a păstra simbolul și customer_id -ul acestora dacă utilizatorul dorește să revină. Dar după un anumit număr de zile, eliminați aceste date, astfel încât aplicația dvs. să fie mai compatibilă cu PCI.
- Treceți la PayPal versiunea 2 API în partea de server (https://developer.paypal.com/docs/api/payments/v2/) Bijuteria pe care am folosit-o în acest tutorial paypal-sdk-rest , are doar o versiune beta pentru versiune 2, astfel încât să poată fi folosit cu precauție (https://github.com/paypal/PayPal-Ruby-SDK/tree/2.0-beta).
- Includeți cererile idempotente.
- Stripe: https://stripe.com/docs/api/idempotent_requests
- PayPal: https://developer.paypal.com/docs/api-basics/#api-idempotency
De asemenea, vă recomand să citiți despre elementul Stripe Checkout, care este o altă modalitate de a integra Stripe în front-end. Spre deosebire de Stripe Elements, pe care le-am folosit în acest tutorial, Stripe Checkout deschide o fereastră pop-up după ce face clic pe un buton (similar cu PayPal) în care utilizatorul completează informațiile despre cardul de credit SAU alege să plătească cu Google Pay/Apple Pay https://stripe.com /docs/web.
O a doua recomandare de lectură sunt paginile de securitate pentru ambele Gateway-uri de plată.
- Pentru Stripe
- Pentru PayPal
În sfârșit, mulțumesc că ai citit acest articol! De asemenea, puteți verifica proiectul meu GitHub folosit pentru acest exemplu de proiect. Acolo, am adăugat și teste rspec în timpul dezvoltării.