spree_vpago 2.3.8 → 2.3.10

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: feafa3aabbe7fd192e7d70028c28467cb990edda91c4e2180bcc127d445cdc9d
4
- data.tar.gz: 0cfc058b9ff6f04a07cbde6c8ca29d3b46a00582c143e5cad6b3b672f635caf2
3
+ metadata.gz: 83977e379d14f72df6f9812c0053817ead75a9a29d9dbb26efbb505679fd34f1
4
+ data.tar.gz: d478a6a31649dba472adebefb5890c60a5222107252c71b9a835d7260e95cf97
5
5
  SHA512:
6
- metadata.gz: 49d235f5604b356f4ba1b555be0ce04e4946901319790d7d97a3ca3262e3445415d5a6980780d8ee27712da8b565ee5af3689726c9acb7bf1d20913c8a5c66df
7
- data.tar.gz: b7e51eb7d0d57abb587036189d1d374bd43aee8586c55fc569b19692ff38e8cc9f9bcaa404b92b1e75fe30c87d63e0af77cbafea69ed82a921eeffc1c0b5b327
6
+ metadata.gz: 9c76fd67f78cacde387d8b817ec6b2ff9707dc39fb31d1419498af347c8aee1bf12d4d533af79c0ad90efb44ae80517096a9578e803e6fd2fe937380eca8478b
7
+ data.tar.gz: 3d44c01a03c35f692ba70d5091a41ca03d9c7e3e9fdd37e0a87b984196e155c37534462b39d396e970462a2522fa6fdde9d60b525147689ccc1184c28e8cb42f
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- spree_vpago (2.3.8)
4
+ spree_vpago (2.3.10)
5
5
  faraday
6
6
  google-cloud-firestore
7
7
  spree_api (>= 4.5)
@@ -13693,10 +13693,10 @@ This typically indicates that your device does not have a healthy Internet conne
13693
13693
  firebaseConfigs,
13694
13694
  documentReferencePath,
13695
13695
  onPaymentIsProcessing,
13696
+ onPaymentIsRetrying,
13696
13697
  onOrderIsProcessing,
13697
13698
  onOrderIsCompleted,
13698
13699
  onOrderProcessFailed,
13699
- onPaymentIsRefunded,
13700
13700
  onPaymentProcessFailed,
13701
13701
  onCompleted
13702
13702
  }) {
@@ -13713,6 +13713,9 @@ This typically indicates that your device does not have a healthy Internet conne
13713
13713
  let processing = documentData["processing"] === true;
13714
13714
  let reasonCode = documentData["reason_code"];
13715
13715
  let reasonMessage = documentData["reason_message"];
13716
+ if (window.parent !== window) {
13717
+ window.parent.postMessage(messageCode, "*");
13718
+ }
13716
13719
  let orderCompleted = orderState === "complete";
13717
13720
  if (orderCompleted) {
13718
13721
  queueProcessor.queueStateChange({
@@ -13743,11 +13746,11 @@ This typically indicates that your device does not have a healthy Internet conne
13743
13746
  }
13744
13747
  });
13745
13748
  break;
13746
- case "order_is_processing":
13749
+ case "payment_is_retrying":
13747
13750
  queueProcessor.queueStateChange({
13748
13751
  minDelayInMs: 1500,
13749
13752
  callback: async () => {
13750
- await onOrderIsProcessing(
13753
+ await onPaymentIsRetrying(
13751
13754
  orderState,
13752
13755
  paymentState,
13753
13756
  processing,
@@ -13757,11 +13760,11 @@ This typically indicates that your device does not have a healthy Internet conne
13757
13760
  }
13758
13761
  });
13759
13762
  break;
13760
- case "order_is_completed":
13763
+ case "order_is_processing":
13761
13764
  queueProcessor.queueStateChange({
13762
13765
  minDelayInMs: 1500,
13763
13766
  callback: async () => {
13764
- await onOrderIsCompleted(
13767
+ await onOrderIsProcessing(
13765
13768
  orderState,
13766
13769
  paymentState,
13767
13770
  processing,
@@ -13771,11 +13774,11 @@ This typically indicates that your device does not have a healthy Internet conne
13771
13774
  }
13772
13775
  });
13773
13776
  break;
13774
- case "order_process_failed":
13777
+ case "order_is_completed":
13775
13778
  queueProcessor.queueStateChange({
13776
13779
  minDelayInMs: 1500,
13777
13780
  callback: async () => {
13778
- await onOrderProcessFailed(
13781
+ await onOrderIsCompleted(
13779
13782
  orderState,
13780
13783
  paymentState,
13781
13784
  processing,
@@ -13785,11 +13788,11 @@ This typically indicates that your device does not have a healthy Internet conne
13785
13788
  }
13786
13789
  });
13787
13790
  break;
13788
- case "payment_is_refunded":
13791
+ case "order_process_failed":
13789
13792
  queueProcessor.queueStateChange({
13790
13793
  minDelayInMs: 1500,
13791
13794
  callback: async () => {
13792
- await onPaymentIsRefunded(
13795
+ await onOrderProcessFailed(
13793
13796
  orderState,
13794
13797
  paymentState,
13795
13798
  processing,
@@ -16,6 +16,13 @@ module Spree
16
16
  flash[:error] = Spree.t('vpago.payments.payment_not_found_with_error', error: tran_status.error_message)
17
17
  end
18
18
 
19
+ redirect_to admin_order_payment_path(order_id: @payment.order.number, id: @payment.number)
20
+ rescue Faraday::TimeoutError, Faraday::ConnectionFailed => e
21
+ VpagoLogger.error(
22
+ label: 'Spree::Admin::PaymentPaywayQueriersController#show gateway_timeout',
23
+ data: { payment_number: @payment.number, error_class: e.class.name, error_message: e.message }
24
+ )
25
+ flash[:error] = Spree.t('vpago.payments.gateway_timeout')
19
26
  redirect_to admin_order_payment_path(order_id: @payment.order.number, id: @payment.number)
20
27
  end
21
28
 
@@ -8,11 +8,11 @@ module Spree
8
8
  rescue_from ActiveRecord::RecordNotFound, with: :render_not_found
9
9
  rescue_from CanCan::AccessDenied, with: :access_denied
10
10
 
11
+ before_action :find_payment, only: %i[checkout processing success]
12
+ after_action :allow_iframe_embedding, only: %i[checkout processing success]
13
+
11
14
  # GET
12
15
  def checkout
13
- @payment = Vpago::PaymentFinder.new(params.permit!.to_h).find_and_verify
14
- raise ActiveRecord::RecordNotFound unless @payment.present?
15
-
16
16
  return redirect_to @payment.processing_url, allow_other_host: true unless @payment.checkout?
17
17
 
18
18
  @order = @payment.order
@@ -22,9 +22,6 @@ module Spree
22
22
 
23
23
  # GET
24
24
  def processing
25
- @payment = Vpago::PaymentFinder.new(params.permit!.to_h).find_and_verify
26
- raise ActiveRecord::RecordNotFound unless @payment.present?
27
-
28
25
  @order = @payment.order
29
26
 
30
27
  VpagoLogger.log(label: 'Spree::VpagoPaymentsController#processing', data: vpago_log_context)
@@ -32,9 +29,6 @@ module Spree
32
29
 
33
30
  # GET
34
31
  def success
35
- @payment = Vpago::PaymentFinder.new(params.permit!.to_h).find_and_verify
36
- raise ActiveRecord::RecordNotFound unless @payment.present?
37
-
38
32
  @order = @payment.order
39
33
  raise CanCan::AccessDenied unless @order.completed?
40
34
 
@@ -66,6 +60,12 @@ module Spree
66
60
  else
67
61
  render json: { status: :pending }, status: :ok
68
62
  end
63
+ rescue Faraday::TimeoutError, Faraday::ConnectionFailed => e
64
+ VpagoLogger.error(
65
+ label: 'Spree::VpagoPaymentsController#check_transaction gateway_timeout',
66
+ data: vpago_log_context(error_class: e.class.name, error_message: e.message)
67
+ )
68
+ render json: { status: :pending }, status: :ok
69
69
  end
70
70
 
71
71
  # POST
@@ -147,6 +147,18 @@ module Spree
147
147
  sanitized_params
148
148
  end
149
149
 
150
+ def find_payment
151
+ @payment = Vpago::PaymentFinder.new(params.permit!.to_h).find_and_verify
152
+ raise ActiveRecord::RecordNotFound unless @payment.present?
153
+ end
154
+
155
+ # frame-ancestors (set above) supersedes X-Frame-Options in modern
156
+ # browsers, but the default SAMEORIGIN header would still block legacy
157
+ # browsers from embedding these pages, so drop it for the iframe actions.
158
+ def allow_iframe_embedding
159
+ response.headers.delete('X-Frame-Options')
160
+ end
161
+
150
162
  def render_not_found
151
163
  respond_to do |format|
152
164
  format.html { render file: Rails.public_path.join('404.html'), status: :not_found, layout: false }
@@ -31,6 +31,10 @@ async function listenToProcessingState({
31
31
  let reasonCode = documentData["reason_code"];
32
32
  let reasonMessage = documentData["reason_message"];
33
33
 
34
+ if (window.parent !== window) {
35
+ window.parent.postMessage(messageCode, "*");
36
+ }
37
+
34
38
  let orderCompleted = orderState === "complete";
35
39
  if (orderCompleted) {
36
40
  queueProcessor.queueStateChange({
@@ -40,7 +44,7 @@ async function listenToProcessingState({
40
44
  orderState,
41
45
  paymentState,
42
46
  reasonCode,
43
- reasonMessage
47
+ reasonMessage,
44
48
  );
45
49
  },
46
50
  });
@@ -57,7 +61,7 @@ async function listenToProcessingState({
57
61
  paymentState,
58
62
  processing,
59
63
  reasonCode,
60
- reasonMessage
64
+ reasonMessage,
61
65
  );
62
66
  },
63
67
  });
@@ -71,7 +75,7 @@ async function listenToProcessingState({
71
75
  paymentState,
72
76
  processing,
73
77
  reasonCode,
74
- reasonMessage
78
+ reasonMessage,
75
79
  );
76
80
  },
77
81
  });
@@ -85,7 +89,7 @@ async function listenToProcessingState({
85
89
  paymentState,
86
90
  processing,
87
91
  reasonCode,
88
- reasonMessage
92
+ reasonMessage,
89
93
  );
90
94
  },
91
95
  });
@@ -99,7 +103,7 @@ async function listenToProcessingState({
99
103
  paymentState,
100
104
  processing,
101
105
  reasonCode,
102
- reasonMessage
106
+ reasonMessage,
103
107
  );
104
108
  },
105
109
  });
@@ -113,7 +117,7 @@ async function listenToProcessingState({
113
117
  paymentState,
114
118
  processing,
115
119
  reasonCode,
116
- reasonMessage
120
+ reasonMessage,
117
121
  );
118
122
  },
119
123
  });
@@ -127,7 +131,7 @@ async function listenToProcessingState({
127
131
  paymentState,
128
132
  processing,
129
133
  reasonCode,
130
- reasonMessage
134
+ reasonMessage,
131
135
  );
132
136
  },
133
137
  });
@@ -11,5 +11,12 @@ module Spree
11
11
  def auto_capture?
12
12
  true
13
13
  end
14
+
15
+ # override: Spree::Payment#cancel! calls payment_method.cancel(response_code, payment).
16
+ # Cash has no gateway to void against, so acknowledge success and let the payment
17
+ # transition to `void`.
18
+ def cancel(_response_code, _payment = nil)
19
+ ActiveMerchant::Billing::Response.new(true, 'Cash On: Payment has been canceled.')
20
+ end
14
21
  end
15
22
  end
@@ -102,7 +102,7 @@ module Vpago
102
102
  # override this method if you want flexibility
103
103
  # for example, host per payment method or tenant
104
104
  def payment_host
105
- ENV.fetch('DEFAULT_URL_HOST')
105
+ ENV.fetch('PAYMENT_BASE_URL')
106
106
  end
107
107
  end
108
108
  end
@@ -50,7 +50,7 @@ module Vpago
50
50
 
51
51
  def process_acleda_gateway
52
52
  data = {
53
- href: "#{ENV.fetch('DEFAULT_URL_HOST', nil)}/acleda_redirects?payment_number=#{@payment.number}"
53
+ href: "#{ENV.fetch('PAYMENT_BASE_URL', nil)}/acleda_redirects?payment_number=#{@payment.number}"
54
54
  }
55
55
 
56
56
  @redirect_options = data
@@ -81,7 +81,7 @@ module Vpago
81
81
  def process_payway_v2_card
82
82
  ## TO DO: generate redirect url
83
83
  data = {
84
- href: "#{ENV.fetch('DEFAULT_URL_HOST', nil)}/payway_v2_card_popups?payment_number=#{@payment.number}"
84
+ href: "#{ENV.fetch('PAYMENT_BASE_URL', nil)}/payway_v2_card_popups?payment_number=#{@payment.number}"
85
85
  }
86
86
 
87
87
  @redirect_options = data
@@ -115,7 +115,7 @@ module Vpago
115
115
  end
116
116
 
117
117
  conn.post(abapay_payment.checkout_url, gateway_params) do |request|
118
- request.headers['Referer'] = ENV.fetch('DEFAULT_URL_HOST', nil)
118
+ request.headers['Referer'] = ENV.fetch('PAYMENT_BASE_URL', nil)
119
119
  end
120
120
  end
121
121
 
@@ -127,7 +127,7 @@ module Vpago
127
127
  def process_payway_card
128
128
  ## TO DO: generate redirect url
129
129
  data = {
130
- href: "#{ENV.fetch('DEFAULT_URL_HOST', nil)}/payway_card_popups?payment_number=#{@payment.number}"
130
+ href: "#{ENV.fetch('PAYMENT_BASE_URL', nil)}/payway_card_popups?payment_number=#{@payment.number}"
131
131
  }
132
132
 
133
133
  @redirect_options = data
@@ -135,7 +135,7 @@ module Vpago
135
135
 
136
136
  def process_wing_gateway
137
137
  data = {
138
- href: "#{ENV.fetch('DEFAULT_URL_HOST', nil)}/wing_redirects?payment_number=#{@payment.number}"
138
+ href: "#{ENV.fetch('PAYMENT_BASE_URL', nil)}/wing_redirects?payment_number=#{@payment.number}"
139
139
  }
140
140
 
141
141
  @redirect_options = data
@@ -169,7 +169,7 @@ module Vpago
169
169
  end
170
170
 
171
171
  @response = conn.post(abapay_payment.action_url, gateway_params) do |request|
172
- request.headers['Referer'] = ENV.fetch('DEFAULT_URL_HOST', nil)
172
+ request.headers['Referer'] = ENV.fetch('PAYMENT_BASE_URL', nil)
173
173
  end
174
174
  end
175
175
 
@@ -35,5 +35,6 @@ en:
35
35
  failed_require_updated_reason: "You must provide update reason"
36
36
  payment_found_with_result: "Found payment with result: %{result}"
37
37
  payment_not_found_with_error: "Payment not found with error: %{error}"
38
+ gateway_timeout: "The payment gateway did not respond in time. Please try again shortly."
38
39
  query_status: "Query payment status"
39
40
  confirm_manual_update: "Are you sure to update this order to complete"
@@ -31,5 +31,6 @@ spree:
31
31
  failed_require_updated_reason: "អ្នកត្រូវតែផ្តល់ហេតុផល"
32
32
  payment_found_with_result: "រកឃើញការទូទាត់ជាមួយលទ្ធផល %{result}"
33
33
  payment_not_found_with_error: "ការទូទាត់មិនត្រូវបានរកឃើញដោយកំហុស: %{error}"
34
+ gateway_timeout: "ផ្នែកទូទាត់មិនបានឆ្លើយតបទាន់ពេលទេ។ សូមព្យាយាមម្តងទៀតក្នុងពេលឆាប់ៗនេះ។"
34
35
  query_status: "សួរស្ថានភាពបង់ប្រាក់"
35
36
  confirm_manual_update: "តើអ្នកប្រាកដជាធ្វើបច្ចុប្បន្នភាពការបញ្ជាទិញនេះដើម្បីបញ្ចប់"
@@ -1,7 +1,7 @@
1
1
  module SpreeVpago
2
2
  module_function
3
3
 
4
- VERSION = '2.3.8'.freeze
4
+ VERSION = '2.3.10'.freeze
5
5
 
6
6
  def version
7
7
  Gem::Version.new VERSION
@@ -0,0 +1,6 @@
1
+ module Vpago
2
+ module HttpTimeouts
3
+ OPEN_TIMEOUT = 5
4
+ TIMEOUT = 15
5
+ end
6
+ end
@@ -28,6 +28,11 @@ module Vpago
28
28
  elsif checker.failed?
29
29
  mark_payment_as_failed(checker.error_message)
30
30
  end
31
+ rescue Faraday::TimeoutError, Faraday::ConnectionFailed => e
32
+ VpagoLogger.error(
33
+ label: 'Vpago::PaywayV2::PaymentRequestUpdater#process_payment_status gateway_timeout',
34
+ data: { payment_number: @payment.number, error_class: e.class.name, error_message: e.message }
35
+ )
31
36
  end
32
37
 
33
38
  def mark_payment_as_success(checker)
@@ -37,6 +37,8 @@ module Vpago
37
37
  def check_remote_status
38
38
  conn = Faraday::Connection.new do |faraday|
39
39
  faraday.request :url_encoded
40
+ faraday.options.open_timeout = Vpago::HttpTimeouts::OPEN_TIMEOUT
41
+ faraday.options.timeout = Vpago::HttpTimeouts::TIMEOUT
40
42
  end
41
43
 
42
44
  data = {
@@ -52,6 +52,8 @@ module Vpago
52
52
  def check_remote_status
53
53
  conn = Faraday::Connection.new do |faraday|
54
54
  faraday.request :url_encoded
55
+ faraday.options.open_timeout = Vpago::HttpTimeouts::OPEN_TIMEOUT
56
+ faraday.options.timeout = Vpago::HttpTimeouts::TIMEOUT
55
57
  end
56
58
 
57
59
  data = {
@@ -100,7 +100,7 @@ module Vpago
100
100
  end
101
101
 
102
102
  def fetch_access_token
103
- response = Faraday.post(
103
+ response = Faraday.new(request: { open_timeout: Vpago::HttpTimeouts::OPEN_TIMEOUT, timeout: Vpago::HttpTimeouts::TIMEOUT }).post(
104
104
  access_token_url,
105
105
  URI.encode_www_form(
106
106
  grant_type: 'client_credentials',
@@ -2,7 +2,7 @@ module Vpago
2
2
  module TrueMoney
3
3
  class TransactionStatus < Base
4
4
  def call
5
- @response = Faraday.get(check_transaction_url, nil, default_headers)
5
+ @response = Faraday.new(request: { open_timeout: Vpago::HttpTimeouts::OPEN_TIMEOUT, timeout: Vpago::HttpTimeouts::TIMEOUT }).get(check_transaction_url, nil, default_headers)
6
6
  end
7
7
 
8
8
  def success?
@@ -70,7 +70,8 @@ module Vpago
70
70
  private
71
71
 
72
72
  def fetch_access_token
73
- response = Faraday.post(access_token_url, { username: username, password: password }.to_json, { 'Content-Type' => CONTENT_TYPE_JSON })
73
+ response = Faraday.new(request: { open_timeout: Vpago::HttpTimeouts::OPEN_TIMEOUT, timeout: Vpago::HttpTimeouts::TIMEOUT })
74
+ .post(access_token_url, { username: username, password: password }.to_json, { 'Content-Type' => CONTENT_TYPE_JSON })
74
75
 
75
76
  raise "Access Token Error: #{response.status} - #{response.body}" unless response.success?
76
77
 
@@ -78,7 +79,7 @@ module Vpago
78
79
  end
79
80
 
80
81
  def post(url, body)
81
- response = Faraday.post(url, body.to_json, default_headers)
82
+ response = Faraday.new(request: { open_timeout: Vpago::HttpTimeouts::OPEN_TIMEOUT, timeout: Vpago::HttpTimeouts::TIMEOUT }).post(url, body.to_json, default_headers)
82
83
  parse_json(response.body)
83
84
  end
84
85
  end
@@ -33,7 +33,7 @@ module Vpago
33
33
  end
34
34
 
35
35
  def return_url
36
- "#{ENV.fetch('DEFAULT_URL_HOST', nil)}/webhook/wings/#{payment_number}/return?app_checkout=#{app_checkout}"
36
+ "#{ENV.fetch('PAYMENT_BASE_URL', nil)}/webhook/wings/#{payment_number}/return?app_checkout=#{app_checkout}"
37
37
  end
38
38
 
39
39
  def app_checkout
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.3.8
4
+ version: 2.3.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - You
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-07-22 00:00:00.000000000 Z
11
+ date: 2026-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -401,6 +401,7 @@ files:
401
401
  - lib/vpago/acleda_v2/base.rb
402
402
  - lib/vpago/acleda_v2/checkout.rb
403
403
  - lib/vpago/acleda_v2/transaction_status.rb
404
+ - lib/vpago/http_timeouts.rb
404
405
  - lib/vpago/payment_amount_calculator.rb
405
406
  - lib/vpago/payment_request_updater.rb
406
407
  - lib/vpago/payment_status_marker.rb