Browse Source

Update thanh toán qua ví gọi qua a quang

student 1 month ago
parent
commit
f805cfa29a

+ 46 - 9
website/Areas/LotteryV2/Views/Home/BuyTicket.cshtml

@@ -471,6 +471,18 @@ else
                                    placeholder="-">
                         }
                     </div>
+                    <div id="walletPinContainer" class="hidden w-full mt-1 px-2">
+                        <div class="relative">
+                            <i class="fa-solid fa-lock absolute left-4 top-1/2 -translate-y-1/2 text-[#0A9800]"></i>
+                            <input id="walletPinInput" type="password" inputmode="numeric" autocomplete="off"
+                                   oninput="this.value = this.value.replace(/[^0-9]/g, ''); updateWalletPinState()"
+                                   class="h-[52px] w-full rounded-[14px] border-2 border-gray-200 bg-gray-50 pl-11 pr-12 text-center text-[22px] font-black tracking-[0.3em] text-gray-800 outline-none transition focus:border-[#0A9800] focus:bg-white focus:ring-4 focus:ring-green-100"
+                                   placeholder="••••">
+                            <button type="button" onclick="toggleWalletPinVisibility()" class="absolute right-4 top-1/2 -translate-y-1/2 text-gray-400 active:scale-90" aria-label="Show PIN">
+                                <i id="walletPinEye" class="fa-solid fa-eye"></i>
+                            </button>
+                        </div>
+                    </div>
         
                     <!-- OTP Error Message -->
                     <p id="otpError" class="text-[#EE0033] font-bold text-[14px] text-center mb-1 hidden animate__animated animate__shakeX"></p>
@@ -1030,9 +1042,10 @@ else
             hideOrderSummary();
             $("#otpModal").removeClass("hidden").addClass("flex");
             $("#otpInputs input").val("");
+            $("#walletPinInput").val("").attr("type", "password");
+            $("#walletPinEye").attr("class", "fa-solid fa-eye");
             $("#otpConfirmBtn").prop('disabled', true);
             $("#otpError").addClass("hidden").text("");
-            $("#otp1").focus();
             
             // Map game type to readable name & image
             let gameTypeStr = "@Model.termType";
@@ -1070,14 +1083,33 @@ else
             $("#otpTotalAmount").text($("#summaryTotalAmount").text());
             if (isWalletPin) {
                 $("#paymentCodeInstruction").text('@Html.Raw(Lang.payment_wallet_pin_instruction.Replace("'", "\\'"))');
+                $("#otpInputs").addClass("hidden");
+                $("#walletPinContainer").removeClass("hidden");
                 $("#otpTimer, #resendOtpBtn").addClass("hidden");
                 clearInterval(otpInterval);
+                $("#walletPinInput").focus();
             } else {
                 $("#paymentCodeInstruction").text('@Html.Raw(Lang.v2_otp_instruction.Replace("'", "\\'"))');
+                $("#walletPinContainer").addClass("hidden");
+                $("#otpInputs").removeClass("hidden");
                 startOtpTimer(60);
+                $("#otp1").focus();
             }
         }
 
+        function updateWalletPinState() {
+            $("#otpConfirmBtn").prop('disabled', $("#walletPinInput").val().length === 0);
+            $("#otpError").addClass("hidden").text("");
+        }
+
+        function toggleWalletPinVisibility() {
+            const input = $("#walletPinInput");
+            const showPin = input.attr("type") === "password";
+            input.attr("type", showPin ? "text" : "password");
+            $("#walletPinEye").attr("class", showPin ? "fa-solid fa-eye-slash" : "fa-solid fa-eye");
+            input.focus();
+        }
+
         // Add backspace support for OTP inputs
         $("#otpInputs input").on("keyup", function() {
             let otp = "";
@@ -1175,13 +1207,14 @@ else
         }
 
         function finalizePurchase(btn) {
-            let otpCode = "";
-            $("#otpInputs input").each(function() {
-                otpCode += $(this).val();
-            });
+            const isWalletPayment = currentChannelPayment === '@Constants.NATCASH_WALLET_TICKET';
+            let otpCode = isWalletPayment ? $("#walletPinInput").val().trim() : "";
+            if (!isWalletPayment) {
+                $("#otpInputs input").each(function() { otpCode += $(this).val(); });
+            }
             
-            if (otpCode.length < 6) {
-                showNotification(currentChannelPayment === '@Constants.NATCASH_WALLET_TICKET' ? "Please enter full 6-digit PIN" : "Please enter full 6-digit OTP", "warning");
+            if ((isWalletPayment && otpCode.length === 0) || (!isWalletPayment && otpCode.length < 6)) {
+                showNotification(isWalletPayment ? '@Html.Raw(Lang.payment_wallet_pin_instruction.Replace("'", "\\'"))' : "Please enter full 6-digit OTP", "warning");
                 return;
             }
 
@@ -1213,8 +1246,12 @@ else
                              showNotification(res.responseMessage || "System is upgrading", res.responseCode);
                         } else {
                              $("#otpError").text(res.responseMessage || "Invalid OTP").removeClass("hidden");
-                             $("#otpInputs input").val("");
-                             $("#otp1").focus();
+                             if (isWalletPayment) {
+                                 $("#walletPinInput").val("").focus();
+                             } else {
+                                 $("#otpInputs input").val("");
+                                 $("#otp1").focus();
+                             }
                         }
                     }
                 },

+ 2 - 2
website/Areas/Millions/Controllers/HomeController.cs

@@ -934,7 +934,7 @@ namespace LotteryWebApp.Areas.Millions.Controllers
             {
                 log.Error(ex);
             }
-
+            
             return model;
         }
 
@@ -1161,7 +1161,7 @@ namespace LotteryWebApp.Areas.Millions.Controllers
                     log.Info($"[Millions.BuyTicket] Redirect login - missing token, termType={termType}, msisdn={msisdn}");
                     return RedirectToAction("Login", "Account", new { area = "" });
                 }
-
+                
                 HomeIndex_ViewModel model = new HomeIndex_ViewModel();
                 model.termType = termType ?? Constants.Millions_CODE;
                 log.Info($"[Millions.BuyTicket] Check active term - gameId={model.termType}, msisdn={msisdn}");

+ 44 - 9
website/Areas/Millions/Views/Home/BuyTicket.cshtml

@@ -478,6 +478,16 @@ else
                                    placeholder="-">
                         }
                     </div>
+                    <div id="walletPinContainer" class="hidden w-full mt-1 px-2">
+                        <div class="relative">
+                            <i class="fa-solid fa-lock absolute left-4 top-1/2 -translate-y-1/2 text-[#0A9800]"></i>
+                            <input id="walletPinInput" type="password" inputmode="numeric" autocomplete="off"
+                                   oninput="this.value = this.value.replace(/[^0-9]/g, ''); updateWalletPinState()"
+                                   class="h-[52px] w-full rounded-[14px] border-2 border-gray-200 bg-gray-50 pl-11 pr-12 text-center text-[22px] font-black tracking-[0.3em] text-gray-800 outline-none transition focus:border-[#0A9800] focus:bg-white focus:ring-4 focus:ring-green-100"
+                                   placeholder="••••">
+                            <button type="button" onclick="toggleWalletPinVisibility()" class="absolute right-4 top-1/2 -translate-y-1/2 text-gray-400 active:scale-90" aria-label="Show PIN"><i id="walletPinEye" class="fa-solid fa-eye"></i></button>
+                        </div>
+                    </div>
         
                     <!-- OTP Error Message -->
                     <p id="otpError" class="text-[#0062FF] font-bold text-[14px] text-center mb-1 hidden animate__animated animate__shakeX"></p>
@@ -1162,9 +1172,10 @@ else
             hideOrderSummary();
             $("#otpModal").removeClass("hidden").addClass("flex");
             $("#otpInputs input").val("");
+            $("#walletPinInput").val("").attr("type", "password");
+            $("#walletPinEye").attr("class", "fa-solid fa-eye");
             $("#otpConfirmBtn").prop('disabled', true);
             $("#otpError").addClass("hidden").text("");
-            $("#otp1").focus();
             
             // Map game type to readable name & image
             let gameTypeStr = "@Model.termType";
@@ -1203,14 +1214,33 @@ else
             $("#otpTotalAmount").text($("#summaryTotalAmount").text());
             if (isWalletPin) {
                 $("#paymentCodeInstruction").text('@Html.Raw(Lang.payment_wallet_pin_instruction.Replace("'", "\\'"))');
+                $("#otpInputs").addClass("hidden");
+                $("#walletPinContainer").removeClass("hidden");
                 $("#otpTimer, #resendOtpBtn").addClass("hidden");
                 clearInterval(otpInterval);
+                $("#walletPinInput").focus();
             } else {
                 $("#paymentCodeInstruction").text('@Html.Raw(Lang.millions_otp_instruction.Replace("'", "\\'"))');
+                $("#walletPinContainer").addClass("hidden");
+                $("#otpInputs").removeClass("hidden");
                 startOtpTimer(60);
+                $("#otp1").focus();
             }
         }
 
+        function updateWalletPinState() {
+            $("#otpConfirmBtn").prop('disabled', $("#walletPinInput").val().length === 0);
+            $("#otpError").addClass("hidden").text("");
+        }
+
+        function toggleWalletPinVisibility() {
+            const input = $("#walletPinInput");
+            const showPin = input.attr("type") === "password";
+            input.attr("type", showPin ? "text" : "password");
+            $("#walletPinEye").attr("class", showPin ? "fa-solid fa-eye-slash" : "fa-solid fa-eye");
+            input.focus();
+        }
+
         // Add backspace support for OTP inputs
         $("#otpInputs input").on("keyup", function() {
             let otp = "";
@@ -1309,13 +1339,14 @@ else
         }
 
         function finalizePurchase(btn) {
-            let otpCode = "";
-            $("#otpInputs input").each(function() {
-                otpCode += $(this).val();
-            });
+            const isWalletPayment = currentChannelPayment === '@Constants.NATCASH_WALLET_TICKET';
+            let otpCode = isWalletPayment ? $("#walletPinInput").val().trim() : "";
+            if (!isWalletPayment) {
+                $("#otpInputs input").each(function() { otpCode += $(this).val(); });
+            }
             
-            if (otpCode.length < 6) {
-                showNotification(currentChannelPayment === '@Constants.NATCASH_WALLET_TICKET' ? "Please enter full 6-digit PIN" : "Please enter full 6-digit OTP", "warning");
+            if ((isWalletPayment && otpCode.length === 0) || (!isWalletPayment && otpCode.length < 6)) {
+                showNotification(isWalletPayment ? '@Html.Raw(Lang.payment_wallet_pin_instruction.Replace("'", "\\'"))' : "Please enter full 6-digit OTP", "warning");
                 return;
             }
 
@@ -1347,8 +1378,12 @@ else
                              showNotification(res.responseMessage || "System is upgrading", res.responseCode);
                         } else {
                              $("#otpError").text(res.responseMessage || "Invalid OTP").removeClass("hidden");
-                             $("#otpInputs input").val("");
-                             $("#otp1").focus();
+                             if (isWalletPayment) {
+                                 $("#walletPinInput").val("").focus();
+                             } else {
+                                 $("#otpInputs input").val("");
+                                 $("#otp1").focus();
+                             }
                         }
                     }
                 },