spree_vpago 2.0.9.pre.beta9 → 2.0.9
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 +4 -4
- data/Gemfile.lock +3 -3
- data/app/assets/config/spree_vpago_manifest.js +0 -1
- data/app/helpers/vpago/admin/base_helper_decorator.rb +0 -1
- data/app/models/vpago/payment_decorator.rb +1 -5
- data/app/models/vpago/payment_method_decorator.rb +1 -7
- data/app/serializers/spree/v2/storefront/payment_serializer_decorator.rb +1 -1
- data/app/services/vpago/payment_processable.rb +1 -1
- data/app/services/vpago/payment_url_constructor.rb +2 -12
- data/app/services/vpago/rsa_handler.rb +1 -7
- data/app/views/layouts/vpago_payments.html.erb +0 -1
- data/app/views/spree/vpago_payments/forms/spree/gateway/_vattanac_mini_app.html.erb +81 -40
- data/lib/spree_vpago/engine.rb +1 -2
- data/lib/spree_vpago/version.rb +1 -1
- metadata +4 -12
- data/app/assets/javascripts/vpago/vpago_payments/payment_processing_listener.js +0 -46
- data/app/models/spree/gateway/true_money.rb +0 -91
- data/app/views/spree/admin/payments/source_views/_true_money.html.erb +0 -6
- data/app/views/spree/vpago_payments/forms/spree/gateway/_true_money.html.erb +0 -37
- data/lib/vpago/true_money/base.rb +0 -163
- data/lib/vpago/true_money/checkout.rb +0 -30
- data/lib/vpago/true_money/refund_issuer.rb +0 -21
- data/lib/vpago/true_money/transaction_status.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57be1c944cfc7c9b6f6836bc4cd263f8c0a837260d751f06749a2fc3d07f7aae
|
4
|
+
data.tar.gz: 50fff6ef2579d035dd6c4d38aa0aff975a1fc6f2e29d48c446b911e5300eecbd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12708c2c3c43f7bb9ea8f8a4678ff323e968ef8b309fcb365f36ad29a72e5bda8f4a55ae1c46dd389e309a8f98db29af81de72336acf4ed4c8f2387c4ac117a4
|
7
|
+
data.tar.gz: f3d2f44ff9e88e50a47305412beeaadd6a95b020971cc7fb1c1b8e01e25fd9f2f98211a6c9dc70295eb8c3e0ae9d151b8172451b982c38947bedcdf702f68da8
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
spree_vpago (2.0.9
|
4
|
+
spree_vpago (2.0.9)
|
5
5
|
faraday
|
6
6
|
google-cloud-firestore
|
7
7
|
spree_api (>= 4.5)
|
@@ -242,7 +242,7 @@ GEM
|
|
242
242
|
gapic-common (~> 1.0)
|
243
243
|
google-cloud-errors (~> 1.0)
|
244
244
|
google-logging-utils (0.2.0)
|
245
|
-
google-protobuf (4.31.1
|
245
|
+
google-protobuf (4.31.1)
|
246
246
|
bigdecimal
|
247
247
|
rake (>= 13)
|
248
248
|
googleapis-common-protos (1.8.0)
|
@@ -259,7 +259,7 @@ GEM
|
|
259
259
|
multi_json (~> 1.11)
|
260
260
|
os (>= 0.9, < 2.0)
|
261
261
|
signet (>= 0.16, < 2.a)
|
262
|
-
grpc (1.73.0
|
262
|
+
grpc (1.73.0)
|
263
263
|
google-protobuf (>= 3.25, < 5.0)
|
264
264
|
googleapis-common-protos-types (~> 1.0)
|
265
265
|
hashdiff (1.1.0)
|
@@ -5,7 +5,6 @@ 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,
|
9
8
|
:processing_url,
|
10
9
|
:success_url,
|
11
10
|
:process_payment_url,
|
@@ -57,13 +56,10 @@ module Vpago
|
|
57
56
|
pre_auth_status == 'CANCELLED'
|
58
57
|
end
|
59
58
|
|
60
|
-
def true_money_payment?
|
61
|
-
payment_method.type_true_money?
|
62
|
-
end
|
63
|
-
|
64
59
|
def vattanac_mini_app_payment?
|
65
60
|
payment_method.type_vattanac_mini_app?
|
66
61
|
end
|
62
|
+
|
67
63
|
end
|
68
64
|
end
|
69
65
|
|
@@ -6,7 +6,6 @@ module Vpago
|
|
6
6
|
TYPE_ACLEDA = 'Spree::Gateway::Acleda'.freeze
|
7
7
|
TYPE_ACLEDA_MOBILE = 'Spree::Gateway::AcledaMobile'.freeze
|
8
8
|
TYPE_VATTANAC_MINI_APP = 'Spree::Gateway::VattanacMiniApp'.freeze
|
9
|
-
TYPE_TRUE_MONEY = 'Spree::Gateway::TrueMoney'.freeze
|
10
9
|
|
11
10
|
def self.prepended(base)
|
12
11
|
base.preference :icon_name, :string, default: 'cheque'
|
@@ -19,8 +18,7 @@ module Vpago
|
|
19
18
|
Spree::PaymentMethod::TYPE_WINGSDK,
|
20
19
|
Spree::PaymentMethod::TYPE_ACLEDA,
|
21
20
|
Spree::PaymentMethod::TYPE_ACLEDA_MOBILE,
|
22
|
-
Spree::PaymentMethod::TYPE_VATTANAC_MINI_APP
|
23
|
-
Spree::PaymentMethod::TYPE_TRUE_MONEY
|
21
|
+
Spree::PaymentMethod::TYPE_VATTANAC_MINI_APP
|
24
22
|
]
|
25
23
|
end
|
26
24
|
end
|
@@ -93,10 +91,6 @@ module Vpago
|
|
93
91
|
def type_vattanac_mini_app?
|
94
92
|
type == Spree::PaymentMethod::TYPE_VATTANAC_MINI_APP
|
95
93
|
end
|
96
|
-
|
97
|
-
def type_true_money?
|
98
|
-
type == Spree::PaymentMethod::TYPE_TRUE_MONEY
|
99
|
-
end
|
100
94
|
end
|
101
95
|
end
|
102
96
|
|
@@ -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
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
@@ -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?
|
20
20
|
end
|
21
21
|
|
22
22
|
def extract_completer_failure_reason_code(error)
|
@@ -9,23 +9,13 @@ module Vpago
|
|
9
9
|
@order = payment.order
|
10
10
|
end
|
11
11
|
|
12
|
-
def checkout_url = "#{base_url}/vpago_payments/checkout?#{query}
|
13
|
-
def web_checkout_url = "#{base_url}/vpago_payments/checkout?#{query}&platform=web"
|
12
|
+
def checkout_url = "#{base_url}/vpago_payments/checkout?#{query}"
|
14
13
|
def processing_url = "#{base_url}/vpago_payments/processing?#{query}"
|
15
14
|
def success_url = "#{base_url}/vpago_payments/success?#{query}"
|
16
15
|
def process_payment_url = "#{base_url}/vpago_payments/process_payment?#{query}"
|
17
16
|
|
18
17
|
def query
|
19
|
-
{
|
20
|
-
payment_number: payment.number,
|
21
|
-
order_number: order.number,
|
22
|
-
order_jwt_token: order_jwt_token,
|
23
|
-
offsite_payment: offsite_payment? ? true : nil
|
24
|
-
}.compact.to_query
|
25
|
-
end
|
26
|
-
|
27
|
-
def offsite_payment?
|
28
|
-
payment.payment_method.type_true_money?
|
18
|
+
{ payment_number: payment.number, order_number: order.number, order_jwt_token: order_jwt_token }.to_query
|
29
19
|
end
|
30
20
|
|
31
21
|
private
|
@@ -23,11 +23,5 @@ module Vpago
|
|
23
23
|
signature_bytes = Base64.decode64(signature)
|
24
24
|
public_key_object.verify(OpenSSL::Digest.new('SHA256'), signature_bytes, data)
|
25
25
|
end
|
26
|
-
|
27
|
-
def generate_signature(payload)
|
28
|
-
sign_hash = OpenSSL::Digest.new('SHA256')
|
29
|
-
private_key = OpenSSL::PKey::RSA.new(@private_key)
|
30
|
-
Base64.strict_encode64(private_key.sign(sign_hash, payload))
|
31
|
-
end
|
32
26
|
end
|
33
|
-
end
|
27
|
+
end
|
@@ -8,7 +8,6 @@
|
|
8
8
|
<%= csrf_meta_tags %>
|
9
9
|
<%= csp_meta_tag %>
|
10
10
|
|
11
|
-
<%= javascript_include_tag "vpago/vpago_payments/payment_processing_listener", 'data-turbo-track': 'reload' %>
|
12
11
|
<%= javascript_include_tag "vpago/vpago_payments/request_process_payment", 'data-turbo-track': 'reload' %>
|
13
12
|
<%= javascript_include_tag "vpago/vpago_payments/user_informers/#{user_informer}", 'data-turbo-track': 'reload' %>
|
14
13
|
</head>
|
@@ -2,51 +2,92 @@
|
|
2
2
|
<% @payment.user_informer.payment_is_processing(processing: true) %>
|
3
3
|
|
4
4
|
<p id="unsupported-message"
|
5
|
-
style="margin-top: 10px;
|
5
|
+
style="margin-top: 10px;
|
6
|
+
font-weight: bold;
|
7
|
+
color: red;
|
8
|
+
display: none;">
|
6
9
|
</p>
|
7
10
|
|
8
11
|
<script>
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
}
|
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 %>"
|
34
24
|
};
|
35
25
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
+
}
|
40
35
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
+
},
|
55
|
+
|
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
|
+
});
|
51
92
|
});
|
52
93
|
</script>
|
data/lib/spree_vpago/engine.rb
CHANGED
data/lib/spree_vpago/version.rb
CHANGED
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.9
|
4
|
+
version: 2.0.9
|
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-
|
11
|
+
date: 2025-07-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -134,7 +134,6 @@ 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
|
138
137
|
- app/assets/javascripts/vpago/vpago_payments/request_process_payment.js
|
139
138
|
- app/assets/javascripts/vpago/vpago_payments/user_informers/firebase.js
|
140
139
|
- app/controllers/.gitkeep
|
@@ -180,7 +179,6 @@ files:
|
|
180
179
|
- app/models/spree/gateway/acleda_mobile.rb
|
181
180
|
- app/models/spree/gateway/payway.rb
|
182
181
|
- app/models/spree/gateway/payway_v2.rb
|
183
|
-
- app/models/spree/gateway/true_money.rb
|
184
182
|
- app/models/spree/gateway/vattanac_mini_app.rb
|
185
183
|
- app/models/spree/gateway/wing_sdk.rb
|
186
184
|
- app/models/spree/payout.rb
|
@@ -264,7 +262,6 @@ files:
|
|
264
262
|
- app/views/spree/admin/payments/source_views/_acleda_mobile.html.erb
|
265
263
|
- app/views/spree/admin/payments/source_views/_payment_payway.html.erb
|
266
264
|
- app/views/spree/admin/payments/source_views/_payway_v2.html.erb
|
267
|
-
- app/views/spree/admin/payments/source_views/_true_money.html.erb
|
268
265
|
- app/views/spree/admin/payments/source_views/_vattanac_mini_app.html.erb
|
269
266
|
- app/views/spree/admin/payments/source_views/_vpago_payment_tmpl.html.erb
|
270
267
|
- app/views/spree/admin/payments/source_views/_wingsdk.html.erb
|
@@ -312,7 +309,6 @@ files:
|
|
312
309
|
- app/views/spree/payway_v2_card_popups/show.html.erb
|
313
310
|
- app/views/spree/vpago_payments/checkout.html.erb
|
314
311
|
- app/views/spree/vpago_payments/forms/spree/gateway/_payway_v2.html.erb
|
315
|
-
- app/views/spree/vpago_payments/forms/spree/gateway/_true_money.html.erb
|
316
312
|
- app/views/spree/vpago_payments/forms/spree/gateway/_vattanac_mini_app.html.erb
|
317
313
|
- app/views/spree/vpago_payments/processing.html.erb
|
318
314
|
- app/views/spree/vpago_payments/success.html.erb
|
@@ -382,10 +378,6 @@ files:
|
|
382
378
|
- lib/vpago/payway_v2/pre_auth_canceler.rb
|
383
379
|
- lib/vpago/payway_v2/pre_auth_completer.rb
|
384
380
|
- lib/vpago/payway_v2/transaction_status.rb
|
385
|
-
- lib/vpago/true_money/base.rb
|
386
|
-
- lib/vpago/true_money/checkout.rb
|
387
|
-
- lib/vpago/true_money/refund_issuer.rb
|
388
|
-
- lib/vpago/true_money/transaction_status.rb
|
389
381
|
- lib/vpago/vattanac_mini_app/base.rb
|
390
382
|
- lib/vpago/vattanac_mini_app/checkout.rb
|
391
383
|
- lib/vpago/vattanac_mini_app/refund_issuer.rb
|
@@ -416,9 +408,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
416
408
|
version: 3.2.0
|
417
409
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
418
410
|
requirements:
|
419
|
-
- - "
|
411
|
+
- - ">="
|
420
412
|
- !ruby/object:Gem::Version
|
421
|
-
version:
|
413
|
+
version: '0'
|
422
414
|
requirements:
|
423
415
|
- none
|
424
416
|
rubygems_version: 3.4.1
|
@@ -1,46 +0,0 @@
|
|
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
|
-
};
|
@@ -1,91 +0,0 @@
|
|
1
|
-
module Spree
|
2
|
-
class Gateway::TrueMoney < PaymentMethod
|
3
|
-
preference :check_transaction_url, :string
|
4
|
-
preference :refund_url, :string
|
5
|
-
preference :generate_payment_url, :string
|
6
|
-
preference :access_token_url, :string
|
7
|
-
|
8
|
-
preference :client_id, :string
|
9
|
-
preference :client_secret, :string
|
10
|
-
preference :private_key, :text
|
11
|
-
preference :return_url_scheme, :string
|
12
|
-
preference :android_package_name, :string
|
13
|
-
preference :redirect_type, :string
|
14
|
-
|
15
|
-
def method_type
|
16
|
-
'true_money'
|
17
|
-
end
|
18
|
-
|
19
|
-
def payment_source_class
|
20
|
-
Spree::VpagoPaymentSource
|
21
|
-
end
|
22
|
-
|
23
|
-
# force to purchase instead of authorize
|
24
|
-
def auto_capture?
|
25
|
-
true
|
26
|
-
end
|
27
|
-
|
28
|
-
# override
|
29
|
-
# purchase is used when pre auth disabled
|
30
|
-
def purchase(_amount, _source, gateway_options = {})
|
31
|
-
_, payment_number = gateway_options[:order_id].split('-')
|
32
|
-
payment = Spree::Payment.find_by(number: payment_number)
|
33
|
-
|
34
|
-
checker = check_transaction(payment)
|
35
|
-
payment.update(transaction_response: checker.json_response)
|
36
|
-
|
37
|
-
success = checker.success?
|
38
|
-
params = {}
|
39
|
-
|
40
|
-
params[:payment_response] = payment.transaction_response
|
41
|
-
|
42
|
-
if success
|
43
|
-
ActiveMerchant::Billing::Response.new(true, 'Payway Gateway: Purchased', params)
|
44
|
-
else
|
45
|
-
ActiveMerchant::Billing::Response.new(false, 'Payway Gateway: Purchasing Failed', params)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
# override
|
50
|
-
def void(_response_code, gateway_options)
|
51
|
-
_, payment_number = gateway_options[:order_id].split('-')
|
52
|
-
payment = Spree::Payment.find_by(number: payment_number)
|
53
|
-
|
54
|
-
if payment.true_money_payment?
|
55
|
-
params = {}
|
56
|
-
success, params[:refund_response] = true_money_refund(payment)
|
57
|
-
|
58
|
-
if success
|
59
|
-
ActiveMerchant::Billing::Response.new(true, 'True money Gateway: successfully canceled.', params)
|
60
|
-
else
|
61
|
-
ActiveMerchant::Billing::Response.new(false, 'True money Gateway: Failed to canceleed', params)
|
62
|
-
end
|
63
|
-
else
|
64
|
-
ActiveMerchant::Billing::Response.new(true, 'True money Gateway: Payment has been voided.')
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def true_money_refund(payment)
|
69
|
-
refund_issuer = Vpago::TrueMoney::RefundIssuer.new(payment, {})
|
70
|
-
refund_issuer.call
|
71
|
-
|
72
|
-
[refund_issuer.success?, refund_issuer.parsed_response]
|
73
|
-
end
|
74
|
-
|
75
|
-
def cancel(_response_code, _payment)
|
76
|
-
# we can use this to send request to payment gateway api to cancel the payment ( void )
|
77
|
-
# currently True money does not support to cancel the gateway
|
78
|
-
|
79
|
-
# in our case don't do anything
|
80
|
-
ActiveMerchant::Billing::Response.new(true, '')
|
81
|
-
end
|
82
|
-
|
83
|
-
private
|
84
|
-
|
85
|
-
def check_transaction(payment)
|
86
|
-
checker = Vpago::TrueMoney::TransactionStatus.new(payment)
|
87
|
-
checker.call
|
88
|
-
checker
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
<% @checkout = ::Vpago::TrueMoney::Checkout.new(@payment) %>
|
2
|
-
<% redirect_urls = @checkout.generate_payment_urls(params[:platform]) %>
|
3
|
-
<% @payment.user_informer.payment_is_processing(processing: true) %>
|
4
|
-
|
5
|
-
<script>
|
6
|
-
document.addEventListener("DOMContentLoaded", () => {
|
7
|
-
const platform = "<%= params[:platform] %>";
|
8
|
-
const redirectUrls = <%= redirect_urls.to_json.html_safe %>;
|
9
|
-
const confirmButton = document.getElementById("confirm-payment-button");
|
10
|
-
const firebaseConfigs = <%= Rails.application.credentials.firebase_web_config.to_json.html_safe %>;
|
11
|
-
const docRefPath = "<%= @payment.user_informer.document_reference_path %>";
|
12
|
-
const successUrl = "<%= @payment.success_url %>";
|
13
|
-
|
14
|
-
function setupConfirmPaymentButton() {
|
15
|
-
if (platform === "app") {
|
16
|
-
window.location.href = redirectUrls.deeplink;
|
17
|
-
setTimeout(() => {
|
18
|
-
window.location.href = redirectUrls.webview;
|
19
|
-
}, 1500);
|
20
|
-
} else if (confirmButton) {
|
21
|
-
confirmButton.addEventListener("click", () => {
|
22
|
-
window.open(redirectUrls.webview, '_blank');
|
23
|
-
});
|
24
|
-
}
|
25
|
-
}
|
26
|
-
|
27
|
-
function setupPaymentProcessingListener() {
|
28
|
-
if (window.initPaymentProcessingListener) {
|
29
|
-
window.initPaymentProcessingListener(firebaseConfigs, docRefPath, successUrl);
|
30
|
-
} else {
|
31
|
-
console.warn("initPaymentProcessingListener is not defined");
|
32
|
-
}
|
33
|
-
}
|
34
|
-
setupConfirmPaymentButton();
|
35
|
-
setupPaymentProcessingListener();
|
36
|
-
});
|
37
|
-
</script>
|
@@ -1,163 +0,0 @@
|
|
1
|
-
module Vpago
|
2
|
-
module TrueMoney
|
3
|
-
class Base
|
4
|
-
TOKEN_HEADERS = { 'Content-Type' => 'application/x-www-form-urlencoded' }.freeze
|
5
|
-
CONTENT_TYPE_JSON = 'application/json'.freeze
|
6
|
-
DEFAULT_ALGORITHM = 'rsa-sha256'.freeze
|
7
|
-
DEFAULT_KEY_VERSION = 1
|
8
|
-
|
9
|
-
def initialize(payment, options = {})
|
10
|
-
@payment = payment
|
11
|
-
@options = options
|
12
|
-
end
|
13
|
-
|
14
|
-
def client_id
|
15
|
-
payment_method.preferred_client_id
|
16
|
-
end
|
17
|
-
|
18
|
-
def client_secret
|
19
|
-
payment_method.preferred_client_secret
|
20
|
-
end
|
21
|
-
|
22
|
-
def private_key
|
23
|
-
payment_method.preferred_private_key
|
24
|
-
end
|
25
|
-
|
26
|
-
def redirect_type
|
27
|
-
payment_method.preferred_redirect_type
|
28
|
-
end
|
29
|
-
|
30
|
-
def external_ref_id
|
31
|
-
@payment.number
|
32
|
-
end
|
33
|
-
|
34
|
-
def service_type = '01'
|
35
|
-
def currency = 'USD'
|
36
|
-
def user_type = 'CUSTOMER'
|
37
|
-
|
38
|
-
def amount
|
39
|
-
@payment.amount
|
40
|
-
end
|
41
|
-
|
42
|
-
def timestamp
|
43
|
-
@timestamp ||= Time.now.to_i
|
44
|
-
end
|
45
|
-
|
46
|
-
def access_token
|
47
|
-
@access_token ||= fetch_access_token
|
48
|
-
end
|
49
|
-
|
50
|
-
def payload
|
51
|
-
{
|
52
|
-
service_type: service_type,
|
53
|
-
external_ref_id: external_ref_id,
|
54
|
-
amount: amount,
|
55
|
-
currency: currency,
|
56
|
-
user_type: user_type
|
57
|
-
}
|
58
|
-
end
|
59
|
-
|
60
|
-
def signature
|
61
|
-
Vpago::RsaHandler
|
62
|
-
.new(private_key: private_key)
|
63
|
-
.generate_signature(signature_input)
|
64
|
-
end
|
65
|
-
|
66
|
-
def default_headers
|
67
|
-
{
|
68
|
-
'Client-Id' => client_id,
|
69
|
-
'Authorization' => "Bearer #{access_token}",
|
70
|
-
'Signature' => "algorithm=#{algorithm};keyVersion=#{key_version};signature=#{signature}",
|
71
|
-
'Timestamp' => timestamp.to_s,
|
72
|
-
'Content-Type' => CONTENT_TYPE_JSON
|
73
|
-
}
|
74
|
-
end
|
75
|
-
|
76
|
-
def check_transaction_url
|
77
|
-
"#{payment_method.preferred_check_transaction_url}/#{external_ref_id}"
|
78
|
-
end
|
79
|
-
|
80
|
-
def refund_url
|
81
|
-
payment_method.preferred_refund_url
|
82
|
-
end
|
83
|
-
|
84
|
-
def generate_payment_url
|
85
|
-
payment_method.preferred_generate_payment_url
|
86
|
-
end
|
87
|
-
|
88
|
-
def access_token_url
|
89
|
-
payment_method.preferred_access_token_url
|
90
|
-
end
|
91
|
-
|
92
|
-
def android_package_name
|
93
|
-
payment_method.preferred_android_package_name
|
94
|
-
end
|
95
|
-
|
96
|
-
def parse_json(body)
|
97
|
-
JSON.parse(body)
|
98
|
-
rescue JSON::ParserError
|
99
|
-
{}
|
100
|
-
end
|
101
|
-
|
102
|
-
def fetch_access_token
|
103
|
-
response = Faraday.post(
|
104
|
-
access_token_url,
|
105
|
-
URI.encode_www_form(
|
106
|
-
grant_type: 'client_credentials',
|
107
|
-
client_id: client_id,
|
108
|
-
client_secret: client_secret
|
109
|
-
),
|
110
|
-
TOKEN_HEADERS
|
111
|
-
)
|
112
|
-
|
113
|
-
raise "Access Token Error: #{response.status} - #{response.body}" unless response.success?
|
114
|
-
|
115
|
-
JSON.parse(response.body).fetch('access_token')
|
116
|
-
end
|
117
|
-
|
118
|
-
def return_url_scheme
|
119
|
-
payment_method.preferred_return_url_scheme
|
120
|
-
end
|
121
|
-
|
122
|
-
def return_deeplink
|
123
|
-
"#{return_url_scheme}vpago_payments/processing?#{query_string}"
|
124
|
-
end
|
125
|
-
|
126
|
-
def query_string
|
127
|
-
{
|
128
|
-
payment_number: external_ref_id,
|
129
|
-
order_number: order.number,
|
130
|
-
order_jwt_token: order_jwt_token
|
131
|
-
}.to_param
|
132
|
-
end
|
133
|
-
|
134
|
-
def order_jwt_token
|
135
|
-
@order_jwt_token ||= JWT.encode(jwt_payload, order.token, 'HS256')
|
136
|
-
end
|
137
|
-
|
138
|
-
def order
|
139
|
-
@payment.order
|
140
|
-
end
|
141
|
-
|
142
|
-
def jwt_payload
|
143
|
-
{ order_number: order.number, order_id: order.id }
|
144
|
-
end
|
145
|
-
|
146
|
-
def payment_method
|
147
|
-
@payment.payment_method
|
148
|
-
end
|
149
|
-
|
150
|
-
def algorithm
|
151
|
-
DEFAULT_ALGORITHM
|
152
|
-
end
|
153
|
-
|
154
|
-
def key_version
|
155
|
-
DEFAULT_KEY_VERSION
|
156
|
-
end
|
157
|
-
|
158
|
-
def signature_input
|
159
|
-
"#{timestamp}#{payload.to_json}"
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module Vpago
|
2
|
-
module TrueMoney
|
3
|
-
class Checkout < Base
|
4
|
-
def generate_payment_urls(_platform)
|
5
|
-
request_body = {
|
6
|
-
payment_info: payload.to_json,
|
7
|
-
redirectionType: redirect_type,
|
8
|
-
merchantDeepLink: return_deeplink,
|
9
|
-
merchantAndroidPackageName: android_package_name,
|
10
|
-
refererLink: @payment.processing_url
|
11
|
-
}
|
12
|
-
|
13
|
-
response = Faraday.post(generate_payment_url) do |req|
|
14
|
-
req.headers = default_headers
|
15
|
-
req.body = request_body.to_json
|
16
|
-
end
|
17
|
-
|
18
|
-
body = parse_json(response.body)
|
19
|
-
|
20
|
-
{
|
21
|
-
webview: body['data']['webview'],
|
22
|
-
deeplink: body['data']['deeplink']
|
23
|
-
}
|
24
|
-
rescue Faraday::Error, JSON::ParserError, NoMethodError => e
|
25
|
-
Rails.logger.error("Failed to generate payment URL: #{e.class} - #{e.message}")
|
26
|
-
raise
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Vpago
|
2
|
-
module TrueMoney
|
3
|
-
class RefundIssuer < Base
|
4
|
-
def call
|
5
|
-
@response = Faraday.post(refund_url, payload.to_json, default_headers)
|
6
|
-
end
|
7
|
-
|
8
|
-
def success?
|
9
|
-
parsed_response.dig('status', 'code') == '000001'
|
10
|
-
end
|
11
|
-
|
12
|
-
def payload
|
13
|
-
{ external_ref_id: external_ref_id }
|
14
|
-
end
|
15
|
-
|
16
|
-
def parsed_response
|
17
|
-
@parsed_response ||= parse_json(@response.body)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module Vpago
|
2
|
-
module TrueMoney
|
3
|
-
class TransactionStatus < Base
|
4
|
-
def call
|
5
|
-
@response = Faraday.get(check_transaction_url, nil, default_headers)
|
6
|
-
end
|
7
|
-
|
8
|
-
def success?
|
9
|
-
response_code == '000001'
|
10
|
-
end
|
11
|
-
|
12
|
-
def response_code
|
13
|
-
json_response.dig('status', 'code')
|
14
|
-
end
|
15
|
-
|
16
|
-
def signature_input
|
17
|
-
timestamp.to_s
|
18
|
-
end
|
19
|
-
|
20
|
-
def json_response
|
21
|
-
@json_response ||= parse_json(@response.body)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|