spree_vpago 2.1.5 → 2.1.7.pre.pre1

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: 5e0bef3dae037547659fac051e034deacaa809aa6fa124f3be53e5240312172b
4
- data.tar.gz: b5fe3d1d212949d5770a4a10fd4cb69458430268975a41c2d7b7956b27e8d68c
3
+ metadata.gz: 87136a1f5a93bf4b0a1b465895df7235f9ad4aee4e26f5cdf17c5523609cb63e
4
+ data.tar.gz: 2291730a6de4b9100723fa803bb7b17c8e38d6ca70187c7de8ce5de9e7a4062d
5
5
  SHA512:
6
- metadata.gz: b0220a86b6f7283308819ce31a46d684691a37ef00dd21722c6b27e8ae2048f18fc34527414973faa532148630145a60b2374510de47a868ca20ae641db9c35f
7
- data.tar.gz: 6bf0a80d5392dc21b3bf379feac65bdcc41b9f29db1c3e6a326156ac27ce195833db8eb8950db5603027382e29c6292d8d56816f00c84cb9a8bacc29198d5868
6
+ metadata.gz: 9c9f885d4cc09498c50d9d47971c4b1554c0ac8185e8ae4675ae716383c3997681776ff68c914be70060b0677a4bcbe74bb087af440a9c3951fe3ec1e5c0dcce
7
+ data.tar.gz: 40fa3cd8be136446101fc71183cbc464c32d87b7998f859eeb5643e6c9dca0117c797bbd79ce9be1c857b7bc3573c4413a586b431d8a2c7bba748cbde7aba3c1
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- spree_vpago (2.1.5)
4
+ spree_vpago (2.1.7.pre.pre1)
5
5
  faraday
6
6
  google-cloud-firestore
7
7
  spree_api (>= 4.5)
@@ -242,7 +242,7 @@ GEM
242
242
  gapic-common (~> 1.2)
243
243
  google-cloud-errors (~> 1.0)
244
244
  google-logging-utils (0.2.0)
245
- google-protobuf (4.33.0-arm64-darwin)
245
+ google-protobuf (4.33.2)
246
246
  bigdecimal
247
247
  rake (>= 13)
248
248
  googleapis-common-protos (1.9.0)
@@ -251,7 +251,7 @@ GEM
251
251
  grpc (~> 1.41)
252
252
  googleapis-common-protos-types (1.22.0)
253
253
  google-protobuf (~> 4.26)
254
- googleauth (1.15.1)
254
+ googleauth (1.16.0)
255
255
  faraday (>= 1.0, < 3.a)
256
256
  google-cloud-env (~> 2.2)
257
257
  google-logging-utils (~> 0.1)
@@ -259,7 +259,7 @@ GEM
259
259
  multi_json (~> 1.11)
260
260
  os (>= 0.9, < 2.0)
261
261
  signet (>= 0.16, < 2.a)
262
- grpc (1.76.0-arm64-darwin)
262
+ grpc (1.76.0)
263
263
  google-protobuf (>= 3.25, < 5.0)
264
264
  googleapis-common-protos-types (~> 1.0)
265
265
  hashdiff (1.1.0)
@@ -6,7 +6,9 @@ window.initPaymentProcessingListener = async function (
6
6
  function log(status, processing, reasonCode, reasonMessage) {
7
7
  console.log(`Status: ${status}`);
8
8
  console.log(`Reason Code: ${reasonCode}`);
9
- console.log(`Processing: ${processing ? "Processing..." : "No more process."}`);
9
+ console.log(
10
+ `Processing: ${processing ? "Processing..." : "No more process."}`
11
+ );
10
12
  console.log(`Reason Message: ${reasonMessage}`);
11
13
  }
12
14
 
@@ -14,33 +16,80 @@ window.initPaymentProcessingListener = async function (
14
16
  firebaseConfigs,
15
17
  documentReferencePath,
16
18
 
17
- onPaymentIsProcessing(orderState, paymentState, processing, reasonCode, reasonMessage) {
19
+ onPaymentIsProcessing(
20
+ orderState,
21
+ paymentState,
22
+ processing,
23
+ reasonCode,
24
+ reasonMessage
25
+ ) {
18
26
  log("Payment is processing", processing, reasonCode, reasonMessage);
19
27
  },
20
28
 
21
- onOrderIsProcessing(orderState, paymentState, processing, reasonCode, reasonMessage) {
29
+ onPaymentIsRetrying(
30
+ orderState,
31
+ paymentState,
32
+ processing,
33
+ reasonCode,
34
+ reasonMessage
35
+ ) {
36
+ log("Payment is retrying", processing, reasonCode, reasonMessage);
37
+ },
38
+
39
+ onOrderIsProcessing(
40
+ orderState,
41
+ paymentState,
42
+ processing,
43
+ reasonCode,
44
+ reasonMessage
45
+ ) {
22
46
  log("Order is processing", processing, reasonCode, reasonMessage);
23
47
  },
24
48
 
25
- onOrderIsCompleted(orderState, paymentState, processing, reasonCode, reasonMessage) {
49
+ onOrderIsCompleted(
50
+ orderState,
51
+ paymentState,
52
+ processing,
53
+ reasonCode,
54
+ reasonMessage
55
+ ) {
26
56
  log("Order is completed", processing, reasonCode, reasonMessage);
27
57
  },
28
58
 
29
- onOrderProcessFailed(orderState, paymentState, processing, reasonCode, reasonMessage) {
59
+ onOrderProcessFailed(
60
+ orderState,
61
+ paymentState,
62
+ processing,
63
+ reasonCode,
64
+ reasonMessage
65
+ ) {
30
66
  log("Order process failed", processing, reasonCode, reasonMessage);
31
67
  },
32
68
 
33
- onPaymentIsRefunded(orderState, paymentState, processing, reasonCode, reasonMessage) {
34
- log("Payment is refunded", processing, reasonCode, reasonMessage);
35
- },
36
-
37
- onPaymentProcessFailed(orderState, paymentState, processing, reasonCode, reasonMessage) {
69
+ onPaymentProcessFailed(
70
+ orderState,
71
+ paymentState,
72
+ processing,
73
+ reasonCode,
74
+ reasonMessage
75
+ ) {
38
76
  log("Payment process failed", processing, reasonCode, reasonMessage);
39
77
  },
40
78
 
41
- onCompleted(orderState, paymentState, processing, reasonCode, reasonMessage) {
42
- log("Completed — redirecting to success URL", processing, reasonCode, reasonMessage);
79
+ onCompleted(
80
+ orderState,
81
+ paymentState,
82
+ processing,
83
+ reasonCode,
84
+ reasonMessage
85
+ ) {
86
+ log(
87
+ "Completed — redirecting to success URL",
88
+ processing,
89
+ reasonCode,
90
+ reasonMessage
91
+ );
43
92
  window.location.href = successUrl;
44
- }
93
+ },
45
94
  });
46
95
  };
@@ -6,10 +6,10 @@ async function listenToProcessingState({
6
6
  firebaseConfigs,
7
7
  documentReferencePath,
8
8
  onPaymentIsProcessing,
9
+ onPaymentIsRetrying,
9
10
  onOrderIsProcessing,
10
11
  onOrderIsCompleted,
11
12
  onOrderProcessFailed,
12
- onPaymentIsRefunded,
13
13
  onPaymentProcessFailed,
14
14
  onCompleted,
15
15
  }) {
@@ -62,11 +62,11 @@ async function listenToProcessingState({
62
62
  },
63
63
  });
64
64
  break;
65
- case "order_is_processing":
65
+ case "payment_is_retrying":
66
66
  queueProcessor.queueStateChange({
67
67
  minDelayInMs: 1500,
68
68
  callback: async () => {
69
- await onOrderIsProcessing(
69
+ await onPaymentIsRetrying(
70
70
  orderState,
71
71
  paymentState,
72
72
  processing,
@@ -76,11 +76,11 @@ async function listenToProcessingState({
76
76
  },
77
77
  });
78
78
  break;
79
- case "order_is_completed":
79
+ case "order_is_processing":
80
80
  queueProcessor.queueStateChange({
81
81
  minDelayInMs: 1500,
82
82
  callback: async () => {
83
- await onOrderIsCompleted(
83
+ await onOrderIsProcessing(
84
84
  orderState,
85
85
  paymentState,
86
86
  processing,
@@ -90,11 +90,11 @@ async function listenToProcessingState({
90
90
  },
91
91
  });
92
92
  break;
93
- case "order_process_failed":
93
+ case "order_is_completed":
94
94
  queueProcessor.queueStateChange({
95
95
  minDelayInMs: 1500,
96
96
  callback: async () => {
97
- await onOrderProcessFailed(
97
+ await onOrderIsCompleted(
98
98
  orderState,
99
99
  paymentState,
100
100
  processing,
@@ -104,11 +104,11 @@ async function listenToProcessingState({
104
104
  },
105
105
  });
106
106
  break;
107
- case "payment_is_refunded":
107
+ case "order_process_failed":
108
108
  queueProcessor.queueStateChange({
109
109
  minDelayInMs: 1500,
110
110
  callback: async () => {
111
- await onPaymentIsRefunded(
111
+ await onOrderProcessFailed(
112
112
  orderState,
113
113
  paymentState,
114
114
  processing,
@@ -0,0 +1,11 @@
1
+ # Put :payment_processing at a higher priority in your project: config/sidekiq.yml
2
+ module Vpago
3
+ class PaymentCancelerJob < ::ApplicationUniqueJob
4
+ queue_as :payment_processing
5
+
6
+ def perform(payment_id)
7
+ payment = Spree::Payment.find(payment_id)
8
+ payment.cancel! if payment.actions.include?('cancel')
9
+ end
10
+ end
11
+ end
@@ -5,7 +5,7 @@ module Vpago
5
5
 
6
6
  def perform(payment_id)
7
7
  payment = Spree::Payment.find(payment_id)
8
- payment.capture! if payment.pending?
8
+ payment.capture! if payment.actions.include?('capture')
9
9
  end
10
10
  end
11
11
  end
@@ -4,7 +4,7 @@ module Vpago
4
4
  queue_as :payment_processing
5
5
 
6
6
  def perform(options)
7
- payment = Spree::Payment.find_by(number: options[:payment_number])
7
+ payment = Spree::Payment.find_by!(number: options[:payment_number])
8
8
  Vpago::PaymentProcessor.new(payment: payment).call
9
9
  end
10
10
  end
@@ -0,0 +1,11 @@
1
+ # Put :payment_processing at a higher priority in your project: config/sidekiq.yml
2
+ module Vpago
3
+ class PaymentVoiderJob < ::ApplicationUniqueJob
4
+ queue_as :payment_processing
5
+
6
+ def perform(payment_id)
7
+ payment = Spree::Payment.find(payment_id)
8
+ payment.void_transaction! if payment.actions.include?('void')
9
+ end
10
+ end
11
+ end
@@ -58,10 +58,12 @@ module Spree
58
58
  checker = check_transaction(payment)
59
59
  payment.update(transaction_response: checker.json_response)
60
60
 
61
+ params = { check: { response: checker.json_response } }
62
+
61
63
  if checker.success?
62
- ActiveMerchant::Billing::Response.new(true, 'Payway Gateway: Authorized')
64
+ ActiveMerchant::Billing::Response.new(true, 'Payway Gateway: Authorized', params)
63
65
  else
64
- ActiveMerchant::Billing::Response.new(false, 'Payway Gateway: Authorization Failed')
66
+ ActiveMerchant::Billing::Response.new(false, 'Payway Gateway: Authorization Failed', params)
65
67
  end
66
68
  end
67
69
 
@@ -140,14 +142,16 @@ module Spree
140
142
  canceler = Vpago::PaywayV2::PreAuthCanceler.new(payment)
141
143
  canceler.call
142
144
 
143
- [canceler.success?, canceler.request_data]
145
+ data = { request: canceler.request_data, response: canceler.json_response }
146
+ [canceler.success?, data]
144
147
  end
145
148
 
146
149
  def complete_pre_auth(payment)
147
150
  completer = Vpago::PaywayV2::PreAuthCompleter.new(payment)
148
-
149
151
  completer.call
150
- [completer.success?, completer.request_data]
152
+
153
+ data = { request: completer.request_data, response: completer.json_response }
154
+ [completer.success?, data]
151
155
  end
152
156
 
153
157
  def confirm_payouts(payment)
@@ -40,17 +40,18 @@ module Spree
40
40
  params[:payment_response] = payment.transaction_response
41
41
 
42
42
  if success
43
- ActiveMerchant::Billing::Response.new(true, 'Payway Gateway: Purchased', params)
43
+ ActiveMerchant::Billing::Response.new(true, 'True money Gateway: Purchased', params)
44
44
  else
45
- ActiveMerchant::Billing::Response.new(false, 'Payway Gateway: Purchasing Failed', params)
45
+ ActiveMerchant::Billing::Response.new(false, 'True money Gateway: Purchasing Failed', params)
46
46
  end
47
47
  end
48
48
 
49
49
  # override
50
- def void(_response_code, gateway_options)
51
- _, payment_number = gateway_options[:order_id].split('-')
52
- payment = Spree::Payment.find_by(number: payment_number)
50
+ def void(_response_code, _gateway_options)
51
+ ActiveMerchant::Billing::Response.new(true, 'True money Gateway: Payment has been voided.')
52
+ end
53
53
 
54
+ def cancel(_response_code, payment)
54
55
  if payment.true_money_payment?
55
56
  params = {}
56
57
  success, params[:refund_response] = true_money_refund(payment)
@@ -72,14 +73,6 @@ module Spree
72
73
  [refund_issuer.success?, refund_issuer.parsed_response]
73
74
  end
74
75
 
75
- def cancel(_response_code, _payment)
76
- # we can use this to send request to payment gateway api to cancel the payment ( void )
77
- # currently True money does not support to cancel the gateway
78
-
79
- # in our case don't do anything
80
- ActiveMerchant::Billing::Response.new(true, '')
81
- end
82
-
83
76
  private
84
77
 
85
78
  def check_transaction(payment)
@@ -34,10 +34,12 @@ module Spree
34
34
  end
35
35
 
36
36
  # override
37
- def void(_response_code, gateway_options)
38
- _, payment_number = gateway_options[:order_id].split('-')
39
- payment = Spree::Payment.find_by(number: payment_number)
37
+ def void(_response_code, _gateway_options)
38
+ ActiveMerchant::Billing::Response.new(true, 'Vattanac order has been voided.')
39
+ end
40
40
 
41
+ # override
42
+ def cancel(_response_code, payment)
41
43
  if payment.vattanac_mini_app_payment?
42
44
  params = {}
43
45
  success, params[:refund_response] = vattanac_mini_app_refund(payment)
@@ -58,13 +60,5 @@ module Spree
58
60
 
59
61
  [refund_issuer.success?, refund_issuer.response]
60
62
  end
61
-
62
- def cancel(_response_code, _payment)
63
- # we can use this to send request to payment gateway api to cancel the payment ( void )
64
- # currently Payway does not support to cancel the gateway
65
-
66
- # in our case don't do anything
67
- ActiveMerchant::Billing::Response.new(true, 'Vattanac order has been cancelled.')
68
- end
69
63
  end
70
64
  end
@@ -1,4 +1,5 @@
1
1
  class Spree::VpagoPaymentSource < Spree::Base
2
+ # deprecated preferences from older versions kept for data integrity
2
3
  preference :wing_response, :hash
3
4
  preference :acleda_response, :hash
4
5
  preference :payway_v2_response, :hash
@@ -11,11 +12,64 @@ class Spree::VpagoPaymentSource < Spree::Base
11
12
 
12
13
  # validates :updated_reason, presence: true, on: :update
13
14
 
15
+ # Define possible available actions for vpago payments.
16
+ # Then Spree::Payment#actions will select only those where can_<action>? returns true.
17
+ #
18
+ # These actions are triggered via: payment.send("#{action}!")
19
+ # - [void] can be triggered void_transaction (the alias by spree is to avoid conflict with the transition method name)
20
+ # - [open_checkout] is a view action and is handled manually in gems/spree_vpago/app/overrides/spree/admin/payments/_list/actions.html.erb.deface
21
+ # - [process] [capture] [void] [cancel] are built-in methods in the Spree::Payment model.
22
+ #
23
+ # Usages:
24
+ # See fire request method in gems/spree_backend/app/controllers/spree/admin/payments_controller.rb
25
+ # See jobs in gems/spree_vpago/app/jobs/vpago which are triggered by processor jobs.
26
+ #
27
+ # override
14
28
  def actions
15
- actions = []
16
- actions << 'open_checkout' if payment.checkout?
17
- actions << 'process' if payment.processing? || payment.checkout? || payment.send(:has_invalid_state?)
18
- actions << 'capture' if payment.pending?
19
- actions
29
+ %w[open_checkout process capture void cancel]
30
+ end
31
+
32
+ def can_open_checkout?(payment)
33
+ payment.checkout?
34
+ end
35
+
36
+ def can_process?(payment)
37
+ return false if payment.completed? || payment.pending?
38
+
39
+ payment.processing? || payment.checkout? || payment.send(:has_invalid_state?)
40
+ end
41
+
42
+ # The flow is as follows: payment authorized -> order completed -> capture the amount -> end.
43
+ def can_capture?(payment)
44
+ # Capture action should be triggered when the order is completed/secured for the user.
45
+ # Otherwise, we don't need to capture the payment as the order is not completed.
46
+ return false unless payment.order.completed?
47
+
48
+ # Most likely the payment is already captured, so we don't need to capture it again.
49
+ return false if payment.completed?
50
+
51
+ payment.pending?
52
+ end
53
+
54
+ # Spree has different refund logic, called credit. We use cancel as refund for now, but only for Vattanac/True Money.
55
+ # In the future, we can adopt Spree's credit logic instead of cancel if needed.
56
+ #
57
+ # The flow is as follows: payment paid -> order fails -> cancel (refund) -> end.
58
+ def can_cancel?(payment)
59
+ return false unless payment.vattanac_mini_app_payment? || payment.true_money_payment?
60
+
61
+ # Cancel action is triggered when an order fails to complete.
62
+ # So if the order somehow completes, we do not need to cancel the payment.
63
+ return false if payment.order.completed?
64
+
65
+ # Most likely the payment is already canceled/voided, so we don't need to cancel it again.
66
+ return false if payment.void?
67
+
68
+ payment.completed?
69
+ end
70
+
71
+ # The flow is as follows: payment authorized -> order failed -> void (release held payment) -> end.
72
+ def can_void?(payment)
73
+ payment.pending?
20
74
  end
21
75
  end
@@ -1,3 +1,17 @@
1
+ # Note for process! & capture! method:
2
+ #
3
+ # Original process! & capture! calls started_processing! to move state
4
+ # [:checkout, :pending, :completed, :processing] → :processing.
5
+ #
6
+ # When gateway call fails, handle_response calls send(:failure) which transitions
7
+ # the payment to :failed state. This happens BEFORE the GatewayError is raised,
8
+ # so when Sidekiq retries the job, the payment is already in :failed state.
9
+ #
10
+ # The :started_processing event doesn't allow transition from :failed → :processing,
11
+ # so we need to reset the state back to :checkout first via reset_for_retry!
12
+ #
13
+ # This allows process! or capture! to be retried by Sidekiq or by admin via /fire after connection errors
14
+ # or other transient gateway failures.
1
15
  module Vpago
2
16
  module PaymentDecorator
3
17
  def self.prepended(base)
@@ -11,12 +25,23 @@ module Vpago
11
25
  :process_payment_url,
12
26
  :success_deeplink_url,
13
27
  to: :url_constructor
28
+
29
+ # Add state machine event for payment retry
30
+ base.state_machine.event :reset_for_retry do
31
+ transition from: %i[failed], to: :checkout
32
+ end
14
33
  end
15
34
 
16
- # override:
17
- # to give payment another chance to re-process, even if it failed.
35
+ # override
18
36
  def process!
19
- update!(state: :checkout) if processing? || send(:has_invalid_state?)
37
+ reset_for_retry! if failed?
38
+
39
+ super
40
+ end
41
+
42
+ # override
43
+ def capture!(amount = nil)
44
+ reset_for_retry! if failed?
20
45
 
21
46
  super
22
47
  end
@@ -1,22 +1,20 @@
1
1
  module Vpago
2
2
  module PaymentProcessable
3
- def cancel_pre_auth(reason_code, reason_message)
4
- log_process('cancel_pre_auth') do
5
- @payment.void_transaction!
6
- user_informer.payment_is_refunded(
7
- processing: false,
8
- reason_code: reason_code,
9
- reason_message: reason_message
10
- )
3
+ def enqueue_capture_payment_if_available!
4
+ Vpago::PaymentCapturerJob.perform_later(@payment.id) if available_actions.include?('capture')
5
+ end
6
+
7
+ def enqueue_void_or_cancel_payment_if_available!
8
+ if available_actions.include?('void')
9
+ Vpago::PaymentVoiderJob.perform_later(@payment.id)
10
+ elsif available_actions.include?('cancel')
11
+ Vpago::PaymentCancelerJob.perform_later(@payment.id)
11
12
  end
12
13
  end
13
14
 
14
- # Allows canceling pre-authorization if:
15
- # 1. The payment is pending or authorized.
16
- # 2. Pre-auth is enabled, ensuring funds can be released to user if processing fails.
17
- # PaymentProcessor is usually called after payment is made, so canceling pre-auth typically works.
18
- def can_cancel_pre_auth?
19
- @payment.pending? || @payment.payment_method.enable_pre_auth? || @payment.vattanac_mini_app_payment? || @payment.true_money_payment?
15
+ # To check available actions, see app/models/spree/vpago_payment_source.rb
16
+ def available_actions
17
+ @payment.actions
20
18
  end
21
19
 
22
20
  def extract_completer_failure_reason_code(error)
@@ -19,10 +19,15 @@ module Vpago
19
19
  end
20
20
 
21
21
  def call!
22
- process_payment!
22
+ process_payment! if available_actions.include?('process')
23
23
  process_order! if @payment.completed? || @payment.pending?
24
24
  rescue Spree::Core::GatewayError => e
25
- return handle_payment_failure(:unable_to_connect_to_gateway, e.message) if e.message == Spree.t(:unable_to_connect_to_gateway)
25
+ if e.message == Spree.t(:unable_to_connect_to_gateway)
26
+ user_informer.payment_is_retrying(processing: true)
27
+
28
+ # Re-raise to trigger Sidekiq retry mechanism.
29
+ raise
30
+ end
26
31
 
27
32
  handle_payment_failure(:gateway_error, e.message)
28
33
  rescue StateMachines::InvalidTransition => e
@@ -39,6 +44,9 @@ module Vpago
39
44
  end
40
45
  end
41
46
 
47
+ # If this job retries, we run this method/completer again even if the order is already completed.
48
+ # This ensures flow consistency. The completer will return success & this method will call handle_order_process_completed,
49
+ # which will enqueue a capture payment if available.
42
50
  def process_order!
43
51
  log_process('process_order!') do
44
52
  user_informer.order_is_processing(processing: true)
@@ -55,7 +63,7 @@ module Vpago
55
63
 
56
64
  def handle_order_process_completed
57
65
  log_process('handle_order_process_completed') do
58
- Vpago::PaymentCapturerJob.perform_later(@payment.id) if @payment.pending?
66
+ enqueue_capture_payment_if_available!
59
67
  user_informer.order_is_completed(processing: false)
60
68
  end
61
69
  end
@@ -63,12 +71,12 @@ module Vpago
63
71
  def handle_order_process_failure(reason_code, reason_message = nil)
64
72
  log_process('handle_order_process_failure', reason_code, reason_message) do
65
73
  user_informer.order_process_failed(
66
- processing: can_cancel_pre_auth?,
74
+ processing: false,
67
75
  reason_code: reason_code,
68
76
  reason_message: reason_message
69
77
  )
70
78
 
71
- cancel_pre_auth(reason_code, reason_message) if can_cancel_pre_auth?
79
+ enqueue_void_or_cancel_payment_if_available!
72
80
  failure(reason_message)
73
81
  end
74
82
  end
@@ -76,12 +84,12 @@ module Vpago
76
84
  def handle_payment_failure(reason_code, reason_message)
77
85
  log_process('handle_payment_failure', reason_code, reason_message) do
78
86
  user_informer.payment_process_failed(
79
- processing: can_cancel_pre_auth?,
87
+ processing: false,
80
88
  reason_code: reason_code,
81
89
  reason_message: reason_message
82
90
  )
83
91
 
84
- cancel_pre_auth(reason_code, reason_message) if can_cancel_pre_auth?
92
+ enqueue_void_or_cancel_payment_if_available!
85
93
  failure(reason_message)
86
94
  end
87
95
  end
@@ -10,10 +10,10 @@ module Vpago
10
10
  end
11
11
 
12
12
  def payment_is_processing(processing:) = notify(:payment_is_processing, processing)
13
+ def payment_is_retrying(processing:) = notify(:payment_is_retrying, processing)
13
14
  def order_is_processing(processing:) = notify(:order_is_processing, processing)
14
15
  def order_is_completed(processing:) = notify(:order_is_completed, processing)
15
16
  def order_process_failed(processing:, reason_code:, reason_message: nil) = notify(:order_process_failed, processing, reason_code, reason_message)
16
- def payment_is_refunded(processing:, reason_code:, reason_message: nil) = notify(:payment_is_refunded, processing, reason_code, reason_message)
17
17
  def payment_process_failed(processing:, reason_code:, reason_message: nil) = notify(:payment_process_failed, processing, reason_code, reason_message)
18
18
 
19
19
  def notify(message_code, processing, reason_code = nil, reason_message = nil)
@@ -23,6 +23,12 @@
23
23
  document.getElementById("processing").innerText = processing ? "Processing..." : "No more process.";
24
24
  document.getElementById("reason_message").innerText = reasonMessage;
25
25
  },
26
+ onPaymentIsRetrying: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
27
+ document.getElementById("status").innerText = "Payment is retrying";
28
+ document.getElementById("reason_code").innerText = reasonCode;
29
+ document.getElementById("processing").innerText = processing ? "Retrying..." : "No more process.";
30
+ document.getElementById("reason_message").innerText = reasonMessage;
31
+ },
26
32
  onOrderIsProcessing: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
27
33
  document.getElementById("status").innerText = "Order is processing";
28
34
  document.getElementById("reason_code").innerText = reasonCode;
@@ -41,12 +47,6 @@
41
47
  document.getElementById("processing").innerText = processing ? "Processing..." : "No more process.";
42
48
  document.getElementById("reason_message").innerText = reasonMessage;
43
49
  },
44
- onPaymentIsRefunded: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
45
- document.getElementById("status").innerText = "Payment is refunded";
46
- document.getElementById("reason_code").innerText = reasonCode;
47
- document.getElementById("processing").innerText = processing ? "Processing..." : "No more process.";
48
- document.getElementById("reason_message").innerText = reasonMessage
49
- },
50
50
  onPaymentProcessFailed: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
51
51
  document.getElementById("status").innerText = "Payment process failed";
52
52
  document.getElementById("reason_code").innerText = reasonCode;
@@ -1,7 +1,7 @@
1
1
  module SpreeVpago
2
2
  module_function
3
3
 
4
- VERSION = '2.1.5'.freeze
4
+ VERSION = '2.1.7-pre1'.freeze
5
5
 
6
6
  def version
7
7
  Gem::Version.new VERSION
@@ -10,7 +10,7 @@ module Vpago
10
10
  end
11
11
 
12
12
  def success?
13
- @response.dig('msgEntity', 'code') == '0'
13
+ @response.dig('data', 'status') == 'SUCCESS'
14
14
  end
15
15
 
16
16
  private
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.1.5
4
+ version: 2.1.7.pre.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - You
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-11-14 00:00:00.000000000 Z
11
+ date: 2025-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -184,8 +184,10 @@ files:
184
184
  - app/javascripts/queue_processor.test.js
185
185
  - app/javascripts/vpago/vpago_payments/user_informers/firebase.js
186
186
  - app/jobs/application_unique_job.rb
187
+ - app/jobs/vpago/payment_canceler_job.rb
187
188
  - app/jobs/vpago/payment_capturer_job.rb
188
189
  - app/jobs/vpago/payment_processor_job.rb
190
+ - app/jobs/vpago/payment_voider_job.rb
189
191
  - app/models/.gitkeep
190
192
  - app/models/concerns/vpago/payoutable.rb
191
193
  - app/models/spree/gateway/acleda.rb
@@ -434,9 +436,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
434
436
  version: 3.2.0
435
437
  required_rubygems_version: !ruby/object:Gem::Requirement
436
438
  requirements:
437
- - - ">="
439
+ - - ">"
438
440
  - !ruby/object:Gem::Version
439
- version: '0'
441
+ version: 1.3.1
440
442
  requirements:
441
443
  - none
442
444
  rubygems_version: 3.4.1