JIWOO 2025-08-19
Merge branch '5361_알림톡_환불수정'
@846c6cec4a05110edb7eec655e27fad15a37a4aa
src/main/java/itn/let/kakao/user/kakaoAt/service/KakaoAlimTalkService.java
--- src/main/java/itn/let/kakao/user/kakaoAt/service/KakaoAlimTalkService.java
+++ src/main/java/itn/let/kakao/user/kakaoAt/service/KakaoAlimTalkService.java
@@ -23,12 +23,10 @@
 	//카카오 친구톡 발신
 	public MjonMsgReturnVO insertKakaoFtSendAjax(KakaoVO kakaoVO) throws Exception;
 	
-	//카카오 알림톡 전송 실패 환불리스트 조회
-	public void selectKakaoAtSentRefundList() throws Exception;
-	
-	//카카오 친구톡 전송 실패 환불리스트 조회
-	public void selectKakaoFtSentRefundList() throws Exception;
-
 	StatusResponse insertKakaoAtSandAjax_advc(KakaoVO kakaoVO, HttpServletRequest request) throws Exception;
 	
+	//카카오(알림톡, 친구톡 통합) 전송 실패 환불리스트 조회
+	public List<KakaoVO> selectKakaoSentRefundListForSingle() throws Exception;
+	
+	public void kakaoSingleRefund(KakaoVO kakaoVO) throws Exception;
 }
src/main/java/itn/let/kakao/user/kakaoAt/service/impl/KakaoAlimTalkDAO.java
--- src/main/java/itn/let/kakao/user/kakaoAt/service/impl/KakaoAlimTalkDAO.java
+++ src/main/java/itn/let/kakao/user/kakaoAt/service/impl/KakaoAlimTalkDAO.java
@@ -49,13 +49,8 @@
 	}
 	
 	@SuppressWarnings("unchecked")
-	public List<KakaoVO> selectKakaoAtSentRefundList() throws Exception{
-		return (List<KakaoVO>) list("kakaoAlimTalkDAO.selectKakaoAtSentRefundList");
-	}
-	
-	@SuppressWarnings("unchecked")
-	public List<KakaoVO> selectKakaoFtSentRefundList() throws Exception{
-		return (List<KakaoVO>) list("kakaoAlimTalkDAO.selectKakaoFtSentRefundList");
+	public List<KakaoVO> selectKakaoSentRefundList() throws Exception{
+		return (List<KakaoVO>) list("kakaoAlimTalkDAO.selectKakaoSentRefundList");
 	}
 	
 	public KakaoVO selectKakaoAtUmid(KakaoVO kakaoVO) throws Exception{
src/main/java/itn/let/kakao/user/kakaoAt/service/impl/KakaoAlimTalkServiceImpl.java
--- src/main/java/itn/let/kakao/user/kakaoAt/service/impl/KakaoAlimTalkServiceImpl.java
+++ src/main/java/itn/let/kakao/user/kakaoAt/service/impl/KakaoAlimTalkServiceImpl.java
@@ -1,7 +1,6 @@
 package itn.let.kakao.user.kakaoAt.service.impl;
 
 import java.math.BigDecimal;
-import java.math.RoundingMode;
 import java.text.SimpleDateFormat;
 import java.time.Duration;
 import java.time.Instant;
@@ -11,8 +10,6 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
 import java.util.stream.Collectors;
 
 import javax.annotation.Resource;
@@ -22,12 +19,13 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
 
 import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;
 import egovframework.rte.fdl.idgnr.EgovIdGnrService;
 import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper;
 import itn.com.cmm.LoginVO;
-import itn.com.cmm.MjonMsgSendVO;
 import itn.com.utl.fcc.service.EgovStringUtil;
 import itn.let.kakao.kakaoComm.BizKakaoPriceVO;
 import itn.let.kakao.kakaoComm.KakaoSendAdvcVO;
@@ -51,7 +49,6 @@
 import itn.let.sym.site.service.JoinSettingVO;
 import itn.let.sym.site.service.impl.SiteManagerDAO;
 import itn.let.uss.umt.service.EgovUserManageService;
-import itn.let.uss.umt.service.UserManageVO;
 import lombok.extern.slf4j.Slf4j;
 
 @Slf4j
@@ -105,6 +102,8 @@
 	final String RESEND_YN_YES = "Y";
 	final String SMS_SUCCESS_CODE = "4100"; // SMS 성공 코드
 	final String MMS_SUCCESS_CODE = "6600"; // MMS 성공 코드
+	final String AT_MSG_TYPE = "8"; // MSG 타입 알림톡
+	final String FT_MSG_TYPE = "9"; // MSG 타입 친구톡
 	
 	//발신프로필 상태값 변경(삭제/복구 기능)
 	@Override
@@ -793,144 +792,76 @@
 		return returnVO;
 	}
 	
-	
-	/*
-	 * 카카오 알림톡 발송 실패에 따른 금액 환불 처리
-	 * 
-	 * */
-	@Override
-	public void selectKakaoAtSentRefundList() throws Exception {
+	private void processKakaoSendCharge(KakaoVO kakaoVO) throws Exception {
 		
-		/**
-		 * 1. 카카오 AT 전송성공 확인
-		 * 2. 카카오 AT 전송실패, 대채문자 전송확인
-		 * 3. 카카오 AT 전송 실패 확인
-		 */
-		List<KakaoVO> kakaoAtSentRefundList = kakaoAlimTalkDAO.selectKakaoAtSentRefundList();
-		
-		for(KakaoVO vo : kakaoAtSentRefundList) {
-			System.out.println(vo.getMsgGroupId() +"________결과 : " +vo.getRsltCode() +"     대체문자 전송 : "+vo.getSubMsgSendYn());			
-			if(vo.getRsltCode().equals("7000")) {
-				kakaoAlimTalkDAO.updateKakaoAtSend(vo);
-			}else if(vo.getSubMsgSendYn().equals("Y")) {
-				KakaoVO info = kakaoAlimTalkDAO.selectKakaoAtUmid(vo);
-				
-				System.out.println("대체문자 전송 : " + info.getBizUmid());
-				if (info.getBizUmid() != null) {
-					kakaoAlimTalkDAO.updateKakaoAtSubMsgSend(vo);
-				}else {
-					kakaoAlimTalkDAO.updateKakaoAtNotSend(vo);	 
-				}
-				
-			}else {
-				kakaoAlimTalkDAO.updateKakaoAtNotSend(vo);
-			}
-		}
-	}
-	
-	
-	/**
-	 * @ 카카오 친구톡 환불 
-	 */
-	@Override
-	public void selectKakaoFtSentRefundList() throws Exception {
-		
-		List<KakaoVO> kakaoFtSentRefundList = kakaoAlimTalkDAO.selectKakaoFtSentRefundList();
-		
-		for(KakaoVO kakaoVO : kakaoFtSentRefundList) {
-			System.out.println(kakaoVO.getMsgGroupId() +"________결과 : " +kakaoVO.getRsltCode() +"     대체문자 전송 : "+kakaoVO.getSubMsgSendYn());
-			
-			if(KAKAO_SUCCESS_CODE.equals(kakaoVO.getRsltCode())) {//친구톡 발송 성공시
-			
-				processFtSendCharge(kakaoVO); 
-				
-			}else if(RESEND_YN_YES.equals(kakaoVO.getSubMsgSendYn())) {
-				//친구톡 발송 실패 했고, 대체문자 발송 했을 경우
-				handleAlternativeMessageScenario(kakaoVO);
-				
-			}else {
-				handleRefund(kakaoVO, "카카오 친구톡 전송 실패로 인한 결재 금액 환불");
-			}
-		}
-	}
-	
-
-	private void processFtSendCharge(KakaoVO kakaoVO) throws Exception {
-		
-
+		//1-1.카카오톡 발송 성공 + 대체문자 신청 O : 대체문자 금액 환불
 		if(RESEND_YN_YES.equals(kakaoVO.getSubMsgSendYn())) {
 
 			BizKakaoPriceVO bizKakaoPriceVO = mjonPayDAO.selectBizKakaoPrice(kakaoVO.getMsgGroupId());
 			
 			BigDecimal sendPrice = null;
-			if(StringUtils.isEmpty(kakaoVO.getBizKakaoImageType())){
-				sendPrice = new BigDecimal(bizKakaoPriceVO.getBizKakaoFtPrice());
-			}else if("I".equals(kakaoVO.getBizKakaoImageType())){
-				sendPrice = new BigDecimal(bizKakaoPriceVO.getBizKakaoFtImgPrice());
-			}else if("W".equals(kakaoVO.getBizKakaoImageType())){
-				sendPrice = new BigDecimal(bizKakaoPriceVO.getBizKakaoFtWideImgPrice());
+			
+			if(AT_MSG_TYPE.equals(kakaoVO.getMsgType())){
+				sendPrice = new BigDecimal(bizKakaoPriceVO.getBizKakaoAtPrice());
+			}else {
+				if(StringUtils.isEmpty(kakaoVO.getBizKakaoImageType())){
+					sendPrice = new BigDecimal(bizKakaoPriceVO.getBizKakaoFtPrice());
+				}else if("I".equals(kakaoVO.getBizKakaoImageType())){
+					sendPrice = new BigDecimal(bizKakaoPriceVO.getBizKakaoFtImgPrice());
+				}else if("W".equals(kakaoVO.getBizKakaoImageType())){
+					sendPrice = new BigDecimal(bizKakaoPriceVO.getBizKakaoFtWideImgPrice());
+				}
 			}
-
 			// 예시: 각 건당 가격이 이미 String 형태라면 변환
 			BigDecimal eachPrice = new BigDecimal(kakaoVO.getEachPrice());
 
 			// 차이 계산
 			BigDecimal diffPrice = eachPrice.subtract(sendPrice);
 			
-			
+			//대체문자 비용(eachPrace - sendPrice)
 			if (diffPrice.compareTo(BigDecimal.ZERO) > 0) {
 				String result = diffPrice.toString();
 				kakaoVO.setEachPrice(result);
-
-				handleRefund(kakaoVO, "카카오 친구톡 전송으로 인한 결재 차액 환불");
+				handleRefund(kakaoVO, "카카오 " + kakaoVO.getMsgTypeTxt() + " 발송 성공 후 대체문자 금액 환불");
 			}
 			
-		}else {
-			mjonMsgDAO.updateRefundY(kakaoVO);
-			
 		}
-		// TODO Auto-generated method stub
 		
+		//1-2.카카오톡 발송 성공 + 대체문자 신청 X : 금액 환불 X
 	}
 
 	private void handleAlternativeMessageScenario(KakaoVO kakaoVO) throws Exception {
 		KakaoVO bizLogVO = kakaoAlimTalkDAO.selectBizLog(kakaoVO.getBizUmid());
 		log.info("대체문자 전송 UMID: {}", kakaoVO.getBizUmid());
 	
-		// 대체문자가 성공적으로 발송되었는지 확인 (SMS 또는 MMS 성공)
+		//2-1.카카오톡 발송 실패 + 대체문자 발송 성공 : 금액 환불 X
 		boolean isAlternativeMessageSuccessful = false;
 		if (bizLogVO != null && StringUtils.isNotEmpty(bizLogVO.getBizLogCallStatus())) {
 			if (SMS_SUCCESS_CODE.equals(bizLogVO.getBizLogCallStatus()) 
 					|| MMS_SUCCESS_CODE.equals(bizLogVO.getBizLogCallStatus())) {
 				isAlternativeMessageSuccessful = true;
 			}
+			log.info("bizLogVO.getBizLogCallStatus() :: [{}]", bizLogVO.getBizLogCallStatus());
+			log.info("isAlternativeMessageSuccessful :: [{}]", isAlternativeMessageSuccessful);
 		}
 
-		log.info("bizLogVO.getBizLogCallStatus() :: [{}]", bizLogVO.getBizLogCallStatus());
-		log.info("isAlternativeMessageSuccessful :: [{}]", isAlternativeMessageSuccessful);
 		
-		// 대체문자 성공이면 환불 완료처리면 한다.
-		if (isAlternativeMessageSuccessful) {
-			mjonMsgDAO.updateRefundY(kakaoVO);
-		} else {
-			// 대체문자 발송 실패 된 경우 (친구톡 비용 환불 필요)
-			handleRefund(kakaoVO, "카카오 친구톡 전송 실패로 인한 결재 금액 환불");
-		}
+		//2-2.카카오톡 발송 실패 + 대체문자 발송 실패 : 전액 환불
+		if (!isAlternativeMessageSuccessful) {
+			handleRefund(kakaoVO, "카카오 " + kakaoVO.getMsgTypeTxt() + " 전송 실패로 인한 결제 금액 환불");
+		} 
 	}
 	
 	private void handleRefund(KakaoVO vo, String msg) throws Exception {
 		// mj_cash 테이블에 환불 내역 추가 및 회원 금액 업데이트
 		// eachPrice는 환불될 금액이므로 양수여야 합니다.
-		priceAndPoint.insertCashAndPoint(
+		priceAndPoint.insertCashAndPointNoUpdate(
 			vo.getUserId(),
 			Float.parseFloat(vo.getEachPrice()), // 환불 금액은 양수
 			msg,
 			vo.getMsgGroupId(),
 			vo.getUserData()
 		);
-		
-		// 해당 row 환불 처리 (mj_msg_data.REFUND_YN = 'Y')
-		mjonMsgDAO.updateRefundY(vo);
 	}
 
 	@Override
@@ -1104,8 +1035,33 @@
 		return statusResponse;
 	}
 	
-	
+	@Override
+	public List<KakaoVO> selectKakaoSentRefundListForSingle() throws Exception{
+		return kakaoAlimTalkDAO.selectKakaoSentRefundList();
+	}	
 
+	@Override
+	public void kakaoSingleRefund(KakaoVO kakaoVO) throws Exception {
+		
+		System.out.println(kakaoVO.getMsgGroupId() +"________결과 : " +kakaoVO.getRsltCode() +"     대체문자 전송 : "+kakaoVO.getSubMsgSendYn());
+		kakaoVO.setMsgTypeTxt(AT_MSG_TYPE.equals(kakaoVO.getMsgType()) ? "알림톡" : "친구톡");
+		
+		if(KAKAO_SUCCESS_CODE.equals(kakaoVO.getRsltCode())) {
+			//1.카카오톡 발송 성공
+			processKakaoSendCharge(kakaoVO); 
+			
+		}else if(RESEND_YN_YES.equals(kakaoVO.getSubMsgSendYn())) {//카카오톡 발송 실패, 대체문자 발송 신청 O
+			//2.카카오톡 발송 실패 + 대체문자 신청 O
+			handleAlternativeMessageScenario(kakaoVO);
+			
+		}else {
+			//3.카카오톡 발송 실패 + 대체문자 신청 X : 전액 환불
+			handleRefund(kakaoVO, "카카오 " + kakaoVO.getMsgTypeTxt() + " 전송 실패로 인한 결제 금액 환불");
+		}
+		
+		//모든 유형 환불 완료 처리
+		mjonMsgDAO.updateRefundY(kakaoVO);
+	}
 
 //	// 보유 금액이 충분한지 확인하는 메서드
 //	private boolean isCashSufficient(String userId, List<KakaoSendAdvcVO> kakaoSendAdvcListVO) throws Exception {
@@ -1127,35 +1083,6 @@
 //		// 비교 수행
 //		return befCash.compareTo(totalEachPrice) >= 0;
 //	}
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
 	
 	
 }
src/main/java/itn/let/kakao/user/kakaoAt/web/KakaoAlimTalkSendController.java
--- src/main/java/itn/let/kakao/user/kakaoAt/web/KakaoAlimTalkSendController.java
+++ src/main/java/itn/let/kakao/user/kakaoAt/web/KakaoAlimTalkSendController.java
@@ -9,9 +9,11 @@
 import java.util.Calendar;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 import javax.annotation.Resource;
@@ -61,7 +63,6 @@
 import itn.com.cmm.util.StringUtil;
 import itn.com.utl.fcc.service.EgovStringUtil;
 import itn.let.kakao.kakaoComm.KakaoReturnVO;
-import itn.let.kakao.kakaoComm.KakaoSendAdvcVO;
 import itn.let.kakao.kakaoComm.KakaoSendUtil;
 import itn.let.kakao.kakaoComm.KakaoVO;
 import itn.let.kakao.kakaoComm.kakaoApi.KakaoApiJsonSave;
@@ -79,6 +80,9 @@
 import itn.let.mjo.msgholiday.service.MsgAlarmSetVO;
 import itn.let.mjo.msgholiday.service.MsgHolidayService;
 import itn.let.mjo.msgholiday.service.MsgHolidayVO;
+import itn.let.mjo.pay.service.MjonPayService;
+import itn.let.mjo.pay.service.MjonPayVO;
+import itn.let.org.web.OrgChartManageController;
 import itn.let.sym.site.service.EgovSiteManagerService;
 import itn.let.sym.site.service.JoinSettingVO;
 import itn.let.uss.umt.service.EgovUserManageService;
@@ -101,6 +105,8 @@
  */
 @Controller
 public class KakaoAlimTalkSendController {
+
+    private final OrgChartManageController orgChartManageController;
 
 	@Resource(name = "egovMjonMsgGroupIdGnrService")
 	private EgovIdGnrService idgenMjonMsgGroupId;
@@ -149,6 +155,13 @@
 	
 	@Autowired
 	private MjonCommon mjonCommon;
+	
+	@Resource(name = "mjonPayService")
+	private MjonPayService mjonPayService;
+
+    KakaoAlimTalkSendController(OrgChartManageController orgChartManageController) {
+        this.orgChartManageController = orgChartManageController;
+    }
 
 	@RequestMapping(value= {"/web/mjon/alimtalk/kakaoAlimtalkMsgDataView.do"})
 	public String KakaoAlimtalkMsgDataView(ModelMap model
@@ -1540,4 +1553,55 @@
 		
 		return "web/kakao/msgdata/at/KakaoAlimtalkMsgDataView_tmp";
 	}
+	
+	public void kakaoRefundSingleTransaction() throws Exception{
+		System.out.println("=============카카오 환불 싱글 트랜잭션 수행 =============");
+		
+		/* 회원 money 업데이트 처리 트랜잭션 분리를 위하여 impl이 아닌 현재 위치에서 반복문 실행 */
+		System.out.println("=============SchedulerUtil=====runKakaoOneTime =============>");
+		List<KakaoVO> kakaoRefundList = kakaoAlimTalkService.selectKakaoSentRefundListForSingle();
+		Set<String> targetIdSet = new HashSet<>();
+		
+		for(KakaoVO kakaoVO : kakaoRefundList) {
+			try {
+				kakaoAlimTalkService.kakaoSingleRefund(kakaoVO);
+				targetIdSet.add(kakaoVO.getUserId());
+			} catch (Exception e) {
+				String msg = "[문자온] 환불 실패 - " + kakaoVO.getMsgId() +"("+ kakaoVO.getUserId() + ")";
+				mjonCommon.sendSimpleSlackMsg(msg);;
+			}
+		}
+		
+		MjonPayVO mjonPayVO = new MjonPayVO();
+		for(String userId : targetIdSet) {
+			try {
+			mjonPayVO.setUserId(userId);
+			mjonPayService.updateMemberCash(mjonPayVO); //회원정보 업데이트
+			} catch(Exception e) {
+				String msg = "[문자온] 환불 후 잔액 갱신 실패 - " + userId;
+				mjonCommon.sendSimpleSlackMsg(msg);;
+			}
+		}
+		
+	}
+	
+	/**
+	* @Method Name : kakaoMsgSendRefundTestAjax
+	* @작성일 : 2025. 8. 6.
+	* @작성자 :  이지우
+	* @Method 설명 : 카카오 친구톡 전송 환불 스케줄러 서비스 테스트
+	*/
+	@RequestMapping(value= {"/web/mjon/kakao/alimtalk/kakaoMsgSendRefundTestAjax.do"})
+	public ModelAndView kakaoMsgSendRefundTestAjax(ModelMap model
+			, HttpServletRequest request
+			, @ModelAttribute("kakaoVO")  KakaoVO kakaoVO) throws Exception {
+		
+		ModelAndView modelAndView = new ModelAndView(); 
+		modelAndView.setViewName("jsonView");
+		
+		this.kakaoRefundSingleTransaction();
+		
+		modelAndView.addObject("result", "success");
+		return modelAndView;
+	}
 }
src/main/java/itn/let/kakao/user/kakaoFt/web/KakaoFriendsTalkSendController.java
--- src/main/java/itn/let/kakao/user/kakaoFt/web/KakaoFriendsTalkSendController.java
+++ src/main/java/itn/let/kakao/user/kakaoFt/web/KakaoFriendsTalkSendController.java
@@ -711,27 +711,6 @@
 		return modelAndView;
 	}
 	
-	
-	/**
-	* @Method Name : kakaoFriendsTalkMsgSendRefundTestAjax
-	* @작성일 : 2024. 1. 18.
-	* @작성자 :  우영두
-	* @Method 설명 : 카카오 친구톡 전송 환불 스케줄러 서비스 테스트
-	*/
-	@RequestMapping(value= {"/web/mjon/kakao/friendstalk/kakaoFriendsTalkMsgSendRefundTestAjax.do"})
-	public ModelAndView kakaoFriendsTalkMsgSendRefundTestAjax(ModelMap model
-			, HttpServletRequest request
-			, @ModelAttribute("kakaoVO")  KakaoVO kakaoVO) throws Exception {
-		
-		ModelAndView modelAndView = new ModelAndView(); 
-		modelAndView.setViewName("jsonView");
-		
-		kakaoAlimTalkService.selectKakaoFtSentRefundList();
-		
-		modelAndView.addObject("result", "success");
-		return modelAndView;
-	}
-	
 	/**
 	* @Method Name : kakaoFriendsTalkMsgSendRefundTestAjax
 	* @작성일 : 2024. 1. 18.
src/main/java/itn/let/module/base/PriceAndPoint.java
--- src/main/java/itn/let/module/base/PriceAndPoint.java
+++ src/main/java/itn/let/module/base/PriceAndPoint.java
@@ -213,6 +213,36 @@
 		kakaoAlimTalkDAO.insertKakaoSendPrice(kakaoVO);
 		
 	}
- 
+
+	/**
+	 * @methodName	: insertCashAndPoint 
+	 * @author		: 이지우
+	 * @date		: 2025. 8. 14.
+	 * @description	: insertCashAndPoint 에서 updateMemberCash 제외
+	 * @return : void
+	 * @param userId
+	 * @param totPrice
+	 * @param memo
+	 * @param msgGroupId
+	 * @param userData
+	 * @throws Exception
+	 * 
+	 */
+	public void insertCashAndPointNoUpdate(
+			String userId
+			, float totPrice
+			, String memo
+			, String msgGroupId
+			, String userData
+			) throws Exception {
+		
+		MjonPayVO mjonPayVO = buildPayVO(userId, totPrice, memo, msgGroupId);
+
+//		 환불로 인해 userData가 추후 사용될 경우 여기에 처리
+		 if (StringUtils.isNotEmpty(userData)) { mjonPayVO.setOrderId(userData); }
+		
+		mjonPayDAO.insertCash(mjonPayVO); //캐시 
+		
+	}
  
 }
(No newline at end of file)
src/main/java/itn/let/schdlr/service/SchdlrManageService.java
--- src/main/java/itn/let/schdlr/service/SchdlrManageService.java
+++ src/main/java/itn/let/schdlr/service/SchdlrManageService.java
@@ -47,9 +47,6 @@
 	//전용계좌 자동 충전 배치
 	public void vacsAutoCharge() throws Exception;
 	
-	//문자온 카카오톡 실패 건수 환불 배치
-	public void kakaoFailPayBack() throws Exception;
-	
 	//문자온 문자전송 실패 건수 환불 배치
 	public void payBack(String type, int limitCout) throws Exception;
 
src/main/java/itn/let/schdlr/service/SchedulerUtil.java
--- src/main/java/itn/let/schdlr/service/SchedulerUtil.java
+++ src/main/java/itn/let/schdlr/service/SchedulerUtil.java
@@ -2,7 +2,9 @@
 
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import javax.annotation.Resource;
 import javax.sql.DataSource;
@@ -24,12 +26,16 @@
 import itn.let.fax.admin.service.FaxStatVO;
 import itn.let.kakao.admin.kakaoAt.service.MjonKakaoAtStatVO;
 import itn.let.kakao.admin.statistics.service.KakaoStatisticsService;
+import itn.let.kakao.kakaoComm.KakaoVO;
+import itn.let.kakao.user.kakaoAt.service.KakaoAlimTalkService;
 import itn.let.lett.service.LetterService;
 import itn.let.mail.service.MailTemplateService;
+import itn.let.mjo.mjocommon.MjonCommon;
 import itn.let.mjo.msg.service.MjonMsgService;
 import itn.let.mjo.msg.service.MjonMsgStatVO;
-import itn.let.mjo.msg.service.MjonMsgVO;
 import itn.let.mjo.msgdata.service.impl.MjonMsgDataDAO;
+import itn.let.mjo.pay.service.MjonPayService;
+import itn.let.mjo.pay.service.MjonPayVO;
 import itn.let.sts.com.StatsVO;
 import itn.let.sts.cst.service.EgovConectStatsService;
 import itn.let.uss.umt.service.EgovUserManageService;
@@ -81,6 +87,15 @@
 	
 	@Resource(name="MjonMsgDataDAO")
 	private MjonMsgDataDAO mjonMsgDataDAO;
+	
+	@Resource(name="kakaoAlimTalkService")
+	private KakaoAlimTalkService kakaoAlimTalkService;
+	
+	@Resource(name="MjonCommon")
+	private MjonCommon mjonCommon;
+
+	@Resource(name = "mjonPayService")
+    private MjonPayService mjonPayService;
 	
     /** 설정값 가져오기 */
 	@Value("#{globalSettings['Globals.Env']}")
@@ -470,15 +485,33 @@
 	@SchedulerLock(name = "runKakaoOneTime", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN)
 	public void runKakaoOneTime() throws Exception {
 		
-		// do something...
-		try {
+			/* 회원 money 업데이트 처리 트랜잭션 분리를 위하여 impl이 아닌 현재 위치에서 반복문 실행 */
 			System.out.println("=============SchedulerUtil=====runKakaoOneTime =============>");
-			schdlrManageService.kakaoFailPayBack();
-		}catch(Exception ex) {
-			ex.printStackTrace();
-		}	
+			List<KakaoVO> kakaoRefundList = kakaoAlimTalkService.selectKakaoSentRefundListForSingle();
+			Set<String> targetIdSet = new HashSet<>();
+			
+			for(KakaoVO kakaoVO : kakaoRefundList) {
+				try {
+					kakaoAlimTalkService.kakaoSingleRefund(kakaoVO);
+					targetIdSet.add(kakaoVO.getUserId());
+				} catch (Exception e) {
+					String msg = "[문자온] 환불 실패 - " + kakaoVO.getMsgId() +"("+ kakaoVO.getUserId() + ")";
+					mjonCommon.sendSimpleSlackMsg(msg);;
+				}
+			}
+			
+			MjonPayVO mjonPayVO = new MjonPayVO();
+			for(String userId : targetIdSet) {
+				try {
+				mjonPayVO.setUserId(userId);
+				mjonPayService.updateMemberCash(mjonPayVO); //회원정보 업데이트
+				} catch(Exception e) {
+					String msg = "[문자온] 환불 후 잔액 갱신 실패 - " + userId;
+					mjonCommon.sendSimpleSlackMsg(msg);;
+				}
+			}
+			
 	}
-	
 	//환불 실행
 	private void PayBack(String p_type) throws Exception {
 		
src/main/java/itn/let/schdlr/service/impl/SchdlrManageServiceImpl.java
--- src/main/java/itn/let/schdlr/service/impl/SchdlrManageServiceImpl.java
+++ src/main/java/itn/let/schdlr/service/impl/SchdlrManageServiceImpl.java
@@ -437,17 +437,6 @@
 
 	}
 
-	// 카카오 환불 처리 리스트
-	public void kakaoFailPayBack() throws Exception {
-
-		// 카카오 알림톡 환불 처리
-		kakaoAlimTalkService.selectKakaoAtSentRefundList();
-
-		// 카카오 친구톡 환불 처리
-		kakaoAlimTalkService.selectKakaoFtSentRefundList();
-
-	}
-
 	@Override
 	public void payBack(String type, int limitCout) throws Exception {
 		// 문자 환불
src/main/resources/egovframework/sqlmap/let/mjo/kakao/Kakao_AT_SQL_Mysql.xml
--- src/main/resources/egovframework/sqlmap/let/mjo/kakao/Kakao_AT_SQL_Mysql.xml
+++ src/main/resources/egovframework/sqlmap/let/mjo/kakao/Kakao_AT_SQL_Mysql.xml
@@ -205,36 +205,11 @@
 		)
 	</insert>
 	
-	<select id="kakaoAlimTalkDAO.selectKakaoAtSentRefundList" resultClass="kakaoVO">
+	<select id="kakaoAlimTalkDAO.selectKakaoSentRefundList" resultClass="kakaoVO">
 		SELECT
 			MMD.USER_ID									AS userId
 			, MMD.MSG_GROUP_ID							AS msgGroupId
-			, MMD.MSG_SEQ								AS msgSeq
-			, MMD.USERDATA								AS userData
-			, MMD.REFUND_YN								AS refundYn
-			, MMD.RSLT_CODE								AS rsltCode
-			, MMD.RSLT_CODE2							AS rsltCode2
-			, MMD.AGENT_CODE							AS agentCode
-			, DATE_FORMAT(MMD.SENT_DATE,'%Y-%m-%d %T')	AS sentDate
-			, DATE_FORMAT(MMD.RSLT_DATE,'%Y-%m-%d %T')	AS rsltDate
-			, MMD.BIZ_KAKAO_RESEND_YN					AS subMsgSendYn
-			, MMD.BIZ_KAKAO_RESEND_TYPE					AS subMsgType
-			
-		FROM
-			MJ_MSG_DATA MMD
-			INNER JOIN LETTNGNRLMBER MB
-			ON MMD.USER_ID = MB.MBER_ID
-		WHERE 1=1
-			AND	MMD.CUR_STATE          = '3'
-			AND	MMD.REFUND_YN          = 'N'
-			AND	MMD.RESERVE_C_YN       = 'N'
-			AND MMD.MSG_TYPE = 8
-	</select>
-	
-	<select id="kakaoAlimTalkDAO.selectKakaoFtSentRefundList" resultClass="kakaoVO">
-		SELECT
-			MMD.USER_ID									AS userId
-			, MMD.MSG_GROUP_ID							AS msgGroupId
+			, MMD.MSG_ID								AS msgId
 			, MMD.MSG_SEQ								AS msgSeq
 			, MMGD.BIZ_KAKAO_IMAGE_TYPE 				AS bizKakaoImageType
 			, MMGD.EACH_PRICE			 				AS eachPrice
@@ -249,6 +224,7 @@
 			, MMD.BIZ_KAKAO_RESEND_TYPE					AS subMsgType
 			, MMD.FILE_CNT 								AS fileCnt
 			, MMD.BIZ_UMID								AS bizUmid
+			, MMD.MSG_TYPE								AS msgType
 		FROM
 			MJ_MSG_DATA MMD
 			INNER JOIN LETTNGNRLMBER MB
@@ -259,7 +235,8 @@
 			AND	MMD.CUR_STATE          = '3'
 			AND	MMD.REFUND_YN          = 'N'
 			AND	MMD.RESERVE_C_YN       = 'N'
-			AND MMD.MSG_TYPE = 9
+			AND MMD.MSG_TYPE IN(8, 9)
+		ORDER BY MMD.USER_ID ASC
 	</select>
 	
 	<select id="kakaoAlimTalkDAO.selectKakaoAtUmid" resultClass="kakaoVO" parameterClass="kakaoVO">
Add a comment
List