spree_vpago 2.3.12 → 2.4.0.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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/app/controllers/spree/admin/payment_payway_queriers_controller.rb +0 -7
  4. data/app/controllers/spree/miniapp/acledas_controller.rb +29 -0
  5. data/app/controllers/spree/vpago_payments_controller.rb +0 -7
  6. data/app/models/spree/gateway/acleda_mini_app.rb +20 -0
  7. data/app/models/spree/payment_method/cash_on.rb +0 -7
  8. data/app/models/vpago/order_decorator.rb +1 -1
  9. data/app/models/vpago/payment_decorator.rb +4 -0
  10. data/app/models/vpago/payment_method_decorator.rb +6 -8
  11. data/app/serializers/spree/v2/storefront/payment_method_serializer_decorator.rb +0 -6
  12. data/app/services/vpago/acleda_mini_app/session/create.rb +99 -0
  13. data/app/services/vpago/payment_redirect_handler.rb +6 -6
  14. data/app/views/spree/admin/payments/source_views/_acleda_mini_app.html.erb +6 -0
  15. data/app/views/spree/admin/payments/source_views/_acleda_v2.html.erb +2 -2
  16. data/app/views/spree/admin/payments/source_views/_vattanac.html.erb +3 -3
  17. data/app/views/spree/vpago_payments/forms/spree/gateway/_acleda_mini_app.html.erb +93 -0
  18. data/config/locales/en.yml +0 -1
  19. data/config/locales/km.yml +0 -1
  20. data/config/routes.rb +7 -6
  21. data/lib/spree_vpago/engine.rb +1 -0
  22. data/lib/spree_vpago/version.rb +1 -1
  23. data/lib/vpago/acleda_mini_app/checkout.rb +23 -0
  24. data/lib/vpago/payway_v2/payment_request_updater.rb +0 -5
  25. data/lib/vpago/payway_v2/transaction_status.rb +0 -2
  26. data/lib/vpago/payway_v2/transaction_status_v2.rb +0 -2
  27. data/lib/vpago/true_money/base.rb +1 -1
  28. data/lib/vpago/true_money/transaction_status.rb +1 -1
  29. data/lib/vpago/vattanac/base.rb +2 -3
  30. data/lib/vpago/vattanac/transaction_status.rb +1 -17
  31. data/lib/vpago/wing_sdk/base.rb +1 -1
  32. metadata +10 -13
  33. data/app/controllers/spree/admin/payment_acleda_v2_base_controller.rb +0 -21
  34. data/app/controllers/spree/admin/payment_acleda_v2_checkers_controller.rb +0 -26
  35. data/app/controllers/spree/admin/payment_acleda_v2_queriers_controller.rb +0 -38
  36. data/app/controllers/spree/admin/payment_vattanac_base_controller.rb +0 -21
  37. data/app/controllers/spree/admin/payment_vattanac_checkers_controller.rb +0 -26
  38. data/app/controllers/spree/admin/payment_vattanac_queriers_controller.rb +0 -38
  39. data/lib/vpago/acleda_v2/payment_request_updater.rb +0 -54
  40. data/lib/vpago/http_timeouts.rb +0 -6
  41. data/lib/vpago/vattanac/payment_request_updater.rb +0 -54
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f7c6fc347bce48aed54a98bf47d4432f79ec1144a882f7c6cf14b55ad1f87663
4
- data.tar.gz: c62d76d1e6661bc0460b3a4be75feeb6d4c6c8a3b1278d1b62dccb53324b6e1a
3
+ metadata.gz: 2b281c3ae420620dbd3d1da80ed2bc713c9283292484c1812cd1e9c979e6bf52
4
+ data.tar.gz: 70b7603d37c2c5e8f434e1ab333e622619296fd1ced75642ea9c0512a7591eb1
5
5
  SHA512:
6
- metadata.gz: 2973459504b60f1f6308e6f0db319c1b2e25f19747d2f94aeb3bf48f69b75e87c508f57c197a49440920464952df30e1cb3b6797ba9a782ff375ec1a7c0b0893
7
- data.tar.gz: e8418cf6a8298850075104813a93da543ab148327d7ee6cafdd63be2c1ce5eb64fe457888d695af4931a1b459ee3e60282553e22875a7b530d3099d002c60b8b
6
+ metadata.gz: 718d7eb47ff0a91b7cbcd43d13bd28f4808e008bed9ebee489c913af2d18d5069b5bdc4f06cca8e57693559e96da51a7af8c6e8843e5e01952898c7853c919e1
7
+ data.tar.gz: dd5f68ec20858da961d36f88a488bd3906d0623baa9f88a3811bbe10957ebd93bf891d047df9b2b8123a549d6881ef8ef32e1c7674144e6dd7901c779e79ae8b
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- spree_vpago (2.3.12)
4
+ spree_vpago (2.4.0.pre.pre1)
5
5
  faraday
6
6
  google-cloud-firestore
7
7
  spree_api (>= 4.5)
@@ -16,13 +16,6 @@ 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')
26
19
  redirect_to admin_order_payment_path(order_id: @payment.order.number, id: @payment.number)
27
20
  end
28
21
 
@@ -0,0 +1,29 @@
1
+ module Spree
2
+ module Miniapp
3
+ # Partner Session Initialization API (ACLEDA Mini App Integration Spec, Step 01).
4
+ # ACLEDA (server-to-server) POSTs { phone, first_name, last_name }; we return a
5
+ # session-based miniAppUrl for ACLEDA to open in the WebView.
6
+ class AcledasController < Spree::Api::V2::BaseController
7
+ # POST /miniapp/acleda
8
+ def create
9
+ result = ::Vpago::AcledaMiniApp::Session::Create.call(
10
+ phone: session_params[:phone],
11
+ first_name: session_params[:first_name],
12
+ last_name: session_params[:last_name]
13
+ )
14
+
15
+ if result.success?
16
+ render json: { message: 'SUCCESS', miniAppUrl: result.value[:mini_app_url] }
17
+ else
18
+ render json: { message: 'FAILED', error: result.error.to_s }, status: :unprocessable_entity
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def session_params
25
+ params.permit(:phone, :first_name, :last_name)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -23,7 +23,6 @@ module Spree
23
23
  # GET
24
24
  def processing
25
25
  @order = @payment.order
26
- return redirect_to @payment.success_url, allow_other_host: true if @order.completed?
27
26
 
28
27
  VpagoLogger.log(label: 'Spree::VpagoPaymentsController#processing', data: vpago_log_context)
29
28
  end
@@ -61,12 +60,6 @@ module Spree
61
60
  else
62
61
  render json: { status: :pending }, status: :ok
63
62
  end
64
- rescue Faraday::TimeoutError, Faraday::ConnectionFailed => e
65
- VpagoLogger.error(
66
- label: 'Spree::VpagoPaymentsController#check_transaction gateway_timeout',
67
- data: vpago_log_context(error_class: e.class.name, error_message: e.message)
68
- )
69
- render json: { status: :pending }, status: :ok
70
63
  end
71
64
 
72
65
  # POST
@@ -0,0 +1,20 @@
1
+ module Spree
2
+ # ACLEDA Mini App payment method.
3
+ #
4
+ # Reuses the ACLEDA V2 integration in deeplink mode: the deeplink produced by
5
+ # ACLEDA's openSessionV2 API is handed to the ACLEDA super-app through the
6
+ # `acledaJSBridge` (startPayment) instead of redirecting the page. Server-side
7
+ # verification reuses AcledaV2's #check_transaction (getTxnStatus).
8
+ class Gateway::AcledaMiniApp < Gateway::AcledaV2
9
+ # override: partial to render in admin / checkout form lookup
10
+ def method_type
11
+ 'acleda_mini_app'
12
+ end
13
+
14
+ # The mini app always uses the deeplink + JS bridge, so admins don't need to
15
+ # set the ACLEDA V2 mode.
16
+ def deeplink?
17
+ true
18
+ end
19
+ end
20
+ end
@@ -11,12 +11,5 @@ 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
21
14
  end
22
15
  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('PAYMENT_BASE_URL')
105
+ ENV.fetch('DEFAULT_URL_HOST')
106
106
  end
107
107
  end
108
108
  end
@@ -109,6 +109,10 @@ module Vpago
109
109
  payment_method.type_vattanac_mini_app?
110
110
  end
111
111
 
112
+ def acleda_mini_app_payment?
113
+ payment_method.type_acleda_mini_app?
114
+ end
115
+
112
116
  def check_payment?
113
117
  payment_method.type_check?
114
118
  end
@@ -6,6 +6,7 @@ module Vpago
6
6
  TYPE_ACLEDA = 'Spree::Gateway::Acleda'.freeze
7
7
  TYPE_ACLEDA_V2 = 'Spree::Gateway::AcledaV2'.freeze
8
8
  TYPE_ACLEDA_MOBILE = 'Spree::Gateway::AcledaMobile'.freeze
9
+ TYPE_ACLEDA_MINI_APP = 'Spree::Gateway::AcledaMiniApp'.freeze
9
10
  TYPE_TRUE_MONEY = 'Spree::Gateway::TrueMoney'.freeze
10
11
  TYPE_VATTANAC = 'Spree::Gateway::Vattanac'.freeze
11
12
  TYPE_VATTANAC_MINI_APP = 'Spree::Gateway::VattanacMiniApp'.freeze
@@ -24,6 +25,7 @@ module Vpago
24
25
  Spree::PaymentMethod::TYPE_ACLEDA,
25
26
  Spree::PaymentMethod::TYPE_ACLEDA_V2,
26
27
  Spree::PaymentMethod::TYPE_ACLEDA_MOBILE,
28
+ Spree::PaymentMethod::TYPE_ACLEDA_MINI_APP,
27
29
  Spree::PaymentMethod::TYPE_VATTANAC,
28
30
  Spree::PaymentMethod::TYPE_VATTANAC_MINI_APP,
29
31
  Spree::PaymentMethod::TYPE_TRUE_MONEY,
@@ -80,10 +82,6 @@ module Vpago
80
82
  ::Vpago::Acleda::PaymentRequestUpdater
81
83
  elsif type_acleda_mobile?
82
84
  ::Vpago::AcledaMobile::PaymentRequestUpdater
83
- elsif type_acleda_v2?
84
- ::Vpago::AcledaV2::PaymentRequestUpdater
85
- elsif type_vattanac?
86
- ::Vpago::Vattanac::PaymentRequestUpdater
87
85
  end
88
86
  end
89
87
 
@@ -99,6 +97,10 @@ module Vpago
99
97
  type == Spree::PaymentMethod::TYPE_ACLEDA_V2
100
98
  end
101
99
 
100
+ def type_acleda_mini_app?
101
+ type == Spree::PaymentMethod::TYPE_ACLEDA_MINI_APP
102
+ end
103
+
102
104
  def type_payway?
103
105
  type == Spree::PaymentMethod::TYPE_PAYWAY
104
106
  end
@@ -111,10 +113,6 @@ module Vpago
111
113
  type == Spree::PaymentMethod::TYPE_WINGSDK
112
114
  end
113
115
 
114
- def type_vattanac?
115
- type == Spree::PaymentMethod::TYPE_VATTANAC
116
- end
117
-
118
116
  def type_vattanac_mini_app?
119
117
  type == Spree::PaymentMethod::TYPE_VATTANAC_MINI_APP
120
118
  end
@@ -14,12 +14,6 @@ module Spree
14
14
 
15
15
  pref.blank? || pref[:payment_option].blank? ? payment_method.method_type : pref[:payment_option]
16
16
  end
17
-
18
- # Overried the payment method type to show all payment methods as one list on App.
19
- # Controlled by ENV["PAYMENT_METHOD_VIEW"] = "split" | "join" (default: "join").
20
- base.attribute :type do |payment_method|
21
- ENV.fetch('PAYMENT_METHOD_VIEW', 'join') == 'split' ? payment_method.type : 'payment_method'
22
- end
23
17
  end
24
18
  end
25
19
  end
@@ -0,0 +1,99 @@
1
+ module Vpago
2
+ module AcledaMiniApp
3
+ module Session
4
+ # Partner Session Initialization (ACLEDA Mini App Integration Spec, Step 01).
5
+ #
6
+ # ACLEDA calls POST /miniapp/acleda with { phone, first_name, last_name }.
7
+ # We find or create the customer (tagged with the acleda_bank identity),
8
+ # mint a session JWT, and return a session-based miniAppUrl for ACLEDA to
9
+ # open in the WebView. The generic session_id OAuth grant validates the JWT
10
+ # when the WebView later authenticates.
11
+ class Create
12
+ prepend Spree::ServiceModule::Base
13
+
14
+ def call(phone: nil, first_name: nil, last_name: nil)
15
+ return failure(nil, 'phone is required') if phone.blank?
16
+
17
+ @phone = phone
18
+ @first_name = first_name
19
+ @last_name = last_name
20
+
21
+ user = find_or_create_user
22
+ return failure(user, 'user creation failed') if user.nil? || !user.persisted?
23
+
24
+ success(mini_app_url: mini_app_url(user))
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :phone, :first_name, :last_name
30
+
31
+ def find_or_create_user
32
+ identity = acleda_identity
33
+
34
+ # Returning customer: the ACLEDA identity already points at a user.
35
+ return identity.user if identity.persisted?
36
+
37
+ # New to ACLEDA: reuse a customer matched by phone, otherwise build one,
38
+ # then tag them with the acleda_bank identity so the lookup above hits
39
+ # next time.
40
+ user = find_existing_user || build_user
41
+ identity.name = full_name
42
+ user.user_identity_providers << identity
43
+ user.save
44
+
45
+ user
46
+ end
47
+
48
+ def acleda_identity
49
+ SpreeCmCommissioner::UserIdentityProvider.acleda_bank.find_or_initialize_by(sub: phone)
50
+ end
51
+
52
+ def find_existing_user
53
+ return if intel_phone.blank?
54
+
55
+ Spree::User.by_non_tenant.find_by(intel_phone_number: intel_phone)
56
+ end
57
+
58
+ def build_user
59
+ Spree::User.new(
60
+ first_name: first_name,
61
+ last_name: last_name,
62
+ phone_number: phone,
63
+ intel_phone_number: intel_phone,
64
+ password: SecureRandom.base64(16),
65
+ confirmed_at: Time.zone.now
66
+ )
67
+ end
68
+
69
+ def mini_app_url(user)
70
+ # A JWT signed with the user's secure_token. Passed as `session_key` (not
71
+ # `session_id`) so the OAuth grant routes it to the ACLEDA authenticator,
72
+ # which enforces the signature.
73
+ session_key = SpreeCmCommissioner::UserSessionJwtToken.encode(
74
+ { user_id: user.id },
75
+ user.reload.secure_token
76
+ )
77
+
78
+ "#{Spree::Store.default.formatted_url}/mini_app/acleda?session_key=#{session_key}&ds=#{CGI.escape(disable_services)}"
79
+ end
80
+
81
+ def full_name
82
+ [first_name, last_name].compact.join(' ').presence
83
+ end
84
+
85
+ def intel_phone
86
+ return @intel_phone if defined?(@intel_phone)
87
+
88
+ @intel_phone = SpreeCmCommissioner::PhoneNumberParser.call(phone_number: phone).intel_phone_number
89
+ end
90
+
91
+ # Services to disable in the mini app storefront. Configurable per ACLEDA's
92
+ # requirement; defaults to none.
93
+ def disable_services
94
+ ENV.fetch('ACLEDA_MINI_APP_DISABLE_SERVICES', '')
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -50,7 +50,7 @@ module Vpago
50
50
 
51
51
  def process_acleda_gateway
52
52
  data = {
53
- href: "#{ENV.fetch('PAYMENT_BASE_URL', nil)}/acleda_redirects?payment_number=#{@payment.number}"
53
+ href: "#{ENV.fetch('DEFAULT_URL_HOST', 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('PAYMENT_BASE_URL', nil)}/payway_v2_card_popups?payment_number=#{@payment.number}"
84
+ href: "#{ENV.fetch('DEFAULT_URL_HOST', 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('PAYMENT_BASE_URL', nil)
118
+ request.headers['Referer'] = ENV.fetch('DEFAULT_URL_HOST', 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('PAYMENT_BASE_URL', nil)}/payway_card_popups?payment_number=#{@payment.number}"
130
+ href: "#{ENV.fetch('DEFAULT_URL_HOST', 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('PAYMENT_BASE_URL', nil)}/wing_redirects?payment_number=#{@payment.number}"
138
+ href: "#{ENV.fetch('DEFAULT_URL_HOST', 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('PAYMENT_BASE_URL', nil)
172
+ request.headers['Referer'] = ENV.fetch('DEFAULT_URL_HOST', nil)
173
173
  end
174
174
  end
175
175
 
@@ -0,0 +1,6 @@
1
+ <%= render 'spree/admin/payments/source_views/vpago_payment_tmpl',
2
+ payment: payment,
3
+ check_status_url: '',
4
+ heal_payment_url: '',
5
+ manual_update_payment_url: ''
6
+ %>
@@ -1,5 +1,5 @@
1
1
  <%= render 'spree/admin/payments/source_views/vpago_payment_tmpl',
2
2
  payment: payment,
3
- check_status_url: admin_payment_acleda_v2_querier_path(payment),
4
- heal_payment_url: admin_payment_acleda_v2_checker_path(payment),
3
+ check_status_url: '',
4
+ heal_payment_url: '',
5
5
  manual_update_payment_url: '' %>
@@ -1,6 +1,6 @@
1
1
  <%= render 'spree/admin/payments/source_views/vpago_payment_tmpl',
2
- payment: payment,
3
- check_status_url: admin_payment_vattanac_querier_path(payment),
4
- heal_payment_url: admin_payment_vattanac_checker_path(payment),
2
+ payment: payment,
3
+ check_status_url: '',
4
+ heal_payment_url: '',
5
5
  manual_update_payment_url: ''
6
6
  %>
@@ -0,0 +1,93 @@
1
+ <%
2
+ opr_device = request.user_agent.to_s.downcase.match?(/iphone|ipad|ipod/) ? 'ios' : 'android'
3
+ checkout = ::Vpago::AcledaMiniApp::Checkout.new(@payment, { platform: 'app', opr_device: opr_device })
4
+
5
+ begin
6
+ checkout.call
7
+ rescue => e
8
+ Rails.logger.error("Acleda Mini App checkout.call failed: #{e.message}")
9
+ end
10
+ %>
11
+
12
+ <p id="unsupported-message"
13
+ style="margin-top: 10px; font-weight: bold; color: red; display: none;">
14
+ </p>
15
+
16
+ <% if checkout.failed? %>
17
+ <script>
18
+ console.error("[Vpago] Acleda Mini App checkout error: <%= j checkout.error_message.to_s %>");
19
+ document.addEventListener("DOMContentLoaded", () => {
20
+ const loadingContainer = document.getElementById('vpago_loading_container');
21
+ if (loadingContainer) {
22
+ loadingContainer.textContent = "We couldn't start your payment. Please go back and try again.";
23
+ }
24
+ });
25
+ </script>
26
+ <% else %>
27
+ <script>
28
+ // ACLEDA JS bridge (unified iOS + Android). Defined before use so it is
29
+ // available when the native layer injects its handlers.
30
+ window.acledaJSBridge = window.acledaJSBridge || {
31
+ call: function (action, data = {}) {
32
+ const payload = { action, data };
33
+
34
+ // iOS WKWebView
35
+ if (
36
+ window.webkit &&
37
+ window.webkit.messageHandlers &&
38
+ window.webkit.messageHandlers.acledaIOSJSBridge
39
+ ) {
40
+ window.webkit.messageHandlers.acledaIOSJSBridge.postMessage(payload);
41
+ return true;
42
+ }
43
+
44
+ // Android WebView
45
+ if (
46
+ window.acledaAndroidJSBridge &&
47
+ typeof window.acledaAndroidJSBridge.postMessage === "function"
48
+ ) {
49
+ window.acledaAndroidJSBridge.postMessage(JSON.stringify(payload));
50
+ return true;
51
+ }
52
+
53
+ console.warn("[acledaJSBridge] Native bridge not found");
54
+ return false;
55
+ }
56
+ };
57
+
58
+ function showRedirectContainer(buttonLabel, onClick) {
59
+ const loadingContainer = document.getElementById('vpago_loading_container');
60
+ const redirectContainer = document.getElementById('vpago_redirect_container');
61
+ const redirectButton = document.getElementById('vpago_redirect_button');
62
+
63
+ redirectButton.textContent = buttonLabel;
64
+ redirectButton.addEventListener('click', onClick);
65
+
66
+ loadingContainer.style.display = 'none';
67
+ redirectContainer.style.removeProperty('display');
68
+ }
69
+
70
+ document.addEventListener("DOMContentLoaded", () => {
71
+ const acledaDeeplink = "<%= raw checkout.acleda_deeplink %>";
72
+ const processingUrl = "<%= raw @payment.processing_url %>";
73
+
74
+ // Native -> JS after payment completes. Primary completion signal; the
75
+ // transaction checker polling is the fallback.
76
+ window.onPaymentResult = function (result) {
77
+ console.log("[acledaJSBridge] Payment result:", result);
78
+ // result.batchId, result.status = "success" | "failed" | "cancelled"
79
+ window.location.href = processingUrl;
80
+ };
81
+
82
+ const startPayment = () => window.acledaJSBridge.call("startPayment", { acleda_deeplink: acledaDeeplink });
83
+
84
+ if (startPayment()) {
85
+ showRedirectContainer("Continue", startPayment);
86
+ } else {
87
+ const unsupported = document.getElementById('unsupported-message');
88
+ unsupported.style.display = 'block';
89
+ unsupported.innerText = 'Unsupported environment';
90
+ }
91
+ });
92
+ </script>
93
+ <% end %>
@@ -35,6 +35,5 @@ 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."
39
38
  query_status: "Query payment status"
40
39
  confirm_manual_update: "Are you sure to update this order to complete"
@@ -31,6 +31,5 @@ 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: "ផ្នែកទូទាត់មិនបានឆ្លើយតបទាន់ពេលទេ។ សូមព្យាយាមម្តងទៀតក្នុងពេលឆាប់ៗនេះ។"
35
34
  query_status: "សួរស្ថានភាពបង់ប្រាក់"
36
35
  confirm_manual_update: "តើអ្នកប្រាកដជាធ្វើបច្ចុប្បន្នភាពការបញ្ជាទិញនេះដើម្បីបញ្ចប់"
data/config/routes.rb CHANGED
@@ -17,6 +17,13 @@ Spree::Core::Engine.add_routes do
17
17
  resources :transactions, only: [:show]
18
18
  end
19
19
 
20
+ # ACLEDA Mini App session init (ACLEDA Mini App Integration Spec, Step 01).
21
+ # ACLEDA calls POST /miniapp/acleda with { phone, first_name, last_name }
22
+ # and receives a session-based miniAppUrl.
23
+ namespace :miniapp do
24
+ resources :acleda, only: [:create], controller: 'acledas'
25
+ end
26
+
20
27
  resource :vpago_payments do
21
28
  collection do
22
29
  get :checkout
@@ -73,12 +80,6 @@ Spree::Core::Engine.add_routes do
73
80
  resources :payment_payway_checkers
74
81
  resources :payment_payway_markers
75
82
 
76
- resources :payment_acleda_v2_queriers, only: [:show]
77
- resources :payment_acleda_v2_checkers, only: [:update]
78
-
79
- resources :payment_vattanac_queriers, only: [:show]
80
- resources :payment_vattanac_checkers, only: [:update]
81
-
82
83
  resources :products do
83
84
  resources :payout_profile_products
84
85
  end
@@ -23,6 +23,7 @@ module SpreeVpago
23
23
  Spree::Gateway::Acleda,
24
24
  Spree::Gateway::AcledaV2,
25
25
  Spree::Gateway::AcledaMobile,
26
+ Spree::Gateway::AcledaMiniApp,
26
27
  Spree::Gateway::Vattanac,
27
28
  Spree::Gateway::VattanacMiniApp,
28
29
  Spree::Gateway::TrueMoney,
@@ -1,7 +1,7 @@
1
1
  module SpreeVpago
2
2
  module_function
3
3
 
4
- VERSION = '2.3.12'.freeze
4
+ VERSION = '2.4.0-pre1'.freeze
5
5
 
6
6
  def version
7
7
  Gem::Version.new VERSION
@@ -0,0 +1,23 @@
1
+ module Vpago
2
+ module AcledaMiniApp
3
+ # ACLEDA Mini App checkout. Reuses ACLEDA V2's openSessionV2 flow to obtain a
4
+ # deeplink, which is passed to the ACLEDA super-app via the acledaJSBridge
5
+ # (startPayment) instead of redirecting the page.
6
+ class Checkout < Vpago::AcledaV2::Checkout
7
+ # The mini app always uses the deeplink + JS bridge, regardless of the
8
+ # gateway's configured mode.
9
+ def deeplink?
10
+ true
11
+ end
12
+
13
+ # The deeplink string handed to
14
+ # acledaJSBridge.call('startPayment', { acleda_deeplink: ... })
15
+ # Ensures openSessionV2 has run (persisting paymentTokenid for later
16
+ # getTxnStatus verification) before returning the deeplinkUrl.
17
+ def acleda_deeplink
18
+ call if @response.nil?
19
+ deeplink_url
20
+ end
21
+ end
22
+ end
23
+ end
@@ -28,11 +28,6 @@ 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
- )
36
31
  end
37
32
 
38
33
  def mark_payment_as_success(checker)
@@ -37,8 +37,6 @@ 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
42
40
  end
43
41
 
44
42
  data = {
@@ -52,8 +52,6 @@ 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
57
55
  end
58
56
 
59
57
  data = {
@@ -100,7 +100,7 @@ module Vpago
100
100
  end
101
101
 
102
102
  def fetch_access_token
103
- response = Faraday.new(request: { open_timeout: Vpago::HttpTimeouts::OPEN_TIMEOUT, timeout: Vpago::HttpTimeouts::TIMEOUT }).post(
103
+ response = Faraday.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.new(request: { open_timeout: Vpago::HttpTimeouts::OPEN_TIMEOUT, timeout: Vpago::HttpTimeouts::TIMEOUT }).get(check_transaction_url, nil, default_headers)
5
+ @response = Faraday.get(check_transaction_url, nil, default_headers)
6
6
  end
7
7
 
8
8
  def success?
@@ -70,8 +70,7 @@ module Vpago
70
70
  private
71
71
 
72
72
  def fetch_access_token
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 })
73
+ response = Faraday.post(access_token_url, { username: username, password: password }.to_json, { 'Content-Type' => CONTENT_TYPE_JSON })
75
74
 
76
75
  raise "Access Token Error: #{response.status} - #{response.body}" unless response.success?
77
76
 
@@ -79,7 +78,7 @@ module Vpago
79
78
  end
80
79
 
81
80
  def post(url, body)
82
- response = Faraday.new(request: { open_timeout: Vpago::HttpTimeouts::OPEN_TIMEOUT, timeout: Vpago::HttpTimeouts::TIMEOUT }).post(url, body.to_json, default_headers)
81
+ response = Faraday.post(url, body.to_json, default_headers)
83
82
  parse_json(response.body)
84
83
  end
85
84
  end
@@ -13,22 +13,6 @@ module Vpago
13
13
  @response.dig('data', 'status') == 'SUCCESS'
14
14
  end
15
15
 
16
- def error_message
17
- @response.dig('msgEntity', 'message') || @response.dig('data', 'message') || 'Unknown error'
18
- end
19
-
20
- # msgEntity.code is the API-envelope result code ("0" = call succeeded; check
21
- # data.status for the actual transaction state). Any other code is a gateway-level
22
- # error with no transaction data (e.g. "03" / "Transaction not found") and is
23
- # treated as terminal failure.
24
- def failed?
25
- @response.dig('msgEntity', 'code').to_s != '0'
26
- end
27
-
28
- def pending?
29
- !success? && !failed?
30
- end
31
-
32
16
  private
33
17
 
34
18
  def payload
@@ -36,4 +20,4 @@ module Vpago
36
20
  end
37
21
  end
38
22
  end
39
- end
23
+ end
@@ -33,7 +33,7 @@ module Vpago
33
33
  end
34
34
 
35
35
  def return_url
36
- "#{ENV.fetch('PAYMENT_BASE_URL', nil)}/webhook/wings/#{payment_number}/return?app_checkout=#{app_checkout}"
36
+ "#{ENV.fetch('DEFAULT_URL_HOST', 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.12
4
+ version: 2.4.0.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: 2026-09-07 00:00:00.000000000 Z
11
+ date: 2026-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -151,17 +151,11 @@ files:
151
151
  - app/assets/javascripts/vpago/vpago_payments/user_informers/firebase.js
152
152
  - app/controllers/.gitkeep
153
153
  - app/controllers/spree/acleda_redirects_controller.rb
154
- - app/controllers/spree/admin/payment_acleda_v2_base_controller.rb
155
- - app/controllers/spree/admin/payment_acleda_v2_checkers_controller.rb
156
- - app/controllers/spree/admin/payment_acleda_v2_queriers_controller.rb
157
154
  - app/controllers/spree/admin/payment_methods_controller_decorator.rb
158
155
  - app/controllers/spree/admin/payment_payway_base_controller.rb
159
156
  - app/controllers/spree/admin/payment_payway_checkers_controller.rb
160
157
  - app/controllers/spree/admin/payment_payway_markers_controller.rb
161
158
  - app/controllers/spree/admin/payment_payway_queriers_controller.rb
162
- - app/controllers/spree/admin/payment_vattanac_base_controller.rb
163
- - app/controllers/spree/admin/payment_vattanac_checkers_controller.rb
164
- - app/controllers/spree/admin/payment_vattanac_queriers_controller.rb
165
159
  - app/controllers/spree/admin/payment_wing_sdk_base_controller.rb
166
160
  - app/controllers/spree/admin/payment_wing_sdk_checkers_controller.rb
167
161
  - app/controllers/spree/admin/payment_wing_sdk_markers_controller.rb
@@ -173,6 +167,7 @@ files:
173
167
  - app/controllers/spree/admin/payouts_controller.rb
174
168
  - app/controllers/spree/admin/suspicious_orders_controller.rb
175
169
  - app/controllers/spree/api/v2/storefront/checkout_controller_decorator.rb
170
+ - app/controllers/spree/miniapp/acledas_controller.rb
176
171
  - app/controllers/spree/payway_card_popups_controller.rb
177
172
  - app/controllers/spree/payway_results_controller.rb
178
173
  - app/controllers/spree/payway_v2_card_popups_controller.rb
@@ -198,6 +193,7 @@ files:
198
193
  - app/models/.gitkeep
199
194
  - app/models/concerns/vpago/payoutable.rb
200
195
  - app/models/spree/gateway/acleda.rb
196
+ - app/models/spree/gateway/acleda_mini_app.rb
201
197
  - app/models/spree/gateway/acleda_mobile.rb
202
198
  - app/models/spree/gateway/acleda_v2.rb
203
199
  - app/models/spree/gateway/payway.rb
@@ -262,6 +258,7 @@ files:
262
258
  - app/serializers/spree/v2/storefront/payment_serializer_decorator.rb
263
259
  - app/serializers/spree/v2/storefront/vpago_payment_source_serializer.rb
264
260
  - app/services/.gitkeep
261
+ - app/services/vpago/acleda_mini_app/session/create.rb
265
262
  - app/services/vpago/aes_encrypter.rb
266
263
  - app/services/vpago/payment_finder.rb
267
264
  - app/services/vpago/payment_processable.rb
@@ -289,6 +286,7 @@ files:
289
286
  - app/views/spree/admin/payments/source_forms/_payment_payway.html.erb
290
287
  - app/views/spree/admin/payments/source_forms/_payway_v2.html.erb
291
288
  - app/views/spree/admin/payments/source_views/_acleda.html.erb
289
+ - app/views/spree/admin/payments/source_views/_acleda_mini_app.html.erb
292
290
  - app/views/spree/admin/payments/source_views/_acleda_mobile.html.erb
293
291
  - app/views/spree/admin/payments/source_views/_acleda_v2.html.erb
294
292
  - app/views/spree/admin/payments/source_views/_payment_payway.html.erb
@@ -346,6 +344,7 @@ files:
346
344
  - app/views/spree/payway_v2_card_popups/show.html.erb
347
345
  - app/views/spree/vpago_payments/_transaction_checker.html.erb
348
346
  - app/views/spree/vpago_payments/checkout.html.erb
347
+ - app/views/spree/vpago_payments/forms/spree/gateway/_acleda_mini_app.html.erb
349
348
  - app/views/spree/vpago_payments/forms/spree/gateway/_acleda_v2.html.erb
350
349
  - app/views/spree/vpago_payments/forms/spree/gateway/_payway_v2.html.erb
351
350
  - app/views/spree/vpago_payments/forms/spree/gateway/_true_money.html.erb
@@ -397,6 +396,7 @@ files:
397
396
  - lib/vpago/acleda/deeplink_checkout.rb
398
397
  - lib/vpago/acleda/payment_request_updater.rb
399
398
  - lib/vpago/acleda/transaction_status.rb
399
+ - lib/vpago/acleda_mini_app/checkout.rb
400
400
  - lib/vpago/acleda_mobile/base.rb
401
401
  - lib/vpago/acleda_mobile/callback_validator.php
402
402
  - lib/vpago/acleda_mobile/callback_validator.rb
@@ -406,9 +406,7 @@ files:
406
406
  - lib/vpago/acleda_mobile/transaction_status.rb
407
407
  - lib/vpago/acleda_v2/base.rb
408
408
  - lib/vpago/acleda_v2/checkout.rb
409
- - lib/vpago/acleda_v2/payment_request_updater.rb
410
409
  - lib/vpago/acleda_v2/transaction_status.rb
411
- - lib/vpago/http_timeouts.rb
412
410
  - lib/vpago/payment_amount_calculator.rb
413
411
  - lib/vpago/payment_request_updater.rb
414
412
  - lib/vpago/payment_status_marker.rb
@@ -432,7 +430,6 @@ files:
432
430
  - lib/vpago/true_money/transaction_status.rb
433
431
  - lib/vpago/vattanac/base.rb
434
432
  - lib/vpago/vattanac/checkout.rb
435
- - lib/vpago/vattanac/payment_request_updater.rb
436
433
  - lib/vpago/vattanac/transaction_status.rb
437
434
  - lib/vpago/vattanac_mini_app/base.rb
438
435
  - lib/vpago/vattanac_mini_app/checkout.rb
@@ -465,9 +462,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
465
462
  version: 3.2.0
466
463
  required_rubygems_version: !ruby/object:Gem::Requirement
467
464
  requirements:
468
- - - ">="
465
+ - - ">"
469
466
  - !ruby/object:Gem::Version
470
- version: '0'
467
+ version: 1.3.1
471
468
  requirements:
472
469
  - none
473
470
  rubygems_version: 3.4.1
@@ -1,21 +0,0 @@
1
- module Spree
2
- module Admin
3
- class PaymentAcledaV2BaseController < Spree::Admin::BaseController
4
- include Spree::Backend::Callbacks
5
-
6
- before_action :load_payment, only: %i[show update]
7
- before_action :validate_order, only: [:update]
8
-
9
- def validate_order
10
- return unless @payment.order.completed?
11
-
12
- flash[:error] = Spree.t('vpago.payments.not_allow_for_order_completed')
13
- redirect_to admin_order_payment_path(order_id: @payment.order.number, id: @payment.number)
14
- end
15
-
16
- def load_payment
17
- @payment = Payment.find_by!(number: params[:id])
18
- end
19
- end
20
- end
21
- end
@@ -1,26 +0,0 @@
1
- module Spree
2
- module Admin
3
- class PaymentAcledaV2CheckersController < PaymentAcledaV2BaseController
4
- include Spree::Backend::Callbacks
5
-
6
- def update
7
- options = {
8
- updated_by_user_id: try_spree_current_user.id,
9
- updated_reason: Spree.t('vpago.payments.checker_updated_by_description')
10
- }
11
- spree_updater = Vpago::AcledaV2::PaymentRequestUpdater.new(@payment, options)
12
- spree_updater.call
13
-
14
- @payment.reload
15
-
16
- if @payment.order.completed?
17
- flash[:success] = Spree.t(:successfully_updated, resource: Spree.t(:payments))
18
- else
19
- flash[:error] = Spree.t(:unsuccessfully_updated, resource: Spree.t(:payments))
20
- end
21
-
22
- redirect_to admin_order_payment_path(order_id: @payment.order.number, id: @payment.number)
23
- end
24
- end
25
- end
26
- end
@@ -1,38 +0,0 @@
1
- module Spree
2
- module Admin
3
- class PaymentAcledaV2QueriersController < PaymentAcledaV2BaseController
4
- include Spree::Backend::Callbacks
5
-
6
- around_action :set_writing_role, only: %i[show]
7
-
8
- def show
9
- tran_status = @payment.payment_method.check_transaction(@payment)
10
-
11
- if tran_status.success?
12
- @payment.update_column(:gateway_status, true)
13
- flash[:success] =
14
- Spree.t('vpago.payments.payment_found_with_result', result: tran_status.json_response)
15
- else
16
- flash[:error] = Spree.t('vpago.payments.payment_not_found_with_error', error: tran_status.error_message)
17
- end
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::PaymentAcledaV2QueriersController#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')
26
- redirect_to admin_order_payment_path(order_id: @payment.order.number, id: @payment.number)
27
- end
28
-
29
- private
30
-
31
- def set_writing_role
32
- ActiveRecord::Base.connected_to(role: :writing) do
33
- yield if block_given?
34
- end
35
- end
36
- end
37
- end
38
- end
@@ -1,21 +0,0 @@
1
- module Spree
2
- module Admin
3
- class PaymentVattanacBaseController < Spree::Admin::BaseController
4
- include Spree::Backend::Callbacks
5
-
6
- before_action :load_payment, only: %i[show update]
7
- before_action :validate_order, only: [:update]
8
-
9
- def validate_order
10
- return unless @payment.order.completed?
11
-
12
- flash[:error] = Spree.t('vpago.payments.not_allow_for_order_completed')
13
- redirect_to admin_order_payment_path(order_id: @payment.order.number, id: @payment.number)
14
- end
15
-
16
- def load_payment
17
- @payment = Payment.find_by!(number: params[:id])
18
- end
19
- end
20
- end
21
- end
@@ -1,26 +0,0 @@
1
- module Spree
2
- module Admin
3
- class PaymentVattanacCheckersController < PaymentVattanacBaseController
4
- include Spree::Backend::Callbacks
5
-
6
- def update
7
- options = {
8
- updated_by_user_id: try_spree_current_user.id,
9
- updated_reason: Spree.t('vpago.payments.checker_updated_by_description')
10
- }
11
- spree_updater = Vpago::Vattanac::PaymentRequestUpdater.new(@payment, options)
12
- spree_updater.call
13
-
14
- @payment.reload
15
-
16
- if @payment.order.completed?
17
- flash[:success] = Spree.t(:successfully_updated, resource: Spree.t(:payments))
18
- else
19
- flash[:error] = Spree.t(:unsuccessfully_updated, resource: Spree.t(:payments))
20
- end
21
-
22
- redirect_to admin_order_payment_path(order_id: @payment.order.number, id: @payment.number)
23
- end
24
- end
25
- end
26
- end
@@ -1,38 +0,0 @@
1
- module Spree
2
- module Admin
3
- class PaymentVattanacQueriersController < PaymentVattanacBaseController
4
- include Spree::Backend::Callbacks
5
-
6
- around_action :set_writing_role, only: %i[show]
7
-
8
- def show
9
- tran_status = @payment.payment_method.check_transaction(@payment)
10
-
11
- if tran_status.success?
12
- @payment.update_column(:gateway_status, true)
13
- flash[:success] =
14
- Spree.t('vpago.payments.payment_found_with_result', result: tran_status.json_response)
15
- else
16
- flash[:error] = Spree.t('vpago.payments.payment_not_found_with_error', error: tran_status.error_message)
17
- end
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::PaymentVattanacQueriersController#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')
26
- redirect_to admin_order_payment_path(order_id: @payment.order.number, id: @payment.number)
27
- end
28
-
29
- private
30
-
31
- def set_writing_role
32
- ActiveRecord::Base.connected_to(role: :writing) do
33
- yield if block_given?
34
- end
35
- end
36
- end
37
- end
38
- end
@@ -1,54 +0,0 @@
1
- module Vpago
2
- module AcledaV2
3
- class PaymentRequestUpdater < ::Vpago::PaymentRequestUpdater
4
- def call
5
- return if @payment.order.paid?
6
-
7
- if items_eligible?
8
- process_payment_status
9
- else
10
- mark_items_as_ineligible
11
- end
12
- end
13
-
14
- private
15
-
16
- def process_payment_status
17
- checker = @payment.payment_method.check_transaction(@payment)
18
-
19
- if checker.success?
20
- mark_payment_as_success
21
- elsif checker.failed? && !ignore_on_failed?
22
- mark_payment_as_failed(checker.error_message)
23
- end
24
- rescue Faraday::TimeoutError, Faraday::ConnectionFailed => e
25
- VpagoLogger.error(
26
- label: 'Vpago::AcledaV2::PaymentRequestUpdater#process_payment_status gateway_timeout',
27
- data: { payment_number: @payment.number, error_class: e.class.name, error_message: e.message }
28
- )
29
- end
30
-
31
- def items_eligible?
32
- @payment&.order&.line_items&.all?(&:sufficient_stock?) == true # rubocop:disable Style/SafeNavigationChainLength
33
- end
34
-
35
- def mark_items_as_ineligible
36
- @error_message = 'Items are not eligible due to insufficient stock'
37
- marker_options = @options.merge(status: false, description: @error_message)
38
- ::Vpago::PaymentStatusMarker.new(@payment, marker_options).call
39
- end
40
-
41
- def mark_payment_as_success
42
- @error_message = nil
43
- marker_options = @options.merge(status: true, description: nil)
44
- ::Vpago::PaymentStatusMarker.new(@payment, marker_options).call
45
- end
46
-
47
- def mark_payment_as_failed(error_message)
48
- @error_message = error_message
49
- marker_options = @options.merge(status: false, description: @error_message)
50
- ::Vpago::PaymentStatusMarker.new(@payment, marker_options).call
51
- end
52
- end
53
- end
54
- end
@@ -1,6 +0,0 @@
1
- module Vpago
2
- module HttpTimeouts
3
- OPEN_TIMEOUT = 5
4
- TIMEOUT = 15
5
- end
6
- end
@@ -1,54 +0,0 @@
1
- module Vpago
2
- module Vattanac
3
- class PaymentRequestUpdater < ::Vpago::PaymentRequestUpdater
4
- def call
5
- return if @payment.order.paid?
6
-
7
- if items_eligible?
8
- process_payment_status
9
- else
10
- mark_items_as_ineligible
11
- end
12
- end
13
-
14
- private
15
-
16
- def process_payment_status
17
- checker = @payment.payment_method.check_transaction(@payment)
18
-
19
- if checker.success?
20
- mark_payment_as_success
21
- elsif checker.failed? && !ignore_on_failed?
22
- mark_payment_as_failed(checker.error_message)
23
- end
24
- rescue Faraday::TimeoutError, Faraday::ConnectionFailed => e
25
- VpagoLogger.error(
26
- label: 'Vpago::Vattanac::PaymentRequestUpdater#process_payment_status gateway_timeout',
27
- data: { payment_number: @payment.number, error_class: e.class.name, error_message: e.message }
28
- )
29
- end
30
-
31
- def items_eligible?
32
- @payment&.order&.line_items&.all?(&:sufficient_stock?) == true # rubocop:disable Style/SafeNavigationChainLength
33
- end
34
-
35
- def mark_items_as_ineligible
36
- @error_message = 'Items are not eligible due to insufficient stock'
37
- marker_options = @options.merge(status: false, description: @error_message)
38
- ::Vpago::PaymentStatusMarker.new(@payment, marker_options).call
39
- end
40
-
41
- def mark_payment_as_success
42
- @error_message = nil
43
- marker_options = @options.merge(status: true, description: nil)
44
- ::Vpago::PaymentStatusMarker.new(@payment, marker_options).call
45
- end
46
-
47
- def mark_payment_as_failed(error_message)
48
- @error_message = error_message
49
- marker_options = @options.merge(status: false, description: @error_message)
50
- ::Vpago::PaymentStatusMarker.new(@payment, marker_options).call
51
- end
52
- end
53
- end
54
- end