spree_vpago 2.2.2.pre.pre15 → 2.2.2.pre.pre17

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: 2e8b2ed39701b994d1334481c2e6abaaf9d1e7f8139d0bfa85e776dd56f77f64
4
- data.tar.gz: 1640e2aaa90a6c156c1abf61998e7b12e559e6be88bdb0c5c4eef9b97cc7ea33
3
+ metadata.gz: a41c53551544436fc2973a85d085bf8dd9712ebd84ae9d6b8d820ffeeea6d5b2
4
+ data.tar.gz: e0141d5b5968a647843616bfcea9a458c2805215cc78bc3651a999565bed6a59
5
5
  SHA512:
6
- metadata.gz: b89362c53d5398d9cd17498fbd294fac146eb7d8b6121ab3b93dc4ab914daab4c868b73b1ff650c83c2c45909cf1cad088830f85f23c566618c0d5ed8fc886f5
7
- data.tar.gz: 1c5981c54969f653d06f45e45e11da30944b1488b40f0c6cea3219b4a1bf17e0b946e2e647c3f30590f5565ecfc74a561cfbc146a2d36ad04b62fbed62a2415d
6
+ metadata.gz: dc3468dcff8511b38149ec840b73c09ed669c0347d0daa84956983edde8b8e4470f23825efc5e662424f6057d008f5ca788623a580cd21f45f3ab726923638a8
7
+ data.tar.gz: 9ed4fe39e71672992963611effb80f9e781b24b677a9ac040de0b75cf56762d2e210a3c60abde7e3e69a838816715d7969412a92db588de3cf543eba81a39cd2
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- spree_vpago (2.2.2.pre.pre15)
4
+ spree_vpago (2.2.2.pre.pre17)
5
5
  faraday
6
6
  google-cloud-firestore
7
7
  spree_api (>= 4.5)
@@ -37,6 +37,12 @@ module Vpago
37
37
  class: 'fullwidth select2')
38
38
  when 'preferred_icon_name'
39
39
  return form.select(:preferred_icon_name, available_payment_icons, {}, class: 'fullwidth select2')
40
+ when 'preferred_payment_option'
41
+ return form.select(:preferred_payment_option, Spree::Gateway::PaywayV2::PAYMENT_OPTIONS, {}, class: 'fullwidth select2')
42
+ when 'preferred_abapay_khqr_deeplink_option'
43
+ return ''.html_safe unless form.object.abapay_khqr_deeplink?
44
+
45
+ return form.select(:preferred_abapay_khqr_deeplink_option, Spree::Gateway::PaywayV2::ABAPAY_KHQR_DEEPLINK_OPTIONS, {}, class: 'fullwidth select2')
40
46
  when 'preferred_vattanac_payment_option'
41
47
  return form.select(:preferred_vattanac_payment_option, available_vattanac_payment_options, {}, class: 'fullwidth select2')
42
48
  end
@@ -8,5 +8,37 @@ module Vpago
8
8
  def render_form
9
9
  render partial: "spree/vpago_payments/forms/#{@payment.payment_method.class.to_s.underscore}"
10
10
  end
11
+
12
+ def render_payment_status_listener
13
+ render partial: 'spree/vpago_payments/payment_status_listener'
14
+ end
15
+
16
+ # when return nil, each payment method should use their default URL.
17
+ # eg. PayWayV2 will use the continue_success_url as deeplink back URL.
18
+ def custom_return_deeplink_url
19
+ if telegram_user_agent?
20
+ 'tg://'
21
+ elsif facebook_user_agent?
22
+ 'fb://'
23
+ elsif messenger_user_agent?
24
+ 'fb-messenger://'
25
+ end
26
+ end
27
+
28
+ def mobile_user_agent?
29
+ request.user_agent.to_s.downcase.match?(/android|iphone|ipad|ipod/)
30
+ end
31
+
32
+ def telegram_user_agent?
33
+ request.user_agent.to_s.downcase.include?('telegram')
34
+ end
35
+
36
+ def facebook_user_agent?
37
+ request.user_agent.to_s.downcase.include?('fban') || request.user_agent.to_s.downcase.include?('facebook')
38
+ end
39
+
40
+ def messenger_user_agent?
41
+ request.user_agent.to_s.downcase.include?('messenger')
42
+ end
11
43
  end
12
44
  end
@@ -1,20 +1,38 @@
1
1
  module Spree
2
2
  class Gateway::PaywayV2 < PaymentMethod
3
+ ABAPAY_KHQR_DEEPLINK_OPTIONS = %w[open_both open_deeplink_only open_checkout_url_only].freeze
4
+ PAYMENT_OPTIONS = %w[abapay_khqr_deeplink abapay_khqr cards wechat alipay].freeze
5
+
3
6
  preference :host, :string
4
7
  preference :api_key, :string
5
8
  preference :merchant_id, :string
6
- preference :payment_option, :string # 'abapay', 'cards', 'abapay_deeplink'
9
+ preference :payment_option, :string
7
10
  preference :transaction_fee_fix, :string
8
11
  preference :transaction_fee_percentage, :string
9
12
  preference :public_key, :text
13
+ preference :abapay_khqr_deeplink_option, :string, default: 'open_both'
10
14
 
11
15
  validates :preferred_public_key, presence: true, if: :enable_pre_auth?
16
+ validates :preferred_abapay_khqr_deeplink_option, inclusion: { in: ABAPAY_KHQR_DEEPLINK_OPTIONS }, if: :abapay_khqr_deeplink?
17
+ validates :preferred_payment_option, inclusion: { in: PAYMENT_OPTIONS }
12
18
 
13
19
  # override: partial to render in admin
14
20
  def method_type
15
21
  'payway_v2'
16
22
  end
17
23
 
24
+ def abapay_khqr_deeplink?
25
+ preferred_payment_option == 'abapay_khqr_deeplink'
26
+ end
27
+
28
+ def open_abapay_deeplink?
29
+ preferred_abapay_khqr_deeplink_option.in?(%w[open_both open_deeplink_only])
30
+ end
31
+
32
+ def open_checkout_url?
33
+ preferred_abapay_khqr_deeplink_option.in?(%w[open_both open_checkout_url_only])
34
+ end
35
+
18
36
  # override
19
37
  def default_payout_profile
20
38
  Spree::PayoutProfiles::PaywayV2.default
@@ -0,0 +1,35 @@
1
+ <%# This partial listens to payment status changes and does not process the payment. %>
2
+ <%# When it detects a status change, it automatically redirects to the processing URL for actual processing. %>
3
+ <%# Designed to be used in checkout.html.erb %>
4
+
5
+ <script>
6
+ document.addEventListener("DOMContentLoaded", function() {
7
+ let firebaseConfigs = <%= Rails.application.credentials.firebase_web_config.to_json.html_safe %>;
8
+
9
+ window.listenToProcessingState({
10
+ firebaseConfigs: firebaseConfigs,
11
+ documentReferencePath: "<%= @payment.user_informer.document_reference_path %>",
12
+ onPaymentIsProcessing: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
13
+ window.location.href = "<%= @payment.processing_url %>";
14
+ },
15
+ onPaymentIsRetrying: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
16
+ window.location.href = "<%= @payment.processing_url %>";
17
+ },
18
+ onOrderIsProcessing: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
19
+ window.location.href = "<%= @payment.processing_url %>";
20
+ },
21
+ onOrderIsCompleted: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
22
+ window.location.href = "<%= @payment.processing_url %>";
23
+ },
24
+ onOrderProcessFailed: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
25
+ window.location.href = "<%= @payment.processing_url %>";
26
+ },
27
+ onPaymentProcessFailed: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
28
+ window.location.href = "<%= @payment.processing_url %>";
29
+ },
30
+ onCompleted: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
31
+ window.location.href = "<%= @payment.success_url %>";
32
+ },
33
+ });
34
+ });
35
+ </script>
@@ -1,3 +1,9 @@
1
1
  <h1>Checkout...</h1>
2
2
 
3
- <%= render_form %>
3
+ <%# Primary action button fixed at bottom of screen %>
4
+ <%# Each payment method can customize this button (title, onclick) for their specific action. %>
5
+ <%# See: app/views/spree/vpago_payments/forms/spree/gateway/_payway_v2.html.erb for example %>
6
+ <button id="vpago_primary_button" style="display: none;"></button>
7
+
8
+ <%= render_payment_status_listener %>
9
+ <%= render_form %>
@@ -1,50 +1,77 @@
1
- <% @checkout = ::Vpago::PaywayV2::Checkout.new(@payment) %>
2
- <% @payment_option = @payment.payment_method.preferences[:payment_option] %>
3
-
4
- <form method="POST"
5
- action="<%= @checkout.checkout_url %>"
6
- id="aba_merchant_request"
7
- data-payment-option="<%= @payment_option %>"
8
- style="<%= 'display:none;' if @payment_option == 'abapay_khqr_deeplink' %>">
1
+ <% @checkout_options = { custom_return_deeplink_url: custom_return_deeplink_url } %>
2
+ <% @checkout = ::Vpago::PaywayV2::Checkout.new(@payment, @checkout_options) %>
9
3
 
4
+ <form method="POST" action="<%= @checkout.checkout_url %>" id="aba_merchant_request">
10
5
  <% @checkout.gateway_params.each do |key, value| %>
11
6
  <input type="hidden" name="<%= key %>" value="<%= value %>">
12
7
  <% end %>
13
8
  </form>
14
9
 
15
10
  <script>
16
- document.addEventListener("DOMContentLoaded", function () {
17
- const form = document.getElementById("aba_merchant_request");
18
- const paymentOption = form.dataset.paymentOption;
19
-
20
- if (paymentOption === "abapay_khqr_deeplink") {
21
-
22
- fetch(form.action, {
23
- method: "POST",
24
- body: new FormData(form)
25
- })
26
- .then(res => res.json())
27
- .then(data => {
28
- if (data.checkout_qr_url && data.abapay_deeplink) {
29
- // 1) Show checkout QR in this tab
30
- window.location.href = data.checkout_qr_url;
31
-
32
- // 2) Try to open the deeplink in a new tab
33
- setTimeout(() => {
34
- window.open(data.abapay_deeplink, "_blank");
35
- }, 5000);
36
- } else if (data.checkout_qr_url) {
37
- window.location.href = data.checkout_qr_url;
38
- } else if (data.abapay_deeplink) {
39
- window.location.href = data.abapay_deeplink;
40
- }
41
- })
42
- .catch(err => {
43
- console.error("Error:", err);
11
+ const isTelegram = <%= telegram_user_agent? %>;
12
+ const isMobile = <%= mobile_user_agent? %>;
13
+
14
+ const abapayKhqrDeeplink = "<%= @payment.payment_method.abapay_khqr_deeplink? %>";
15
+ const shouldOpenAbaPayDeeplink = isMobile && <%= @payment.payment_method.open_abapay_deeplink? %>;
16
+ const shouldOpenCheckoutUrl = <%= @payment.payment_method.open_checkout_url? %>;
17
+
18
+ function openDeeplink(abapay_deeplink) {
19
+ if(isTelegram){
20
+ window.open(abapay_deeplink, '_blank');
21
+ } else {
22
+ window.location.href = abapay_deeplink;
23
+ }
24
+ }
25
+
26
+ function openAbapayDeeplink(abapay_deeplink) {
27
+ document.getElementById("vpago_primary_button").style.display = "block";
28
+ document.getElementById("vpago_primary_button").innerText = "Open ABA Pay";
29
+ document.getElementById("vpago_primary_button").addEventListener("click", function() {
30
+ openDeeplink(abapay_deeplink)
44
31
  });
45
32
 
46
- } else {
47
- form.submit();
33
+ openDeeplink(abapay_deeplink)
48
34
  }
49
- });
50
- </script>
35
+
36
+ function openCheckoutUrl(checkout_qr_url, delay = 0) {
37
+ if(delay > 0) {
38
+ setTimeout(function() {
39
+ window.location.href = checkout_qr_url;
40
+ }, delay);
41
+ } else {
42
+ window.location.href = checkout_qr_url;
43
+ }
44
+ }
45
+
46
+ document.addEventListener("DOMContentLoaded", function () {
47
+ if (abapayKhqrDeeplink) {
48
+ var formData = new FormData(document.getElementById("aba_merchant_request"));
49
+ var checkoutUrl = document.getElementById("aba_merchant_request").action;
50
+
51
+ fetch(checkoutUrl, {
52
+ method: "POST",
53
+ body: formData
54
+ })
55
+ .then(function(response) {
56
+ return response.json();
57
+ })
58
+ .then(function(data) {
59
+ var shouldDelayBeforeOpenCheckoutUrl = false;
60
+
61
+ if (data.abapay_deeplink && shouldOpenAbaPayDeeplink) {
62
+ openAbapayDeeplink(data.abapay_deeplink);
63
+ shouldDelayBeforeOpenCheckoutUrl = true;
64
+ }
65
+
66
+ if (data.checkout_qr_url && shouldOpenCheckoutUrl) {
67
+ openCheckoutUrl(data.checkout_qr_url, shouldDelayBeforeOpenCheckoutUrl ? 500 : 0);
68
+ }
69
+ })
70
+ .catch(function(error) {
71
+ console.error("Payment request failed:", error);
72
+ });
73
+ } else {
74
+ document.getElementById("aba_merchant_request").submit();
75
+ }
76
+ })
77
+ </script>
@@ -1,7 +1,7 @@
1
1
  module SpreeVpago
2
2
  module_function
3
3
 
4
- VERSION = '2.2.2-pre15'.freeze
4
+ VERSION = '2.2.2-pre17'.freeze
5
5
 
6
6
  def version
7
7
  Gem::Version.new VERSION
@@ -4,6 +4,7 @@ module Vpago
4
4
  def initialize(payment, options = {})
5
5
  @options = options
6
6
  @payment = payment
7
+ @custom_return_deeplink_url = options[:custom_return_deeplink_url]
7
8
  end
8
9
 
9
10
  def req_time
@@ -76,8 +77,7 @@ module Vpago
76
77
  end
77
78
 
78
79
  def payment_option
79
- card_option = @payment.payment_method.preferences[:payment_option]
80
- Vpago::Payway::CARD_TYPES.index(card_option).nil? ? Vpago::Payway::CARD_TYPE_ABAPAY : card_option
80
+ @payment.payment_method.preferences[:payment_option]
81
81
  end
82
82
 
83
83
  # optional
@@ -105,6 +105,8 @@ module Vpago
105
105
  # redirect to continue URL, let it handle redirecting to app.
106
106
  # allowed override to specific app eg. from tg://t.me
107
107
  def return_deeplink_url
108
+ return @custom_return_deeplink_url if @custom_return_deeplink_url.present?
109
+
108
110
  app_scheme = @payment.payment_method.preferences[:app_scheme]
109
111
 
110
112
  if app_scheme.present?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_vpago
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.2.pre.pre15
4
+ version: 2.2.2.pre.pre17
5
5
  platform: ruby
6
6
  authors:
7
7
  - You
@@ -329,6 +329,7 @@ files:
329
329
  - app/views/spree/payway_results/success.html.erb
330
330
  - app/views/spree/payway_v2_card_popups/_form.html.erb
331
331
  - app/views/spree/payway_v2_card_popups/show.html.erb
332
+ - app/views/spree/vpago_payments/_payment_status_listener.html.erb
332
333
  - app/views/spree/vpago_payments/checkout.html.erb
333
334
  - app/views/spree/vpago_payments/forms/spree/gateway/_payway_v2.html.erb
334
335
  - app/views/spree/vpago_payments/forms/spree/gateway/_true_money.html.erb