spree_vpago 2.2.2.pre.pre24 → 2.2.2.pre.pre25
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 +1 -1
- data/app/assets/javascripts/vpago/vpago_payments/check_transaction_periodically.js +22 -2
- data/app/models/spree/gateway/payway_v2.rb +4 -0
- data/app/views/spree/vpago_payments/forms/spree/gateway/_payway_v2.html.erb +19 -3
- data/app/views/spree/vpago_payments/processing_scripts/spree/gateway/_payway_v2.html.erb +3 -3
- data/lib/spree_vpago/version.rb +1 -1
- data/lib/vpago/payway_v2/transaction_status.rb +30 -15
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 29529e321925044873800efe95fe7c33f3a160eb6e1834bc559a13643312e611
|
|
4
|
+
data.tar.gz: f981b34874e102697eabcc34c99241ceb1cde1f173c2606ba4c60e971c74e481
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 388ee4b184d978d3c618418e67371e7dc7117a86dad1a55e58241d06cf903d037282cd3cad479bcff2bfab8af57bda450c657a91a4ce468b223eed55b04aadc0
|
|
7
|
+
data.tar.gz: a2565dfd78710e26b006cceb23f2d6b5218f7d27cd728443894df95af5c00c4f615a134582e67d93e7c5e0e6e5174321e6a0d0f2ea0561d2b706bced8f23c688
|
data/Gemfile.lock
CHANGED
|
@@ -17,15 +17,31 @@ async function checkTransactionPeriodically({
|
|
|
17
17
|
var shouldPoll = true;
|
|
18
18
|
var intervalId;
|
|
19
19
|
var startTime = Date.now();
|
|
20
|
+
var pollCount = 0;
|
|
21
|
+
|
|
22
|
+
console.log("[Vpago] Starting transaction status polling", {
|
|
23
|
+
url: checkTransactionUrl,
|
|
24
|
+
maxDurationMs,
|
|
25
|
+
pollIntervalMs,
|
|
26
|
+
});
|
|
20
27
|
|
|
21
28
|
var pollStatus = function () {
|
|
22
|
-
if (shouldPoll) return;
|
|
29
|
+
if (!shouldPoll) return;
|
|
23
30
|
|
|
24
31
|
if (Date.now() - startTime >= maxDurationMs) {
|
|
32
|
+
console.warn(
|
|
33
|
+
"[Vpago] Polling timeout reached after " + pollCount + " attempts",
|
|
34
|
+
);
|
|
25
35
|
if (intervalId) clearInterval(intervalId);
|
|
26
36
|
return;
|
|
27
37
|
}
|
|
28
38
|
|
|
39
|
+
pollCount++;
|
|
40
|
+
var elapsedMs = Date.now() - startTime;
|
|
41
|
+
console.log(
|
|
42
|
+
"[Vpago] Poll attempt #" + pollCount + " (elapsed: " + elapsedMs + "ms)",
|
|
43
|
+
);
|
|
44
|
+
|
|
29
45
|
fetch(checkTransactionUrl, {
|
|
30
46
|
method: "GET",
|
|
31
47
|
headers: { Accept: "application/json" },
|
|
@@ -42,6 +58,8 @@ async function checkTransactionPeriodically({
|
|
|
42
58
|
? String(result.body.status)
|
|
43
59
|
: "pending";
|
|
44
60
|
|
|
61
|
+
console.log("[Vpago] Transaction status:", JSON.stringify(result.body));
|
|
62
|
+
|
|
45
63
|
if (status === "success" || status === "failed") {
|
|
46
64
|
shouldPoll = false;
|
|
47
65
|
if (intervalId) clearInterval(intervalId);
|
|
@@ -50,7 +68,9 @@ async function checkTransactionPeriodically({
|
|
|
50
68
|
if (status === "failed") onFailure(status);
|
|
51
69
|
}
|
|
52
70
|
})
|
|
53
|
-
.catch(function () {
|
|
71
|
+
.catch(function (error) {
|
|
72
|
+
console.error("[Vpago] Transaction status polling failed:", error);
|
|
73
|
+
});
|
|
54
74
|
};
|
|
55
75
|
|
|
56
76
|
intervalId = window.setInterval(pollStatus, pollIntervalMs);
|
|
@@ -19,6 +19,10 @@ module Spree
|
|
|
19
19
|
validates :preferred_abapay_khqr_deeplink_option, inclusion: { in: ABAPAY_KHQR_DEEPLINK_OPTIONS }, if: :abapay_khqr_deeplink?
|
|
20
20
|
validates :preferred_payment_option, inclusion: { in: PAYMENT_OPTIONS }
|
|
21
21
|
|
|
22
|
+
def reviewing_mode?
|
|
23
|
+
preferred_reviewing
|
|
24
|
+
end
|
|
25
|
+
|
|
22
26
|
# override: partial to render in admin
|
|
23
27
|
def method_type
|
|
24
28
|
'payway_v2'
|
|
@@ -33,13 +33,17 @@
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
function showRedirectContainer(buttonLabel, onClick) {
|
|
36
|
+
function showRedirectContainer(buttonLabel = null, onClick = null) {
|
|
37
37
|
const loadingContainer = document.getElementById('vpago_loading_container');
|
|
38
38
|
const redirectContainer = document.getElementById('vpago_redirect_container');
|
|
39
39
|
const redirectButton = document.getElementById('vpago_redirect_button');
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
if (buttonLabel && onClick) {
|
|
42
|
+
redirectButton.textContent = buttonLabel;
|
|
43
|
+
redirectButton.addEventListener('click', onClick);
|
|
44
|
+
} else {
|
|
45
|
+
redirectButton.style.display = 'none';
|
|
46
|
+
}
|
|
43
47
|
|
|
44
48
|
loadingContainer.style.display = 'none';
|
|
45
49
|
redirectContainer.style.removeProperty('display');
|
|
@@ -61,6 +65,18 @@
|
|
|
61
65
|
var shouldDelayBeforeOpenCheckoutUrl = false;
|
|
62
66
|
var shouldShowRedirectContainer = false;
|
|
63
67
|
|
|
68
|
+
console.log("[Vpago] checkout response data:", JSON.stringify(data));
|
|
69
|
+
|
|
70
|
+
// When status code is 4 (dublicated transaction),
|
|
71
|
+
// Possibly user refresh the checkout page even after the transaction is completed.
|
|
72
|
+
// So in this case, we should hide loading spinner and show redirect container UI
|
|
73
|
+
// While it check transaction status in the background. It will automatically redirect user to the result page after checking.
|
|
74
|
+
if (data.status.code === 4){
|
|
75
|
+
shouldShowRedirectContainer = true;
|
|
76
|
+
showRedirectContainer();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
64
80
|
if (data.abapay_deeplink && shouldOpenAbaPayDeeplink) {
|
|
65
81
|
openDeeplinkUrl(data.abapay_deeplink);
|
|
66
82
|
shouldDelayBeforeOpenCheckoutUrl = true;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<% if @payment.payment_method.
|
|
1
|
+
<% if @payment.payment_method.reviewing_mode? %>
|
|
2
2
|
<script>
|
|
3
3
|
// This block in /processing is purely JUST for review/audit purposes (ABA requirement).
|
|
4
4
|
// It checks the bank transaction status periodically without actually
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
document.addEventListener("DOMContentLoaded", function() {
|
|
18
18
|
window.checkTransactionPeriodically({
|
|
19
19
|
checkTransactionUrl: "<%= raw @payment.check_transaction_url %>",
|
|
20
|
-
onFailure: () => console.log("ABA Review Mode: bank transaction failed ❌"),
|
|
21
|
-
onSuccess: () => console.log("ABA Review Mode: bank transaction confirmed ✅"),
|
|
20
|
+
onFailure: () => console.log("[Vpago] ABA Review Mode: bank transaction failed ❌"),
|
|
21
|
+
onSuccess: () => console.log("[Vpago] ABA Review Mode: bank transaction confirmed ✅"),
|
|
22
22
|
maxDurationMs: 5 * 60 * 1000, // 5 minutes,
|
|
23
23
|
pollIntervalMs: 5000, // 5 seconds
|
|
24
24
|
})
|
data/lib/spree_vpago/version.rb
CHANGED
|
@@ -1,37 +1,52 @@
|
|
|
1
1
|
require 'faraday'
|
|
2
2
|
|
|
3
|
+
# API documentation:
|
|
4
|
+
# https://developer.payway.com.kh/check-transaction-14530826e0
|
|
3
5
|
module Vpago
|
|
4
6
|
module PaywayV2
|
|
5
7
|
class TransactionStatus < Base
|
|
6
|
-
# status:
|
|
7
|
-
# 0 – Approved, PRE_AUTH, PREAUTH_APPROVED
|
|
8
|
-
# 1 – Created
|
|
9
|
-
# 2 – Pending
|
|
10
|
-
# 3 – Declined
|
|
11
|
-
# 4 – Refunded
|
|
12
|
-
# 5 – Wrong Hash
|
|
13
|
-
# 7 - Cancelled
|
|
14
|
-
# 11 – Other Server-side Error
|
|
15
8
|
def call
|
|
16
9
|
@response = check_remote_status
|
|
17
10
|
end
|
|
18
11
|
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
# 00 : Success!
|
|
13
|
+
# 5 : Invalid hash
|
|
14
|
+
# 6 : Transaction not found
|
|
15
|
+
# 8 : Invalid merchant profile
|
|
16
|
+
# 11 : Internal server error
|
|
17
|
+
# 429 : Reach request limit
|
|
18
|
+
def status_code
|
|
19
|
+
status_data = json_response['status']
|
|
20
|
+
return nil unless status_data.is_a?(Hash)
|
|
21
|
+
|
|
22
|
+
status_data['code']
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# APPROVED : Transaction successfully completed with the full purchase amount.
|
|
26
|
+
# PRE-AUTH : Transaction successfully processed with a pre-authorization hold on funds pending final capture.
|
|
27
|
+
# REFUNDED : Transaction has been fully or partially refunded.
|
|
28
|
+
# PENDING : Transaction is awaiting payment completion by the payer.
|
|
29
|
+
# DECLINED : Transaction has been declined.
|
|
30
|
+
# CANCELLED : Merchant canceled the pre-authorization or closed the transaction.
|
|
31
|
+
def payment_status
|
|
32
|
+
data = json_response['data']
|
|
33
|
+
return nil unless data.is_a?(Hash)
|
|
34
|
+
|
|
35
|
+
data['payment_status']
|
|
21
36
|
end
|
|
22
37
|
|
|
23
38
|
def success?
|
|
24
|
-
|
|
39
|
+
%w[APPROVED PRE-AUTH].include?(payment_status)
|
|
25
40
|
end
|
|
26
41
|
|
|
27
42
|
# request failed does not mean payment failed.
|
|
28
43
|
# but it failed when status is failed.
|
|
29
44
|
def pending?
|
|
30
|
-
%w[
|
|
45
|
+
%w[PENDING].include?(payment_status)
|
|
31
46
|
end
|
|
32
47
|
|
|
33
48
|
def failed?
|
|
34
|
-
%w[
|
|
49
|
+
%w[5 6 8].include?(status_code) || %w[DECLINED CANCELLED].include?(payment_status)
|
|
35
50
|
end
|
|
36
51
|
|
|
37
52
|
def check_remote_status
|
|
@@ -76,7 +91,7 @@ module Vpago
|
|
|
76
91
|
# somehow php counter part are not able to decode if the \n present.
|
|
77
92
|
hash.delete("\n")
|
|
78
93
|
end
|
|
79
|
-
|
|
94
|
+
|
|
80
95
|
def check_transaction_url
|
|
81
96
|
"#{host}/api/payment-gateway/v1/payments/check-transaction-2"
|
|
82
97
|
end
|