package com.bb.front; import java.net.SocketTimeoutException; import java.text.SimpleDateFormat; import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import jakarta.servlet.http.HttpServletRequest; import org.apache.http.conn.ConnectTimeoutException; import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.ResourceAccessException; import com.bb.model.NexusBalanceData; import com.bb.model.NexusResponse; import com.bb.model.NexusSmlData; import com.bb.model.NexusSmlRequest; import com.bb.service.AsyncSiteService; import com.bb.service.CallBackService; import com.bb.service.SiteService; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @Slf4j @RequestMapping("/api/callback/ace2") @RequiredArgsConstructor @SecurityRequirement(name = "Authorization") @EnableScheduling @RestController public class CallBackAceController { @Autowired SiteService siteService; @Autowired CallBackService callBackService; @Autowired AsyncSiteService asyncCallBackService; @ResponseBody @RequestMapping(path = "/callBalance") public ResponseEntity callBalance(HttpServletRequest request, @RequestBody net.sf.json.JSONObject requestBody) throws Exception { NexusResponse response = null; HttpStatus httpStatus = null; String apiKey = requestBody.getString("apiKey"); net.sf.json.JSONObject params = requestBody.getJSONObject("params"); String siteUsername = params.getString("siteUsername"); String requestedAt = params.getString("requestedAt"); if(siteUsername == null || siteUsername.equals("") || siteUsername.equals("invalid-user")) { response = new NexusResponse(); response.setCode(-1); response.setMsg("존재하지 않는 회원입니다"); httpStatus = HttpStatus.OK; return new ResponseEntity(response, httpStatus); } long siteIdx = Long.parseLong(siteUsername.substring(0, 3), 16); String memberId = siteUsername.substring(3, siteUsername.length()); final String LOG_PREFIX = "#-CB::ACE::::callBalance::"+memberId+"::"+requestedAt+":::"; log.info(LOG_PREFIX+ "Request::" + requestBody.toString()); try { //사이트정보 HashMap sParam = new HashMap(); sParam.put("siteIdx", siteIdx); sParam.put("memberId", memberId); sParam.put("vendor", "ace2"); sParam.put("apiKey", apiKey); log.info(LOG_PREFIX + "getSiteVendorInfo::"+sParam.toString()); HashMap siteApiInfo = siteService.getSiteApiInfoByApiKey(sParam); if(siteApiInfo == null) { response = new NexusResponse(); response.setCode(-1); response.setMsg("API키가 일치하지 않습니다"); httpStatus = HttpStatus.OK; return new ResponseEntity(response, httpStatus); } if(siteApiInfo.get("memberIdx") == null) { response = new NexusResponse(); response.setCode(-1); response.setMsg("존재하지 않는 회원입니다"); httpStatus = HttpStatus.OK; return new ResponseEntity(response, httpStatus); } // ##--isTransfer 처리-## int balance = 0; if("N".equals(siteApiInfo.get("isTransfer").toString())) { log.info(LOG_PREFIX + "PLAY_SEAMLESS"); JSONObject member = new JSONObject(); member.put("userId", memberId); long startTimestamp = System.currentTimeMillis(); JSONObject resData = callBackService.getBalance(siteApiInfo, member); if(resData == null) { response = new NexusResponse(); response.setCode(-1); response.setMsg("BALANCE_CALLBACK_ERROR"); httpStatus = HttpStatus.OK; return new ResponseEntity(response, httpStatus); } long endTimestamp = System.currentTimeMillis(); double diffTime = (startTimestamp - endTimestamp)/1000.0; //두 시간에 차 계산 if(diffTime < -1.5) { log.error(LOG_PREFIX+ "잔액요청 응답시간("+diffTime+"초) 초과"); } log.info(LOG_PREFIX + "resData::"+resData.toString()); balance = resData.getInt("balance"); } else { log.info(LOG_PREFIX + "PLAY_TRANSFER"); HashMap balanceMap = new HashMap<>(); balanceMap.put("siteIdx", siteIdx); balanceMap.put("memberId", memberId); balance = siteService.getUserBalance(balanceMap); if(siteApiInfo.get("siteCbUrl") != null && !"".equals(siteApiInfo.get("siteCbUrl").toString())) { JSONObject member = new JSONObject(); member.put("userId", memberId); member.put("balance", balance); asyncCallBackService.asyncBalance(LOG_PREFIX, siteApiInfo, member); } } NexusBalanceData data = new NexusBalanceData(); data.setBalance(balance); data.setCurrency("KRW"); response = new NexusResponse(); response.setCode(0); response.setData(data); httpStatus = HttpStatus.OK; } catch (ResourceAccessException rae) { if(rae.getCause() instanceof ConnectTimeoutException) { log.error(LOG_PREFIX+ "[ConnectTimeoutException]"+rae.getMessage()); } if(rae.getCause() instanceof SocketTimeoutException) { log.error(LOG_PREFIX+ "[SocketTimeoutException]"+rae.getMessage()); } if(rae.getCause() instanceof InterruptedException) { log.error(LOG_PREFIX+ "[InterruptedException]"+rae.getMessage()); } response = new NexusResponse(); response.setCode(-999); response.setMsg("TIMEOUT_ERROR"); httpStatus = HttpStatus.OK; } catch (Exception e) { log.error(LOG_PREFIX+ "[Exception]"+e.toString()); e.printStackTrace(); response = new NexusResponse(); response.setCode(-999); response.setMsg("BALANCE_SERVER_ERROR"); httpStatus = HttpStatus.OK; } ResponseEntity res = new ResponseEntity(response, httpStatus); log.info(LOG_PREFIX+ "Response::" + response.toString()); return res; } @ResponseBody @RequestMapping(path = "/callBet") public ResponseEntity callBet(HttpServletRequest request, @RequestBody NexusSmlRequest requestBody) throws Exception { NexusResponse response = null; HttpStatus httpStatus = null; String apiKey = requestBody.getApiKey(); NexusSmlData data = requestBody.getParams(); String siteUsername = data.getSiteUsername(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); String betDateTimeStr = data.getCreatedAt(); if(betDateTimeStr == null || betDateTimeStr.equals("")) { betDateTimeStr = sdf.format(System.currentTimeMillis()); } else { betDateTimeStr = betDateTimeStr.replace("T", " ").replace("Z", ""); betDateTimeStr = makeEdate(betDateTimeStr, 32400000); } data.setBetDateTime(betDateTimeStr); if(siteUsername == null || siteUsername.equals("") || siteUsername.equals("invalid-user")) { response = new NexusResponse(); response.setCode(-1); response.setMsg("존재하지 않는 회원입니다"); httpStatus = HttpStatus.OK; return new ResponseEntity(response, httpStatus); } long siteIdx = Long.parseLong(siteUsername.substring(0, 3), 16); String memberId = siteUsername.substring(3, siteUsername.length()); final String LOG_PREFIX = "#-CB::ACE::"+memberId+"::"+data.getTransactionKey()+"::callBet:::"; log.info(LOG_PREFIX+ "Request::" + requestBody.toString()); try { //사이트정보 HashMap sParam = new HashMap(); sParam.put("siteIdx", siteIdx); sParam.put("memberId", memberId); sParam.put("vendor", "ace2"); sParam.put("vendorGameCode", data.getVendorKey()); log.info(LOG_PREFIX + "getSiteVendorInfo::"+sParam.toString()); HashMap siteVendorInfo = siteService.getSiteVendorInfo(sParam); if(siteVendorInfo == null) { response = new NexusResponse(); response.setCode(-1); response.setMsg("존재하지 않는 회원입니다"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "존재하지 않는 회원입니다::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } if(!apiKey.equals(siteVendorInfo.get("vendorApiKey").toString())) { response = new NexusResponse(); response.setCode(-1); response.setMsg("API키가 일치하지 않습니다"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "API키가 일치하지 않습니다::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } // ##--isTransfer 처리-## final String IS_TRANSFER = siteVendorInfo.get("isTransfer").toString(); // vendors_info.useYn 게임막기 기능 if("N".equals(siteVendorInfo.get("vendorAllUseYn").toString())) { response = new NexusResponse(); response.setCode(-1); response.setMsg("사용불가 벤더사"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "사용불가 벤더사::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } String siteId = siteVendorInfo.get("siteId").toString(); long memberIdx = Long.parseLong(siteVendorInfo.get("memberIdx").toString()); String vendorApiId = siteVendorInfo.get("vendorApiId").toString(); if(siteVendorInfo.get("lastInVendorIdx")==null || "0".equals(siteVendorInfo.get("lastInVendorIdx").toString())) { HashMap memParam = new HashMap<>(); memParam.put("siteIdx", siteIdx); memParam.put("memberIdx", memberIdx); memParam.put("lastInVendorIdx", Integer.parseInt(siteVendorInfo.get("vendorIdx").toString())); int updResult = siteService.updMemLastVendorIdx(memParam); } else { Long lastInVendorIdx = Long.parseLong(siteVendorInfo.get("lastInVendorIdx").toString()); Long vendorIdx = Long.parseLong(siteVendorInfo.get("vendorIdx").toString()); if(lastInVendorIdx.longValue() != vendorIdx.longValue()) { response = new NexusResponse(); response.setCode(-1); response.setMsg("VendorIdx doesn't match"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "VendorIdx doesn't match::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } } Double amountD = Double.parseDouble(data.getAmount()); int amount = Math.abs(amountD.intValue()); long siteCredit = Long.parseLong(siteVendorInfo.get("credit").toString()); // ##--isTransfer 처리-## if(siteCredit < amount && IS_TRANSFER.equals("N")) { response = new NexusResponse(); response.setCode(-1); response.setMsg("NO_SITE_CREDIT"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "NO_SITE_CREDIT::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } if(amount < 0) { response = new NexusResponse(); response.setCode(-1); response.setMsg("금액이 올바르지 않습니다"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "금액이 올바르지 않습니다::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } long siteMaxBet = Long.parseLong(siteVendorInfo.get("siteMaxBet").toString()); long userMaxBet = 0; if(siteVendorInfo.get("userMaxBet") != null && !siteVendorInfo.get("userMaxBet").toString().isEmpty()) { try { userMaxBet = Long.parseLong(siteVendorInfo.get("userMaxBet").toString()); } catch (NumberFormatException e) { userMaxBet = 0; } } // 최종 maxBet 결정: userMaxBet이 0이면 siteMaxBet 사용, 0이 아니면 userMaxBet 사용 long finalMaxBet = (userMaxBet > 0) ? userMaxBet : siteMaxBet; log.info(LOG_PREFIX+ "MaxBet Info - siteMaxBet: " + siteMaxBet + ", userMaxBet: " + userMaxBet + ", finalMaxBet: " + finalMaxBet); if(finalMaxBet < amount) { log.error(LOG_PREFIX+ "MAX_BET_AMOUNT_OVER"); log.error(LOG_PREFIX+ "finalMaxBet : " + finalMaxBet +", amount : " + amount); response = new NexusResponse(); response.setCode(-1); response.setMsg("MAX_BET_AMOUNT_OVER"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "MAX_BET_AMOUNT_OVER::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } String vendorTranKey = data.getTransactionKey(); String tranId = data.getTransactionKey(); // ##--isTransfer 처리-## if(IS_TRANSFER.equals("Y")) { // tranId 중복체크 int cntTr = siteService.getTranIdCheck2(tranId); if(cntTr > 0) { HashMap balanceMap = new HashMap<>(); balanceMap.put("siteIdx", siteIdx); balanceMap.put("memberId", memberId); int balance = siteService.getUserBalance(balanceMap); NexusBalanceData balanceData = new NexusBalanceData(); balanceData.setBalance(balance); balanceData.setBeforeBalance(balance + amount); balanceData.setCurrency("KRW"); response = new NexusResponse(); response.setCode(0); response.setData(balanceData); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "중복요청::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } } String betId = data.getParentTransactionKey(); if(betId == null || betId.equals("")) { betId = data.getTransactionKey(); } String vendorKey = siteVendorInfo.get("vendorKey").toString(); int vendorIdx = Integer.parseInt(siteVendorInfo.get("vendorIdx").toString()); String vendorCetegory = siteVendorInfo.get("vendorCetegory").toString(); String gameName = data.getGameName(); String gameType = data.getGameType().replaceAll(" ", "").toLowerCase(); if(data.getGameId() == null) data.setGameId(""); String gameId = data.getGameId().replaceAll(" ", "").toLowerCase(); String banGameType = siteVendorInfo.get("banGameType").toString().replaceAll(" ", "").toLowerCase(); String banGameId = siteVendorInfo.get("banGameId").toString().replaceAll(" ", "").toLowerCase(); if(!"".equals(gameType) && !"".equals(banGameType) && banGameType.contains(gameType+"|")) { // Ban Game Type Exception HashMap logParam = new HashMap(); logParam.put("siteIdx", siteIdx); logParam.put("memberIdx", memberIdx); logParam.put("vendorIdx", vendorIdx); logParam.put("statusCode", 501L); logParam.put("callBackType", "debit"); logParam.put("tranId", tranId); logParam.put("callBackReqBody", "gameType:"+gameType+"이 블락설정"); logParam.put("callBackResBody", ""); logParam.put("errorCode", "BLOCK_GAME_TYPE"); logParam.put("errorMsg", "gameType:"+gameType+"이 블락설정"); long startTimestamp = System.currentTimeMillis(); logParam.put("regDate", startTimestamp); logParam.put("updDate", startTimestamp); callBackService.insertCallBackErrLog(logParam); log.error(LOG_PREFIX+ "Ban Game Type : " + gameType); response = new NexusResponse(); response.setCode(-1); response.setMsg("Ban Game Type : " + gameType); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "VendorIdx doesn't match::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } if(!"".equals(gameId) && !"".equals(banGameId) && banGameId.contains(gameId+"|")) { // Ban Game Id Exception HashMap logParam = new HashMap(); logParam.put("siteIdx", siteIdx); logParam.put("memberIdx", memberIdx); logParam.put("vendorIdx", vendorIdx); logParam.put("statusCode", 502L); logParam.put("callBackType", "debit"); logParam.put("tranId", tranId); logParam.put("callBackReqBody", "gameId:"+gameId+"("+gameName+")이 블락설정"); logParam.put("callBackResBody", ""); logParam.put("errorCode", "BLOCK_GAME_ID"); logParam.put("errorMsg", "gameId:"+gameId+"("+gameName+")이 블락설정"); long startTimestamp = System.currentTimeMillis(); logParam.put("regDate", startTimestamp); logParam.put("updDate", startTimestamp); callBackService.insertCallBackErrLog(logParam); log.error(LOG_PREFIX+ "Ban Game Id : " + gameId); response = new NexusResponse(); response.setCode(-1); response.setMsg("Ban Game Id : " + gameId); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "VendorIdx doesn't match::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } HashMap tranParam = new HashMap(); tranParam.put("tranId", tranId); tranParam.put("refId", betId); tranParam.put("siteIdx", siteIdx); tranParam.put("siteId", siteId); tranParam.put("memberIdx", memberIdx); tranParam.put("memberId", memberId); tranParam.put("vendorCetegory", vendorCetegory); tranParam.put("vendorIdx", vendorIdx); tranParam.put("vendorCode", "ace2"); tranParam.put("vendorTranKey", vendorTranKey); tranParam.put("gameType", data.getGameType()); tranParam.put("gameId", data.getGameId()); tranParam.put("gameIdx", data.getGameName()); tranParam.put("tranType", "debit"); tranParam.put("depositAmt", amount); tranParam.put("creditAmt", "0"); tranParam.put("isCancel", "N"); tranParam.put("isTie", "N"); tranParam.put("apiStatus", 0); tranParam.put("vendorApiId", vendorApiId); JSONObject callBackObj = new JSONObject(); callBackObj.put("betId", betId); callBackObj.put("tranId", tranId); callBackObj.put("userId", memberId); callBackObj.put("vendorIdx", vendorIdx); callBackObj.put("vendorKey", vendorKey); callBackObj.put("vendor", "ace2"); callBackObj.put("gameIdx", vendorIdx); callBackObj.put("gameKey", data.getGameName()); if(data.getGameId() == null) data.setGameId(""); callBackObj.put("gameId", data.getGameId()); callBackObj.put("gameType", data.getGameType()); callBackObj.put("tranType", "debit"); callBackObj.put("debit", amount); callBackObj.put("credit", 0); callBackObj.put("isCancel", 0); if(data.getIsBonus().equals("true")) { callBackObj.put("isBonus", 1); } else { callBackObj.put("isBonus", 0); } callBackObj.put("requestAt", betDateTimeStr); log.info(LOG_PREFIX + "SEND_BET request body: " + callBackObj.toString()); // ##--isTransfer 처리-## if(IS_TRANSFER.equals("N")) { log.info(LOG_PREFIX + "PLAY_SEAMLESS"); log.info(LOG_PREFIX + "-----INSERT_BET_START-----"); long startTime = System.currentTimeMillis(); siteService.commonBetinsert(tranParam); long endTime = System.currentTimeMillis(); // 코드 실행 후에 시간 받아오기 double diffTime = (startTime - endTime)/1000.0; //두 시간에 차 계산 if(diffTime < -1.0) { log.error(LOG_PREFIX + "commonBetinsert::배팅 쓰기지연::"+diffTime+"초 지연발생"); response = new NexusResponse(); response.setCode(-999); response.setMsg("TIMEOUT_ERROR"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "TIMEOUT_ERROR::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } log.info(LOG_PREFIX + "-----INSERT_BET_END-----"); JSONObject resData = null; if(data.getGameCategory().equals("casino")) { resData = callBackService.changeBalance(LOG_PREFIX, siteVendorInfo, callBackObj); } else { resData = callBackService.changeBalanceSlot(LOG_PREFIX, siteVendorInfo, callBackObj); } log.info(LOG_PREFIX + "SEND_BET status code: " + resData.getLong("result_code")); log.info(LOG_PREFIX + "SEND_BET response body: " + resData.toString()); if(resData.getLong("result_code") == 0) { tranParam.put("balance", resData.getInt("balance")); tranParam.put("isTransfer", IS_TRANSFER); int res = siteService.updateCbApi(tranParam); log.info(LOG_PREFIX + "UPDATE_CALLBACK_API_STATUS END"); int balance = resData.getInt("balance"); NexusBalanceData balanceData = new NexusBalanceData(); balanceData.setBalance(balance); balanceData.setBeforeBalance(balance + amount); balanceData.setCurrency("KRW"); response = new NexusResponse(); response.setCode(0); response.setData(balanceData); httpStatus = HttpStatus.OK; } else if(resData.getLong("result_code") == 80) { response = new NexusResponse(); response.setCode(-1); response.setMsg("금액을 확인하여 주세요"); httpStatus = HttpStatus.OK; } else if(resData.getLong("result_code") == 98) { int balance = resData.getInt("balance"); NexusBalanceData balanceData = new NexusBalanceData(); balanceData.setBalance(balance); balanceData.setBeforeBalance(balance + amount); balanceData.setCurrency("KRW"); response = new NexusResponse(); response.setCode(0); response.setData(balanceData); httpStatus = HttpStatus.OK; } else { response = new NexusResponse(); response.setCode(-999); String msg = ""; if(resData.has("error_msg")) msg = resData.getString("error_msg"); response.setMsg(msg); httpStatus = HttpStatus.OK; } } else { log.info(LOG_PREFIX + "PLAY_TRANSFER"); HashMap balanceMap = new HashMap<>(); balanceMap.put("siteIdx", siteIdx); balanceMap.put("memberId", memberId); int balance = siteService.getUserBalance(balanceMap); int afBalance = balance - amount; if(balance < amount) { response = new NexusResponse(); response.setCode(-1); response.setMsg("금액을 확인하여 주세요"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } log.info(LOG_PREFIX + "-----INSERT_BET_START-----"); long startTime = System.currentTimeMillis(); siteService.commonBetinsert(tranParam); long endTime = System.currentTimeMillis(); // 코드 실행 후에 시간 받아오기 double diffTime = (startTime - endTime)/1000.0; //두 시간에 차 계산 if(diffTime < -1.0) { log.error(LOG_PREFIX + "commonBetinsert::배팅 쓰기지연::"+diffTime+"초 지연발생"); response = new NexusResponse(); response.setCode(-999); response.setMsg("TIMEOUT_ERROR"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "TIMEOUT_ERROR::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } log.info(LOG_PREFIX + "-----INSERT_BET_END-----"); tranParam.put("balance", afBalance); tranParam.put("preBalance", balance); tranParam.put("isTransfer", IS_TRANSFER); int res = siteService.updateCbApi(tranParam); log.info(LOG_PREFIX + "UPDATE_CALLBACK_API_STATUS END"); NexusBalanceData balanceData = new NexusBalanceData(); balanceData.setBalance(afBalance); balanceData.setBeforeBalance(balance); balanceData.setCurrency("KRW"); response = new NexusResponse(); response.setCode(0); response.setData(balanceData); httpStatus = HttpStatus.OK; if(siteVendorInfo.get("siteCbUrl") != null && !"".equals(siteVendorInfo.get("siteCbUrl").toString())) { callBackObj.put("balance", afBalance); if(data.getGameCategory().equals("casino")) { asyncCallBackService.asyncChangeBalance(LOG_PREFIX, siteVendorInfo, callBackObj); } else { asyncCallBackService.asyncChangeBalanceSlot(LOG_PREFIX, siteVendorInfo, callBackObj); } } } } catch (ResourceAccessException rae) { if(rae.getCause() instanceof ConnectTimeoutException) { log.error(LOG_PREFIX+ "[ConnectTimeoutException]"+rae.getMessage()); } if(rae.getCause() instanceof SocketTimeoutException) { log.error(LOG_PREFIX+ "[SocketTimeoutException]"+rae.getMessage()); } if(rae.getCause() instanceof InterruptedException) { log.error(LOG_PREFIX+ "[InterruptedException]"+rae.getMessage()); } response = new NexusResponse(); response.setCode(-999); response.setMsg("TIMEOUT_ERROR"); httpStatus = HttpStatus.OK; } catch (Exception e) { log.error(LOG_PREFIX+ "[Exception]"+e.toString()); e.printStackTrace(); response = new NexusResponse(); response.setCode(-999); response.setMsg("BET_SERVER_ERROR"); httpStatus = HttpStatus.OK; } ResponseEntity res = new ResponseEntity(response, httpStatus); log.info(LOG_PREFIX+ "Response::" + response.toString()); return res; } @ResponseBody @RequestMapping(path = "/callResult") public ResponseEntity callResult(HttpServletRequest request, @RequestBody NexusSmlRequest requestBody) throws Exception { NexusResponse response = null; HttpStatus httpStatus = null; String apiKey = requestBody.getApiKey(); NexusSmlData data = requestBody.getParams(); String siteUsername = data.getSiteUsername(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); String betDateTimeStr = data.getCreatedAt(); if(betDateTimeStr == null || betDateTimeStr.equals("")) { betDateTimeStr = sdf.format(System.currentTimeMillis()); } else { betDateTimeStr = betDateTimeStr.replace("T", " ").replace("Z", ""); betDateTimeStr = makeEdate(betDateTimeStr, 32400000); } data.setBetDateTime(betDateTimeStr); if(siteUsername == null || siteUsername.equals("") || siteUsername.equals("invalid-user")) { response = new NexusResponse(); response.setCode(-1); response.setMsg("존재하지 않는 회원입니다"); httpStatus = HttpStatus.OK; return new ResponseEntity(response, httpStatus); } long siteIdx = Long.parseLong(siteUsername.substring(0, 3), 16); String memberId = siteUsername.substring(3, siteUsername.length()); final String LOG_PREFIX = "#-CB::ACE::"+memberId+"::"+data.getTransactionKey()+"::callResult:::"; log.info(LOG_PREFIX+ "Request::" + requestBody.toString()); if(data.getType().equals("turn_promotion")) { data.setVendorKey("pragmaticplay_casino"); } try { //사이트정보 HashMap sParam = new HashMap(); sParam.put("siteIdx", siteIdx); sParam.put("memberId", memberId); sParam.put("vendor", "ace2"); sParam.put("vendorGameCode", data.getVendorKey()); log.info(LOG_PREFIX + "getSiteVendorInfo::"+sParam.toString()); HashMap siteVendorInfo = siteService.getSiteVendorInfo(sParam); if(siteVendorInfo == null) { response = new NexusResponse(); response.setCode(-1); response.setMsg("존재하지 않는 회원입니다"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "존재하지 않는 회원입니다::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } if(!apiKey.equals(siteVendorInfo.get("vendorApiKey").toString())) { response = new NexusResponse(); response.setCode(-1); response.setMsg("API키가 일치하지 않습니다"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "API키가 일치하지 않습니다::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } // ##--isTransfer 처리-## final String IS_TRANSFER = siteVendorInfo.get("isTransfer").toString(); String siteId = siteVendorInfo.get("siteId").toString(); long memberIdx = Long.parseLong(siteVendorInfo.get("memberIdx").toString()); String vendorApiId = siteVendorInfo.get("vendorApiId").toString(); Double amountD = Double.parseDouble(data.getAmount()); int amount = Math.abs(amountD.intValue()); if(amount < 0) { response = new NexusResponse(); response.setCode(-1); response.setMsg("금액이 올바르지 않습니다"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "금액이 올바르지 않습니다::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } String vendorTranKey = data.getTransactionKey(); String tranId = data.getTransactionKey(); String betId = data.getParentTransactionKey(); if(betId == null || betId.equals("")) { betId = data.getTransactionKey(); } // ##--isTransfer 처리-## if(IS_TRANSFER.equals("Y")) { // tranId 중복체크 int cntTr = siteService.getTranIdCheck2(tranId); if(cntTr > 0) { HashMap balanceMap = new HashMap<>(); balanceMap.put("siteIdx", siteIdx); balanceMap.put("memberId", memberId); int balance = siteService.getUserBalance(balanceMap); NexusBalanceData balanceData = new NexusBalanceData(); balanceData.setBalance(balance); balanceData.setBeforeBalance(balance + amount); balanceData.setCurrency("KRW"); response = new NexusResponse(); response.setCode(0); response.setData(balanceData); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "중복요청::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } // 베팅 체크 int cntBet = siteService.getBetIdCheck2(betId); if(cntBet == 0) { response = new NexusResponse(); response.setCode(-999); response.setMsg("NOT_FOUND_REF_DATA"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "NOT_FOUND_REF_DATA::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } } String vendorKey = siteVendorInfo.get("vendorKey").toString(); int vendorIdx = Integer.parseInt(siteVendorInfo.get("vendorIdx").toString()); String vendorCetegory = siteVendorInfo.get("vendorCetegory").toString(); String gameName = data.getGameName(); HashMap tranParam = new HashMap(); tranParam.put("tranId", tranId); tranParam.put("refId", betId); tranParam.put("siteIdx", siteIdx); tranParam.put("siteId", siteId); tranParam.put("memberIdx", memberIdx); tranParam.put("memberId", memberId); tranParam.put("vendorCetegory", vendorCetegory); tranParam.put("vendorIdx", vendorIdx); tranParam.put("vendorCode", "ace2"); tranParam.put("vendorTranKey", vendorTranKey); tranParam.put("gameType", data.getGameType()); tranParam.put("gameId", data.getGameId()); tranParam.put("gameIdx", gameName); tranParam.put("tranType", "credit"); tranParam.put("depositAmt", "0"); tranParam.put("creditAmt", amount); tranParam.put("isCancel", "N"); tranParam.put("isTie", "N"); tranParam.put("apiStatus", 0); tranParam.put("vendorApiId", vendorApiId); JSONObject callBackObj = new JSONObject(); callBackObj.put("betId", betId); callBackObj.put("tranId", tranId); callBackObj.put("userId", memberId); callBackObj.put("vendorIdx", vendorIdx); callBackObj.put("vendorKey", vendorKey); callBackObj.put("vendor", "ace2"); callBackObj.put("gameIdx", vendorIdx); callBackObj.put("gameKey", gameName); if(data.getGameId() == null) data.setGameId(""); callBackObj.put("gameId", data.getGameId()); callBackObj.put("gameType", data.getGameType()); callBackObj.put("tranType", "credit"); callBackObj.put("debit", 0); callBackObj.put("credit", amount); callBackObj.put("isCancel", 0); if(data.getIsBonus().equals("true") || data.getIsPromo().equals("true") || data.getType().equals("turn_promotion")) { callBackObj.put("isBonus", 1); } else { callBackObj.put("isBonus", 0); } callBackObj.put("requestAt", betDateTimeStr); log.info(LOG_PREFIX + "SEND_RESULT request body: " + callBackObj.toString()); // ##--isTransfer 처리-## if(IS_TRANSFER.equals("N")) { log.info(LOG_PREFIX + "PLAY_SEAMLESS"); log.info(LOG_PREFIX + "-----INSERT_RESULT_START-----"); siteService.commonBetinsert(tranParam); log.info(LOG_PREFIX + "-----INSERT_RESULT_END-----"); JSONObject resData = null; if(data.getGameCategory().equals("casino")) { resData = callBackService.changeBalance(LOG_PREFIX, siteVendorInfo, callBackObj); } else { resData = callBackService.changeBalanceSlot(LOG_PREFIX, siteVendorInfo, callBackObj); } log.info(LOG_PREFIX + "SEND_RESULT status code: " + resData.getLong("result_code")); log.info(LOG_PREFIX + "SEND_RESULT response body: " + resData.toString()); if(resData.getLong("result_code") == 0) { tranParam.put("balance", resData.getInt("balance")); tranParam.put("isTransfer", IS_TRANSFER); int res = siteService.updateCbApi(tranParam); log.info(LOG_PREFIX + "UPDATE_CALLBACK_API_STATUS END"); int balance = resData.getInt("balance"); NexusBalanceData balanceData = new NexusBalanceData(); balanceData.setBalance(balance); balanceData.setBeforeBalance(balance - amount); balanceData.setCurrency("KRW"); response = new NexusResponse(); response.setCode(0); response.setData(balanceData); httpStatus = HttpStatus.OK; } else if(resData.getLong("result_code") == 98) { int balance = resData.getInt("balance"); NexusBalanceData balanceData = new NexusBalanceData(); balanceData.setBalance(balance); balanceData.setBeforeBalance(balance - amount); balanceData.setCurrency("KRW"); response = new NexusResponse(); response.setCode(0); response.setData(balanceData); httpStatus = HttpStatus.OK; } else { response = new NexusResponse(); response.setCode(-999); String msg = ""; if(resData.has("error_msg")) msg = resData.getString("error_msg"); response.setMsg(msg); httpStatus = HttpStatus.OK; } } else { log.info(LOG_PREFIX + "PLAY_TRANSFER"); HashMap balanceMap = new HashMap<>(); balanceMap.put("siteIdx", siteIdx); balanceMap.put("memberId", memberId); int balance = siteService.getUserBalance(balanceMap); int afBalance = balance + amount; log.info(LOG_PREFIX + "-----INSERT_RESULT_START-----"); siteService.commonBetinsert(tranParam); log.info(LOG_PREFIX + "-----INSERT_RESULT_END-----"); tranParam.put("balance", afBalance); tranParam.put("preBalance", balance); tranParam.put("isTransfer", IS_TRANSFER); int res = siteService.updateCbApi(tranParam); log.info(LOG_PREFIX + "UPDATE_CALLBACK_API_STATUS END"); NexusBalanceData balanceData = new NexusBalanceData(); balanceData.setBalance(afBalance); balanceData.setBeforeBalance(balance); balanceData.setCurrency("KRW"); response = new NexusResponse(); response.setCode(0); response.setData(balanceData); httpStatus = HttpStatus.OK; if(siteVendorInfo.get("siteCbUrl") != null && !"".equals(siteVendorInfo.get("siteCbUrl").toString())) { callBackObj.put("balance", afBalance); if(data.getGameCategory().equals("casino")) { asyncCallBackService.asyncChangeBalance(LOG_PREFIX, siteVendorInfo, callBackObj); } else { asyncCallBackService.asyncChangeBalanceSlot(LOG_PREFIX, siteVendorInfo, callBackObj); } } } } catch (ResourceAccessException rae) { if(rae.getCause() instanceof ConnectTimeoutException) { log.error(LOG_PREFIX+ "[ConnectTimeoutException]"+rae.getMessage()); } if(rae.getCause() instanceof SocketTimeoutException) { log.error(LOG_PREFIX+ "[SocketTimeoutException]"+rae.getMessage()); } if(rae.getCause() instanceof InterruptedException) { log.error(LOG_PREFIX+ "[InterruptedException]"+rae.getMessage()); } response = new NexusResponse(); response.setCode(-999); response.setMsg("TIMEOUT_ERROR"); httpStatus = HttpStatus.OK; } catch (Exception e) { log.error(LOG_PREFIX+ "[Exception]"+e.toString()); e.printStackTrace(); response = new NexusResponse(); response.setCode(-999); response.setMsg("RESULT_SERVER_ERROR"); httpStatus = HttpStatus.OK; } ResponseEntity res = new ResponseEntity(response, httpStatus); log.info(LOG_PREFIX+ "Response::" + response.toString()); return res; } @ResponseBody @RequestMapping(path = "/callCancel") public ResponseEntity callCancel(HttpServletRequest request, @RequestBody NexusSmlRequest requestBody) throws Exception { NexusResponse response = null; HttpStatus httpStatus = null; String apiKey = requestBody.getApiKey(); NexusSmlData data = requestBody.getParams(); String siteUsername = data.getSiteUsername(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); String betDateTimeStr = data.getCreatedAt(); if(betDateTimeStr == null || betDateTimeStr.equals("")) { betDateTimeStr = sdf.format(System.currentTimeMillis()); } else { betDateTimeStr = betDateTimeStr.replace("T", " ").replace("Z", ""); betDateTimeStr = makeEdate(betDateTimeStr, 32400000); } data.setBetDateTime(betDateTimeStr); if(siteUsername == null || siteUsername.equals("") || siteUsername.equals("invalid-user")) { response = new NexusResponse(); response.setCode(-1); response.setMsg("존재하지 않는 회원입니다"); httpStatus = HttpStatus.OK; return new ResponseEntity(response, httpStatus); } long siteIdx = Long.parseLong(siteUsername.substring(0, 3), 16); String memberId = siteUsername.substring(3, siteUsername.length()); final String LOG_PREFIX = "#-CB::ACE::"+memberId+"::"+data.getTransactionKey()+"::callCancel:::"; log.info(LOG_PREFIX+ "Request::" + requestBody.toString()); try { //사이트정보 HashMap sParam = new HashMap(); sParam.put("siteIdx", siteIdx); sParam.put("memberId", memberId); sParam.put("vendor", "ace2"); sParam.put("vendorGameCode", data.getVendorKey()); log.info(LOG_PREFIX + "getSiteVendorInfo::"+sParam.toString()); HashMap siteVendorInfo = siteService.getSiteVendorInfo(sParam); if(siteVendorInfo == null) { response = new NexusResponse(); response.setCode(-1); response.setMsg("존재하지 않는 회원입니다"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "존재하지 않는 회원입니다::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } if(!apiKey.equals(siteVendorInfo.get("vendorApiKey").toString())) { response = new NexusResponse(); response.setCode(-1); response.setMsg("API키가 일치하지 않습니다"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "API키가 일치하지 않습니다::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } // ##--isTransfer 처리-## final String IS_TRANSFER = siteVendorInfo.get("isTransfer").toString(); String siteId = siteVendorInfo.get("siteId").toString(); long memberIdx = Long.parseLong(siteVendorInfo.get("memberIdx").toString()); String vendorApiId = siteVendorInfo.get("vendorApiId").toString(); Double amountD = Double.parseDouble(data.getAmount()); int amount = Math.abs(amountD.intValue()); if(amount < 0) { response = new NexusResponse(); response.setCode(-1); response.setMsg("금액이 올바르지 않습니다"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "금액이 올바르지 않습니다::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } String vendorTranKey = data.getTransactionKey(); String tranId = data.getTransactionKey(); String betId = data.getParentTransactionKey(); if(betId == null || betId.equals("")) { betId = data.getTransactionKey(); } // ##--isTransfer 처리-## if(IS_TRANSFER.equals("Y")) { // tranId 중복체크 int cntTr = siteService.getTranIdCheck2(tranId); if(cntTr > 0) { HashMap balanceMap = new HashMap<>(); balanceMap.put("siteIdx", siteIdx); balanceMap.put("memberId", memberId); int balance = siteService.getUserBalance(balanceMap); NexusBalanceData balanceData = new NexusBalanceData(); balanceData.setBalance(balance); balanceData.setBeforeBalance(balance + amount); balanceData.setCurrency("KRW"); response = new NexusResponse(); response.setCode(0); response.setData(balanceData); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "중복요청::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } // 베팅 체크 int cntBet = siteService.getBetIdCheck2(betId); if(cntBet == 0) { response = new NexusResponse(); response.setCode(-999); response.setMsg("NOT_FOUND_REF_DATA"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "NOT_FOUND_REF_DATA::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } } String vendorKey = siteVendorInfo.get("vendorKey").toString(); int vendorIdx = Integer.parseInt(siteVendorInfo.get("vendorIdx").toString()); String vendorCetegory = siteVendorInfo.get("vendorCetegory").toString(); String gameName = data.getGameName(); HashMap tranParam = new HashMap(); tranParam.put("tranId", tranId); tranParam.put("refId", betId); tranParam.put("siteIdx", siteIdx); tranParam.put("siteId", siteId); tranParam.put("memberIdx", memberIdx); tranParam.put("memberId", memberId); tranParam.put("vendorCetegory", vendorCetegory); tranParam.put("vendorIdx", vendorIdx); tranParam.put("vendorCode", "ace2"); tranParam.put("vendorTranKey", vendorTranKey); tranParam.put("gameType", data.getGameType()); tranParam.put("gameId", data.getGameId()); tranParam.put("gameIdx", gameName); tranParam.put("tranType", "credit"); tranParam.put("depositAmt", "0"); tranParam.put("creditAmt", amount); tranParam.put("isCancel", "Y"); tranParam.put("isTie", "N"); tranParam.put("apiStatus", 0); tranParam.put("vendorApiId", vendorApiId); JSONObject callBackObj = new JSONObject(); callBackObj.put("betId", betId); callBackObj.put("tranId", tranId); callBackObj.put("userId", memberId); callBackObj.put("vendorIdx", vendorIdx); callBackObj.put("vendorKey", vendorKey); callBackObj.put("vendor", "ace2"); callBackObj.put("gameIdx", vendorIdx); callBackObj.put("gameKey", gameName); if(data.getGameId() == null) data.setGameId(""); callBackObj.put("gameId", data.getGameId()); callBackObj.put("gameType", data.getGameType()); callBackObj.put("tranType", "credit"); callBackObj.put("debit", 0); callBackObj.put("credit", amount); callBackObj.put("isCancel", 1); callBackObj.put("isBonus", 0); callBackObj.put("requestAt", betDateTimeStr); log.info(LOG_PREFIX + "SEND_CANCEL request body: " + callBackObj.toString()); // ##--isTransfer 처리-## if(IS_TRANSFER.equals("N")) { log.info(LOG_PREFIX + "PLAY_SEAMLESS"); log.info(LOG_PREFIX + "-----INSERT_CANCEL_START-----"); siteService.commonBetinsert(tranParam); log.info(LOG_PREFIX + "-----INSERT_CANCEL_END-----"); JSONObject resData = null; if(data.getGameCategory().equals("casino")) { resData = callBackService.changeBalance(LOG_PREFIX, siteVendorInfo, callBackObj); } else { resData = callBackService.changeBalanceSlot(LOG_PREFIX, siteVendorInfo, callBackObj); } log.info(LOG_PREFIX + "SEND_CANCEL status code: " + resData.getLong("result_code")); log.info(LOG_PREFIX + "SEND_CANCEL response body: " + resData.toString()); if(resData.getLong("result_code") == 0) { tranParam.put("balance", resData.getInt("balance")); tranParam.put("isTransfer", IS_TRANSFER); int res = siteService.updateCbApi(tranParam); log.info(LOG_PREFIX + "UPDATE_CALLBACK_API_STATUS END"); int balance = resData.getInt("balance"); NexusBalanceData balanceData = new NexusBalanceData(); balanceData.setBalance(balance); balanceData.setBeforeBalance(balance - amount); balanceData.setCurrency("KRW"); response = new NexusResponse(); response.setCode(0); response.setData(balanceData); httpStatus = HttpStatus.OK; } else if(resData.getLong("result_code") == 98) { int balance = resData.getInt("balance"); NexusBalanceData balanceData = new NexusBalanceData(); balanceData.setBalance(balance); balanceData.setBeforeBalance(balance - amount); balanceData.setCurrency("KRW"); response = new NexusResponse(); response.setCode(0); response.setData(balanceData); httpStatus = HttpStatus.OK; } else { response = new NexusResponse(); response.setCode(-999); String msg = ""; if(resData.has("error_msg")) msg = resData.getString("error_msg"); response.setMsg(msg); httpStatus = HttpStatus.OK; } } else { log.info(LOG_PREFIX + "PLAY_TRANSFER"); HashMap balanceMap = new HashMap<>(); balanceMap.put("siteIdx", siteIdx); balanceMap.put("memberId", memberId); int balance = siteService.getUserBalance(balanceMap); int afBalance = balance + amount; log.info(LOG_PREFIX + "-----INSERT_CANCEL_START-----"); siteService.commonBetinsert(tranParam); log.info(LOG_PREFIX + "-----INSERT_CANCEL_END-----"); tranParam.put("balance", afBalance); tranParam.put("preBalance", balance); tranParam.put("isTransfer", IS_TRANSFER); int res = siteService.updateCbApi(tranParam); log.info(LOG_PREFIX + "UPDATE_CALLBACK_API_STATUS END"); NexusBalanceData balanceData = new NexusBalanceData(); balanceData.setBalance(afBalance); balanceData.setBeforeBalance(balance); balanceData.setCurrency("KRW"); response = new NexusResponse(); response.setCode(0); response.setData(balanceData); httpStatus = HttpStatus.OK; if(siteVendorInfo.get("siteCbUrl") != null && !"".equals(siteVendorInfo.get("siteCbUrl").toString())) { callBackObj.put("balance", afBalance); if(data.getGameCategory().equals("casino")) { asyncCallBackService.asyncChangeBalance(LOG_PREFIX, siteVendorInfo, callBackObj); } else { asyncCallBackService.asyncChangeBalanceSlot(LOG_PREFIX, siteVendorInfo, callBackObj); } } } } catch (ResourceAccessException rae) { if(rae.getCause() instanceof ConnectTimeoutException) { log.error(LOG_PREFIX+ "[ConnectTimeoutException]"+rae.getMessage()); } if(rae.getCause() instanceof SocketTimeoutException) { log.error(LOG_PREFIX+ "[SocketTimeoutException]"+rae.getMessage()); } if(rae.getCause() instanceof InterruptedException) { log.error(LOG_PREFIX+ "[InterruptedException]"+rae.getMessage()); } response = new NexusResponse(); response.setCode(-999); response.setMsg("TIMEOUT_ERROR"); httpStatus = HttpStatus.OK; } catch (Exception e) { log.error(LOG_PREFIX+ "[Exception]"+e.toString()); e.printStackTrace(); response = new NexusResponse(); response.setCode(-999); response.setMsg("RESULT_SERVER_ERROR"); httpStatus = HttpStatus.OK; } ResponseEntity res = new ResponseEntity(response, httpStatus); log.info(LOG_PREFIX+ "Response::" + response.toString()); return res; } @ResponseBody @RequestMapping(path = "/callAdjust") public ResponseEntity callAdjust(HttpServletRequest request, @RequestBody NexusSmlRequest requestBody) throws Exception { NexusResponse response = null; HttpStatus httpStatus = null; String apiKey = requestBody.getApiKey(); NexusSmlData data = requestBody.getParams(); String siteUsername = data.getSiteUsername(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); String betDateTimeStr = data.getCreatedAt(); if(betDateTimeStr == null || betDateTimeStr.equals("")) { betDateTimeStr = sdf.format(System.currentTimeMillis()); } else { betDateTimeStr = betDateTimeStr.replace("T", " ").replace("Z", ""); betDateTimeStr = makeEdate(betDateTimeStr, 32400000); } data.setBetDateTime(betDateTimeStr); if(siteUsername == null || siteUsername.equals("") || siteUsername.equals("invalid-user")) { response = new NexusResponse(); response.setCode(-1); response.setMsg("존재하지 않는 회원입니다"); httpStatus = HttpStatus.OK; return new ResponseEntity(response, httpStatus); } long siteIdx = Long.parseLong(siteUsername.substring(0, 3), 16); String memberId = siteUsername.substring(3, siteUsername.length()); final String LOG_PREFIX = "#-CB::ACE::"+memberId+"::"+data.getTransactionKey()+"::callAdjust:::"; log.info(LOG_PREFIX+ "Request::" + requestBody.toString()); try { //사이트정보 HashMap sParam = new HashMap(); sParam.put("siteIdx", siteIdx); sParam.put("memberId", memberId); sParam.put("vendor", "ace2"); sParam.put("vendorGameCode", data.getVendorKey()); log.info(LOG_PREFIX + "getSiteVendorInfo::"+sParam.toString()); HashMap siteVendorInfo = siteService.getSiteVendorInfo(sParam); if(siteVendorInfo == null) { response = new NexusResponse(); response.setCode(-1); response.setMsg("존재하지 않는 회원입니다"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "존재하지 않는 회원입니다::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } if(!apiKey.equals(siteVendorInfo.get("vendorApiKey").toString())) { response = new NexusResponse(); response.setCode(-1); response.setMsg("API키가 일치하지 않습니다"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "API키가 일치하지 않습니다::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } // ##--isTransfer 처리-## final String IS_TRANSFER = siteVendorInfo.get("isTransfer").toString(); String siteId = siteVendorInfo.get("siteId").toString(); long memberIdx = Long.parseLong(siteVendorInfo.get("memberIdx").toString()); String vendorApiId = siteVendorInfo.get("vendorApiId").toString(); Double amountD = Double.parseDouble(data.getAmount()); int amount = amountD.intValue(); String vendorTranKey = data.getTransactionKey(); String tranId = data.getTransactionKey(); String betId = data.getParentTransactionKey(); if(betId == null || betId.equals("")) { betId = data.getTransactionKey(); } // ##--isTransfer 처리-## if(IS_TRANSFER.equals("Y")) { // tranId 중복체크 int cntTr = siteService.getTranIdCheck2(tranId); if(cntTr > 0) { HashMap balanceMap = new HashMap<>(); balanceMap.put("siteIdx", siteIdx); balanceMap.put("memberId", memberId); int balance = siteService.getUserBalance(balanceMap); NexusBalanceData balanceData = new NexusBalanceData(); balanceData.setBalance(balance); balanceData.setBeforeBalance(balance + amount); balanceData.setCurrency("KRW"); response = new NexusResponse(); response.setCode(0); response.setData(balanceData); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "중복요청::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } // 베팅 체크 int cntBet = siteService.getBetIdCheck2(betId); if(cntBet == 0) { response = new NexusResponse(); response.setCode(-999); response.setMsg("NOT_FOUND_REF_DATA"); httpStatus = HttpStatus.OK; log.error(LOG_PREFIX+ "NOT_FOUND_REF_DATA::Response::" + response.toString()); return new ResponseEntity(response, httpStatus); } } String vendorKey = siteVendorInfo.get("vendorKey").toString(); int vendorIdx = Integer.parseInt(siteVendorInfo.get("vendorIdx").toString()); String vendorCetegory = siteVendorInfo.get("vendorCetegory").toString(); String gameName = data.getGameName(); HashMap tranParam = new HashMap(); tranParam.put("tranId", tranId); tranParam.put("refId", betId); tranParam.put("siteIdx", siteIdx); tranParam.put("siteId", siteId); tranParam.put("memberIdx", memberIdx); tranParam.put("memberId", memberId); tranParam.put("vendorCetegory", vendorCetegory); tranParam.put("vendorIdx", vendorIdx); tranParam.put("vendorCode", "ace2"); tranParam.put("vendorTranKey", vendorTranKey); tranParam.put("gameType", data.getGameType()); tranParam.put("gameId", data.getGameId()); tranParam.put("gameIdx", gameName); if(amount >= 0) { tranParam.put("tranType", "credit"); tranParam.put("depositAmt", "0"); tranParam.put("creditAmt", amount); } else { tranParam.put("tranType", "debit"); tranParam.put("depositAmt", amount*-1); tranParam.put("creditAmt", "0"); } tranParam.put("isCancel", "N"); tranParam.put("isTie", "N"); tranParam.put("apiStatus", 0); tranParam.put("vendorApiId", vendorApiId); JSONObject callBackObj = new JSONObject(); callBackObj.put("betId", betId); callBackObj.put("tranId", tranId); callBackObj.put("userId", memberId); callBackObj.put("vendorIdx", vendorIdx); callBackObj.put("vendorKey", vendorKey); callBackObj.put("vendor", "ace2"); callBackObj.put("gameIdx", vendorIdx); callBackObj.put("gameKey", gameName); if(data.getGameId() == null) data.setGameId(""); callBackObj.put("gameId", data.getGameId()); callBackObj.put("gameType", data.getGameType()); callBackObj.put("tranType", "adjust"); if(amount >= 0) { callBackObj.put("debit", 0); callBackObj.put("credit", amount); } else { callBackObj.put("debit", amount*-1); callBackObj.put("credit", 0); } callBackObj.put("isCancel", 0); callBackObj.put("isBonus", 0); callBackObj.put("requestAt", betDateTimeStr); log.info(LOG_PREFIX + "SEND_ADJUST request body: " + callBackObj.toString()); // ##--isTransfer 처리-## if(IS_TRANSFER.equals("N")) { log.info(LOG_PREFIX + "PLAY_SEAMLESS"); log.info(LOG_PREFIX + "-----INSERT_ADJUST_START-----"); siteService.commonBetinsert(tranParam); log.info(LOG_PREFIX + "-----INSERT_ADJUST_END-----"); JSONObject resData = null; if(data.getGameCategory().equals("casino")) { resData = callBackService.changeBalance(LOG_PREFIX, siteVendorInfo, callBackObj); } else { resData = callBackService.changeBalanceSlot(LOG_PREFIX, siteVendorInfo, callBackObj); } log.info(LOG_PREFIX + "SEND_ADJUST status code: " + resData.getLong("result_code")); log.info(LOG_PREFIX + "SEND_ADJUST response body: " + resData.toString()); if(resData.getLong("result_code") == 0) { tranParam.put("balance", resData.getInt("balance")); tranParam.put("isTransfer", IS_TRANSFER); int res = siteService.updateCbApi(tranParam); log.info(LOG_PREFIX + "UPDATE_CALLBACK_API_STATUS END"); int balance = resData.getInt("balance"); NexusBalanceData balanceData = new NexusBalanceData(); balanceData.setBalance(balance); balanceData.setBeforeBalance(balance + amount); balanceData.setCurrency("KRW"); response = new NexusResponse(); response.setCode(0); response.setData(balanceData); httpStatus = HttpStatus.OK; } else if(resData.getLong("result_code") == 98) { int balance = resData.getInt("balance"); NexusBalanceData balanceData = new NexusBalanceData(); balanceData.setBalance(balance); balanceData.setBeforeBalance(balance + amount); balanceData.setCurrency("KRW"); response = new NexusResponse(); response.setCode(0); response.setData(balanceData); httpStatus = HttpStatus.OK; } else { response = new NexusResponse(); response.setCode(-999); String msg = ""; if(resData.has("error_msg")) msg = resData.getString("error_msg"); response.setMsg(msg); httpStatus = HttpStatus.OK; } } else { log.info(LOG_PREFIX + "PLAY_TRANSFER"); HashMap balanceMap = new HashMap<>(); balanceMap.put("siteIdx", siteIdx); balanceMap.put("memberId", memberId); int balance = siteService.getUserBalance(balanceMap); int afBalance = balance + amount; log.info(LOG_PREFIX + "-----INSERT_ADJUST_START-----"); siteService.commonBetinsert(tranParam); log.info(LOG_PREFIX + "-----INSERT_ADJUST_END-----"); tranParam.put("balance", afBalance); tranParam.put("preBalance", balance); tranParam.put("isTransfer", IS_TRANSFER); int res = siteService.updateCbApi(tranParam); log.info(LOG_PREFIX + "UPDATE_CALLBACK_API_STATUS END"); NexusBalanceData balanceData = new NexusBalanceData(); balanceData.setBalance(afBalance); balanceData.setBeforeBalance(balance); balanceData.setCurrency("KRW"); response = new NexusResponse(); response.setCode(0); response.setData(balanceData); httpStatus = HttpStatus.OK; if(siteVendorInfo.get("siteCbUrl") != null && !"".equals(siteVendorInfo.get("siteCbUrl").toString())) { callBackObj.put("balance", afBalance); if(data.getGameCategory().equals("casino")) { asyncCallBackService.asyncChangeBalance(LOG_PREFIX, siteVendorInfo, callBackObj); } else { asyncCallBackService.asyncChangeBalanceSlot(LOG_PREFIX, siteVendorInfo, callBackObj); } } } } catch (ResourceAccessException rae) { if(rae.getCause() instanceof ConnectTimeoutException) { log.error(LOG_PREFIX+ "[ConnectTimeoutException]"+rae.getMessage()); } if(rae.getCause() instanceof SocketTimeoutException) { log.error(LOG_PREFIX+ "[SocketTimeoutException]"+rae.getMessage()); } if(rae.getCause() instanceof InterruptedException) { log.error(LOG_PREFIX+ "[InterruptedException]"+rae.getMessage()); } response = new NexusResponse(); response.setCode(-999); response.setMsg("TIMEOUT_ERROR"); httpStatus = HttpStatus.OK; } catch (Exception e) { log.error(LOG_PREFIX+ "[Exception]"+e.toString()); e.printStackTrace(); response = new NexusResponse(); response.setCode(-999); response.setMsg("RESULT_SERVER_ERROR"); httpStatus = HttpStatus.OK; } ResponseEntity res = new ResponseEntity(response, httpStatus); log.info(LOG_PREFIX+ "Response::" + response.toString()); return res; } /** * 에볼루션 상세 콜백 * @param request * @param requestBody * @return * @throws Exception */ @ResponseBody @RequestMapping(path = "/callDetail") public ResponseEntity callDetail(HttpServletRequest request, @RequestBody net.sf.json.JSONObject requestBody) throws Exception { NexusResponse response = null; HttpStatus httpStatus = null; String apiKey = requestBody.getString("apiKey"); final String LOG_PREFIX = "#-CB::ACE::callDetail::"+apiKey+":::"; // log.info(LOG_PREFIX+ "Request::" + requestBody.toString()); try { JSONObject bodyObj = new JSONObject(requestBody.toString()); JSONArray params = bodyObj.getJSONArray("params"); String prevRefId = ""; for(int i=0; i(); detailMap.put("refId", refId); detailMap.put("orgDetail", orgDetail.toString()); detailMap.put("parDetail", null); try { int result = siteService.insertEvoDetail(detailMap); log.info(LOG_PREFIX2+ "insertEvoDetail result::" + result); } catch(DataIntegrityViolationException de) { log.error(LOG_PREFIX2+ "Duplicate refId"); continue; } } response = new NexusResponse(); response.setCode(0); response.setMsg("SUCCESS"); httpStatus = HttpStatus.OK; } catch (ResourceAccessException rae) { if(rae.getCause() instanceof ConnectTimeoutException) { log.error(LOG_PREFIX+ "[ConnectTimeoutException]"+rae.getMessage()); } if(rae.getCause() instanceof SocketTimeoutException) { log.error(LOG_PREFIX+ "[SocketTimeoutException]"+rae.getMessage()); } if(rae.getCause() instanceof InterruptedException) { log.error(LOG_PREFIX+ "[InterruptedException]"+rae.getMessage()); } response = new NexusResponse(); response.setCode(-8); response.setMsg("TIMEOUT_ERROR"); httpStatus = HttpStatus.OK; } catch (Exception e) { log.error(LOG_PREFIX+ "[Exception]"+e.toString()); e.printStackTrace(); response = new NexusResponse(); response.setCode(-9); response.setMsg("DETAIL_SERVER_ERROR"); httpStatus = HttpStatus.OK; } ResponseEntity res = new ResponseEntity(response, httpStatus); log.info(LOG_PREFIX+ "Response::" + response.toString()); return res; } /** * UTC 시간을 한국 시간(KST)으로 변환 * @param utcTimeStr UTC 시간 문자열 (예: 2026-02-06T04:39:05.243Z) * @return 한국 시간 문자열 (예: 2026-02-06T13:39:05.243+09:00) */ private static String convertUtcToKstTime(String utcTimeStr) { try { if (utcTimeStr == null || !utcTimeStr.endsWith("Z")) { return utcTimeStr; } // UTC 시간 파싱 Instant instant = Instant.parse(utcTimeStr); // 한국 시간대로 변환 (UTC+9) ZonedDateTime kstTime = instant.atZone(ZoneId.of("Asia/Seoul")); // ISO 8601 형식으로 포맷 (타임존 포함) return kstTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); } catch (Exception e) { log.error("UTC to KST conversion error: " + e.getMessage()); return utcTimeStr; // 변환 실패시 원본 반환 } } /** * JSON 객체를 재귀적으로 순회하며 시간 필드를 UTC에서 KST로 변환 * @param jsonObj 변환할 JSON 객체 */ private static void convertUtcToKst(JSONObject jsonObj) { try { // 변환할 시간 필드 목록 String[] timeFields = {"startedAt", "settledAt", "placedOn", "recordedAt"}; Iterator keys = jsonObj.keys(); while (keys.hasNext()) { String key = keys.next(); Object value = jsonObj.get(key); // 시간 필드인 경우 변환 for (String timeField : timeFields) { if (key.equals(timeField) && value instanceof String) { String utcTime = (String) value; String kstTime = convertUtcToKstTime(utcTime); jsonObj.put(key, kstTime); break; } } // 중첩된 JSONObject인 경우 재귀 호출 if (value instanceof JSONObject) { convertUtcToKst((JSONObject) value); } // 중첩된 JSONArray인 경우 각 요소 처리 else if (value instanceof JSONArray) { JSONArray jsonArray = (JSONArray) value; for (int i = 0; i < jsonArray.length(); i++) { Object arrayItem = jsonArray.get(i); if (arrayItem instanceof JSONObject) { convertUtcToKst((JSONObject) arrayItem); } } } } } catch (Exception e) { log.error("JSON time conversion error: " + e.getMessage()); } } private static String makeDateStrForUTC(boolean flag, String strDate) { String result = ""; if(flag) { // 2022-05-01 00:00:00.000 => 2022-05-01T00:00:00.000Z result = strDate.replace(" ", "T") + "Z"; } else { // 2022-05-01T00:00:00.000Z => 2022-05-01 00:00:00.000 result = strDate.replace("T", " ").replace("Z", ""); } return result; } private static String makeEdate(String paramDate, int flag) { // TODO Auto-generated method stub String eDate = ""; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); try { if(paramDate == null) { // eDate = sdf.format(System.currentTimeMillis()); eDate = sdf.format(System.currentTimeMillis() - 32400000); } else { Date date = sdf.parse(paramDate); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.MILLISECOND, flag); Date date2 = calendar.getTime(); eDate = sdf.format(date2); } } catch(Exception e) { log.error(e.getMessage()); } return eDate; } }