spree_vpago 2.0.8.pre.beta2 → 2.0.8.pre.beta4

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: d006f101539dd059e92dd575c6a40c036a753638e0f095c4680fb8fec2e3fc27
4
- data.tar.gz: 5b7137318a4d5be9fea18f55951414bfc973d39cef0d67b8459aacefcee78c01
3
+ metadata.gz: 347bcfd7a5120dff061943a3ac91bdc64e22dca81f9bf046b028c06bd7f50521
4
+ data.tar.gz: e7261ee32ab96b7e3f43e4089b88f6b7a2505674055e6d48e0da434c90b6dbf5
5
5
  SHA512:
6
- metadata.gz: 40a1984b36bf03669c53488af115deac0ca3b694fe5c039864b0589abf94be54bdd47154d19b47e5a834af13e2ec581dd55e90d54f6021e6543d6c1e0980c3bd
7
- data.tar.gz: d0fa00d9485ac9493cbe82d49e1c7a4f5f671f000ea7dd385e17b08dc7304cacb061ff9c3bc3d106bc5bbb76883e2afd8ab7029f702fb1da64ab6fee97251ce4
6
+ metadata.gz: 3705d3643e441c22533dd68def749c8e7569afe2f78a6a0134046674d82d60d9e8416720817d9cebc7d351b4011081b3fb284822612bf2f324b53ab6f92acf77
7
+ data.tar.gz: bb38cab70179348c732fd2358086a8c3e4957f5fad20fa7a9ee18ef8abea2febcb01c9efae211882e8ad7f6fbbdc1803ec5e3d57bed923c0b1d35bdbe4f819cb
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- spree_vpago (2.0.8.pre.beta2)
4
+ spree_vpago (2.0.8.pre.beta4)
5
5
  faraday
6
6
  google-cloud-firestore
7
7
  spree_api (>= 4.5)
@@ -198,7 +198,7 @@ GEM
198
198
  flatpickr (4.6.13.1)
199
199
  friendly_id (5.5.0)
200
200
  activerecord (>= 4.0.0)
201
- gapic-common (1.0.0)
201
+ gapic-common (1.0.1)
202
202
  faraday (>= 1.9, < 3.a)
203
203
  faraday-retry (>= 1.0, < 3.a)
204
204
  google-cloud-env (~> 2.2)
@@ -234,7 +234,7 @@ GEM
234
234
  google-cloud-core (~> 1.7)
235
235
  google-cloud-firestore-v1 (~> 2.0)
236
236
  rbtree (~> 0.4.2)
237
- google-cloud-firestore-v1 (2.1.0)
237
+ google-cloud-firestore-v1 (2.1.1)
238
238
  gapic-common (~> 1.0)
239
239
  google-cloud-errors (~> 1.0)
240
240
  google-cloud-location (~> 1.0)
@@ -1,3 +1,4 @@
1
1
  //= link_tree ../images
2
2
  //= link vpago/vpago_payments/request_process_payment.js
3
3
  //= link vpago/vpago_payments/user_informers/firebase.js
4
+ //= link vpago/vpago_payments/payment_processing_listener.js
@@ -0,0 +1,46 @@
1
+ window.initPaymentProcessingListener = async function (
2
+ firebaseConfigs,
3
+ documentReferencePath,
4
+ successUrl
5
+ ) {
6
+ function log(status, processing, reasonCode, reasonMessage) {
7
+ console.log(`Status: ${status}`);
8
+ console.log(`Reason Code: ${reasonCode}`);
9
+ console.log(`Processing: ${processing ? "Processing..." : "No more process."}`);
10
+ console.log(`Reason Message: ${reasonMessage}`);
11
+ }
12
+
13
+ window.listenToProcessingState({
14
+ firebaseConfigs,
15
+ documentReferencePath,
16
+
17
+ onPaymentIsProcessing(orderState, paymentState, processing, reasonCode, reasonMessage) {
18
+ log("Payment is processing", processing, reasonCode, reasonMessage);
19
+ },
20
+
21
+ onOrderIsProcessing(orderState, paymentState, processing, reasonCode, reasonMessage) {
22
+ log("Order is processing", processing, reasonCode, reasonMessage);
23
+ },
24
+
25
+ onOrderIsCompleted(orderState, paymentState, processing, reasonCode, reasonMessage) {
26
+ log("Order is completed", processing, reasonCode, reasonMessage);
27
+ },
28
+
29
+ onOrderProcessFailed(orderState, paymentState, processing, reasonCode, reasonMessage) {
30
+ log("Order process failed", processing, reasonCode, reasonMessage);
31
+ },
32
+
33
+ onPaymentIsRefunded(orderState, paymentState, processing, reasonCode, reasonMessage) {
34
+ log("Payment is refunded", processing, reasonCode, reasonMessage);
35
+ },
36
+
37
+ onPaymentProcessFailed(orderState, paymentState, processing, reasonCode, reasonMessage) {
38
+ log("Payment process failed", processing, reasonCode, reasonMessage);
39
+ },
40
+
41
+ onCompleted(orderState, paymentState, processing, reasonCode, reasonMessage) {
42
+ log("Completed — redirecting to success URL", processing, reasonCode, reasonMessage);
43
+ window.location.href = successUrl;
44
+ }
45
+ });
46
+ };
@@ -5,7 +5,7 @@ module Spree
5
5
 
6
6
  skip_before_action :verify_authenticity_token, only: [:process_payment]
7
7
 
8
- rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
8
+ rescue_from ActiveRecord::RecordNotFound, with: :render_not_found
9
9
  rescue_from CanCan::AccessDenied, with: :access_denied
10
10
 
11
11
  # GET
@@ -33,12 +33,6 @@ module Spree
33
33
 
34
34
  @order = @payment.order
35
35
  raise CanCan::AccessDenied unless @order.completed?
36
-
37
- if params[:offsite_payment].present?
38
- redirect_to @payment.payment_url, allow_other_host: true
39
- else
40
- render :success
41
- end
42
36
  end
43
37
 
44
38
  # POST
@@ -8,9 +8,8 @@ module Spree
8
8
  preference :client_id, :string
9
9
  preference :client_secret, :string
10
10
  preference :private_key, :text
11
- preference :merchant_scheme, :string
12
- preference :merchant_android_package_name, :string
13
- preference :redirection_type, :string
11
+ preference :return_url_scheme, :string
12
+ preference :android_package_name, :string
14
13
 
15
14
  def method_type
16
15
  'true_money'
@@ -56,12 +55,12 @@ module Spree
56
55
  success, params[:refund_response] = true_money_refund(payment)
57
56
 
58
57
  if success
59
- ActiveMerchant::Billing::Response.new(true, 'Payway Gateway: successfully canceled.', params)
58
+ ActiveMerchant::Billing::Response.new(true, 'True money Gateway: successfully canceled.', params)
60
59
  else
61
- ActiveMerchant::Billing::Response.new(false, 'Payway Gateway: Failed to canceleed', params)
60
+ ActiveMerchant::Billing::Response.new(false, 'True money Gateway: Failed to canceleed', params)
62
61
  end
63
62
  else
64
- ActiveMerchant::Billing::Response.new(true, 'Payway Gateway: Payment has been voided.')
63
+ ActiveMerchant::Billing::Response.new(true, 'True money Gateway: Payment has been voided.')
65
64
  end
66
65
  end
67
66
 
@@ -69,12 +68,12 @@ module Spree
69
68
  refund_issuer = Vpago::TrueMoney::RefundIssuer.new(payment, {})
70
69
  refund_issuer.call
71
70
 
72
- [refund_issuer.success?, refund_issuer.response]
71
+ [refund_issuer.success?, refund_issuer.parsed_response]
73
72
  end
74
73
 
75
74
  def cancel(_response_code, _payment)
76
75
  # we can use this to send request to payment gateway api to cancel the payment ( void )
77
- # currently Payway does not support to cancel the gateway
76
+ # currently True money does not support to cancel the gateway
78
77
 
79
78
  # in our case don't do anything
80
79
  ActiveMerchant::Billing::Response.new(true, '')
@@ -5,11 +5,11 @@ module Vpago
5
5
  base.after_create -> { Vpago::PayoutsGenerator.new(self).call }, if: :should_generate_payouts?
6
6
 
7
7
  base.delegate :checkout_url,
8
+ :web_checkout_url,
8
9
  :processing_url,
10
+ :processing_deeplink_url,
9
11
  :success_url,
10
12
  :process_payment_url,
11
- :processing_app_url,
12
- :payment_url,
13
13
  to: :url_constructor
14
14
  end
15
15
 
@@ -58,6 +58,10 @@ module Vpago
58
58
  pre_auth_status == 'CANCELLED'
59
59
  end
60
60
 
61
+ def true_money_payment?
62
+ payment_method.type_true_money?
63
+ end
64
+
61
65
  def vattanac_mini_app_payment?
62
66
  payment_method.type_vattanac_mini_app?
63
67
  end
@@ -30,7 +30,15 @@ module Vpago
30
30
  return [] if payouts.all?(&:default?)
31
31
  return [] unless payouts.all? { |payout| validated?(payout) }
32
32
 
33
- ActiveRecord::Base.transaction { payouts.each(&:save!) }
33
+ ActiveRecord::Base.transaction do
34
+ payouts.each(&:save!)
35
+
36
+ # If any payouts were rounded, the total may increase slightly.
37
+ # Update the payment amount to match the sum of payouts to avoid mismatch errors.
38
+ payment.update(amount: payouts.map(&:amount).sum)
39
+
40
+ payouts
41
+ end
34
42
  end
35
43
 
36
44
  def validated?(payout)
@@ -47,7 +55,7 @@ module Vpago
47
55
  total_confirmed_payouts = line_item.confirmed_payouts_for_vendor.sum(:amount)
48
56
  next if total_confirmed_payouts >= line_item.pre_commission_amount
49
57
 
50
- amount_owed_to_vendor = line_item.pre_commission_amount - total_confirmed_payouts
58
+ amount_owed_to_vendor = round_up(line_item.pre_commission_amount - total_confirmed_payouts)
51
59
  payout_amount = [amount_owed_to_vendor, remaining_amount].min
52
60
  outstanding_amount = [amount_owed_to_vendor - payout_amount, 0].max
53
61
 
@@ -80,7 +88,7 @@ module Vpago
80
88
  total_confirmed_payouts = shipment.confirmed_payouts_for_vendor.sum(:amount)
81
89
  next if total_confirmed_payouts >= shipment.cost_with_vendor_adjustment_total
82
90
 
83
- amount_owed_to_shipping_vendor = shipment.cost_with_vendor_adjustment_total - total_confirmed_payouts
91
+ amount_owed_to_shipping_vendor = round_up(shipment.cost_with_vendor_adjustment_total - total_confirmed_payouts)
84
92
  payout_amount = [amount_owed_to_shipping_vendor, remaining_amount].min
85
93
  outstanding_amount = [amount_owed_to_shipping_vendor - payout_amount, 0].max
86
94
 
@@ -117,9 +125,33 @@ module Vpago
117
125
  state: :created,
118
126
  payment: payment,
119
127
  payout_profile: Spree::PayoutProfiles::PaywayV2.default,
120
- amount: self.remaining_amount
128
+ amount: round_up(self.remaining_amount)
121
129
  )
122
130
  ]
123
131
  end
132
+
133
+ # ABA does not support amounts with more than 2 decimal places.
134
+ # Therefore, we must round all 3-decimal payouts to 2 decimals beforehand.
135
+ #
136
+ # Our rounding strategy:
137
+ # - We round up for vendors & shipment payouts (to favor external parties).
138
+ # - The remaining amount is adjusted in the platform's share (may be slightly less).
139
+ #
140
+ # Example:
141
+ # Total amount: $5.00
142
+ #
143
+ # Vendor payouts:
144
+ # - Vendor 1: $0.625 → $0.63
145
+ # - Vendor 2: $0.625 → $0.63
146
+ #
147
+ # Shipment payouts:
148
+ # - Shipment 1: $0.625 → $0.63
149
+ # - Shipment 2: $0.625 → $0.63
150
+ #
151
+ # Platform payout:
152
+ # - $2.50 → $2.48 (adjusted to ensure total remains $5.00)
153
+ def round_up(amount)
154
+ (amount * 100).ceil / 100.0
155
+ end
124
156
  end
125
157
  end
@@ -3,7 +3,7 @@ module Spree
3
3
  module Storefront
4
4
  module PaymentSerializerDecorator
5
5
  def self.prepended(base)
6
- base.attributes :pre_auth_status, :checkout_url, :process_payment_url
6
+ base.attributes :pre_auth_status, :checkout_url, :process_payment_url, :web_checkout_url
7
7
  end
8
8
  end
9
9
  end
@@ -7,7 +7,6 @@ module Vpago
7
7
  end
8
8
 
9
9
  def find_and_verify
10
-
11
10
  find_and_verify!
12
11
  rescue StandardError, ActiveRecord::RecordNotFound => e
13
12
  Rails.logger.error("PaymentJwtVerifier#find_and_verify error: #{e.class} - #{e.message}")
@@ -15,16 +14,15 @@ module Vpago
15
14
  end
16
15
 
17
16
  def find_and_verify!
18
-
19
17
  if vattanac_mini_app_payload?
20
- payload = Vpago::VattanacMiniAppDataHandler.new.decrypt_data(@params_hash[:data])
18
+ payload = Vpago::VattanacMiniAppDataHandler.new.decrypt_data(@params_hash[:data])
21
19
  payment = Spree::Payment.find_by!(number: payload['paymentId'])
22
20
  payment.update(transaction_response: payload)
23
21
  payment
24
- else
22
+ else
25
23
  order = Spree::Order.find_by!(number: params_hash[:order_number])
26
24
  verify_jwt!(order)
27
-
25
+
28
26
  Spree::Payment.find_by!(number: params_hash[:payment_number])
29
27
  end
30
28
  end
@@ -36,8 +34,5 @@ module Vpago
36
34
  def vattanac_mini_app_payload?
37
35
  params_hash[:data].present?
38
36
  end
39
-
40
37
  end
41
38
  end
42
-
43
-
@@ -16,7 +16,7 @@ module Vpago
16
16
  # 2. Pre-auth is enabled, ensuring funds can be released to user if processing fails.
17
17
  # PaymentProcessor is usually called after payment is made, so canceling pre-auth typically works.
18
18
  def can_cancel_pre_auth?
19
- @payment.pending? || @payment.payment_method.enable_pre_auth? || @payment.vattanac_mini_app_payment?
19
+ @payment.pending? || @payment.payment_method.enable_pre_auth? || @payment.vattanac_mini_app_payment? || @payment.true_money_payment?
20
20
  end
21
21
 
22
22
  def extract_completer_failure_reason_code(error)
@@ -10,26 +10,23 @@ module Vpago
10
10
  end
11
11
 
12
12
  def checkout_url = "#{base_url}/vpago_payments/checkout?#{query}"
13
+ def web_checkout_url = "#{base_url}/vpago_payments/checkout?#{query}&platform=web"
13
14
  def processing_url = "#{base_url}/vpago_payments/processing?#{query}"
15
+ def processing_deeplink_url = "#{@payment.payment_method.preferred_return_url_scheme}/vpago_payments/processing?#{query}"
14
16
  def success_url = "#{base_url}/vpago_payments/success?#{query}"
15
17
  def process_payment_url = "#{base_url}/vpago_payments/process_payment?#{query}"
16
18
 
17
- def processing_app_url = "#{@payment.payment_method.preferred_merchant_scheme}/vpago_payments/processing?#{query}"
18
-
19
19
  def query
20
- params = {
20
+ {
21
21
  payment_number: payment.number,
22
22
  order_number: order.number,
23
- order_jwt_token: order_jwt_token
24
- }
25
-
26
- params[:offsite_payment] = true if payment.payment_method.type_true_money?
27
-
28
- params.to_query
23
+ order_jwt_token: order_jwt_token,
24
+ offsite_payment: offsite_payment? ? true : nil
25
+ }.compact.to_query
29
26
  end
30
27
 
31
- def payment_url
32
- "#{base_url}/book/payment?number=#{@payment.order.number}&tk=#{@payment.order.token}"
28
+ def offsite_payment?
29
+ payment.payment_method.type_true_money?
33
30
  end
34
31
 
35
32
  private
@@ -1,12 +1,33 @@
1
1
  <% @checkout = ::Vpago::TrueMoney::Checkout.new(@payment) %>
2
- <% webview_url = @checkout.generate_payment_urls[:webview] rescue nil %>
3
-
4
- <% if webview_url.present? %>
5
- <script>
6
- document.addEventListener("DOMContentLoaded", function () {
7
- window.top.location.href = "<%= j webview_url %>";
8
- });
9
- </script>
10
- <% else %>
11
- <p>Unable to generate the payment URL. Please try again.</p>
12
- <% end %>
2
+ <% redirect_url = @checkout.generate_payment_urls(params[:platform]) %>
3
+ <% @payment.user_informer.payment_is_processing(processing: true) %>
4
+
5
+ <script>
6
+ document.addEventListener("DOMContentLoaded", () => {
7
+
8
+ const setupConfirmPaymentButton = () => {
9
+ const confirmButton = document.getElementById("confirm-payment-button");
10
+ if (!confirmButton) return;
11
+
12
+ confirmButton.addEventListener("click", () => {
13
+ window.open("<%= j redirect_url %>", "_blank");
14
+ });
15
+ };
16
+
17
+ const setupPaymentProcessingListener = () => {
18
+ const firebaseConfigs = <%= Rails.application.credentials.firebase_web_config.to_json.html_safe %>;
19
+ const documentReferencePath = "<%= @payment.user_informer.document_reference_path %>";
20
+ const successUrl = "<%= @payment.success_url %>";
21
+
22
+ if (window.initPaymentProcessingListener) {
23
+ window.initPaymentProcessingListener(firebaseConfigs, documentReferencePath, successUrl);
24
+ } else {
25
+ console.warn("initPaymentProcessingListener is not defined");
26
+ }
27
+ };
28
+
29
+ setupConfirmPaymentButton();
30
+ setupPaymentProcessingListener();
31
+
32
+ });
33
+ </script>
@@ -2,92 +2,51 @@
2
2
  <% @payment.user_informer.payment_is_processing(processing: true) %>
3
3
 
4
4
  <p id="unsupported-message"
5
- style="margin-top: 10px;
6
- font-weight: bold;
7
- color: red;
8
- display: none;">
5
+ style="margin-top: 10px; font-weight: bold; color: red; display: none;">
9
6
  </p>
10
7
 
11
8
  <script>
12
- function detectMobileOS() {
13
- const ua = navigator.userAgent || navigator.vendor || window.opera;
14
- if (/iPad|iPhone|iPod/.test(ua) && !window.MSStream) return 'iOS';
15
- if (/Android/i.test(ua)) return 'Android';
16
- return 'unknown';
17
- }
18
-
19
- document.addEventListener('DOMContentLoaded', () => {
20
- const os = detectMobileOS();
21
- const payload = {
22
- data: "<%= j @checkout.signed_payload %>",
23
- paymentId: "<%= @checkout.payment_id %>"
9
+ document.addEventListener("DOMContentLoaded", () => {
10
+
11
+ const setupMiniAppPayment = () => {
12
+ const detectMobileOS = () => {
13
+ const ua = navigator.userAgent || navigator.vendor || window.opera;
14
+ if (/iPad|iPhone|iPod/.test(ua) && !window.MSStream) return 'iOS';
15
+ if (/Android/i.test(ua)) return 'Android';
16
+ return 'unknown';
17
+ };
18
+
19
+ const os = detectMobileOS();
20
+ const payload = {
21
+ data: "<%= j @checkout.signed_payload %>",
22
+ paymentId: "<%= @checkout.payment_id %>"
23
+ };
24
+
25
+ if (os === 'iOS' && window.webkit?.messageHandlers?.startPayment) {
26
+ window.webkit.messageHandlers.startPayment.postMessage(JSON.stringify(payload));
27
+ } else if (os === 'Android' && window.AndroidInterface?.startPayment) {
28
+ window.AndroidInterface.startPayment(JSON.stringify(payload));
29
+ } else {
30
+ const unsupported = document.getElementById('unsupported-message');
31
+ unsupported.style.display = 'block';
32
+ unsupported.innerText = 'Unsupported OS';
33
+ }
24
34
  };
25
35
 
26
- if (os === 'iOS' && window.webkit?.messageHandlers?.startPayment) {
27
- window.webkit.messageHandlers.startPayment.postMessage(JSON.stringify(payload));
28
- } else if (os === 'Android' && window.AndroidInterface?.startPayment) {
29
- window.AndroidInterface.startPayment(JSON.stringify(payload));
30
- } else {
31
- const unsupported = document.getElementById('unsupported-message');
32
- unsupported.style.display = 'block';
33
- unsupported.innerText = 'Unsupported OS';
34
- }
35
-
36
- const firebaseConfigs = <%= Rails.application.credentials.firebase_web_config.to_json.html_safe %>;
37
-
38
- window.listenToProcessingState({
39
- firebaseConfigs: firebaseConfigs,
40
- documentReferencePath: "<%= @payment.user_informer.document_reference_path %>",
41
-
42
- onPaymentIsProcessing: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
43
- console.log("Status: Payment is processing");
44
- console.log("Reason Code:", reasonCode);
45
- console.log("Processing:", processing ? "Processing..." : "No more process.");
46
- console.log("Reason Message:", reasonMessage);
47
- },
48
-
49
- onOrderIsProcessing: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
50
- console.log("Status: Order is processing");
51
- console.log("Reason Code:", reasonCode);
52
- console.log("Processing:", processing ? "Processing..." : "No more process.");
53
- console.log("Reason Message:", reasonMessage);
54
- },
36
+ const setupPaymentProcessingListener = () => {
37
+ const firebaseConfigs = <%= Rails.application.credentials.firebase_web_config.to_json.html_safe %>;
38
+ const documentReferencePath = "<%= @payment.user_informer.document_reference_path %>";
39
+ const successUrl = "<%= @payment.success_url %>";
55
40
 
56
- onOrderIsCompleted: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
57
- console.log("Status: Order is completed");
58
- console.log("Reason Code:", reasonCode);
59
- console.log("Processing:", processing ? "Processing..." : "No more process.");
60
- console.log("Reason Message:", reasonMessage);
61
- },
62
-
63
- onOrderProcessFailed: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
64
- console.log("Status: Order process failed");
65
- console.log("Reason Code:", reasonCode);
66
- console.log("Processing:", processing ? "Processing..." : "No more process.");
67
- console.log("Reason Message:", reasonMessage);
68
- },
69
-
70
- onPaymentIsRefunded: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
71
- console.log("Status: Payment is refunded");
72
- console.log("Reason Code:", reasonCode);
73
- console.log("Processing:", processing ? "Processing..." : "No more process.");
74
- console.log("Reason Message:", reasonMessage);
75
- },
76
-
77
- onPaymentProcessFailed: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
78
- console.log("Status: Payment process failed");
79
- console.log("Reason Code:", reasonCode);
80
- console.log("Processing:", processing ? "Processing..." : "No more process.");
81
- console.log("Reason Message:", reasonMessage);
82
- },
83
-
84
- onCompleted: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
85
- console.log("Status: Completed — redirecting to success URL");
86
- console.log("Reason Code:", reasonCode);
87
- console.log("Reason Message:", reasonMessage);
88
- let successPath = "<%= @payment.success_url %>";
89
- window.location.href = successPath;
90
- },
91
- });
41
+ if (window.initPaymentProcessingListener) {
42
+ window.initPaymentProcessingListener(firebaseConfigs, documentReferencePath, successUrl);
43
+ } else {
44
+ console.log("initPaymentProcessingListener is not defined");
45
+ }
46
+ };
47
+
48
+ setupMiniAppPayment();
49
+ setupPaymentProcessingListener();
50
+
92
51
  });
93
52
  </script>
@@ -1,7 +1,7 @@
1
1
  module SpreeVpago
2
2
  module_function
3
3
 
4
- VERSION = '2.0.8-beta2'.freeze
4
+ VERSION = '2.0.8-beta4'.freeze
5
5
 
6
6
  def version
7
7
  Gem::Version.new VERSION
@@ -69,10 +69,6 @@ module Vpago
69
69
  }
70
70
  end
71
71
 
72
- def redirection_type
73
- payment_method.preferred_redirection_type
74
- end
75
-
76
72
  def check_transaction_url
77
73
  "#{payment_method.preferred_check_transaction_url}/#{external_ref_id}"
78
74
  end
@@ -89,8 +85,8 @@ module Vpago
89
85
  payment_method.preferred_access_token_url
90
86
  end
91
87
 
92
- def merchant_android_package_name
93
- payment_method.preferred_merchant_android_package_name
88
+ def android_package_name
89
+ payment_method.preferred_android_package_name
94
90
  end
95
91
 
96
92
  def parse_json(body)
@@ -130,10 +126,6 @@ module Vpago
130
126
  def signature_input
131
127
  "#{timestamp}#{payload.to_json}"
132
128
  end
133
-
134
- def processing_url
135
- "#{@payment.processing_url}&offsite_payment=true"
136
- end
137
129
  end
138
130
  end
139
131
  end
@@ -1,32 +1,27 @@
1
1
  module Vpago
2
2
  module TrueMoney
3
3
  class Checkout < Base
4
- def generate_payment_urls
4
+ def generate_payment_urls(platform)
5
+ redirection_type = platform == 'web' ? 'web_redirect' : 'mobileapp'
6
+
5
7
  request_body = {
6
8
  payment_info: payload.to_json,
7
- redirectionType: redirection_type
9
+ redirectionType: redirection_type,
10
+ merchantDeepLink: @payment.processing_deeplink_url,
11
+ merchantAndroidPackageName: android_package_name,
12
+ refererLink: @payment.processing_url
8
13
  }
9
14
 
10
- if redirection_type == 'mobileapp'
11
- request_body[:merchantDeepLink] = @payment.processing_app_url
12
- request_body[:merchantAndroidPackageName] = merchant_android_package_name
13
- else
14
- request_body[:refererLink] = @payment.processing_url
15
- end
16
-
17
15
  response = Faraday.post(generate_payment_url) do |req|
18
16
  req.headers = default_headers
19
17
  req.body = request_body.to_json
20
18
  end
21
19
 
22
20
  body = parse_json(response.body)
23
-
24
- raise "Generate Payment Error: #{response.status} - #{body['message'] || response.body}" unless response.success? && body.dig('status', 'code') == '000001'
25
-
26
- {
27
- webview: body['data']['webview'],
28
- deeplink: body['data']['deeplink']
29
- }
21
+ platform == 'web' ? body['data']['webview'] : body['data']['deeplink']
22
+ rescue Faraday::Error, JSON::ParserError, NoMethodError => e
23
+ Rails.logger.error("Failed to generate payment URL: #{e.class} - #{e.message}")
24
+ raise
30
25
  end
31
26
  end
32
27
  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.0.8.pre.beta2
4
+ version: 2.0.8.pre.beta4
5
5
  platform: ruby
6
6
  authors:
7
7
  - You
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-07-17 00:00:00.000000000 Z
11
+ date: 2025-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -134,6 +134,7 @@ files:
134
134
  - app/assets/images/backend-process.svg
135
135
  - app/assets/images/vpago/payway/abapay.png
136
136
  - app/assets/images/vpago/payway/cards.png
137
+ - app/assets/javascripts/vpago/vpago_payments/payment_processing_listener.js
137
138
  - app/assets/javascripts/vpago/vpago_payments/request_process_payment.js
138
139
  - app/assets/javascripts/vpago/vpago_payments/user_informers/firebase.js
139
140
  - app/controllers/.gitkeep