spree_vpago 2.4.0 → 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 +4 -4
- data/Gemfile.lock +1 -1
- data/app/controllers/spree/vpago_orders_controller.rb +113 -0
- data/app/controllers/spree/vpago_payments_controller.rb +6 -0
- data/app/jobs/vpago/order_processor_job.rb +21 -0
- data/app/models/vpago/order_decorator.rb +13 -0
- data/app/serializers/spree/v2/storefront/cart_serializer_decorator.rb +18 -0
- data/app/services/vpago/order_finder.rb +29 -0
- data/app/services/vpago/order_processor.rb +91 -0
- data/app/services/vpago/order_url_constructor.rb +29 -0
- data/app/services/vpago/payments/find_or_create.rb +7 -0
- data/app/views/spree/{vpago_payments → vpago_shared}/processing.html.erb +14 -4
- data/config/routes.rb +9 -0
- data/lib/spree_vpago/version.rb +1 -1
- metadata +10 -4
- /data/app/views/spree/{vpago_payments → vpago_shared}/success.html.erb +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ece936406834ee468fa22709a7ddb241fc472d2d6729b73e731a3e9868ee78f0
|
|
4
|
+
data.tar.gz: f7d47a531890cb5354a2c007cb52690e0ce6f61902c228b33b5ecb45a3753336
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9e211536c98efcec86053b88dcaa146ea50f3767ba41e3ddf5cd39eb9200f9fc5236f09ac6813a8c3fc478a34739c8366724f2e5643a45ec1c42c09b6f3c41f4
|
|
7
|
+
data.tar.gz: 0d4045c9c3f0587df01a81f65a930165f4d12bb35dddca7cddc5e1357d311af35308afc02a42b6a39d718bb5af40d604ea60b56bdffbc8bf853a3f7dc277ecaa
|
data/Gemfile.lock
CHANGED
|
@@ -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: "<%=
|
|
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: "<%=
|
|
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 = "<%=
|
|
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]
|
data/lib/spree_vpago/version.rb
CHANGED
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.
|
|
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-
|
|
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/
|
|
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
|
|
File without changes
|