spree_vpago 2.3.8 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: feafa3aabbe7fd192e7d70028c28467cb990edda91c4e2180bcc127d445cdc9d
4
- data.tar.gz: 0cfc058b9ff6f04a07cbde6c8ca29d3b46a00582c143e5cad6b3b672f635caf2
3
+ metadata.gz: 2b281c3ae420620dbd3d1da80ed2bc713c9283292484c1812cd1e9c979e6bf52
4
+ data.tar.gz: 70b7603d37c2c5e8f434e1ab333e622619296fd1ced75642ea9c0512a7591eb1
5
5
  SHA512:
6
- metadata.gz: 49d235f5604b356f4ba1b555be0ce04e4946901319790d7d97a3ca3262e3445415d5a6980780d8ee27712da8b565ee5af3689726c9acb7bf1d20913c8a5c66df
7
- data.tar.gz: b7e51eb7d0d57abb587036189d1d374bd43aee8586c55fc569b19692ff38e8cc9f9bcaa404b92b1e75fe30c87d63e0af77cbafea69ed82a921eeffc1c0b5b327
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.8)
4
+ spree_vpago (2.4.0.pre.pre1)
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,
@@ -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
@@ -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
 
@@ -147,6 +141,18 @@ module Spree
147
141
  sanitized_params
148
142
  end
149
143
 
144
+ def find_payment
145
+ @payment = Vpago::PaymentFinder.new(params.permit!.to_h).find_and_verify
146
+ raise ActiveRecord::RecordNotFound unless @payment.present?
147
+ end
148
+
149
+ # frame-ancestors (set above) supersedes X-Frame-Options in modern
150
+ # browsers, but the default SAMEORIGIN header would still block legacy
151
+ # browsers from embedding these pages, so drop it for the iframe actions.
152
+ def allow_iframe_embedding
153
+ response.headers.delete('X-Frame-Options')
154
+ end
155
+
150
156
  def render_not_found
151
157
  respond_to do |format|
152
158
  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
  });
@@ -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
@@ -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,
@@ -95,6 +97,10 @@ module Vpago
95
97
  type == Spree::PaymentMethod::TYPE_ACLEDA_V2
96
98
  end
97
99
 
100
+ def type_acleda_mini_app?
101
+ type == Spree::PaymentMethod::TYPE_ACLEDA_MINI_APP
102
+ end
103
+
98
104
  def type_payway?
99
105
  type == Spree::PaymentMethod::TYPE_PAYWAY
100
106
  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
@@ -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
+ %>
@@ -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 %>
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
@@ -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.8'.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
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.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-07-22 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
@@ -167,6 +167,7 @@ files:
167
167
  - app/controllers/spree/admin/payouts_controller.rb
168
168
  - app/controllers/spree/admin/suspicious_orders_controller.rb
169
169
  - app/controllers/spree/api/v2/storefront/checkout_controller_decorator.rb
170
+ - app/controllers/spree/miniapp/acledas_controller.rb
170
171
  - app/controllers/spree/payway_card_popups_controller.rb
171
172
  - app/controllers/spree/payway_results_controller.rb
172
173
  - app/controllers/spree/payway_v2_card_popups_controller.rb
@@ -192,6 +193,7 @@ files:
192
193
  - app/models/.gitkeep
193
194
  - app/models/concerns/vpago/payoutable.rb
194
195
  - app/models/spree/gateway/acleda.rb
196
+ - app/models/spree/gateway/acleda_mini_app.rb
195
197
  - app/models/spree/gateway/acleda_mobile.rb
196
198
  - app/models/spree/gateway/acleda_v2.rb
197
199
  - app/models/spree/gateway/payway.rb
@@ -256,6 +258,7 @@ files:
256
258
  - app/serializers/spree/v2/storefront/payment_serializer_decorator.rb
257
259
  - app/serializers/spree/v2/storefront/vpago_payment_source_serializer.rb
258
260
  - app/services/.gitkeep
261
+ - app/services/vpago/acleda_mini_app/session/create.rb
259
262
  - app/services/vpago/aes_encrypter.rb
260
263
  - app/services/vpago/payment_finder.rb
261
264
  - app/services/vpago/payment_processable.rb
@@ -283,6 +286,7 @@ files:
283
286
  - app/views/spree/admin/payments/source_forms/_payment_payway.html.erb
284
287
  - app/views/spree/admin/payments/source_forms/_payway_v2.html.erb
285
288
  - app/views/spree/admin/payments/source_views/_acleda.html.erb
289
+ - app/views/spree/admin/payments/source_views/_acleda_mini_app.html.erb
286
290
  - app/views/spree/admin/payments/source_views/_acleda_mobile.html.erb
287
291
  - app/views/spree/admin/payments/source_views/_acleda_v2.html.erb
288
292
  - app/views/spree/admin/payments/source_views/_payment_payway.html.erb
@@ -340,6 +344,7 @@ files:
340
344
  - app/views/spree/payway_v2_card_popups/show.html.erb
341
345
  - app/views/spree/vpago_payments/_transaction_checker.html.erb
342
346
  - app/views/spree/vpago_payments/checkout.html.erb
347
+ - app/views/spree/vpago_payments/forms/spree/gateway/_acleda_mini_app.html.erb
343
348
  - app/views/spree/vpago_payments/forms/spree/gateway/_acleda_v2.html.erb
344
349
  - app/views/spree/vpago_payments/forms/spree/gateway/_payway_v2.html.erb
345
350
  - app/views/spree/vpago_payments/forms/spree/gateway/_true_money.html.erb
@@ -391,6 +396,7 @@ files:
391
396
  - lib/vpago/acleda/deeplink_checkout.rb
392
397
  - lib/vpago/acleda/payment_request_updater.rb
393
398
  - lib/vpago/acleda/transaction_status.rb
399
+ - lib/vpago/acleda_mini_app/checkout.rb
394
400
  - lib/vpago/acleda_mobile/base.rb
395
401
  - lib/vpago/acleda_mobile/callback_validator.php
396
402
  - lib/vpago/acleda_mobile/callback_validator.rb
@@ -456,9 +462,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
456
462
  version: 3.2.0
457
463
  required_rubygems_version: !ruby/object:Gem::Requirement
458
464
  requirements:
459
- - - ">="
465
+ - - ">"
460
466
  - !ruby/object:Gem::Version
461
- version: '0'
467
+ version: 1.3.1
462
468
  requirements:
463
469
  - none
464
470
  rubygems_version: 3.4.1