|
@@ -396,6 +396,28 @@ else
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
+<!-- Payment source selection -->
|
|
|
|
|
+<div id="paymentSourceModal" class="fixed inset-0 bg-black/70 backdrop-blur-sm z-[190] hidden items-center justify-center p-4 font-bricolage">
|
|
|
|
|
+ <div class="bg-white w-full max-w-[350px] rounded-[28px] overflow-hidden shadow-2xl animate__animated animate__zoomIn animate__faster">
|
|
|
|
|
+ <div class="bg-[#0062FF] px-5 py-4 text-white text-center relative">
|
|
|
|
|
+ <h2 class="text-[19px] font-black">@Lang.millions_choose_account</h2>
|
|
|
|
|
+ <button type="button" onclick="hidePaymentSourceModal()" class="absolute right-3 top-3 w-9 h-9 rounded-full bg-white/15 flex items-center justify-center">
|
|
|
|
|
+ <i class="fa-solid fa-xmark"></i>
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="p-5 grid gap-3">
|
|
|
|
|
+ <button type="button" onclick="selectPaymentSource('@Constants.BASIC_WALLET_TICKET', this)" class="payment-source-button w-full border-2 border-[#0062FF] rounded-2xl px-4 py-4 flex items-center gap-4 text-left active:scale-[0.98] transition-all">
|
|
|
|
|
+ <span class="w-11 h-11 rounded-full bg-[#0062FF]/10 text-[#0062FF] flex items-center justify-center"><i class="fa-solid fa-mobile-screen-button text-xl"></i></span>
|
|
|
|
|
+ <span class="font-black text-[16px] text-gray-800">@Lang.basic_account</span>
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <button type="button" onclick="selectPaymentSource('@Constants.NATCASH_WALLET_TICKET', this)" class="payment-source-button w-full border-2 border-[#0A9800] rounded-2xl px-4 py-4 flex items-center gap-4 text-left active:scale-[0.98] transition-all">
|
|
|
|
|
+ <span class="w-11 h-11 rounded-full bg-[#0A9800]/10 text-[#0A9800] flex items-center justify-center"><i class="fa-solid fa-wallet text-xl"></i></span>
|
|
|
|
|
+ <span class="font-black text-[16px] text-gray-800">@Lang.NatCash</span>
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</div>
|
|
|
|
|
+
|
|
|
<!-- OTP Verification Modal (V2 Design Overhaul - Matching Figma) -->
|
|
<!-- OTP Verification Modal (V2 Design Overhaul - Matching Figma) -->
|
|
|
<div id="otpModal" class="fixed inset-0 bg-black/80 backdrop-blur-sm z-[200] hidden items-center justify-center p-4">
|
|
<div id="otpModal" class="fixed inset-0 bg-black/80 backdrop-blur-sm z-[200] hidden items-center justify-center p-4">
|
|
|
|
|
|
|
@@ -960,6 +982,8 @@ else
|
|
|
|
|
|
|
|
// --- Order Summary Modal Logic ---
|
|
// --- Order Summary Modal Logic ---
|
|
|
// --- Payment Preparation & Order Summary Logic ---
|
|
// --- Payment Preparation & Order Summary Logic ---
|
|
|
|
|
+ let pendingPaymentRequest = null;
|
|
|
|
|
+
|
|
|
function preparePayment(event) {
|
|
function preparePayment(event) {
|
|
|
const isBSMode = @(Model.termType == Constants.PIC10_BIGSMALL_CODE || Model.termType == Constants.PIC10_ODDEVEN_CODE ? "true" : "false");
|
|
const isBSMode = @(Model.termType == Constants.PIC10_BIGSMALL_CODE || Model.termType == Constants.PIC10_ODDEVEN_CODE ? "true" : "false");
|
|
|
const tickets = [];
|
|
const tickets = [];
|
|
@@ -1001,52 +1025,18 @@ else
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const requestData = {
|
|
|
|
|
|
|
+ pendingPaymentRequest = {
|
|
|
gameId: "@Model.termType",
|
|
gameId: "@Model.termType",
|
|
|
ticket: tickets
|
|
ticket: tickets
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- const btn = event ? event.currentTarget : null;
|
|
|
|
|
- const originalText = btn ? btn.innerHTML : "@Lang.millions_payment";
|
|
|
|
|
- if (btn) {
|
|
|
|
|
- btn.innerHTML = '<i class="fa-solid fa-circle-notch fa-spin"></i> Loading...';
|
|
|
|
|
- btn.disabled = true;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- $.ajax({
|
|
|
|
|
- url: subDomain + '@Url.Action("ConfirmTicketData", "Home")',
|
|
|
|
|
- type: 'POST',
|
|
|
|
|
- contentType: 'application/json',
|
|
|
|
|
- data: JSON.stringify(requestData),
|
|
|
|
|
- success: function(data) {
|
|
|
|
|
-
|
|
|
|
|
- if (btn) {
|
|
|
|
|
- btn.innerHTML = originalText;
|
|
|
|
|
- btn.disabled = false;
|
|
|
|
|
- }
|
|
|
|
|
- if (data.responseCode === "0") {
|
|
|
|
|
- showOrderSummary(data, tickets);
|
|
|
|
|
- } else {
|
|
|
|
|
- showNotification(data.responseMessage || "Confirmation failed", data.responseCode);
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- error: function(err) {
|
|
|
|
|
-
|
|
|
|
|
- if (btn) {
|
|
|
|
|
- btn.innerHTML = originalText;
|
|
|
|
|
- btn.disabled = false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- showNotification("Network error occurred.", "warning");
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ showOrderSummary(null, tickets);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
let currentTransId = null;
|
|
let currentTransId = null;
|
|
|
|
|
|
|
|
function showOrderSummary(apiData, localTickets) {
|
|
function showOrderSummary(apiData, localTickets) {
|
|
|
- currentTransId = apiData.transId;
|
|
|
|
|
|
|
+ currentTransId = apiData ? apiData.transId : null;
|
|
|
const summaryModal = $("#orderSummaryModal");
|
|
const summaryModal = $("#orderSummaryModal");
|
|
|
const summaryList = $("#summaryTicketList");
|
|
const summaryList = $("#summaryTicketList");
|
|
|
summaryList.empty();
|
|
summaryList.empty();
|
|
@@ -1099,7 +1089,9 @@ else
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
$("#summaryTotalCount").text(displayTickets.length);
|
|
$("#summaryTotalCount").text(displayTickets.length);
|
|
|
- const totalMoney = apiData.totalMoneyPayment || apiData.totalMoney || "0";
|
|
|
|
|
|
|
+ const totalMoney = apiData
|
|
|
|
|
+ ? (apiData.totalMoneyPayment || apiData.totalMoney || "0")
|
|
|
|
|
+ : displayTickets.reduce((sum, ticket) => sum + (parseInt(ticket.money, 10) || 0), 0);
|
|
|
$("#summaryTotalAmount").text(formatMoneyV2(totalMoney));
|
|
$("#summaryTotalAmount").text(formatMoneyV2(totalMoney));
|
|
|
|
|
|
|
|
summaryModal.removeClass("hidden").addClass("flex");
|
|
summaryModal.removeClass("hidden").addClass("flex");
|
|
@@ -1110,24 +1102,74 @@ else
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function confirmCheckout(btn) {
|
|
function confirmCheckout(btn) {
|
|
|
|
|
+ if (!pendingPaymentRequest) {
|
|
|
|
|
+ showNotification("@Lang.millions_ticket_not_valid", "warning");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $("#paymentSourceModal").removeClass("hidden").addClass("flex");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function hidePaymentSourceModal() {
|
|
|
|
|
+ $("#paymentSourceModal").removeClass("flex").addClass("hidden");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function selectPaymentSource(paymentSource, btn) {
|
|
|
const originalText = $(btn).html();
|
|
const originalText = $(btn).html();
|
|
|
- $(btn).prop('disabled', true).html('<i class="fa-solid fa-spinner fa-spin mr-2"></i>Processing...');
|
|
|
|
|
|
|
+ const sourceButtons = $(".payment-source-button");
|
|
|
|
|
+ sourceButtons.prop('disabled', true);
|
|
|
|
|
+ $(btn).html('<i class="fa-solid fa-spinner fa-spin mr-2"></i>Processing...');
|
|
|
|
|
|
|
|
- // Trigger SendOTP API
|
|
|
|
|
|
|
+ $.ajax({
|
|
|
|
|
+ url: subDomain + '@Url.Action("PrepareTicketPayment", "Home")',
|
|
|
|
|
+ type: 'POST',
|
|
|
|
|
+ contentType: 'application/json',
|
|
|
|
|
+ data: JSON.stringify({
|
|
|
|
|
+ paymentSource: paymentSource,
|
|
|
|
|
+ ticketData: pendingPaymentRequest
|
|
|
|
|
+ }),
|
|
|
|
|
+ success: function(data) {
|
|
|
|
|
+ sourceButtons.prop('disabled', false);
|
|
|
|
|
+ $(btn).html(originalText);
|
|
|
|
|
+ if (data.responseCode !== "0") {
|
|
|
|
|
+ showNotification(data.responseMessage || "Confirmation failed", data.responseCode);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ currentTransId = data.transId;
|
|
|
|
|
+
|
|
|
|
|
+ if (paymentSource === '@Constants.NATCASH_WALLET_TICKET') {
|
|
|
|
|
+ if (data.redirectUrl) {
|
|
|
|
|
+ window.location.href = data.redirectUrl;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ showNotification(data.responseMessage || "Unable to open wallet payment.", "warning");
|
|
|
|
|
+ }
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ sendOtpAfterTicketConfirmation();
|
|
|
|
|
+ },
|
|
|
|
|
+ error: function() {
|
|
|
|
|
+ sourceButtons.prop('disabled', false);
|
|
|
|
|
+ $(btn).html(originalText);
|
|
|
|
|
+ showNotification("Network error occurred.", "warning");
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function sendOtpAfterTicketConfirmation() {
|
|
|
$.ajax({
|
|
$.ajax({
|
|
|
url: subDomain + '@Url.Action("SendOTP", "Home")',
|
|
url: subDomain + '@Url.Action("SendOTP", "Home")',
|
|
|
type: 'POST',
|
|
type: 'POST',
|
|
|
success: function(data) {
|
|
success: function(data) {
|
|
|
- $(btn).prop('disabled', false).html(originalText);
|
|
|
|
|
-
|
|
|
|
|
if (data.responseCode === "0") {
|
|
if (data.responseCode === "0") {
|
|
|
|
|
+ hidePaymentSourceModal();
|
|
|
showOtpModal();
|
|
showOtpModal();
|
|
|
} else {
|
|
} else {
|
|
|
showNotification(data.responseMessage || "Failed to send OTP", data.responseCode);
|
|
showNotification(data.responseMessage || "Failed to send OTP", data.responseCode);
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
error: function() {
|
|
error: function() {
|
|
|
- $(btn).prop('disabled', false).html(originalText);
|
|
|
|
|
showNotification("Network error occurred.", "warning");
|
|
showNotification("Network error occurred.", "warning");
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|