Bläddra i källkod

update code mới liên quan bổ sung nút mua lượt
tôi ưu css

student 12 timmar sedan
förälder
incheckning
81fadf192f
20 ändrade filer med 129 tillägg och 64 borttagningar
  1. 18 5
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/database/WsProcessUtils.java
  2. 0 4
      Kitty_Fall/Kitty_Fall/Common/CommonConstants.cs
  3. 4 0
      Kitty_Fall/Kitty_Fall/Common/CommonLogic.cs
  4. 1 0
      Kitty_Fall/Kitty_Fall/Common/Http/Apis/Request/UserGameLevelResult.cs
  5. 6 2
      Kitty_Fall/Kitty_Fall/Kitty_Fall.Apis/Business/Game/GameBusinessImpl.cs
  6. 26 23
      Kitty_Fall/Kitty_Fall/Kitty_Fall.Apis/Business/User/UserBusinessImpl.cs
  7. 3 3
      Kitty_Fall/Kitty_Fall/Kitty_Fall.Cms/Views/Shared/_Layout.cshtml
  8. 2 6
      Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/Controllers/BaseController.cs
  9. 7 1
      Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/Controllers/GameController.cs
  10. 0 1
      Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/Controllers/HistoryController.cs
  11. 3 2
      Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/Controllers/HomeController.cs
  12. 0 5
      Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/Helpers/PackagesCacheHelper.cs
  13. 2 2
      Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/Views/Home/Index.cshtml
  14. 4 4
      Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/Views/Play/Index.cshtml
  15. 5 0
      Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/wwwroot/kitty/css/all.min.css
  16. 5 0
      Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/wwwroot/kitty/css/input.css
  17. 11 0
      Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/wwwroot/kitty/js/all.min.js
  18. 11 0
      Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/wwwroot/kitty/js/input.js
  19. 19 4
      Kitty_Fall/Kitty_Fall/Kitty_Fall.Woker/Services/GameRewardPayoutWorker.cs
  20. 2 2
      Kitty_Fall/Kitty_Fall/Kitty_Fall.Woker/appsettings.json

+ 18 - 5
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/database/WsProcessUtils.java

@@ -204,13 +204,26 @@ public class WsProcessUtils extends DbProcessorAbstract {
                             + "FROM RESULT_REQUEST_INBOX WHERE EVENT_ID=?");
                     checkDuplicate.setString(1, event.getEventId());
                     duplicateRs = checkDuplicate.executeQuery();
-                    if (duplicateRs.next()
-                            && event.getPayloadHash().equals(duplicateRs.getString(1))) {
-                        logger.info("Skip duplicate resultRequest eventId=" + event.getEventId());
+                    if (duplicateRs.next()) {
+                        String existingPayloadHash = duplicateRs.getString(1);
+                        if (event.getPayloadHash().equals(existingPayloadHash)) {
+                            logger.info("Skip duplicate resultRequest eventId=" + event.getEventId());
+                            return 1;
+                        }
+                        // The original event has already claimed this transaction identity.
+                        // Do not retry or process the conflicting payload because doing so may
+                        // charge/renew the subscriber a second time. The spool source is retained
+                        // in the done archive for reconciliation.
+                        logger.error("Skip EVENT_ID collision with different payload"
+                                + ", eventId=" + event.getEventId()
+                                + ", incomingPayloadHash=" + event.getPayloadHash()
+                                + ", existingPayloadHash=" + existingPayloadHash
+                                + ", sourceFile=" + sourceFile
+                                + ", sourceLine=" + sourceLine);
                         return 1;
                     }
-                    throw new SQLException("EVENT_ID collision with different payload: "
-                            + event.getEventId(), ex);
+                    throw new SQLException("Duplicate EVENT_ID was reported but the existing row "
+                            + "could not be found: " + event.getEventId(), ex);
                 }
                 throw ex;
             }

+ 0 - 4
Kitty_Fall/Kitty_Fall/Common/CommonConstants.cs

@@ -199,10 +199,6 @@ namespace Common
 
     public static class CommonErrorCode
     {
-        public const int AddPointSuccess = 0;
-        public const int AddPointFailure = -1;
-        public const int AddPointWaiting = 100;
-
         // http code
         public const string WAITING_OTP = "100";
         public const int USER_EXISTED = 2;

+ 4 - 0
Kitty_Fall/Kitty_Fall/Common/CommonLogic.cs

@@ -20,6 +20,10 @@ namespace Common;
 
 public static class CommonLogic
 {
+    public const int AddPointSuccess = 0;
+    public const int AddPointFailure = -1;
+    public const int AddPointWaiting = 100;
+
     private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(CommonLogic));
 
 

+ 1 - 0
Kitty_Fall/Kitty_Fall/Common/Http/Apis/Request/UserGameLevelResult.cs

@@ -27,6 +27,7 @@ namespace Common.Http.Apis.Request
         public string reason { get; set; } = "";
         public decimal totalDataMb { get; set; }
         public decimal totalLoyalty { get; set; }
+        public int totalTurn { get; set; }
     }
 
     public class UserGameLevelResultRes : CommonResponse

+ 6 - 2
Kitty_Fall/Kitty_Fall/Kitty_Fall.Apis/Business/Game/GameBusinessImpl.cs

@@ -708,6 +708,7 @@ namespace Kitty_Fall.Apis.Business.Game
                 session.LastActionTime = now;
                 session.UpdatedTime = now;
                 await dbContext.SaveChangesAsync();
+                var totalTurn = await GetAvailableTurnAsync(msisdn, now);
 
                 return CommonLogic.BuildResponse(
                     url,
@@ -719,7 +720,8 @@ namespace Kitty_Fall.Apis.Business.Game
                         point = "0",
                         data = "",
                         score = session.TotalScore.ToString(CultureInfo.InvariantCulture),
-                        transId = request.transId
+                        transId = request.transId,
+                        totalTurn = totalTurn
                     });
             }
             catch (Exception exception)
@@ -783,6 +785,7 @@ namespace Kitty_Fall.Apis.Business.Game
                     session.LastActionTime = now;
                     session.UpdatedTime = now;
                     await dbContext.SaveChangesAsync();
+                    var totalTurn = await GetAvailableTurnAsync(msisdn, now);
 
                     return CommonLogic.BuildResponse(
                         url,
@@ -796,7 +799,8 @@ namespace Kitty_Fall.Apis.Business.Game
                             score = session.TotalScore.ToString(CultureInfo.InvariantCulture),
                             transId = request.transId,
                             totalDataMb = session.TotalDataMb,
-                            totalLoyalty = session.TotalLoyalty
+                            totalLoyalty = session.TotalLoyalty,
+                            totalTurn = totalTurn
                         });
                 }
 

+ 26 - 23
Kitty_Fall/Kitty_Fall/Kitty_Fall.Apis/Business/User/UserBusinessImpl.cs

@@ -467,14 +467,7 @@ namespace Kitty_Fall.Apis.Business.User
                 {
                     // VAS trả "2" (SUCCESS_FOR_THE_FIRST_TIME_REGISTER) khi user đăng ký lần đầu -> vẫn là thành công.
                     // Đăng ký thẳng (không cần OTP) -> trả kèm danh sách gói để client cập nhật ngay trạng thái thuê bao.
-                    List<RegInfo> userPackage = await dbContext
-                        .RegInfos.Where(x => x.Msisdn == msisdn
-                            && x.Status == true
-                            && x.Renew == 1
-                            )
-                        .OrderByDescending(x => x.RegisterTime)
-                        .ThenByDescending(x => x.RegisterId)
-                        .ToListAsync();
+                    List<RegInfo> userPackage = await TryLoadActiveRegistrationsAfterSuccessfulCharge(msisdn);
                     return CommonLogic.BuildResponse(
                         url,
                         json,
@@ -579,14 +572,7 @@ namespace Kitty_Fall.Apis.Business.User
                 {
                     // VAS trả "2" (SUCCESS_FOR_THE_FIRST_TIME_REGISTER) khi user đăng ký lần đầu -> vẫn là thành công.
                     // Trả kèm danh sách gói đang dùng để client cập nhật ngay trạng thái thuê bao (không phải gọi lại GetProfileInfo).
-                    List<RegInfo> userPackage = await dbContext
-                        .RegInfos.Where(x => x.Msisdn == msisdn
-                            && x.Status == true
-                            && x.Renew == 1
-                         )
-                        .OrderByDescending(x => x.RegisterTime)
-                        .ThenByDescending(x => x.RegisterId)
-                        .ToListAsync();
+                    List<RegInfo> userPackage = await TryLoadActiveRegistrationsAfterSuccessfulCharge(msisdn);
                     return CommonLogic.BuildResponse(
                         url,
                         json,
@@ -675,13 +661,7 @@ namespace Kitty_Fall.Apis.Business.User
                 if (wsRegisterSubQuickResponse.@return.errorCode == CommonErrorCode.Success
                     || wsRegisterSubQuickResponse.@return.errorCode == CommonErrorCode.SuccessFirstRegister)
                 {
-                    List<RegInfo> userPackage = await dbContext
-                        .RegInfos.Where(x => x.Msisdn == msisdn
-                            && x.Status == true
-                            && x.Renew == 1)
-                        .OrderByDescending(x => x.RegisterTime)
-                        .ThenByDescending(x => x.RegisterId)
-                        .ToListAsync();
+                    List<RegInfo> userPackage = await TryLoadActiveRegistrationsAfterSuccessfulCharge(msisdn);
 
                     return CommonLogic.BuildResponse(
                         url,
@@ -1475,6 +1455,29 @@ namespace Kitty_Fall.Apis.Business.User
                 new BadRequestObjectResult(new { message = Lang.badRequest })
             );
         }
+        private async Task<List<RegInfo>> TryLoadActiveRegistrationsAfterSuccessfulCharge(string msisdn)
+        {
+            try
+            {
+                return await dbContext.RegInfos
+                    .Where(x => x.Msisdn == msisdn
+                        && x.Status == true
+                        && x.Renew == 1)
+                    .OrderByDescending(x => x.RegisterTime)
+                    .ThenByDescending(x => x.RegisterId)
+                    .ToListAsync();
+            }
+            catch (Exception exception)
+            {
+                // Charging/registration was already confirmed by VAS. A profile refresh
+                // failure must not turn that completed transaction into a client-visible
+                // failure, which could also encourage a duplicate purchase attempt.
+                log.Warn("VAS registration succeeded, but active package refresh failed. "
+                    + "Returning the confirmed success response without regInfos.", exception);
+                return new List<RegInfo>();
+            }
+        }
+
         private static object GetHttpSendRequest()
         {
             return GetHttpSendRequest;

+ 3 - 3
Kitty_Fall/Kitty_Fall/Kitty_Fall.Cms/Views/Shared/_Layout.cshtml

@@ -84,7 +84,7 @@
                     <div class="bg-admin-active p-1.5 rounded-lg">
                         <i class="fas fa-rocket text-white"></i>
                     </div>
-                    <span>MYJOB CMS</span>
+                    <span>KITTY_FALL CMS</span>
                 </a>
                 <button type="button" onclick="closeMobileSidebar()" class="flex h-10 w-10 items-center justify-center rounded-full bg-white/10 text-white">
                     <i class="fas fa-times"></i>
@@ -287,7 +287,7 @@
                     <div class="bg-admin-active p-1.5 rounded-lg">
                         <i class="fas fa-rocket text-white"></i>
                     </div>
-                    <span>MYJOB CMS</span>
+                    <span>KITTY_FALL CMS</span>
                 </a>
                 <ul class="mt-8">
                     @if (canViewDashboard)
@@ -485,7 +485,7 @@
                             <i class="fas fa-bars"></i>
                         </button>
                         <div class="min-w-0">
-                            <div class="text-xs font-bold uppercase tracking-[0.2em] text-gray-400 md:hidden">MYJOB CMS</div>
+                            <div class="text-xs font-bold uppercase tracking-[0.2em] text-gray-400 md:hidden">KITTY_FALL CMS</div>
                             <div class="truncate text-lg font-bold text-gray-800">@ViewData["Title"]</div>
                         </div>
                     </div>

+ 2 - 6
Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/Controllers/BaseController.cs

@@ -1,17 +1,13 @@
 
 using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.Mvc.Rendering;
-using Microsoft.AspNetCore.Mvc.ViewEngines;
-using Microsoft.AspNetCore.Mvc.ViewFeatures;
 using System.Security.Cryptography;
-using System.ServiceModel;
 
 namespace Kitty_Fall.Website.Controllers;
 
 public class BaseController : Controller
 {
 
-    
+
     private string GenerateAuthId()
     {
 #pragma warning disable SYSLIB0023 // Type or member is obsolete
@@ -88,6 +84,6 @@ public class BaseController : Controller
     }
 
 
-    
+
 
 }

+ 7 - 1
Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/Controllers/GameController.cs

@@ -1,4 +1,3 @@
-using Common;
 using Common.Extension;
 using Common.Http.Apis.Request;
 using Microsoft.AspNetCore.Mvc;
@@ -25,6 +24,7 @@ namespace Kitty_Fall.Website.Controllers
                 if (apiResult.errorCode == "0" && apiResult.data != null)
                 {
                     var maxLevel = await GetTodayMaxLevelAsync(request);
+                    HttpContext.Session.SetComplexData("totalTurn", (long)apiResult.data.totalTurn);
 
                     return Json(new
                     {
@@ -33,6 +33,7 @@ namespace Kitty_Fall.Website.Controllers
                         data = apiResult.data.data,
                         score = apiResult.data.score,
                         transId = apiResult.data.transId,
+                        totalTurn = apiResult.data.totalTurn,
                         max_level = maxLevel
                     });
                 }
@@ -101,6 +102,10 @@ namespace Kitty_Fall.Website.Controllers
                 log.Info($"ExitGame msisdn={request.msisdn}, transId={request.transId}, level={request.level}, score={request.score}, gameType={request.gameType}, gameOver={request.gameOver}");
                 request.gameOver = request.gameOver == 0 ? 1 : request.gameOver;
                 var apiResult = await SendGameApiAsync(request, UrlConstant.GameSaveLevelResultUrl);
+                if (apiResult.errorCode == "0" && apiResult.data != null)
+                {
+                    HttpContext.Session.SetComplexData("totalTurn", (long)apiResult.data.totalTurn);
+                }
                 var payload = JsonSerializer.Serialize(new
                 {
                     type = "EXIT_GAME_RESULT",
@@ -108,6 +113,7 @@ namespace Kitty_Fall.Website.Controllers
                     score = apiResult.data?.score ?? request.score.ToString(),
                     data = apiResult.data?.totalDataMb ?? 0,
                     loyalty = apiResult.data?.totalLoyalty ?? 0,
+                    totalTurn = apiResult.data?.totalTurn,
                     level = request.level,
                     message = apiResult.message ?? ""
                 });

+ 0 - 1
Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/Controllers/HistoryController.cs

@@ -2,7 +2,6 @@ using Common;
 using Common.Extension;
 using Common.Http.Apis.Request;
 using Microsoft.AspNetCore.Mvc;
-using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
 
 namespace Kitty_Fall.Website.Controllers

+ 3 - 2
Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/Controllers/HomeController.cs

@@ -8,7 +8,6 @@ using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
 using System.Diagnostics;
 using System.Net.Http.Headers;
-using System.Security.Policy;
 using System.Text;
 using static DotnetLib.Http.HttpObject;
 
@@ -76,7 +75,9 @@ namespace Kitty_Fall.Website.Controllers
 
                 var allowedTypes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
                 {
-                    ["image/jpeg"] = ".jpg", ["image/png"] = ".png", ["image/webp"] = ".webp"
+                    ["image/jpeg"] = ".jpg",
+                    ["image/png"] = ".png",
+                    ["image/webp"] = ".webp"
                 };
                 if (!allowedTypes.TryGetValue(avatar.ContentType, out var extension))
                     return BadRequest(new { success = false, message = "Only JPG, PNG or WEBP images are supported." });

+ 0 - 5
Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/Helpers/PackagesCacheHelper.cs

@@ -1,11 +1,6 @@
-using Common;
 using Common.Extension;
 using Common.Http.Apis.Request;
-using Microsoft.AspNetCore.Http;
 using Newtonsoft.Json.Linq;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
 
 namespace Kitty_Fall.Website.Helpers
 {

+ 2 - 2
Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/Views/Home/Index.cshtml

@@ -346,8 +346,8 @@
                 url: "/Login/LogoutBackAction",
                 type: "POST",
                 complete: function () {
-                    //window.location.href = "mytel://back";
-                    window.location.href = "Login/index";
+                    window.location.href = "mytel://back";
+                    // window.location.href = "Login/index";
                 }
             });
         }

+ 4 - 4
Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/Views/Play/Index.cshtml

@@ -26,11 +26,11 @@
                 <img src="~/kitty/assets/kitty-fall/coin.png" alt="">
                 <strong>@Model.TotalPoint.ToString("N0")</strong>
             </span>
-            <span class="play-top-chip">
+            <a class="play-top-chip play-turn-chip" href="@Url.Action("Index", "Home", new { buyturn = true })" aria-label="@Lang.BuyTurn">
                 <img src="~/kitty/assets/kitty-fall/ticket.png" alt="">
-                <strong>@Model.TotalTurn.ToString("N0")</strong>
+                <strong data-play-total-turn>@Model.TotalTurn.ToString("N0")</strong>
                 <b>+</b>
-            </span>
+            </a>
         </div>
         <button class="menu-button" aria-label="@Lang.OpenMenu">
             <span></span>
@@ -96,7 +96,7 @@
     </section>
 
     <div class="play-action-bar">
-        <a class="play-back-button" href="/">
+        <a class="play-back-button" href="@Url.Action("Index", "Home")">
             <span aria-hidden="true"></span>
             <strong>@Lang.Back</strong>
         </a>

+ 5 - 0
Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/wwwroot/kitty/css/all.min.css

@@ -203,6 +203,11 @@ button {
     line-height: 1;
     font-weight: 900;
     text-shadow: 0 1px 1px rgba(65, 68, 147, 0.2);
+    text-decoration: none;
+}
+
+.play-turn-chip {
+    cursor: pointer;
 }
 
 .play-top-chip img {

+ 5 - 0
Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/wwwroot/kitty/css/input.css

@@ -203,6 +203,11 @@ button {
     line-height: 1;
     font-weight: 900;
     text-shadow: 0 1px 1px rgba(65, 68, 147, 0.2);
+    text-decoration: none;
+}
+
+.play-turn-chip {
+    cursor: pointer;
 }
 
 .play-top-chip img {

+ 11 - 0
Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/wwwroot/kitty/js/all.min.js

@@ -260,6 +260,7 @@ const initKittyFall = () => {
         const gameOverScore = playGameRoot.querySelector("[data-game-over-score]");
         const gameOverData = playGameRoot.querySelector("[data-game-over-data]");
         const gameOverLoyalty = playGameRoot.querySelector("[data-game-over-loyalty]");
+        const totalTurnElement = playGameRoot.querySelector("[data-play-total-turn]");
         let selectedLevel = playGameRoot.querySelector("[data-level].is-selected")?.dataset.level
             || levelButtons[0]?.dataset.level
             || "Easy";
@@ -311,6 +312,14 @@ const initKittyFall = () => {
 
         const formatNumber = (value) => Math.max(0, Math.round(value)).toLocaleString("en-US");
 
+        const updateTotalTurn = (value) => {
+            if (value === null || value === undefined || value === "") return;
+            const totalTurn = Number(value);
+            if (!totalTurnElement || !Number.isFinite(totalTurn)) return;
+            totalTurnElement.textContent = formatNumber(totalTurn);
+            playGameRoot.dataset.totalTurn = String(Math.max(0, Math.round(totalTurn)));
+        };
+
         const addLevelReward = (data) => {
             const rewardType = String(data?.rewardType || "").toUpperCase();
             const rewardValue = toNumber(data?.rewardValue);
@@ -409,6 +418,7 @@ const initKittyFall = () => {
             }
             if (event.data?.type === "EXIT_GAME_RESULT") {
                 setRunSummary(event.data);
+                updateTotalTurn(event.data.totalTurn);
                 closeEmbeddedGame();
                 showGameOverSummary();
             }
@@ -453,6 +463,7 @@ const initKittyFall = () => {
                     return;
                 }
 
+                updateTotalTurn(result.totalTurn);
                 resetRunRewards();
                 gameStarted = true;
                 playGameRoot.classList.add("is-game-running");

+ 11 - 0
Kitty_Fall/Kitty_Fall/Kitty_Fall.Website/wwwroot/kitty/js/input.js

@@ -260,6 +260,7 @@ const initKittyFall = () => {
         const gameOverScore = playGameRoot.querySelector("[data-game-over-score]");
         const gameOverData = playGameRoot.querySelector("[data-game-over-data]");
         const gameOverLoyalty = playGameRoot.querySelector("[data-game-over-loyalty]");
+        const totalTurnElement = playGameRoot.querySelector("[data-play-total-turn]");
         let selectedLevel = playGameRoot.querySelector("[data-level].is-selected")?.dataset.level
             || levelButtons[0]?.dataset.level
             || "Easy";
@@ -311,6 +312,14 @@ const initKittyFall = () => {
 
         const formatNumber = (value) => Math.max(0, Math.round(value)).toLocaleString("en-US");
 
+        const updateTotalTurn = (value) => {
+            if (value === null || value === undefined || value === "") return;
+            const totalTurn = Number(value);
+            if (!totalTurnElement || !Number.isFinite(totalTurn)) return;
+            totalTurnElement.textContent = formatNumber(totalTurn);
+            playGameRoot.dataset.totalTurn = String(Math.max(0, Math.round(totalTurn)));
+        };
+
         const addLevelReward = (data) => {
             const rewardType = String(data?.rewardType || "").toUpperCase();
             const rewardValue = toNumber(data?.rewardValue);
@@ -409,6 +418,7 @@ const initKittyFall = () => {
             }
             if (event.data?.type === "EXIT_GAME_RESULT") {
                 setRunSummary(event.data);
+                updateTotalTurn(event.data.totalTurn);
                 closeEmbeddedGame();
                 showGameOverSummary();
             }
@@ -453,6 +463,7 @@ const initKittyFall = () => {
                     return;
                 }
 
+                updateTotalTurn(result.totalTurn);
                 resetRunRewards();
                 gameStarted = true;
                 playGameRoot.classList.add("is-game-running");

+ 19 - 4
Kitty_Fall/Kitty_Fall/Kitty_Fall.Woker/Services/GameRewardPayoutWorker.cs

@@ -120,14 +120,23 @@ namespace Kitty_Fall.Woker.Services
                     rewardLog.Msisdn,
                     rewardLog.RewardLogId.ToString(CultureInfo.InvariantCulture),
                     GetPackageName(rewardLog));
-                var isSuccess = addPointRes?.success == true;
+                var responseStatus = addPointRes?.result?.status;
+                var hasResponseCode = int.TryParse(
+                    responseStatus,
+                    NumberStyles.Integer,
+                    CultureInfo.InvariantCulture,
+                    out var responseCode);
+                var isSuccess = addPointRes?.success == true
+                    || (hasResponseCode && responseCode == CommonLogic.AddPointSuccess);
+                var isWaiting = hasResponseCode
+                    && responseCode == CommonLogic.AddPointWaiting;
 
                 rewardLog.ResponseTime = DateTime.Now;
                 // DotnetLib tra ma/trang thai cua doi tac trong result.status.
-                rewardLog.ResponseCode = addPointRes?.result?.status
+                rewardLog.ResponseCode = responseStatus
                     ?? (isSuccess
-                        ? CommonErrorCode.AddPointSuccess.ToString(CultureInfo.InvariantCulture)
-                        : CommonErrorCode.AddPointFailure.ToString(CultureInfo.InvariantCulture));
+                        ? CommonLogic.AddPointSuccess.ToString(CultureInfo.InvariantCulture)
+                        : CommonLogic.AddPointFailure.ToString(CultureInfo.InvariantCulture));
                 rewardLog.ResponseMessage = Truncate(addPointRes?.message, 500);
                 rewardLog.ExternalTransId = rewardLog.RewardLogId.ToString(CultureInfo.InvariantCulture);
                 rewardLog.UpdatedTime = DateTime.Now;
@@ -140,6 +149,12 @@ namespace Kitty_Fall.Woker.Services
                     await SendSuccessMtAsync(dbContext, rewardLog, cancellationToken);
                     return;
                 }
+                else if (isWaiting)
+                {
+                    // Doi tac da nhan giao dich va dang xu ly. Giu PROCESSING de doi soat,
+                    // khong danh dau FAILED va khong tu dong gui lai giao dich.
+                    rewardLog.Status = StatusProcessing;
+                }
                 else
                 {
                     rewardLog.RetryCount++;

+ 2 - 2
Kitty_Fall/Kitty_Fall/Kitty_Fall.Woker/appsettings.json

@@ -18,8 +18,8 @@
     "IntervalSeconds": 10,
     "BatchSize": 20,
     "ServiceId": "Kitty_Fall_DAYLY",
-    "DataPackageName": "GAME_DATA",
-    "LoyaltyPackageName": "GAME_LOYALTY",
+    "DataPackageName": "DATA_",
+    "LoyaltyPackageName": "LOYALTY_",
     "DefaultPackageName": "GAME_REWARD"
   },
   "MonthlyWinner": {