check payment status is not working if the ws server is down

This commit is contained in:
aungthetkhaing
2025-06-10 15:00:44 +06:30
parent 5b374dc48f
commit edccfa0f7b

View File

@@ -253,140 +253,151 @@
<script defer type="text/javascript"> <script defer type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
const $paymentWaiting = $('.payment-waiting'); const $paymentWaiting = $('.payment-waiting');
const amountToReceive = <%= number_with_precision(@sale_data.grand_total, precision: precision.to_i) %>; const amountToReceive = <%= number_with_precision(@sale_data.grand_total, precision: precision.to_i) %>;
const receiptNo = $('#receipt_no').text(); const receiptNo = $('#receipt_no').text();
let paymentProcessed = false; let paymentProcessed = false;
let fallbackTimeout; let fallbackTimeout;
let connected = false;
function handlePaymentSuccess(){ function handlePaymentSuccess() {
if(paymentProcessed) return; if (paymentProcessed) return;
paymentProcessed = true; paymentProcessed = true;
clearTimeout(fallbackTimeout); clearTimeout(fallbackTimeout);
$('#cancel-btn').hide(); $('#cancel-btn').hide();
$paymentWaiting.html(` $paymentWaiting.html(`
<img src="/image/mmqr.webp" alt="MMQR Payment" style="max-width: 120px; margin-bottom: 10px;"> <img src="/image/mmqr.webp" alt="MMQR Payment" style="max-width: 120px; margin-bottom: 10px;">
<div class="payment-success text-center"> <div class="payment-success text-center">
<i class="material-icons" style="font-size: 50px; color: #4CAF50;">check_circle</i> <i class="material-icons" style="font-size: 50px; color: #4CAF50;">check_circle</i>
<h3 class="m-t-20" style="color: #4CAF50;">Payment Successful!</h3> <h3 class="m-t-20" style="color: #4CAF50;">Payment Successful!</h3>
<p>Amount Received: ${amountToReceive}</p> <p>Amount Received: ${amountToReceive}</p>
</div> </div>
`); `);
$.ajax({ $.ajax({
url: '/foodcourt/qrpay/process_payment', url: '/foodcourt/qrpay/process_payment',
method: 'POST', method: 'POST',
contentType: 'application/json', contentType: 'application/json',
headers: { headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
data: JSON.stringify({ sale_id: "<%= @sale_data.sale_id %>" }),
success: (data) => {
if (data.status) {
customer_display_view({
msg: "Payment Successful",
paid_amount: amountToReceive,
receipt_no: receiptNo
}, "pay_success");
setTimeout(() => {
window.location.href = "/";
}, 2000);
}
},
error: (xhr, status, error) => {
console.log("Error:", error);
}
});
}
function checkPaymentStatus() {
$.ajax({
url: '/foodcourt/qrpay/check_payment_status',
method: 'POST',
contentType: 'application/json',
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
data: JSON.stringify({ receipt_no: receiptNo }),
success: function(response) {
if (response.status === "PAY_SUCCESS") {
handlePaymentSuccess();
} else if (response.status === "CONFIG_ERROR") {
clearTimeout(fallbackTimeout);
} else {
if (!paymentProcessed) {
fallbackTimeout = setTimeout(checkPaymentStatus, 5000);
}
}
},
error: function() {
if (!paymentProcessed) {
fallbackTimeout = setTimeout(checkPaymentStatus, 5000);
}
}
});
}
const cable = ActionCable.createConsumer("wss://juicecorner-0mo.sx-fc.app/cable");
const subscription = cable.subscriptions.create(
{
channel: "NagatoChannel",
receipt_no: receiptNo
}, },
{ data: JSON.stringify({ sale_id: "<%= @sale_data.sale_id %>" }),
connected() { success: (data) => {
if (data.status) {
customer_display_view({
msg: "Payment Successful",
paid_amount: amountToReceive,
receipt_no: receiptNo
}, "pay_success");
setTimeout(() => {
window.location.href = "/";
}, 2000);
}
},
error: (xhr, status, error) => {
console.log("Error:", error);
}
});
}
function checkPaymentStatus() {
$.ajax({
url: '/foodcourt/qrpay/check_payment_status',
method: 'POST',
contentType: 'application/json',
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
data: JSON.stringify({ receipt_no: receiptNo }),
success: function(response) {
if (response.status === "PAY_SUCCESS") {
handlePaymentSuccess();
} else if (response.status === "CONFIG_ERROR") {
clearTimeout(fallbackTimeout);
} else if (!paymentProcessed) {
fallbackTimeout = setTimeout(checkPaymentStatus, 5000);
}
},
error: function() {
if (!paymentProcessed) {
fallbackTimeout = setTimeout(checkPaymentStatus, 5000);
}
}
});
}
// ----- WebSocket Setup -----
const cable = ActionCable.createConsumer("wss://juicecorner-0mo.sx-fc.app/cable");
const subscription = cable.subscriptions.create(
{
channel: "NagatoChannel",
receipt_no: receiptNo
},
{
connected() {
console.log("Nagato channel connected"); console.log("Nagato channel connected");
connected = true;
fallbackTimeout = setTimeout(checkPaymentStatus, 30000); fallbackTimeout = setTimeout(checkPaymentStatus, 30000);
}, },
received(data) { received(data) {
console.log("Received:", data); console.log("Received:", data);
if (data.status === "PAY_SUCCESS" && !paymentProcessed) { if (data.status === "PAY_SUCCESS" && !paymentProcessed) {
clearTimeout(fallbackTimeout); clearTimeout(fallbackTimeout);
handlePaymentSuccess(); handlePaymentSuccess();
} }
}, },
disconnected() { disconnected() {
console.log("Nagato channel disconnected"); console.log("Nagato channel disconnected");
if (!paymentProcessed) {
fallbackTimeout = setTimeout(checkPaymentStatus, 30000); fallbackTimeout = setTimeout(checkPaymentStatus, 30000);
} }
} }
);
function customer_display_view(data, status) {
$.post('/foodcourt/customer_view', {
data: data,
status: status
}, function(result) {
}, 'json');
} }
);
$('#cancel-btn').on('click', function(e) { // Fallback if WebSocket doesn't connect within 5 seconds
const postData = { setTimeout(() => {
sale_id: "<%= @sale_data.sale_id %>" if (!connected) {
}; console.warn("WebSocket failed to connect — falling back to polling.");
checkPaymentStatus(); // start polling
}
}, 5000);
$.ajax({ function customer_display_view(data, status) {
url: '/foodcourt/qrpay/cancel', $.post('/foodcourt/customer_view', {
method: 'POST', data: data,
contentType: 'application/json', status: status
headers: { }, function(result) {}, 'json');
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') }
},
data: JSON.stringify(postData), $('#cancel-btn').on('click', function(e) {
success: function(data) { const postData = {
if (data.status) { sale_id: "<%= @sale_data.sale_id %>"
customer_display_view(null, "reload"); };
window.location.href = "/";
} $.ajax({
}, url: '/foodcourt/qrpay/cancel',
error: function(xhr, status, error) { method: 'POST',
console.log("Error:", error); contentType: 'application/json',
} headers: {
}); 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
data: JSON.stringify(postData),
success: function(data) {
if (data.status) {
customer_display_view(null, "reload");
window.location.href = "/";
}
},
error: function(xhr, status, error) {
console.log("Error:", error);
}
}); });
});
}); });
</script> </script>