spree_paypal_checkout 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +12 -0
  3. data/README.md +69 -0
  4. data/Rakefile +21 -0
  5. data/app/assets/config/spree_paypal_checkout_manifest.js +2 -0
  6. data/app/controllers/spree/api/v2/storefront/paypal_orders_controller.rb +55 -0
  7. data/app/controllers/spree_paypal_checkout/store_controller_decorator.rb +9 -0
  8. data/app/helpers/spree_paypal_checkout/base_helper.rb +11 -0
  9. data/app/javascript/spree_paypal_checkout/application.js +16 -0
  10. data/app/javascript/spree_paypal_checkout/controllers/checkout_paypal_controller.js +99 -0
  11. data/app/models/spree_paypal_checkout/base.rb +6 -0
  12. data/app/models/spree_paypal_checkout/gateway.rb +185 -0
  13. data/app/models/spree_paypal_checkout/order.rb +71 -0
  14. data/app/models/spree_paypal_checkout/order_decorator.rb +11 -0
  15. data/app/models/spree_paypal_checkout/payment_method_decorator.rb +15 -0
  16. data/app/models/spree_paypal_checkout/payment_sources/paypal.rb +15 -0
  17. data/app/models/spree_paypal_checkout/store_decorator.rb +9 -0
  18. data/app/presenters/spree_paypal_checkout/order_presenter.rb +59 -0
  19. data/app/serializers/spree/api/v2/storefront/paypal_order_serializer.rb +11 -0
  20. data/app/services/spree_paypal_checkout/capture_order.rb +104 -0
  21. data/app/services/spree_paypal_checkout/create_payment.rb +34 -0
  22. data/app/services/spree_paypal_checkout/create_source.rb +52 -0
  23. data/app/views/spree/admin/payment_methods/configuration_guides/_spree_paypal_checkout.html.erb +6 -0
  24. data/app/views/spree/admin/payment_methods/descriptions/_spree_paypal_checkout.html.erb +10 -0
  25. data/app/views/spree/checkout/payment/_spree_paypal_checkout.html.erb +13 -0
  26. data/app/views/spree/payment_sources/_paypal_checkout.html.erb +16 -0
  27. data/app/views/spree_paypal_checkout/_head.html.erb +10 -0
  28. data/config/importmap.rb +6 -0
  29. data/config/initializers/spree.rb +7 -0
  30. data/config/locales/en.yml +5 -0
  31. data/config/routes.rb +13 -0
  32. data/db/migrate/20250528095719_create_spree_paypal_checkout_orders.rb +20 -0
  33. data/lib/generators/spree_paypal_checkout/install/install_generator.rb +20 -0
  34. data/lib/spree_paypal_checkout/configuration.rb +13 -0
  35. data/lib/spree_paypal_checkout/engine.rb +35 -0
  36. data/lib/spree_paypal_checkout/factories.rb +33 -0
  37. data/lib/spree_paypal_checkout/version.rb +7 -0
  38. data/lib/spree_paypal_checkout.rb +7 -0
  39. metadata +206 -0
@@ -0,0 +1,11 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Storefront
5
+ class PaypalOrderSerializer < BaseSerializer
6
+ attributes :paypal_id, :data, :amount
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,104 @@
1
+ module SpreePaypalCheckout
2
+ class CaptureOrder
3
+ def initialize(paypal_order:)
4
+ @paypal_order = paypal_order
5
+ @order = paypal_order.order
6
+ @gateway = paypal_order.gateway
7
+ @amount = paypal_order.amount
8
+ end
9
+
10
+ attr_reader :paypal_order, :order, :gateway, :amount
11
+
12
+ def call
13
+ return paypal_order if order.completed? || order.canceled?
14
+
15
+ # capture the order in PayPal API
16
+ gateway_response = gateway.capture(
17
+ Money.new(amount, order.currency).cents,
18
+ paypal_order.paypal_id,
19
+ {
20
+ order_id: order.number
21
+ }
22
+ )
23
+
24
+ order.with_lock do
25
+ # gateway_response.params is a JSON response from PayPal APIs
26
+ paypal_order.update!(data: gateway_response.params)
27
+
28
+ # create the Spree::Payment record
29
+ paypal_order.create_payment!
30
+
31
+ # complete the order in Spree
32
+ Spree::Dependencies.checkout_complete_service.constantize.call(order: order)
33
+ end
34
+
35
+ paypal_order
36
+ end
37
+
38
+ private
39
+
40
+ # we need to perform this for quick checkout orders which do not have these fields filled
41
+ def add_customer_information(order, charge)
42
+ billing_details = charge.billing_details
43
+ address = billing_details.address
44
+
45
+ order.email ||= billing_details.email
46
+ order.save! if order.email_changed?
47
+
48
+ # we don't need to perform this if we already have the billing address filled
49
+ return order if order.bill_address.present? && order.bill_address.valid?
50
+
51
+ # determine country...
52
+ country_iso = address.country
53
+ country = Spree::Country.find_by(iso: country_iso) || Spree::Country.default
54
+
55
+ # assign new address if we don't have one
56
+ order.bill_address ||= Spree::Address.new(country: country, user: order.user)
57
+
58
+ # assign attributes
59
+ order.bill_address.quick_checkout = true # skipping some validations
60
+
61
+ # sometimes google pay doesn't provide name (geez)
62
+ first_name = billing_details.name&.split(' ')&.first || order.ship_address&.first_name || order.user&.first_name
63
+ last_name = billing_details.name&.split(' ')&.last || order.ship_address&.last_name || order.user&.last_name
64
+
65
+ order.bill_address.first_name ||= first_name
66
+ order.bill_address.last_name ||= last_name
67
+ order.bill_address.phone ||= billing_details.phone
68
+ order.bill_address.address1 ||= address.line1
69
+ order.bill_address.address2 ||= address.line2
70
+ order.bill_address.city ||= address.city
71
+ order.bill_address.zipcode ||= address.postal_code
72
+
73
+ state_name = address.state
74
+ if country.states_required?
75
+ order.bill_address.state = country.states.find_all_by_name_or_abbr(state_name)&.first if country.states_required?
76
+ else
77
+ order.bill_address.state_name = state_name
78
+ end
79
+
80
+ order.bill_address.state_name ||= state_name
81
+
82
+ if order.bill_address.invalid?
83
+ order.bill_address = order.ship_address
84
+ else
85
+ order.bill_address.save!
86
+ end
87
+
88
+ order.save!
89
+
90
+ copy_bill_info_to_user(order) if order.user.present?
91
+
92
+ order
93
+ end
94
+
95
+ def copy_bill_info_to_user(order)
96
+ user = order.user
97
+ user.first_name ||= order.bill_address.first_name
98
+ user.last_name ||= order.bill_address.last_name
99
+ user.phone ||= order.bill_address.phone
100
+ user.bill_address_id ||= order.bill_address.id
101
+ user.save! if user.changed?
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,34 @@
1
+ module SpreePaypalCheckout
2
+ class CreatePayment
3
+ def initialize(paypal_order:, order: nil, gateway: nil, amount: nil)
4
+ @paypal_order = paypal_order
5
+ @order = order || paypal_order.order
6
+ @gateway = gateway || paypal_order.gateway
7
+ @amount = amount || paypal_order.amount
8
+ end
9
+
10
+ def call
11
+ source = SpreePaypalCheckout::CreateSource.new(
12
+ paypal_payment_source: paypal_order.payment_source,
13
+ gateway: gateway,
14
+ order: order
15
+ ).call
16
+
17
+ # sometimes a job is re-tried and creates a double payment record so we need to avoid it!
18
+ payment = order.payments.find_or_initialize_by(
19
+ payment_method_id: gateway.id,
20
+ response_code: paypal_order.paypal_payment_id,
21
+ amount: amount
22
+ )
23
+
24
+ payment.source = source if source.present?
25
+ payment.state = 'completed' # we're creating the payment record after the order is captured in PayPal API
26
+ payment.save!
27
+ payment
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :order, :gateway, :paypal_order, :amount
33
+ end
34
+ end
@@ -0,0 +1,52 @@
1
+ module SpreePaypalCheckout
2
+ class CreateSource
3
+ def initialize(paypal_payment_source:, gateway:, order: nil, user: nil)
4
+ @paypal_payment_source = paypal_payment_source
5
+ @gateway = gateway
6
+ @user = user || order&.user
7
+ @order = order
8
+ end
9
+
10
+ # TODO: add support for venmo and other providers
11
+ def call
12
+ if paypal_payment_source['paypal'].present?
13
+ create_paypal_source
14
+ else
15
+ raise 'Invalid payment source', paypal_payment_source
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :gateway, :user, :paypal_payment_source, :order
22
+
23
+ # "payment_source": {
24
+ # "paypal": {
25
+ # "email_address": "sb-fxqy4743082799@personal.example.com",
26
+ # "account_id": "RX8ZD67CZ67RU",
27
+ # "account_status": "VERIFIED",
28
+ # "name": {
29
+ # "given_name": "John",
30
+ # "surname": "Doe"
31
+ # },
32
+ # "address": {
33
+ # "country_code": "US"
34
+ # }
35
+ # }
36
+ # },
37
+ def create_paypal_source
38
+ source = SpreePaypalCheckout::PaymentSources::Paypal.find_or_create_by!(
39
+ payment_method: gateway,
40
+ user: user,
41
+ gateway_payment_profile_id: paypal_payment_source['paypal']['account_id']
42
+ )
43
+ source.update!(
44
+ email: paypal_payment_source['paypal']['email_address'],
45
+ name: "#{paypal_payment_source['paypal']['name']['given_name']} #{paypal_payment_source['paypal']['name']['surname']}".strip,
46
+ account_id: paypal_payment_source['paypal']['account_id'],
47
+ account_status: paypal_payment_source['paypal']['account_status']
48
+ )
49
+ source
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,6 @@
1
+ <div class="alert alert-info">
2
+ <p class="mb-0">
3
+ To find your <strong>Client ID</strong> and <strong>Client Secret</strong>, go to the
4
+ <%= external_link_to 'PayPal dashboard', 'https://www.paypal.com/mep/merchantapps/setup/checkout/apicredentials', class: 'alert-link' %>
5
+ </p>
6
+ </div>
@@ -0,0 +1,10 @@
1
+ <p class="mb-1">
2
+ From paying friends to saving money or getting cash back when you shop, explore what the new PayPal app has to offer.
3
+ </p>
4
+
5
+ <div class="d-flex align-items-center">
6
+ <%= payment_method_icon_tag 'paypal', class: 'm-1' %>
7
+ <%= payment_method_icon_tag 'visa', class: 'm-1' %>
8
+ <%= payment_method_icon_tag 'master', class: 'm-1' %>
9
+ <%= payment_method_icon_tag 'venmo', class: 'm-1' %>
10
+ </div>
@@ -0,0 +1,13 @@
1
+ <div
2
+ data-controller="checkout-paypal"
3
+ data-checkout-paypal-client-key-value="<%= current_paypal_checkout_gateway.try(:preferred_client_key) %>"
4
+ data-checkout-paypal-order-number-value="<%= @order.number %>"
5
+ data-checkout-paypal-order-token-value="<%= @order.token %>"
6
+ data-checkout-paypal-currency-value="<%= @order.currency %>"
7
+ data-checkout-paypal-amount-value="<%= @order.total %>"
8
+ data-checkout-paypal-api-create-order-path-value="<%= spree.api_v2_storefront_paypal_orders_path %>"
9
+ data-checkout-paypal-api-capture-order-path-value="<%= spree.capture_api_v2_storefront_paypal_order_path(@order.number) %>"
10
+ data-checkout-paypal-api-checkout-update-path-value="<%= spree.api_v2_storefront_checkout_path %>"
11
+ data-checkout-paypal-return-url-value="<%= spree.checkout_complete_path(@order.token) %>"
12
+ >
13
+ </div>
@@ -0,0 +1,16 @@
1
+ <% if source.is_a?(SpreePaypalCheckout::PaymentSources::Paypal) %>
2
+ <p class="mb-2">
3
+ <code><%= source.account_id %></code>
4
+ <% if source.account_status == 'VERIFIED' %>
5
+ <code class="text-success"><%= source.account_status %></code>
6
+ <% else %>
7
+ <code class="text-danger"><%= source.account_status %></code>
8
+ <% end %>
9
+ </p>
10
+ <p class="mb-0">
11
+ <%= source.email %>
12
+ </p>
13
+ <p class="mb-0">
14
+ <%= source.name %>
15
+ </p>
16
+ <% end %>
@@ -0,0 +1,10 @@
1
+ <% if current_store.paypal_checkout_gateway.present? %>
2
+ <!-- Initialize the JS-SDK -->
3
+ <script
4
+ src="https://www.paypal.com/sdk/js?client-id=<%= current_store.paypal_checkout_gateway.preferred_client_id %>&currency=<%= current_currency %>&components=buttons&enable-funding=paylater&disable-funding=venmo,card,p24"
5
+ data-sdk-integration-source="developer-studio"
6
+ defer
7
+ ></script>
8
+
9
+ <%= javascript_import_module_tag 'application-spree-paypal-checkout' %>
10
+ <% end %>
@@ -0,0 +1,6 @@
1
+ pin 'application-spree-paypal-checkout', to: 'spree_paypal_checkout/application.js', preload: false
2
+
3
+ pin_all_from SpreePaypalCheckout::Engine.root.join('app/javascript/spree_paypal_checkout/controllers'),
4
+ under: 'spree_paypal_checkout/controllers',
5
+ to: 'spree_paypal_checkout/controllers',
6
+ preload: 'application-spree-paypal-checkout'
@@ -0,0 +1,7 @@
1
+ Rails.application.config.after_initialize do
2
+ Rails.application.config.spree.payment_methods << SpreePaypalCheckout::Gateway
3
+
4
+ if Rails.application.config.respond_to?(:spree_storefront)
5
+ Rails.application.config.spree_storefront.head_partials << 'spree_paypal_checkout/head'
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ hello: "Hello world"
data/config/routes.rb ADDED
@@ -0,0 +1,13 @@
1
+ Spree::Core::Engine.add_routes do
2
+ namespace :api, defaults: { format: 'json' } do
3
+ namespace :v2 do
4
+ namespace :storefront do
5
+ resources :paypal_orders, only: [:create] do
6
+ member do
7
+ put :capture
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ class CreateSpreePaypalCheckoutOrders < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :spree_paypal_checkout_orders do |t|
4
+ t.references :order, null: false
5
+ t.references :payment_method, null: false
6
+ t.string :paypal_id, null: false
7
+ t.decimal :amount, null: false, precision: 10, scale: 2
8
+
9
+ if t.respond_to? :jsonb
10
+ t.jsonb :data
11
+ else
12
+ t.json :data
13
+ end
14
+
15
+ t.timestamps
16
+ end
17
+
18
+ add_index :spree_paypal_checkout_orders, [:order_id, :paypal_id], unique: true
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module SpreePaypalCheckout
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ class_option :migrate, type: :boolean, default: true
5
+
6
+ def add_migrations
7
+ run 'bundle exec rake railties:install:migrations FROM=spree_paypal_checkout'
8
+ end
9
+
10
+ def run_migrations
11
+ run_migrations = options[:migrate] || ['', 'y', 'Y'].include?(ask('Would you like to run the migrations now? [Y/n]'))
12
+ if run_migrations
13
+ run 'bin/rails db:migrate'
14
+ else
15
+ puts 'Skipping rails db:migrate, don\'t forget to run it!'
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ module SpreePaypalCheckout
2
+ class Configuration < Spree::Preferences::Configuration
3
+
4
+ # Some example preferences are shown below, for more information visit:
5
+ # https://docs.spreecommerce.org/developer/contributing/creating-an-extension
6
+
7
+ # preference :enabled, :boolean, default: true
8
+ # preference :dark_chocolate, :boolean, default: true
9
+ # preference :color, :string, default: 'Red'
10
+ # preference :favorite_number, :integer
11
+ # preference :supported_locales, :array, default: [:en]
12
+ end
13
+ end
@@ -0,0 +1,35 @@
1
+ module SpreePaypalCheckout
2
+ class Engine < Rails::Engine
3
+ require 'spree/core'
4
+ isolate_namespace Spree
5
+ engine_name 'spree_paypal_checkout'
6
+
7
+ # use rspec for tests
8
+ config.generators do |g|
9
+ g.test_framework :rspec
10
+ end
11
+
12
+ initializer 'spree_paypal_checkout.environment', before: :load_config_initializers do |_app|
13
+ SpreePaypalCheckout::Config = SpreePaypalCheckout::Configuration.new
14
+ end
15
+
16
+ initializer 'spree_paypal_checkout.assets' do |app|
17
+ app.config.assets.paths << root.join('app/javascript')
18
+ app.config.assets.precompile += %w[spree_paypal_checkout_manifest]
19
+ end
20
+
21
+ initializer 'spree_paypal_checkout.importmap', before: 'importmap' do |app|
22
+ app.config.importmap.paths << root.join('config/importmap.rb')
23
+ # https://github.com/rails/importmap-rails?tab=readme-ov-file#sweeping-the-cache-in-development-and-test
24
+ app.config.importmap.cache_sweepers << root.join('app/javascript')
25
+ end
26
+
27
+ def self.activate
28
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
29
+ Rails.configuration.cache_classes ? require(c) : load(c)
30
+ end
31
+ end
32
+
33
+ config.to_prepare(&method(:activate).to_proc)
34
+ end
35
+ end
@@ -0,0 +1,33 @@
1
+ FactoryBot.define do
2
+ # Define your Spree extensions Factories within this file to enable applications, and other extensions to use and override them.
3
+ #
4
+ # Example adding this to your spec_helper will load these Factories for use:
5
+ # require 'spree_paypal_checkout/factories'
6
+ #
7
+
8
+ factory :paypal_checkout_gateway, class: 'SpreePaypalCheckout::Gateway' do
9
+ name { 'PayPal Checkout' }
10
+ preferences do
11
+ {
12
+ client_id: ENV.fetch('PAYPAL_CLIENT_ID', 'client_id_test'),
13
+ client_secret: ENV.fetch('PAYPAL_CLIENT_SECRET', 'client_secret_test'),
14
+ test_mode: true
15
+ }
16
+ end
17
+ end
18
+
19
+ factory :paypal_checkout_payment_source, class: 'SpreePaypalCheckout::PaymentSource' do
20
+ gateway_customer_profile_id { 'PAY-CUSTOMER-ID' }
21
+ end
22
+
23
+ factory :paypal_checkout_order, class: 'SpreePaypalCheckout::Order' do
24
+ paypal_id { 'PAY-ORDER-ID' }
25
+ order { create(:order) }
26
+ amount { order.total }
27
+ data { JSON.parse(File.read(SpreePaypalCheckout::Engine.root.join('spec', 'fixtures', 'paypal_order.json'))) }
28
+
29
+ factory :captured_paypal_checkout_order do
30
+ data { JSON.parse(File.read(SpreePaypalCheckout::Engine.root.join('spec', 'fixtures', 'captured_paypal_order.json'))) }
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,7 @@
1
+ module SpreePaypalCheckout
2
+ VERSION = '0.5.1'.freeze
3
+
4
+ def gem_version
5
+ Gem::Version.new(VERSION)
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'spree_core'
2
+ require 'spree_extension'
3
+ require 'spree_paypal_checkout/engine'
4
+ require 'spree_paypal_checkout/version'
5
+ require 'spree_paypal_checkout/configuration'
6
+
7
+ require 'paypal_server_sdk'
metadata ADDED
@@ -0,0 +1,206 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spree_paypal_checkout
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.1
5
+ platform: ruby
6
+ authors:
7
+ - Vendo Connect Inc.
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2025-06-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: spree
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 5.1.0.beta4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 5.1.0.beta4
27
+ - !ruby/object:Gem::Dependency
28
+ name: spree_storefront
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 5.1.0.beta4
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 5.1.0.beta4
41
+ - !ruby/object:Gem::Dependency
42
+ name: spree_admin
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 5.1.0.beta4
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 5.1.0.beta4
55
+ - !ruby/object:Gem::Dependency
56
+ name: spree_extension
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: paypal-server-sdk
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.1'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: dotenv
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: spree_dev_tools
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: vcr
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: webmock
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description:
140
+ email: hello@spreecommerce.org
141
+ executables: []
142
+ extensions: []
143
+ extra_rdoc_files: []
144
+ files:
145
+ - LICENSE.md
146
+ - README.md
147
+ - Rakefile
148
+ - app/assets/config/spree_paypal_checkout_manifest.js
149
+ - app/controllers/spree/api/v2/storefront/paypal_orders_controller.rb
150
+ - app/controllers/spree_paypal_checkout/store_controller_decorator.rb
151
+ - app/helpers/spree_paypal_checkout/base_helper.rb
152
+ - app/javascript/spree_paypal_checkout/application.js
153
+ - app/javascript/spree_paypal_checkout/controllers/checkout_paypal_controller.js
154
+ - app/models/spree_paypal_checkout/base.rb
155
+ - app/models/spree_paypal_checkout/gateway.rb
156
+ - app/models/spree_paypal_checkout/order.rb
157
+ - app/models/spree_paypal_checkout/order_decorator.rb
158
+ - app/models/spree_paypal_checkout/payment_method_decorator.rb
159
+ - app/models/spree_paypal_checkout/payment_sources/paypal.rb
160
+ - app/models/spree_paypal_checkout/store_decorator.rb
161
+ - app/presenters/spree_paypal_checkout/order_presenter.rb
162
+ - app/serializers/spree/api/v2/storefront/paypal_order_serializer.rb
163
+ - app/services/spree_paypal_checkout/capture_order.rb
164
+ - app/services/spree_paypal_checkout/create_payment.rb
165
+ - app/services/spree_paypal_checkout/create_source.rb
166
+ - app/views/spree/admin/payment_methods/configuration_guides/_spree_paypal_checkout.html.erb
167
+ - app/views/spree/admin/payment_methods/descriptions/_spree_paypal_checkout.html.erb
168
+ - app/views/spree/checkout/payment/_spree_paypal_checkout.html.erb
169
+ - app/views/spree/payment_sources/_paypal_checkout.html.erb
170
+ - app/views/spree_paypal_checkout/_head.html.erb
171
+ - config/importmap.rb
172
+ - config/initializers/spree.rb
173
+ - config/locales/en.yml
174
+ - config/routes.rb
175
+ - db/migrate/20250528095719_create_spree_paypal_checkout_orders.rb
176
+ - lib/generators/spree_paypal_checkout/install/install_generator.rb
177
+ - lib/spree_paypal_checkout.rb
178
+ - lib/spree_paypal_checkout/configuration.rb
179
+ - lib/spree_paypal_checkout/engine.rb
180
+ - lib/spree_paypal_checkout/factories.rb
181
+ - lib/spree_paypal_checkout/version.rb
182
+ homepage: https://github.com/spree/spree_paypal_checkout
183
+ licenses:
184
+ - AGPL-3.0-or-later
185
+ metadata: {}
186
+ post_install_message:
187
+ rdoc_options: []
188
+ require_paths:
189
+ - lib
190
+ required_ruby_version: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '3.0'
195
+ required_rubygems_version: !ruby/object:Gem::Requirement
196
+ requirements:
197
+ - - ">="
198
+ - !ruby/object:Gem::Version
199
+ version: '0'
200
+ requirements:
201
+ - none
202
+ rubygems_version: 3.5.3
203
+ signing_key:
204
+ specification_version: 4
205
+ summary: Spree Commerce PayPal Checkout payment gateway integration
206
+ test_files: []