spree_vpago 2.4.0.pre.pre4 → 2.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e6aa04b95597fa95d61728c47d6d01ae60aa9115f7c6abf841722a00470a67d8
4
- data.tar.gz: f20f863945029f326146aab3bd05204c9b91b217879821838440adafe6fa1003
3
+ metadata.gz: ece936406834ee468fa22709a7ddb241fc472d2d6729b73e731a3e9868ee78f0
4
+ data.tar.gz: f7d47a531890cb5354a2c007cb52690e0ce6f61902c228b33b5ecb45a3753336
5
5
  SHA512:
6
- metadata.gz: d942b7ea7ceeb0de4cee4b999c9e372f4782561dbb2ff269bb3b2cc8198e136b3d8173e5448ba957f4edb400a9b5ecab5d6aa7dad962987d65d4c938715cfde6
7
- data.tar.gz: 1713ce0c8712c50c50a551903f094298ba3cae5bdf5be33f5ddf894a04c513ecbe03a9725799188cd6e492f4f5849877bff22069178a6b030740a99c952e0d39
6
+ metadata.gz: 9e211536c98efcec86053b88dcaa146ea50f3767ba41e3ddf5cd39eb9200f9fc5236f09ac6813a8c3fc478a34739c8366724f2e5643a45ec1c42c09b6f3c41f4
7
+ data.tar.gz: 0d4045c9c3f0587df01a81f65a930165f4d12bb35dddca7cddc5e1357d311af35308afc02a42b6a39d718bb5af40d604ea60b56bdffbc8bf853a3f7dc277ecaa
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- spree_vpago (2.4.0.pre.pre4)
4
+ spree_vpago (2.4.1)
5
5
  faraday
6
6
  google-cloud-firestore
7
7
  spree_api (>= 4.5)
@@ -0,0 +1,113 @@
1
+ # Order-based counterpart to Spree::VpagoPaymentsController, for orders where
2
+ # order_total_after_store_credit is zero -- store credit covering the order in full, cash-on with
3
+ # nothing left to pay after store credit, or a free event. Deliberately client-agnostic to whether
4
+ # a Spree::Payment exists underneath (store credit's checkout-state payment is real; a free event
5
+ # has none at all -- see Vpago::OrderDecorator#processing_url and
6
+ # Vpago::OrderProcessor). No checkout-form step is ever needed here either way -- clients land
7
+ # straight on `processing`.
8
+ #
9
+ # processing/success render spree/vpago_shared/{processing,success} (made @payment-optional there)
10
+ # rather than maintaining a near-duplicate pair under spree/vpago_orders/ -- the two flows share
11
+ # the same card layout, Stimulus controller, and booking-details partial; only the payment info
12
+ # section and a few dataset attributes differ, and those are already guarded on @payment being
13
+ # present.
14
+ module Spree
15
+ class VpagoOrdersController < ApplicationController
16
+ layout 'vpago_payments'
17
+ helper 'vpago/vpago_payments'
18
+
19
+ skip_before_action :verify_authenticity_token, only: %i[process_order]
20
+
21
+ rescue_from ActiveRecord::RecordNotFound, with: :render_not_found
22
+ rescue_from CanCan::AccessDenied, with: :access_denied
23
+
24
+ before_action :find_order, only: %i[processing success]
25
+ after_action :allow_iframe_embedding, only: %i[processing success]
26
+
27
+ # GET
28
+ def processing
29
+ return redirect_to @order.success_url, allow_other_host: true if @order.completed?
30
+
31
+ VpagoLogger.log(label: 'Spree::VpagoOrdersController#processing', data: vpago_log_context)
32
+ render 'spree/vpago_shared/processing'
33
+ end
34
+
35
+ # GET
36
+ def success
37
+ raise CanCan::AccessDenied unless @order.completed?
38
+
39
+ VpagoLogger.log(label: 'Spree::VpagoOrdersController#success', data: vpago_log_context)
40
+ render 'spree/vpago_shared/success'
41
+ end
42
+
43
+ # POST
44
+ def process_order
45
+ return render json: { status: :ok }, status: :ok if request.method != 'POST'
46
+
47
+ @order = Vpago::OrderFinder.new(params.permit!.to_h).find_and_verify
48
+
49
+ if @order.nil?
50
+ VpagoLogger.error(
51
+ label: 'Spree::VpagoOrdersController#process_order order_not_found',
52
+ data: vpago_log_context(params: params.permit!.to_h)
53
+ )
54
+ return render_not_found
55
+ end
56
+
57
+ VpagoLogger.log(label: 'Spree::VpagoOrdersController#process_order order_found', data: vpago_log_context)
58
+
59
+ unless @order.completed?
60
+ VpagoLogger.log(
61
+ label: 'Spree::VpagoOrdersController#process_order enqueue_order_processor_job',
62
+ data: vpago_log_context
63
+ ) { Vpago::OrderProcessorJob.perform_later(order_number: @order.number) }
64
+ end
65
+
66
+ render json: { status: :ok }, status: :ok
67
+ rescue StandardError => e
68
+ VpagoLogger.error(
69
+ label: 'Spree::VpagoOrdersController#process_order failed',
70
+ data: vpago_log_context(error_class: e.class.name, error_message: e.message, backtrace: e.backtrace&.first(5))
71
+ )
72
+ render json: { status: :internal_server_error, message: 'Failed to enqueue order processor job' }, status: :internal_server_error
73
+ end
74
+
75
+ private
76
+
77
+ def find_order
78
+ @order = Vpago::OrderFinder.new(params.permit!.to_h).find_and_verify
79
+ @payment = @order.payments.first if @order.present? # optional, for shared partials
80
+ raise ActiveRecord::RecordNotFound unless @order.present?
81
+ end
82
+
83
+ # frame-ancestors (set above) supersedes X-Frame-Options in modern
84
+ # browsers, but the default SAMEORIGIN header would still block legacy
85
+ # browsers from embedding these pages, so drop it for the iframe actions.
86
+ def allow_iframe_embedding
87
+ response.headers.delete('X-Frame-Options')
88
+ end
89
+
90
+ def render_not_found
91
+ respond_to do |format|
92
+ format.html { render file: Rails.public_path.join('404.html'), status: :not_found, layout: false }
93
+ format.json { render json: { status: :not_found }, status: :not_found }
94
+ end
95
+ end
96
+
97
+ def access_denied
98
+ respond_to do |format|
99
+ format.html { render file: Rails.public_path.join('422.html'), status: :not_found, layout: false }
100
+ format.json { render json: { status: :unauthorized }, status: :unauthorized }
101
+ end
102
+ end
103
+
104
+ def vpago_log_context(extra = {})
105
+ {
106
+ timestamp: Time.current.utc.iso8601(3),
107
+ remote_ip: request.remote_ip,
108
+ order_number: @order&.number,
109
+ request_id: request.request_id
110
+ }.merge(extra)
111
+ end
112
+ end
113
+ end
@@ -1,4 +1,8 @@
1
1
  module Spree
2
+ # processing/success render spree/vpago_shared/{processing,success} -- shared with
3
+ # Spree::VpagoOrdersController, since the two flows share the same card layout, Stimulus
4
+ # controller, and booking-details partial (see spree/vpago_shared/processing.html.erb for how
5
+ # @payment-vs-@order is resolved there).
2
6
  class VpagoPaymentsController < ApplicationController
3
7
  layout 'vpago_payments'
4
8
  helper 'vpago/vpago_payments'
@@ -31,6 +35,7 @@ module Spree
31
35
  return redirect_to @payment.success_url, allow_other_host: true if @order.completed?
32
36
 
33
37
  VpagoLogger.log(label: 'Spree::VpagoPaymentsController#processing', data: vpago_log_context)
38
+ render 'spree/vpago_shared/processing'
34
39
  end
35
40
 
36
41
  # GET
@@ -39,6 +44,7 @@ module Spree
39
44
  raise CanCan::AccessDenied unless @order.completed?
40
45
 
41
46
  VpagoLogger.log(label: 'Spree::VpagoPaymentsController#success', data: vpago_log_context)
47
+ render 'spree/vpago_shared/success'
42
48
  end
43
49
 
44
50
  # GET
@@ -0,0 +1,21 @@
1
+ # Put :payment_processing at a higher priority in your project: config/sidekiq.yml
2
+ module Vpago
3
+ class OrderProcessorJob < ::ApplicationUniqueJob
4
+ queue_as :payment_processing
5
+
6
+ def perform(options)
7
+ order = Spree::Order.find_by!(number: options[:order_number])
8
+
9
+ VpagoLogger.log(
10
+ label: 'Vpago::OrderProcessorJob#perform',
11
+ data: { order_number: order.number }
12
+ ) { Vpago::OrderProcessor.new(order: order).call }
13
+ rescue StandardError => e
14
+ VpagoLogger.error(
15
+ label: 'Vpago::OrderProcessorJob#perform failed',
16
+ data: { order_number: options[:order_number], error_class: e.class.name, error_message: e.message, backtrace: e.backtrace&.first(5) }
17
+ )
18
+ raise
19
+ end
20
+ end
21
+ end
@@ -12,6 +12,19 @@ module Vpago
12
12
 
13
13
  base.state_machine.before_transition from: :cart, do: :ensure_valid_vendor_payment_methods
14
14
  base.state_machine.after_transition to: :complete, do: :generate_line_items_total_metadata
15
+
16
+ base.delegate :processing_url, :success_url, :process_order_url, to: :order_url_constructor
17
+ end
18
+
19
+ # For orders where order_total_after_store_credit is zero (see Vpago::OrderProcessor) --
20
+ # no Spree::Payment is involved, so this mirrors Vpago::PaymentDecorator#user_informer /
21
+ # #url_constructor but keyed on the order directly instead of a payment.
22
+ def user_informer
23
+ @user_informer ||= ::Vpago::UserInformers::Firebase.new(self)
24
+ end
25
+
26
+ def order_url_constructor
27
+ @order_url_constructor ||= Vpago::OrderUrlConstructor.new(self)
15
28
  end
16
29
 
17
30
  # override
@@ -0,0 +1,18 @@
1
+ module Spree
2
+ module V2
3
+ module Storefront
4
+ module CartSerializerDecorator
5
+ def self.prepended(base)
6
+ base.attribute :processing_url
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ # Both CartSerializer and OrderSerializer (which inherits from CartSerializer) need the decorator
14
+ # applied directly -- see SpreeCmCommissioner::V2::Storefront::CartSerializerDecorator for why
15
+ # (prepending to CartSerializer alone doesn't retroactively reach OrderSerializer).
16
+ Spree::V2::Storefront::OrderSerializer.prepend(Spree::V2::Storefront::CartSerializerDecorator) unless Spree::V2::Storefront::OrderSerializer.include?(Spree::V2::Storefront::CartSerializerDecorator)
17
+
18
+ Spree::V2::Storefront::CartSerializer.prepend(Spree::V2::Storefront::CartSerializerDecorator) unless Spree::V2::Storefront::CartSerializer.include?(Spree::V2::Storefront::CartSerializerDecorator)
@@ -0,0 +1,29 @@
1
+ module Vpago
2
+ # Order-based counterpart to Vpago::PaymentFinder, for flows that have no Spree::Payment to key
3
+ # off of (order_total_after_store_credit == 0: store credit covering the order in full, cash-on
4
+ # with nothing left to pay after store credit, or a free event -- see Vpago::OrderProcessor).
5
+ class OrderFinder
6
+ attr_reader :params_hash
7
+
8
+ def initialize(params_hash)
9
+ @params_hash = params_hash
10
+ end
11
+
12
+ def find_and_verify
13
+ find_and_verify!
14
+ rescue StandardError, ActiveRecord::RecordNotFound => e
15
+ Rails.logger.error("Vpago::OrderFinder#find_and_verify error: #{e.class} - #{e.message}")
16
+ nil
17
+ end
18
+
19
+ def find_and_verify!
20
+ order = Spree::Order.find_by!(number: params_hash[:order_number])
21
+ verify_jwt!(order)
22
+ order
23
+ end
24
+
25
+ def verify_jwt!(order)
26
+ JWT.decode(params_hash[:order_jwt_token], order.token, 'HS256')
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,91 @@
1
+ # Order-based counterpart to Vpago::PaymentProcessor, for orders where order_total_after_store_credit
2
+ # is zero -- store credit covering the order in full, cash-on with nothing left to pay after store
3
+ # credit, or a free event. None of these need a Spree::Payment processed (there may be no payment
4
+ # record at all, e.g. free events), only the order completed -- so this only runs the process_order!
5
+ # half of PaymentProcessor#call!, reusing the same completer + Firebase user-informer flow so the
6
+ # vpago_orders webview (processing -> success) behaves like vpago_payments for the client.
7
+ #
8
+ # Error reason code:
9
+ # - :some_line_items_are_out_of_stock
10
+ # - :some_variants_are_discontinued
11
+ # - :unable_to_complete_order
12
+ # - :invalid_state_machine_transition
13
+ module Vpago
14
+ class OrderProcessor
15
+ def initialize(order:)
16
+ @order = order
17
+ @error = nil
18
+ end
19
+
20
+ def call
21
+ log_process('call!') { call! }
22
+ end
23
+
24
+ def call!
25
+ process_order!
26
+ rescue StateMachines::InvalidTransition => e
27
+ handle_order_process_failure(:invalid_state_machine_transition, e.message)
28
+ end
29
+
30
+ def success?
31
+ @error.nil?
32
+ end
33
+
34
+ private
35
+
36
+ def process_order!
37
+ log_process('process_order!') do
38
+ user_informer.order_is_processing(processing: true)
39
+ completer = Spree::Checkout::Complete.new.call(order: @order)
40
+
41
+ if completer.success?
42
+ handle_order_process_completed
43
+ else
44
+ reason_code = extract_completer_failure_reason_code(completer.error)
45
+ handle_order_process_failure(reason_code, completer.error.to_s)
46
+ end
47
+ end
48
+ end
49
+
50
+ def handle_order_process_completed
51
+ log_process('handle_order_process_completed') do
52
+ user_informer.order_is_completed(processing: false)
53
+ end
54
+ end
55
+
56
+ def handle_order_process_failure(reason_code, reason_message = nil)
57
+ log_process('handle_order_process_failure', reason_code, reason_message) do
58
+ user_informer.order_process_failed(
59
+ processing: false,
60
+ reason_code: reason_code,
61
+ reason_message: reason_message
62
+ )
63
+
64
+ failure(reason_message)
65
+ end
66
+ end
67
+
68
+ def extract_completer_failure_reason_code(error)
69
+ return :some_line_items_are_out_of_stock if error.respond_to?(:to_h) && error.to_h[:base]&.include?(Spree.t(:insufficient_stock_lines_present))
70
+ return :some_variants_are_discontinued if error.respond_to?(:to_h) && error.to_h[:base]&.include?(Spree.t(:discontinued_variants_present))
71
+
72
+ :unable_to_complete_order
73
+ end
74
+
75
+ def log_process(method, *args, &)
76
+ VpagoLogger.log(
77
+ label: "#{self.class.name}##{method}",
78
+ data: { order_number: @order.number, args: args },
79
+ &
80
+ )
81
+ end
82
+
83
+ def user_informer
84
+ @user_informer ||= ::Vpago::UserInformers::Firebase.new(@order)
85
+ end
86
+
87
+ def failure(error)
88
+ @error = error
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,29 @@
1
+ module Vpago
2
+ class OrderUrlConstructor
3
+ attr_accessor :order
4
+
5
+ def initialize(order)
6
+ @order = order
7
+ end
8
+
9
+ def processing_url = "#{base_url}/vpago_orders/processing?#{query}"
10
+ def success_url = "#{base_url}/vpago_orders/success?#{query}"
11
+
12
+ def process_order_url = "#{base_url}/vpago_orders/process_order?#{query}"
13
+
14
+ def query
15
+ { order_number: order.number, order_jwt_token: order_jwt_token }.to_query
16
+ end
17
+
18
+ private
19
+
20
+ def base_url
21
+ order.payment_host
22
+ end
23
+
24
+ def order_jwt_token
25
+ payload = { order_number: order.number, order_id: order.id }
26
+ JWT.encode(payload, order.token, 'HS256')
27
+ end
28
+ end
29
+ end
@@ -19,6 +19,13 @@ module Vpago
19
19
  end
20
20
 
21
21
  def find_or_create_payment(order:, params:, payment_method:)
22
+ # Store credit is applied via the storefront's own POST .../checkout/add_store_credit,
23
+ # never through create_payment. Its source_class (Spree::StoreCredit) has neither a
24
+ # payment_method_id column nor the other fields a blank .new(...) below would need to
25
+ # save, so falling through would raise ActiveModel::UnknownAttributeError instead of
26
+ # producing a broken payment -- fail clearly instead.
27
+ return failure(nil, :store_credit_must_be_applied_via_add_store_credit) if payment_method.is_a?(Spree::PaymentMethod::StoreCredit)
28
+
22
29
  payment = order.payments.find_or_initialize_by(
23
30
  state: :checkout,
24
31
  amount: order.order_total_after_store_credit,
@@ -1,16 +1,26 @@
1
+ <%
2
+ # Shared by both Spree::VpagoPaymentsController and Spree::VpagoOrdersController. The flow is
3
+ # decided by which controller the client was sent to -- @payment can't tell them apart, since
4
+ # VpagoOrdersController also sets it for shared partials when the order has a payment.
5
+ vpago_use_order_flow = controller_name == 'vpago_orders'
6
+ # Falls back to the order-level URL when there is no @payment (e.g. a free event).
7
+ vpago_process_url = vpago_use_order_flow ? @order.process_order_url : (@payment&.process_payment_url || @order.process_order_url)
8
+ vpago_user_informer = vpago_use_order_flow ? @order.user_informer : (@payment&.user_informer || @order.user_informer)
9
+ vpago_success_url = vpago_use_order_flow ? @order.success_url : (@payment&.success_url || @order.success_url)
10
+ %>
1
11
  <h1 id="status">THIS IS CURRENT STATE</h1>
2
12
  <p id="reason_code"></p>
3
13
  <p id="processing"></p>
4
14
  <p id="reason_message"></p>
5
15
 
6
- <%= render_additional_processing_script(@payment) %>
16
+ <%= render_additional_processing_script(@payment) if @payment && !vpago_use_order_flow %>
7
17
 
8
18
  <script>
9
19
  document.addEventListener("DOMContentLoaded", function() {
10
20
  let firebaseConfigs = <%= Rails.application.credentials.firebase_web_config.to_json.html_safe %>;
11
21
 
12
22
  window.requestProcessPayment({
13
- url: "<%= @payment.process_payment_url %>",
23
+ url: "<%= vpago_process_url %>",
14
24
  params: <%= params.except(:action, :controller, :amp).to_json.html_safe %>,
15
25
  maxRetries: 5,
16
26
  retryDelayMs: 1000,
@@ -18,7 +28,7 @@
18
28
 
19
29
  window.listenToProcessingState({
20
30
  firebaseConfigs: firebaseConfigs,
21
- documentReferencePath: "<%= @payment.user_informer.document_reference_path %>",
31
+ documentReferencePath: "<%= vpago_user_informer.document_reference_path %>",
22
32
  onPaymentIsProcessing: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
23
33
  document.getElementById("status").innerText = "Payment is processing";
24
34
  document.getElementById("reason_code").innerText = reasonCode;
@@ -56,7 +66,7 @@
56
66
  document.getElementById("reason_message").innerText = reasonMessage;
57
67
  },
58
68
  onCompleted: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
59
- let successPath = "<%= @payment.success_url %>";
69
+ let successPath = "<%= vpago_success_url %>";
60
70
  window.location.href = successPath;
61
71
  },
62
72
  });
data/config/routes.rb CHANGED
@@ -43,6 +43,15 @@ Spree::Core::Engine.add_routes do
43
43
  end
44
44
  end
45
45
 
46
+ resource :vpago_orders do
47
+ collection do
48
+ get :processing
49
+ get :success
50
+
51
+ match :process_order, via: %i[get post]
52
+ end
53
+ end
54
+
46
55
  namespace :webhook do
47
56
  resource :payways, only: [] do
48
57
  match 'return', to: 'payways#return', via: %i[get post]
@@ -1,7 +1,7 @@
1
1
  module SpreeVpago
2
2
  module_function
3
3
 
4
- VERSION = '2.4.0-pre4'.freeze
4
+ VERSION = '2.4.1'.freeze
5
5
 
6
6
  def version
7
7
  Gem::Version.new VERSION
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_vpago
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0.pre.pre4
4
+ version: 2.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - You
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-10-06 00:00:00.000000000 Z
11
+ date: 2026-10-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -181,6 +181,7 @@ files:
181
181
  - app/controllers/spree/payway_card_popups_controller.rb
182
182
  - app/controllers/spree/payway_results_controller.rb
183
183
  - app/controllers/spree/payway_v2_card_popups_controller.rb
184
+ - app/controllers/spree/vpago_orders_controller.rb
184
185
  - app/controllers/spree/vpago_payments_controller.rb
185
186
  - app/controllers/spree/webhook/acleda_mobiles_controller.rb
186
187
  - app/controllers/spree/webhook/acledas_controller.rb
@@ -196,6 +197,7 @@ files:
196
197
  - app/javascripts/queue_processor.test.js
197
198
  - app/javascripts/vpago/vpago_payments/user_informers/firebase.js
198
199
  - app/jobs/application_unique_job.rb
200
+ - app/jobs/vpago/order_processor_job.rb
199
201
  - app/jobs/vpago/payment_canceler_job.rb
200
202
  - app/jobs/vpago/payment_capturer_job.rb
201
203
  - app/jobs/vpago/payment_processor_job.rb
@@ -264,6 +266,7 @@ files:
264
266
  - app/overrides/spree/admin/tax_categories/index/collect_by_table_body.html.erb.deface
265
267
  - app/overrides/spree/admin/tax_categories/index/collect_by_table_header.html.erb.deface
266
268
  - app/serializers/spree/api/v2/platform/vpago_payment_source_serializer.rb
269
+ - app/serializers/spree/v2/storefront/cart_serializer_decorator.rb
267
270
  - app/serializers/spree/v2/storefront/payment_method_serializer_decorator.rb
268
271
  - app/serializers/spree/v2/storefront/payment_redirect_serializer.rb
269
272
  - app/serializers/spree/v2/storefront/payment_serializer_decorator.rb
@@ -271,6 +274,9 @@ files:
271
274
  - app/services/.gitkeep
272
275
  - app/services/vpago/acleda_mini_app/session/create.rb
273
276
  - app/services/vpago/aes_encrypter.rb
277
+ - app/services/vpago/order_finder.rb
278
+ - app/services/vpago/order_processor.rb
279
+ - app/services/vpago/order_url_constructor.rb
274
280
  - app/services/vpago/payment_finder.rb
275
281
  - app/services/vpago/payment_processable.rb
276
282
  - app/services/vpago/payment_processor.rb
@@ -367,10 +373,10 @@ files:
367
373
  - app/views/spree/vpago_payments/forms/spree/gateway/_vattanac.html.erb
368
374
  - app/views/spree/vpago_payments/forms/spree/gateway/_vattanac_mini_app.html.erb
369
375
  - app/views/spree/vpago_payments/forms/spree/gateway/_wing_mini_app.html.erb
370
- - app/views/spree/vpago_payments/processing.html.erb
371
376
  - app/views/spree/vpago_payments/processing_scripts/spree/gateway/_payway_v2.html.erb
372
377
  - app/views/spree/vpago_payments/processing_scripts/spree/gateway/_wing_mini_app.html.erb
373
- - app/views/spree/vpago_payments/success.html.erb
378
+ - app/views/spree/vpago_shared/processing.html.erb
379
+ - app/views/spree/vpago_shared/success.html.erb
374
380
  - app/views/spree/wing_redirects/show.html.erb
375
381
  - bin/rails
376
382
  - build.js
@@ -486,9 +492,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
486
492
  version: 3.2.0
487
493
  required_rubygems_version: !ruby/object:Gem::Requirement
488
494
  requirements:
489
- - - ">"
495
+ - - ">="
490
496
  - !ruby/object:Gem::Version
491
- version: 1.3.1
497
+ version: '0'
492
498
  requirements:
493
499
  - none
494
500
  rubygems_version: 3.4.1