package com.style24.front.biz.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;

import javax.net.ssl.HttpsURLConnection;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.gagaframework.web.parameter.GagaMap;
import com.kcp.J_PP_CLI_N;
import com.style24.core.biz.dao.TscOrderDao;
import com.style24.core.biz.service.TscKakaoPayService;
import com.style24.core.biz.service.TscKcpService;
import com.style24.core.biz.service.TscNaverPayService;
import com.style24.core.biz.service.TscOrderService;
import com.style24.core.support.env.TscConstants;
import com.style24.front.biz.dao.TsfCartDao;
import com.style24.front.biz.dao.TsfGoodsDao;
import com.style24.front.biz.dao.TsfOrderDao;
import com.style24.front.biz.dao.TsfRendererDao;
import com.style24.front.support.security.session.TsfSession;
import com.style24.persistence.domain.Cart;
import com.style24.persistence.domain.Coupon;
import com.style24.persistence.domain.Delivery;
import com.style24.persistence.domain.GiftCard;
import com.style24.persistence.domain.Goods;
import com.style24.persistence.domain.GoodsStock;
import com.style24.persistence.domain.KakaoPay;
import com.style24.persistence.domain.NaverPay;
import com.style24.persistence.domain.Order;
import com.style24.persistence.domain.Payment;
import com.usafe.guarantee.InsuranceInfo;
import com.usafe.guarantee.InsuranceManager;

import lombok.extern.slf4j.Slf4j;

/**
 * 주문 Service
 *
 * @author gagamel
 * @since 2020. 12. 29
 */
@Service
@Slf4j
public class TsfOrderService {

	@Autowired
	private TsfOrderDao orderDao;

	@Autowired
	private TscKcpService coreKcpService;

	@Autowired
	private TscOrderDao coreOrderDao;
	
	@Autowired
	private TscKakaoPayService coreKakaoPayService;
	
	@Autowired
	private TscNaverPayService coreNaverPayService;
	
	@Autowired
	private TsfGoodsService goodsService;
	
	@Autowired
	private TsfCartService cartService;

	@Autowired
	private TsfRendererDao rendererDao;
	
	@Autowired
	private TscOrderService coreOrderService;

	@Autowired
	private Environment env;
	
	@Autowired
	private TsfCartDao cartDao;

	@Autowired
	private TsfGoodsDao goodsDao;

	/**
	 * 마이페이지 주문 정보 조회
	 *
	 * @param Order
	 * @author card007
	 * @since 2021. 02. 04
	 */
	public Collection<GagaMap> getOrderListForMypage(Order order) {
		Collection<GagaMap> orderList = new ArrayList<>();
		Collection<Order> ordDtlList = new ArrayList<>();
		String allCanYn = "Y";
		String allDecideYn = "Y";
		String canChgAddr = "Y";
		int ordNo = 0;
		int index = 0;
		int ordReqChgQty = 0;

		for (Order tmpOrder : orderDao.getOrderListForMypage(order)) {
			// 세트상품 옵션별 배열로 담기
			if (tmpOrder.getItemNm().contains("!@!")) {
				tmpOrder.setItemNmArr(tmpOrder.getItemNm().split("!@!"));
				tmpOrder.setColorNmArr(tmpOrder.getColorNm().split(","));
				tmpOrder.setOptCd1Arr(tmpOrder.getOptCd1().split(","));
				tmpOrder.setOptCd2Arr(tmpOrder.getOptCd2().split(","));
			} else {
				String[] arr = {tmpOrder.getItemNm()}, arr2 = {tmpOrder.getColorNm()}, arr3 = {tmpOrder.getOptCd1()}, arr4 = {tmpOrder.getOptCd2()};
				tmpOrder.setItemNmArr(arr);
				tmpOrder.setColorNmArr(arr2);
				tmpOrder.setOptCd1Arr(arr3);
				tmpOrder.setOptCd2Arr(arr4);
			}

			// 주문 목록 데이터 설정
			if (index > 0 && ordNo != tmpOrder.getOrdNo()) {
				orderList.add(setOrderMap(ordDtlList, allCanYn, allDecideYn, ordReqChgQty, canChgAddr));

				ordDtlList = new ArrayList<>();
				ordDtlList.add(tmpOrder);
				allCanYn = "Y";
				allDecideYn = "Y";
				ordReqChgQty = 0;
			} else {
				ordDtlList.add(tmpOrder);
			}

			// 전체취소 가능 여부 설정
			ordReqChgQty += tmpOrder.getOrdReqChgQty();

			if ("Y".equals(allCanYn)
				&& !TscConstants.OrderDetailStat.DEPOSIT_WAIT.value().equals(tmpOrder.getOrdDtlStat())
				&& !TscConstants.OrderDetailStat.PAYMENT_COMPLETE.value().equals(tmpOrder.getOrdDtlStat())
				&& !TscConstants.OrderDetailStat.GOODS_PREPARE.value().equals(tmpOrder.getOrdDtlStat())) {
				allCanYn = "N";
			}

			// 2021.06.28 취소수량 존재 시 전체취소 불가 처리
			if ("Y".equals(allCanYn) && tmpOrder.getCnclRtnQty() > 0) {
				allCanYn = "N";
			}

			// 전체 구매확정 가능 여부 설정
			if ("Y".equals(allDecideYn)
				&& (!TscConstants.OrderDetailStat.DELIVERY_COMPLETE.value().equals(tmpOrder.getOrdDtlStat()) || ordReqChgQty > 0)) {
				allDecideYn = "N";
			}
			
			// 배송지 수정 가능 여부 설정
			if ("Y".equals(canChgAddr)
				&& !TscConstants.OrderDetailStat.DEPOSIT_WAIT.value().equals(tmpOrder.getOrdDtlStat())
				&& !TscConstants.OrderDetailStat.PAYMENT_COMPLETE.value().equals(tmpOrder.getOrdDtlStat())) {
				canChgAddr = "N";
			}

			ordNo = tmpOrder.getOrdNo();
			index++;
		}

		if (ordDtlList.size() > 0) {
			orderList.add(setOrderMap(ordDtlList, allCanYn, allDecideYn, ordReqChgQty, canChgAddr));
		}
		
		return orderList;
	}
	
	private GagaMap setOrderMap(Collection<Order> ordDtlList, String allCanYn, String allDecideYn, int ordReqChgQty, String canChgAddr) {
		Order order = ordDtlList.iterator().next();

		GagaMap map = new GagaMap();
		map.set("giftPackYn", order.getGiftPackYn());
		map.set("ordNo", order.getOrdNo());
		map.set("ordDt", order.getOrdDt());
		map.set("freeGiftList", orderDao.getOrderFreeGiftListForMypage(order));
		map.set("allCanYn", allCanYn);
		map.set("allDecideYn", allDecideYn);
		map.set("ordReqChgQty", ordReqChgQty);
		map.set("oneData", order);
		map.set("ordDtlList", ordDtlList);
		map.set("canChgAddr", canChgAddr);

		return map;
	}

	public Collection<GagaMap> getOrderListForMypageBak(Order order) {
		Collection<GagaMap> mapList = new ArrayList<>();
		Collection<GagaMap> orderList = new ArrayList<>();
		List<Order> ordDtlList = new ArrayList<>();
		int ordNo = 0;
		String ordDt = "";
		String selfGoodsYn = "";
		String supplyCompCd = "";
		String shipCompNm = "";
		String shipCompCd = "";
		String invoiceNo = "";
		String giftPackYn = "";
		int index = 0;
		Boolean shotDelv = false;
		Boolean selfMall = false;
		Boolean supplyMall = false;
		Boolean review = true;
		
		for (Order tmpOrder : orderDao.getOrderListForMypage(order)) {
			if (ordNo != tmpOrder.getOrdNo()) {
				if (index > 0) {
					// 주문상세내역 목록 설정
					GagaMap ordDtlMap = new GagaMap();
					ordDtlMap.set("ordDtlList", ordDtlList);
					ordDtlMap.set("ordDtlStat", ordDtlList.iterator().next().getOrdDtlStat());
					ordDtlMap.set("shipCompCd", shipCompCd);
					ordDtlMap.set("shipCompNm", shipCompNm);
					ordDtlMap.set("invoiceNo", invoiceNo);
					ordDtlMap.set("recipBaseAddr", ordDtlList.iterator().next().getRecipBaseAddr());
					ordDtlMap.set("giftLimitDay", ordDtlList.iterator().next().getGiftLimitDay());
					ordDtlMap.set("recipNm", ordDtlList.iterator().next().getRecipNm());
					ordDtlMap.set("giftLimitDt", ordDtlList.iterator().next().getGiftLimitDt());
					ordDtlMap.set("purchaseConfirmDay", ordDtlList.iterator().next().getPurchaseConfirmDay());
					ordDtlMap.set("review", review);
					orderList.add(ordDtlMap);

					// 주문내역 목록 설정
					GagaMap map = new GagaMap();
					map.set("ordNo", ordNo);					// 주문번호
					map.set("ordDt", ordDt);					// 주문일시
					map.set("shotDelv", shotDelv);				// 총알배송 아이콘
					map.set("selfMall", selfMall);				// STYLE24 일반배송 아이콘
					map.set("supplyMall", supplyMall);			// 업체직배송 아이콘
					map.set("giftPackYn", giftPackYn);			// 선물하기여부
					map.set("orderList", orderList);			// 주문내역
					mapList.add(map);
				}

				// 데이터 설정 후 초기화 진행
				ordNo = tmpOrder.getOrdNo();
				ordDt = tmpOrder.getOrdDt();
				selfGoodsYn = tmpOrder.getSelfGoodsYn();
				supplyCompCd = tmpOrder.getSupplyCompCd();
				giftPackYn = tmpOrder.getGiftPackYn();
				shotDelv = false;
				selfMall = false;
				supplyMall = false;
				ordDtlList = new ArrayList<>();
				orderList = new ArrayList<>();
			} else if (!selfGoodsYn.equals(tmpOrder.getSelfGoodsYn())
					|| ("N".equals(tmpOrder.getSelfGoodsYn()) && !supplyCompCd.equals(tmpOrder.getSupplyCompCd()))) {
				// 주문내역 목록 설정
				GagaMap ordDtlMap = new GagaMap();
				ordDtlMap.set("ordDtlList", ordDtlList);
				ordDtlMap.set("ordDtlStat", ordDtlList.iterator().next().getOrdDtlStat());
				ordDtlMap.set("shipCompCd", shipCompCd);
				ordDtlMap.set("shipCompNm", shipCompNm);
				ordDtlMap.set("invoiceNo", invoiceNo);
				ordDtlMap.set("purchaseConfirmDay", ordDtlList.iterator().next().getPurchaseConfirmDay());
				ordDtlMap.set("recipBaseAddr", ordDtlList.iterator().next().getRecipBaseAddr());
				ordDtlMap.set("giftLimitDay", ordDtlList.iterator().next().getGiftLimitDay());
				ordDtlMap.set("recipNm", ordDtlList.iterator().next().getRecipNm());
				ordDtlMap.set("giftLimitDt", ordDtlList.iterator().next().getGiftLimitDt());
				ordDtlMap.set("review", review);
				orderList.add(ordDtlMap);

				// 상태 별 배너 설정 후 초기화 진행
				ordDtlList = new ArrayList<>();
				selfGoodsYn = tmpOrder.getSelfGoodsYn();
				supplyCompCd = tmpOrder.getSupplyCompCd();
			}

			// 주문내역 설정
			ordDtlList.add(tmpOrder);
			
			// 총알배송 아이콘 설정
			if (!shotDelv && "Y".equals(tmpOrder.getShotDelvYn())) {
				shotDelv = true;
			}

			// STYLE24 일반배송 아이콘 설정
			if (!selfMall && "Y".equals(tmpOrder.getSelfGoodsYn())) {
				selfMall = true;
			}

			// 업체직배송 아이콘 설정
			if (!supplyMall && "N".equals(tmpOrder.getSelfGoodsYn())) {
				supplyMall = true;
			}
			
			// 리뷰 작성 여부 설정
			if (review && tmpOrder.getReviewSq() == 0) {
				review = false;
			}
			
			// 배송정보 설정
			shipCompCd = tmpOrder.getShipCompCd();
			shipCompNm = tmpOrder.getShipCompNm();
			invoiceNo = tmpOrder.getInvoiceNo();

			// 인덱스 처리
			index++;
		}

		// 마지막 데이터 설정
		if (ordNo > 0) {
			// 주문상세내역 목록 설정
			GagaMap ordDtlMap = new GagaMap();
			ordDtlMap.set("ordDtlList", ordDtlList);
			ordDtlMap.set("ordDtlStat", ordDtlList.iterator().next().getOrdDtlStat());
			ordDtlMap.set("shipCompCd", shipCompCd);
			ordDtlMap.set("shipCompNm", shipCompNm);
			ordDtlMap.set("invoiceNo", invoiceNo);
			ordDtlMap.set("purchaseConfirmDay", ordDtlList.iterator().next().getPurchaseConfirmDay());
			ordDtlMap.set("recipBaseAddr", ordDtlList.iterator().next().getRecipBaseAddr());
			ordDtlMap.set("giftLimitDay", ordDtlList.iterator().next().getGiftLimitDay());
			ordDtlMap.set("recipNm", ordDtlList.iterator().next().getRecipNm());
			ordDtlMap.set("giftLimitDt", ordDtlList.iterator().next().getGiftLimitDt());
			ordDtlMap.set("review", review);
			orderList.add(ordDtlMap);

			// 주문내역 목록 설정
			GagaMap map = new GagaMap();
			map.set("ordNo", ordNo);
			map.set("ordDt", ordDt);
			map.set("shotDelv", shotDelv);
			map.set("selfMall", selfMall);
			map.set("supplyMall", supplyMall);
			map.set("giftPackYn", giftPackYn);
			map.set("orderList", orderList);
			mapList.add(map);
		}
		
		return mapList;
	}

	/**
	 * PG 결제승인
	 * @param param - 필수 : pgGb(결제수단 : KCP, KAKAO 등), payMeans(결제수단 : G014_30(신용카드) 등)
	 * @param request
	 * @param response
	 * @return
	 */
	@Transactional("shopTxnManager")
	public Payment orderPgPayResult(Payment param, HttpServletRequest request, HttpServletResponse response) {
		Payment result = new Payment();
		
		// PC 아니고 PG_GB 없으면 KCP, 신용카드로 설정
		if (!TscConstants.FrontGb.PC.value().equals(TsfSession.getFrontGb()) && StringUtils.isEmpty(param.getPgGb())) {
			param.setPgGb(TscConstants.PgGb.KCP.value());
			param.setPayMeans(TscConstants.PayMeans.CREDIT_CARD.value());
		}
		
		try {
			// 결제수단체크
			if (StringUtils.isEmpty(param.getPgGb())) {
				throw new IllegalArgumentException("결제수단을 선택해주세요.");
			}
			
			// 결제수단이 KCP, PAYCO 일때 실행
			if (TscConstants.PgGb.KCP.value().equals(param.getPgGb()) || TscConstants.PgGb.PAYCO.value().equals(param.getPgGb())) {
				// 상품권 100% 결제 (PG PASS)
				if (TscConstants.PayMeans.GIFTCARD.value().equals(param.getPayMeans())) {
					result.setPayAmt(0);
					result.setPgCpnAmt(0);
					result.setNpayPntAmt(0);
					result.setPayGb("O");
					result.setCardPcableYn("Y");
					result.setEscrowYn("N");
					result.setUpdNo(param.getCustNo());
					result.setRegNo(param.getCustNo());
					result.setPayStat(TscConstants.PaymentStat.PAYMENT_COMPLETE.value());
					result.setPgGb(TscConstants.PgGb.ISTYLE.value());
					result.setOrdNo(Integer.parseInt(request.getParameter("ordr_idxx")));
					result.setPayMeans(param.getPayMeans());
				} 
				// 일반 KCP, PAYCO 결제
				else {
					result = coreKcpService.kcpPayRequest(param, request, response);
				}
			}
			// KAKAO 결제 일때 실행
			else if (TscConstants.PgGb.KAKAO.value().equals(param.getPgGb())) {
				result = coreKakaoPayService.approveKakaoPayment(param);
			}
			// NPAY 결제형 일때 실행
			else if (TscConstants.PgGb.NAVER.value().equals(param.getPgGb())) {
				result = coreNaverPayService.approveNaverPayment(param);
			}
			// 그외 결제수단은 실패
			else {
				throw new IllegalArgumentException("결제 수단이 잘못 입력되었습니다. 새로고침 후 다시 시도해주세요.");
			}
			
			// 결제 수단이 없는 경우(KAKAO, NAVER) CARD로 세팅
			if (StringUtils.isEmpty(param.getPayMeans())) {
				result.setPayMeans(TscConstants.PayMeans.CREDIT_CARD.value());
			}

			if (TscConstants.FrontGb.PC.value().equals(TsfSession.getFrontGb())) {
				result.setUpdNo(param.getCustNo());
				result.setRegNo(param.getCustNo());
			}

			// 페이코의 경우처럼 result로 shop_user_id가 안넘어 오는 경우가 있음. custNo가 없을 경우 한번 더 체크.
			if (result.getCustNo() < 1) {
				result.setCustNo(param.getCustNo());
				result.setRegNo(param.getCustNo());
				result.setUpdNo(param.getCustNo());
			}
			
			// 결제구분 처리
			if (StringUtils.isBlank(param.getPayGb())) {
				result.setPayGb("O");
			} else {
				result.setPayGb(param.getPayGb());
			}

			// TB_PAYMENT 등록. 실패시 PG 환불.
			if (TscConstants.PgGb.NAVER.value().equals(param.getPgGb()) && !"SUCCESS".equals(result.getCode().toUpperCase())) {
				result.setPgGb(param.getPgGb());
				return result;
			}

			
			// 결제완료 업데이트
			int resultCnt = coreOrderDao.updatePaymentOrderComplete(result);
			
			// 결제실패일때 실행
			if (resultCnt < 1) {
				if (TscConstants.PgGb.KCP.value().equals(param.getPgGb()) || TscConstants.PgGb.PAYCO.value().equals(param.getPgGb())) {
					if(TscConstants.PayMeans.GIFTCARD.value().equals(param.getPayMeans())) {
						// 상품권 100% 결제 (PG PASS)
						result.setPayStat(TscConstants.PaymentStat.PAY_BEFORE_CANCEL.value());
						coreOrderDao.insertPayment(result);
					} else {
						result.setModType("STSC");
						coreKcpService.kcpCancel(result);
					}
				} else if (TscConstants.PgGb.KAKAO.value().equals(param.getPgGb())) {
					result.setLeftAmt(0);
					coreKakaoPayService.kakaoPayRollBack(result);
					
					//param.setLeftAmt(0);
					//coreKakaoPayService.kakaoPayRollBack(param);
				} else if (TscConstants.PgGb.NAVER.value().equals(param.getPgGb())) {
					result.setLeftAmt(0);
					coreNaverPayService.naverPayRollBack(result);
				}
				
				throw new IllegalArgumentException("결제 정보 저장 실패. 새로고침 후 다시 시작해주세요.");
			}
			// 결제성공일때 실행
			else {
				// TB_DELIVERY_FEE PAY_SQ 등록
				coreOrderDao.updateDeliveryFeePaySq(result);
			}
		} catch(Exception e) {
			e.printStackTrace();
			
			// 2021.10.27 KCP 결제취소로직
			/*
			if (TscConstants.PgGb.KCP.value().equals(param.getPgGb()) || TscConstants.PgGb.PAYCO.value().equals(param.getPgGb())) {
				if(TscConstants.PayMeans.GIFTCARD.value().equals(param.getPayMeans())) {
					// 상품권 100% 결제 (PG PASS)
					result.setPayStat(TscConstants.PaymentStat.PAY_BEFORE_CANCEL.value());
					coreOrderDao.insertPayment(result);
				} else {
					result.setModType("STSC");
					coreKcpService.kcpCancel(result);
				}
			} else if (TscConstants.PgGb.KAKAO.value().equals(param.getPgGb())) {
				result.setLeftAmt(0);
				coreKakaoPayService.kakaoPayRollBack(result);
			} else if (TscConstants.PgGb.NAVER.value().equals(param.getPgGb())) {
				result.setLeftAmt(0);
				coreNaverPayService.naverPayRollBack(result);
			}
			*/
			
			throw new IllegalArgumentException(e.getMessage());
		}

		return result;
	}

	/**
	 * 카카오페이 모바일 결제승인
	 * 
	 * @param Payment
	 * @return Payment
	 * @author card007
	 * @since 2021. 05. 20
	 */
	@Transactional("shopTxnManager")
	public Payment kakaoPayResult(Payment payment) {
		Payment result;

		try {
			result = coreKakaoPayService.approveKakaoPayment(payment);

			// 결제 수단이 없는 경우(KAKAO, NAVER) CARD로 세팅
			if(StringUtils.isEmpty(result.getPayMeans())) {
				result.setPayMeans(TscConstants.PayMeans.CREDIT_CARD.value());
			}

			result.setPgGb(TscConstants.PgGb.KAKAO.value());
			result.setPayGb("O");

			// TB_PAYMENT 등록. 실패시 PG 환불.
			if (coreOrderDao.updatePaymentOrderComplete(result) < 1) {
				result.setLeftAmt(0);
				coreKakaoPayService.kakaoPayRollBack(result);
				
				//payment.setLeftAmt(0);
				//coreKakaoPayService.kakaoPayRollBack(payment);

				throw new IllegalArgumentException("결제 정보 저장 실패. 새로고침 후 다시 시작해주세요.");
			} else {
				// TB_DELIVERY_FEE PAY_SQ 등록
				result.setPayGb(TscConstants.PaymentGb.ORDER.value());
				result.setUpdNo(payment.getUpdNo());
				coreOrderDao.updateDeliveryFeePaySq(result);
			}
		} catch(Exception e) {
			e.printStackTrace();
			
			// 2021.10.27 카카오페이 결제취소로직
			//result.setLeftAmt(0);
			//coreKakaoPayService.kakaoPayRollBack(result);
			
			throw new IllegalArgumentException(e.getMessage());
		}

		return result;
	}

	/**
	 * 네이버페이 모바일 결제승인
	 *
	 * @param Payment
	 * @return Payment
	 * @author card007
	 * @since 2021. 05. 20
	 */
	@Transactional("shopTxnManager")
	public Payment naverPayResult(Payment payment) {
		Payment result;

		try {
			log.info("payment.getOrdNo() >>> {}", payment.getOrdNo());
			
			result = coreNaverPayService.approveNaverPayment(payment);

			// 결제 수단이 없는 경우(KAKAO, NAVER) CARD로 세팅
			if (StringUtils.isEmpty(result.getPayMeans())) {
				result.setPayMeans(TscConstants.PayMeans.CREDIT_CARD.value());
			}

			result.setPgGb(TscConstants.PgGb.NAVER.value());
			result.setPayGb("O");

			// TB_PAYMENT 등록. 실패시 PG 환불.
			if (coreOrderDao.updatePaymentOrderComplete(result) < 1) {
				result.setLeftAmt(0);
				coreNaverPayService.naverPayRollBack(result);
				
				//payment.setLeftAmt(0);
				//coreNaverPayService.naverPayRollBack(payment);

				throw new IllegalArgumentException("결제 정보 저장 실패. 새로고침 후 다시 시작해주세요.");
			} else {
				// TB_DELIVERY_FEE PAY_SQ 등록
				result.setPayGb(TscConstants.PaymentGb.ORDER.value());
				result.setUpdNo(payment.getUpdNo());
				coreOrderDao.updateDeliveryFeePaySq(result);
			}
		} catch(Exception e) {
			e.printStackTrace();
			
			// 2021.10.27 네이버페이 결제취소로직
			//payment.setLeftAmt(0);
			//coreNaverPayService.naverPayRollBack(payment);
						
			throw new IllegalArgumentException(e.getMessage());
		}

		return result;
	}

	@Transactional("shopTxnManager")
	public int updatePaymentForOrderFinished(Payment param) {
		return orderDao.updatePaymentForOrderFinished(param);
	}


	/**
	 * 마이페이지 주문목록 페이징 처리 주문번호 수 조회
	 *
	 * @param Order
	 * @return int
	 * @author card007
	 * @since 2021. 03. 16
	 */
	public int getPagingOrdNoListCount(Order order) { return orderDao.getPagingOrdNoListCount(order); }

	/**
	 * 마이페이지 주문목록 페이징 처리 주문번호 조회
	 *
	 * @param Order
	 * @return Collection<Order>
	 * @author card007
	 * @since 2021. 02. 18
	 */
	public Collection<Order> getPagingOrdNoList(Order order) { return orderDao.getPagingOrdNoList(order); }

	/**
	 * 마이페이지 주문상세 금액정보 조회
	 *
	 * @param Order
	 * @return Order
	 * @author card007
	 * @since 2021. 02. 16
	 */
	public Order getOrderAmtForMypage(Order order) { return orderDao.getOrderAmtForMypage(order); }

	/**
	 * 마이페이지 주문상세 결제정보 조회
	 *
	 * @param Order
	 * @return Order
	 * @author card007
	 * @since 2021. 02. 16
	 */
	public Order getPaymentInfoForMypage(Order order) {
		order.setPayStat(TscConstants.PaymentStat.PAYMENT_COMPLETE.value());
		order.setPayGb(TscConstants.PaymentGb.ORDER.value());
		return orderDao.getPaymentInfoForMypage(order);
	}

	/**
	 * 마이페이지 주문상세 배송지 정보 조회
	 *
	 * @param Order
	 * @return Order
	 * @author card007
	 * @since 2021. 02. 16
	 */
	public Order getOrderDeliveryAddrInfo(Order order) { return orderDao.getOrderDeliveryAddrInfo(order); }

	/**
	 * 마이페이지 주문상세 주문내역삭제 처리
	 *
	 * @param Order
	 * @return int
	 * @author card007
	 * @since 2021. 02. 17
	 */
	public int updateOrderDisplayYn(Order order) { return orderDao.updateOrderDisplayYn(order); }

	public Payment setPgDataInfo(Order order) {
		// TB_PAYMENT 우선 입력
		Payment prePay = new Payment();
		prePay.setOrdNo(order.getOrdNo());
		prePay.setPayMeans(order.getPayMeans());
		prePay.setPayAmt(order.getPayAmt());
		prePay.setPayStat(TscConstants.PaymentStat.PAYMENT_WAIT.value());
		prePay.setPgGb(order.getPgGb());
		prePay.setCustNo(order.getCustNo());
		prePay.setRegNo(order.getCustNo());
		prePay.setUpdNo(order.getCustNo());

		// 상품권 100% 결제일 경우 PgGb STYLE24로 변경
		if(TscConstants.PayMeans.GIFTCARD.value().equals(order.getPayMeans())) {prePay.setPgGb(TscConstants.PgGb.ISTYLE.value());}

		// 주문데이터인지, 추가배송비 결제 데이터인지 확인
		if(order.getOrdChgSq() != null && order.getOrdChgSq() > 0) {
			prePay.setPayGb("D");
			prePay.setOrdChgSq(order.getOrdChgSq());
		} else {
			prePay.setPayGb("O");
		}

		coreOrderDao.insertPayment(prePay);

		// PG 송부 데이터 세팅
		Payment payment;
		order.setFrontGb(TsfSession.getFrontGb());
		if(TscConstants.PgGb.KAKAO.value().equals(order.getPgGb())) {			// 카카오페이
			KakaoPay kakaoPay = coreKakaoPayService.kakaoPaymentReady(order);
			payment = coreKakaoPayService.setKakaoOrderData(kakaoPay, order);
		} else if(TscConstants.PgGb.NAVER.value().equals(order.getPgGb())) {	// 네이버페이
			NaverPay naverPay = coreNaverPayService.naverPaymentReady(order);
			payment = coreNaverPayService.setNaverOrderData(naverPay);
		} else if(TscConstants.PgGb.KCP.value().equals(order.getPgGb()) || TscConstants.PgGb.PAYCO.value().equals(order.getPgGb())){	// KCP, PAYCO
			payment = coreKcpService.setKcpOrderData(order);
		}
		// 2021.07.15 상품권 100% 결제
		else if (TscConstants.PgGb.ISTYLE.value().equals(order.getPgGb())) {
			return prePay;
		} else {
			throw new IllegalArgumentException("결제타입이 잘못 선택되었습니다. 새로고침 후 다시 시도해주세요.");
		}

		payment.setPgGb(order.getPgGb());
		payment.setPayMeans(order.getPayMeans());
		return payment;
	}
	
	/**
	 * 고객 특정기간 첫구매 여부
	 * 
	 * @param coupon
	 * @return int
	 * @author eskim
	 * @since 2021.03.12
	 */
	public int getCustFirstOrderCount(Coupon coupon) { return orderDao.getCustFirstOrderCount(coupon); }
	
	
	
	/**
	 * 주문정보유효성체크
	 * @param Order
	 * @return Order
	 * @author jsh77b
	 * @since 2021. 03. 09
	 */
	public String orderValidationCheck(Order order) {
		String resultStr	= "SUCCESS";
		
		// 1. 주문상세체크
		Collection<Order> orderDetailList = order.getOrderDetailList();
		
		// 2021.05.07 1.1 장바구니 금액조회 정보
		order.setFrontGb(TsfSession.getFrontGb());
		Collection<Order> cartGoodsList = coreOrderService.getCartGoodsList(order);
		
		int orgGoodsSumAmt 			= 0;
		int cpn1DcSumAmt			= 0;
		int tmtb1DcSumAmt			= 0;
		int tmtb2DcSumAmt			= 0;
		int goodsCpnDcSumAmt		= 0;
		int cartCpnDcSumAmt			= 0;
		int prePntDcSumAmt			= 0;
		int pntDcSumAmt				= 0;
		int gfcdUseSumAmt			= 0;
		int realOrdSumAmt 			= 0;
		
		int cartOrgGoodsSumAmt 		= 0;
		
		// 주문서화면 금액정보 체크
		for (Order orderDetail : orderDetailList) {
			orgGoodsSumAmt 				= orgGoodsSumAmt 	+ ((orderDetail.getCurrPrice() + orderDetail.getOptAddPrice()) * orderDetail.getGoodsQty());
			cpn1DcSumAmt 				= cpn1DcSumAmt 		+ (orderDetail.getCpn1DcAmt() * orderDetail.getGoodsQty());
			tmtb1DcSumAmt 				= tmtb1DcSumAmt 	+ orderDetail.getTmtb1DcAmt();
			tmtb2DcSumAmt 				= tmtb2DcSumAmt 	+ orderDetail.getTmtb2DcAmt();
			goodsCpnDcSumAmt			= goodsCpnDcSumAmt 	+ orderDetail.getGoodsCpnDcAmt();
			cartCpnDcSumAmt				= cartCpnDcSumAmt 	+ orderDetail.getCartCpnDcAmt();
			prePntDcSumAmt				= prePntDcSumAmt 	+ orderDetail.getPrePntDcAmt();
			pntDcSumAmt					= pntDcSumAmt 		+ orderDetail.getPntDcAmt();
			gfcdUseSumAmt				= gfcdUseSumAmt 	+ orderDetail.getGfcdUseAmt();
			realOrdSumAmt 				= realOrdSumAmt 	+ orderDetail.getRealOrdAmt();
		}
		
		realOrdSumAmt = realOrdSumAmt + order.getDelvSumAmt();
		
		if (orgGoodsSumAmt != order.getOrgGoodsSumAmt()) {
			resultStr = "판매가 금액정보가 잘못 되었습니다.";
			return resultStr;
		}
		
		if (cpn1DcSumAmt != order.getCpn1DcSumAmt()) {
			resultStr = "즉시할인 금액정보가 잘못 되었습니다.";
			return resultStr;
		}
		
		if (tmtb1DcSumAmt != order.getTmtb1DcSumAmt()) {
			resultStr = "수량다다익선 할인 금액정보가 잘못 되었습니다.";
			return resultStr;
		}
		
		if (tmtb2DcSumAmt != order.getTmtb2DcSumAmt()) {
			resultStr = "금액다다익선 할인 금액정보가 잘못 되었습니다.";
			return resultStr;
		}
		
		if (goodsCpnDcSumAmt != order.getGoodsCpnDcSumAmt()) {
			resultStr = "상품쿠폰 할인 금액정보가 잘못 되었습니다.";
			return resultStr;
		}
		
		if (cartCpnDcSumAmt != order.getCartCpnDcSumAmt()) {
			resultStr = "장바구니쿠폰 할인 금액정보가 잘못 되었습니다.";
			return resultStr;
		}
		
		if (prePntDcSumAmt != order.getPrePntDcSumAmt()) {
			resultStr = "선포인트 할인 금액정보가 잘못 되었습니다.";
			return resultStr;
		}
		
		if (pntDcSumAmt != order.getPntDcSumAmt()) {
			resultStr = "포인트 할인 금액정보가 잘못 되었습니다.";
			return resultStr;
		}

		if (realOrdSumAmt != order.getRealOrdSumAmt()) {
			resultStr = "실결제 금액정보가 잘못 되었습니다.";
			return resultStr;
		}
		// 장바구니 금액정보 체크
		for (Order orderDetail : cartGoodsList) {
			cartOrgGoodsSumAmt 			= cartOrgGoodsSumAmt + ((orderDetail.getOrgCurrPrice() + orderDetail.getOptAddPrice()) * orderDetail.getGoodsQty());
		}
		
		// 판매가비교
		if (orgGoodsSumAmt != cartOrgGoodsSumAmt) {
			resultStr = "금액정보가 잘못 되었습니다.";
			return resultStr;
		}

		int custCpnSq		= 0;
		int usPntAmt		= 0;
		int usGfcdAmt		= 0;

		for (Order orderDetail : orderDetailList) {

			// 2.1 상품 재고 확인 (상품정보유효성체크)
			Collection<Cart> params = new ArrayList<Cart>();
			Cart cart = new Cart();
			cart.setGoodsCd(orderDetail.getGoodsCd());
			cart.setGoodsType(orderDetail.getGoodsType());
			cart.setGoodsQty(orderDetail.getGoodsQty());
			cart.setCheckGb("O");
			
			// 세트상품
			if ("G056_S".equals(orderDetail.getGoodsType())) {
				
				Collection<Cart> cartCompsList = new ArrayList<Cart>();
				
				// 세트상품일때 구성상품정보 추가 
				for (int i=0 ; i<orderDetail.getItemCdArr().length ; i++) {
					Cart itemCart = new Cart();
					itemCart.setGoodsCd(orderDetail.getGoodsCd());
					itemCart.setGoodsType(orderDetail.getGoodsType());
					itemCart.setItemCd(orderDetail.getItemCdArr()[i]);
					itemCart.setOptCd(orderDetail.getOptCdArr()[i]);
					itemCart.setGoodsQty(orderDetail.getGoodsQty());
					itemCart.setCartGb("O");
					cartCompsList.add(itemCart);
				}
				// 구성상품정보추가
				cart.setCartCompsList(cartCompsList);
			}
			else {
				cart.setItemCd(orderDetail.getItemCdArr()[0]);
				cart.setOptCd(orderDetail.getOptCdArr()[0]);
				cart.setGoodsQty(orderDetail.getGoodsQty());
				cart.setCartGb("O");
			}
						
			// 유효성체크 목록 담기 1개 기준 체크
			params.add(cart);
			
			GagaMap resultMap = cartService.saveCartInfo(params, null);
			
			if (!"SUCCESS".equals(resultMap.get("message").toString())) {
				resultStr = resultMap.get("message").toString();
				return resultStr;
			}

			// 2.2 보유 상품쿠폰체크
			custCpnSq = orderDetail.getGoodsCpnSq();
			if (custCpnSq > 0) {
				orderDetail.setCustCpnSq(custCpnSq);
				orderDetail.setCustNo(order.getCustNo());
				if (orderDao.getCheckCustCpnSq(orderDetail) < 1) {
					resultStr = "보유하신 상품쿠폰이 존재하지 않습니다.";
					return resultStr;
				}
			}
			
			// 2.3 보유 장바구니쿠폰체크
			custCpnSq = orderDetail.getCartCpnSq();
			if (custCpnSq > 0) {
				orderDetail.setCustCpnSq(custCpnSq);
				orderDetail.setCustNo(order.getCustNo());
				if (orderDao.getCheckCustCpnSq(orderDetail) < 1) {
					resultStr = "보유하신 장바구니쿠폰이 존재하지 않습니다.";
					return resultStr;
				}
			}
			
			// 2.4 사용포인트금액등록(구매사용포인트)
			usPntAmt = usPntAmt + orderDetail.getPntDcAmt();
			
			// 2.5 상품권사용금액등록
			usGfcdAmt = usGfcdAmt + orderDetail.getGfcdUseAmt();
		}
		
		// 2.6 사용포인트금액등록(사은품사용포인트)
		int usePoint = 0;
		if (order.getFreegiftUsePointArr().length > 0) {
			for (int i=0 ; i<order.getFreegiftUsePointArr().length ; i++) {
				if (order.getFreegiftUsePointArr()[i] != null && order.getFreegiftUsePointArr()[i] != "") {
					usePoint = Integer.parseInt(order.getFreegiftUsePointArr()[i]);
					if (usePoint > 0) {
						usPntAmt = usPntAmt + usePoint;
					}
				}
			}
		}
		
		// 3. 보유포인트금액 > 포인트사용금액 체크
		int rmPntAmt = coreOrderDao.getCustPointInfo(order);
		if (rmPntAmt < usPntAmt) {
			resultStr = "보유하신 포인트 금액이 부족합니다.";
			return resultStr;
		}
		
		// 4. 보유상품권금액 > 상품권사용금액 체크
		int rmGfcdAmt = coreOrderDao.getGiftcardInfo(order);
		if (rmGfcdAmt < usGfcdAmt) {
			resultStr = "보유하신 상품권 금액이 부족합니다.";
			return resultStr;
		}
		
		// 5. 장바구니 보유쿠폰 체크 (배송목록체크)
		Collection<Order> delvFeeCdList = order.getDelvFeeCdList();
		for (Order delvFeeCd : delvFeeCdList) {
			if (delvFeeCd.getDelvCpnSq() > 0) {
				custCpnSq = delvFeeCd.getDelvCpnSq();
				if (custCpnSq > 0) {
					delvFeeCd.setCustCpnSq(custCpnSq);
					delvFeeCd.setCustNo(order.getCustNo());
					if (orderDao.getCheckCustCpnSq(delvFeeCd) < 1) {
						resultStr = "보유하신 배송비쿠폰이 존재하지 않습니다.";
						return resultStr;
					}
				}
			}
		}
		
		// 6. 사은품채고체크
		int rtnCnt = orderDao.getCheckFreegiftVal(order);
		if (rtnCnt > 0) {
			resultStr = "선택하신 사은품의 재고가 부족 합니다.";
			return resultStr;
		}
	
		return resultStr;
		
	}

	/**
	 * KCP 현금영수증 신청
	 * param.setTradeTime("20210422200347");	// 결제시각 : YYYYMMDDHH24MISS 형식
	 * param.setOrdPhnno("01011111111");		// 현금영수증 대상 휴대폰번호
	 * param.setUsGfcdAmt(10000);				// 현금영수증 신청 금액
	 * param.setOrdNo(211);						// 주문번호
	 * param.setGoodsNm("보라색 원피스");			// 상품명 (“7. 현금영수증 매출전표 연동” 을 통해 고객이 직접 전표를 확인코자 한다면 상품명을 넘겨주지 않았을 경우 구매자 인증 시 인증오류가 발생할 수 있습니다.)
	 * param.setOrdNm("구매자");					// 구매자명
	 * param.setOrdEmail("xxxx@xxxx.com");		// 구매자이메일 (“7. 현금영수증 매출전표 연동” 을 통해 고객이 직접 전표를 확인코자 한다면 메일주소를 넘겨주지 않았을 경우 구매자 인증 시 인증오류가 발생할 수 있습니다.)
	 * @param param
	 * @return
	 * @author xodud1202
	 * @since 2021. 04. 23
	 */
	@Transactional("shopTxnManager")
	public GiftCard kcpCashReceiptsRequest(GiftCard param) {
		GiftCard result = new GiftCard();
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
		String cust_ip = request.getRemoteAddr();
		String reqTx = "pay";		// 현금영수증 신청
		String txCd = "07010000";	// 현금영수증 등록 요청
		String ordPhnno = "";
		if(!StringUtils.isEmpty(param.getOrdPhnno())) {
			ordPhnno = param.getOrdPhnno().replaceAll("-", "");
		}

		J_PP_CLI_N c_PayPlus = new J_PP_CLI_N();
		c_PayPlus.mf_init( "", env.getProperty("pg.kcp.gw.url"), env.getProperty("pg.kcp.gw.port"), Integer.parseInt(env.getProperty("pg.kcp.tx.mode")), env.getProperty("pg.kcp.log.dir"));
		c_PayPlus.mf_init_set();

		int rcpt_data_set   = c_PayPlus.mf_add_set( "rcpt_data" ) ;
		int ordr_data_set   = c_PayPlus.mf_add_set( "ordr_data" ) ;
		int corp_data_set   = c_PayPlus.mf_add_set( "corp_data" ) ;

		// 현금영수증 정보
		c_PayPlus.mf_set_us( rcpt_data_set, "user_type", "PGNW") ;
//		c_PayPlus.mf_set_us( rcpt_data_set, "trad_time", param.getTradeTime()) ; 2021.10.12 상품권 현금영수증 신청 시 당일 날짜 변경으로 아래 사용
		c_PayPlus.mf_set_us( rcpt_data_set, "trad_time", param.getNowTime()) ;
		c_PayPlus.mf_set_us( rcpt_data_set, "tr_code"  , "0") ;							// 0 : 소득공제용(개인), 1 : 지출증빙용(기업)
		c_PayPlus.mf_set_us( rcpt_data_set, "id_info"  , ordPhnno) ;							// 발급 대상이 개인인 경우에는 주민번호, 휴대폰번호,현금영수증 카드를 세팅하며, 기업인 경우에는 대상 사업자 번호를 입력. 자진발급으로 등록 시, “0100001234” 으로 입력.
		c_PayPlus.mf_set_us( rcpt_data_set, "amt_tot"  , param.getUsGfcdAmt() + "") ;	// 현금영수증 금액 (공급가액 + 부가가치세 + 봉사료)
		c_PayPlus.mf_set_us( rcpt_data_set, "amt_sup"  , (param.getUsGfcdAmt() - ((int)(param.getUsGfcdAmt() / 11))) + "") ;		// 공급가액
		c_PayPlus.mf_set_us( rcpt_data_set, "amt_svc"  , "0") ;		// 봉사료
		c_PayPlus.mf_set_us( rcpt_data_set, "amt_tax"  , ((int)(param.getUsGfcdAmt() / 11)) + "") ;		// 부가가치세 (공급가액의 10%)
		c_PayPlus.mf_set_us( rcpt_data_set, "pay_type" , "PAXX") ;

		// 주문 정보
		c_PayPlus.mf_set_us( ordr_data_set, "ordr_idxx", param.getOrdNo() + "") ;		// 주문번호
		c_PayPlus.mf_set_us( ordr_data_set, "good_name", param.getGoodsNm());				// 상품명
		c_PayPlus.mf_set_us( ordr_data_set, "buyr_name", param.getOrdNm());
		c_PayPlus.mf_set_us( ordr_data_set, "buyr_tel1", ordPhnno);
		c_PayPlus.mf_set_us( ordr_data_set, "buyr_mail", param.getOrdEmail());

		// 가맹점 정보
		c_PayPlus.mf_set_us( corp_data_set, "corp_type", "0");		// 사업장 구분 (직접 판매 : 0, 입점몰 판매 : 1)

		// 실행
		c_PayPlus.mf_do_tx(env.getProperty("pg.kcp.site.cd"), "", txCd, cust_ip, String.valueOf(param.getOrdNo()), env.getProperty("pg.kcp.log.level"), "1");

		// 결과
		result.setResultCd(c_PayPlus.m_res_cd);
		result.setResultMsg(c_PayPlus.m_res_msg);
		result.setOrdNo(param.getOrdNo());
		result.setUsGfcdAmt(param.getUsGfcdAmt());
		if("0000".equals(result.getResultCd())) {
			result.setTradeNo(c_PayPlus.mf_get_res("cash_no"));
			result.setAuthNo(c_PayPlus.mf_get_res("receipt_no"));

			// 성공시 TB_GIFTCARD_RECEIPT INSERT
			orderDao.createGiftcartReceipt(result);
		}

		// 성공이든 실패이든 로그성 데이터 TB_GIFTCARD_RECEIPT_API INSERT
		coreOrderDao.createGiftcartReceiptApi(result);

		return result;
	}

	/**
	 * USAFE 보증보험 신청
	 * temp.setItemNmArr(goodsNameArr);			// 상품명 배열
	 * temp.setGoodsPriceArr(goodsPriceArr);	// 상품별 가격 배열
	 * temp.setItemQtyArr(goodsQuantityArr);	// 상품별 수량 배열
	 * temp.setOrdNo(1);						// 주문번호
	 * temp.setRealOrdAmt(32000);				// 결제금액
	 * temp.setBirthYmd("198912021");			// 생년월일 + 성별(남자 : 1, 여자 : 2)
	 * temp.setPayMeans(TscConstants.PayMeans.ACCOUNT_TRANSFER.value());		// 무통장입금 or 계좌이체
	 * temp.setBankNm("신한은행");				// 은행명  >> PG 송부 후 result에서 값 입력하면됨
	 * temp.setOrdNm("이태영");					// 주문자명
	 * temp.setOrdTelno("");					// 주문자전화1 ("-" 포함)
	 * temp.setOrdPhnno("010-7111-4489");		// 주문자전화2 ("-" 포함)
	 * temp.setRecipZipcode("08755");			// 주문자우편번호
	 * temp.setRecipAddr("서울시 관악구 신림동 1414-26 해피타워 501호");	// 주문자주소
	 * temp.setOrdEmail("xodud1202@naver.com");	// 주문자이메일
	 * temp.setRecipNm("이태영");				// 수령인명
	 * temp.setRecipTelno("");					// 수령인전화번호
	 * temp.setRecipPhnno("010-7111-4489");		// 수령인휴대폰번호
	 * temp.setCustNo(100010);					// 고객번호
	 *
	 * 	* 계좌이체 : pgTid, 무통장입금 : 가상계좌번호 *
	 * temp.setPgTid("20210423952698");			// temp.setVaNo("110242222222");  >> PG 송부 후 result에서 값 입력하면됨
	 *
	 * @param param
	 * @author xodud1202
	 * @since 2021. 04. 26
	 */
	@Transactional("shopTxnManager")
	public String uSafeGuaranteeInsurance(Order param) {
		InsuranceManager manager = new InsuranceManager(env.getProperty("usafe.guarantee.send.url") , null );

		InsuranceInfo dInfo = new InsuranceInfo();

		String gubun = "A0";		// 고정
		String payMethod = "";
		String payInfo2 = "";
		String sign = "YYY";

		if(TscConstants.PayMeans.ACCOUNT_TRANSFER.value().equals(param.getPayMeans())) {
			payMethod = "BMC";
			payInfo2 = param.getPgTid();
			param.setIfYn("Y");				// 인터페이스 송부 완료(입금확인)
		} else if (TscConstants.PayMeans.BANK_DEPOSIT.value().equals(param.getPayMeans())) {
			payMethod = "CAS";
			payInfo2 = param.getVaNo();
			param.setIfYn("N");				// 인터페이스 송부 완료X (입금확인시 Y로 UPDATE 예정)
		}

		if(StringUtils.isEmpty(param.getOrdTelno())) {		param.setOrdTelno(param.getOrdPhnno());	}
		if(StringUtils.isEmpty(param.getRecipTelno())) {	param.setRecipTelno(param.getRecipPhnno());	}

		param.setRecipZipcode(param.getRecipZipcode().replaceAll("-", ""));
		if(param.getRecipZipcode().length() < 6) {
			param.setRecipZipcode(param.getRecipZipcode() + "X");
		}

		param.setGoodsCnt(String.valueOf(param.getItemNmArr().length));

		dInfo.setGubun(gubun);
		dInfo.setMallId(env.getProperty("usafe.guarantee.mall.id"));
		dInfo.setOId(String.valueOf(param.getOrdNo()));
		dInfo.setTotalMoney(String.valueOf(param.getRealOrdAmt()));
		dInfo.setPId(param.getBirthYmd());
		dInfo.setPayMethod(payMethod);
		dInfo.setPayInfo1(param.getBankNm());
		dInfo.setPayInfo2(payInfo2);
		dInfo.setOrderNm(param.getOrdNm());
		dInfo.setOrderHomeTel(param.getOrdTelno());
		dInfo.setOrderHpTel(param.getOrdPhnno());
		dInfo.setOrderZip(param.getRecipZipcode());
		dInfo.setOrderAddress(param.getRecipAddr());
		dInfo.setOrderEmail(param.getOrdEmail());
		dInfo.setGoodsCount(param.getGoodsCnt());
		dInfo.setAcceptor(param.getRecipNm());
		dInfo.setDeliveryTel1(param.getRecipTelno());
		dInfo.setDeliveryTel2(param.getRecipPhnno());
		dInfo.setGoodsNameArr(param.getItemNmArr());
		dInfo.setGoodsPriceArr(param.getGoodsPriceArr());
		dInfo.setGoodsQuantityArr(param.getItemQtyArr());
		dInfo.setSign(sign);

		String result = manager.contractInsurance(dInfo);

		// result : 0|주문번호		, 성공시
		// result : 1|Error Message	, 실패시
		String[] rtnResult = result.split("[\u007C]");

		param.setResultCd(rtnResult[0]);
		param.setResultMsg(rtnResult[1]);

		if("0".equals(param.getResultCd())) {
			param.setInsNo(param.getResultMsg());
		} else {
			param.setIfYn("F");			// 인터페이스 송부 실패
		}

		coreOrderDao.updateInsurance(param);

		return "SUCCESS";
	}

	/**
	 * USAFE 보증보험 입금 확인(보증보험 신청 완료 > 완료 후 취소안됨 주의)
	 * temp.setOrdNo(111);			// 주문번호
	 * @param param
	 * @author xodud1202
	 * @since 2021. 04. 26
	 */
	@Transactional("shopTxnManager")
	public String uSafeGuaranteeDepositCompleted(Order param) {
		// 보증보험 정보 조회
		Order insurance = coreOrderDao.getInsuranceInfo(param);

		// 보증보험 신청 이력이 없으면 완료안됨
		if(insurance != null) {
			// 보증보험 입금 완료 정보 송부
			InsuranceManager manager = new InsuranceManager(env.getProperty("usafe.guarantee.send.url"), null);
			String result = manager.confirmPayment(env.getProperty("usafe.guarantee.mall.id"), String.valueOf(param.getOrdNo()), insurance.getInsNo());

			// 송부 결과
			String rtnResult[]	= result.split("[\u007C]");
			param.setResultCd(rtnResult[0]);
			param.setResultMsg(rtnResult[1]);

			if("0".equals(param.getResultCd())) {
				param.setIfYn("Y");
			} else {
				param.setIfYn("F");
			}

			coreOrderDao.updateInsuranceInfo(param);
		}

		return "SUCCESS";
	}

	/**
	 * 네이버페이 주문 정보 생성 및 송부
	 * @param param
	 * @param request
	 * @param response
	 * @author xodud1202
	 * @since 2021. 05. 12
	 */
	@Transactional("shopTxnManager")
	public GagaMap nPayReq50(Order param, HttpServletRequest request, HttpServletResponse response) {
		GagaMap result = new GagaMap();

		// 로그인 정보 조회
		if(TsfSession.isLogin()) {
			param.setCustNo(TsfSession.getInfo().getCustNo());
		} else {
			param.setCustNo(0);
			param.setJsessionId(TsfSession.getSessionId());
		}

		try {
			param.setSiteCd(TscConstants.Site.STYLE24.value());
			param.setFrontGb(TsfSession.getFrontGb());	// 디바이스 정보
			param.setPrePntDcAmtYn("N");				// 네이버페이 : 선포인트 사용하지 않음으로 강제 지정
			param.setShotDelvYn("N");					// 네이버페이 : 총알배송 여부 설정 N
			param.setInsuranceYn("N");					// 네이버페이 : 보증보험 신청 여부 N

			// 장바구니 등록된 주문 정보 조회
			Collection<Order> cartList = coreOrderService.getCartGoodsList(param);

			// 주문 상세 정보 세팅
			for(Order item : cartList) {
				item.setSavePntAmt(0);
				item.setOrdAmt((item.getCurrPrice() + item.getOptAddPrice()) * item.getGoodsQty());			// ordAmt = (즉시할인가 + 옵션가) * 수량
				item.setRealOrdAmt(item.getOrdAmt());														// 네이버페이는 할인 없으므로 ordAmt와 동일
				item.setShotDelvYn("N");
				item.setGiftPackYn("N");
				item.setRegNo(param.getCustNo());
				item.setOrgDelvFee(item.getDelvFee());
			}
			param.setOrderDetailList(cartList);

			// 배송비 정보 조회
			GagaMap delvMap = coreOrderService.getCartDelvGoodsCntList(cartList, param);
			param.setDelvFeeCdList((Collection<Order>) delvMap.get("delvFeeCdList"));

			// 주문 정보 등록
			coreOrderService.createPreOrder(param);
			int ordNo = param.getOrdNo();
			int custNo = param.getCustNo();

			// 네이버페이 기본정보
			String shopId			= env.getProperty("naverPay.shop.id");				// shopId
			String certificationKey	= env.getProperty("naverPay.certification.key");	// 네이버페이 인증키
			String cpaInflowCode	= getCookieValue(request, "CPAValidator");
			String naverInflowCode	= getCookieValue(request, "NA_CO");
			String saClickId		= getCookieValue(request, "NVADID");
			String domain 			= env.getProperty("domain.front");					// 도메인 주소
			String staticUrl		= "/resources";
			String goodsImgUrl		= env.getProperty("upload.goods.view");				// 상품 이미지 경로
			int totPrice			= 0;												// 전체 주문 금액

			// 네이버페이 송부용 xml 작성
			StringBuilder sb = new StringBuilder();
			sb.append("<order>\n");
			sb.append("\t<merchantId>").append(shopId).append("</merchantId>\n");								//<!-- 상점ID -->
			sb.append("\t<certiKey>").append(certificationKey).append("</certiKey>\n");	//<!-- 인증키 -->
			sb.append("\t<backUrl>").append("<![CDATA[").append(param.getBackUrl()).append("]]>").append("</backUrl>\n");	//<!-- 이전페이지 -->
			sb.append("\t<interface>\n");
			sb.append("\t<merchantCustomCode1>").append(param.getOrdNo()).append("</merchantCustomCode1>\n");
			sb.append("\t\t<cpaInflowCode>").append(cpaInflowCode).append("</cpaInflowCode>\n");
			sb.append("\t\t<naverInflowCode>").append(naverInflowCode).append("</naverInflowCode>\n");
			sb.append("\t\t<saClickId>").append(saClickId).append("</saClickId>\n");
			sb.append("\t</interface>\n");

			for(Order item : param.getOrderDetailList()) {
				//<!-- 상품정보 -->
				sb.append("\t<product>\n");
				sb.append("\t\t<id>").append(item.getGoodsCd()).append("</id>\n");								//<!-- 상품코드 -->
				sb.append("\t\t<ecMallProductId>").append(item.getGoodsCd()).append("</ecMallProductId>\n");	//<!-- 상품코드 -->
				sb.append("\t\t<name>").append("<![CDATA[").append(item.getGoodsNm()).append("]]>").append("</name>\n");	//<!-- 상품명 -->
				sb.append("\t\t<basePrice>").append(item.getCurrPrice()).append("</basePrice>\n");				//<!-- 상품금액 -->
				sb.append("\t\t<infoUrl>").append("<![CDATA[https:").append(param.getGoodsUrl()).append(item.getGoodsCd()).append("]]>").append("</infoUrl>\n");		//<!-- 상품상세페이지 URL -->
				sb.append("\t\t<imageUrl>").append("<![CDATA[https:").append(goodsImgUrl).append("/").append(item.getSysImgNm()).append("]]>").append("</imageUrl>\n");	//<!-- 상품원본이미지 URL -->

				if(TscConstants.GoodsType.SET.value().equals(item.getGoodsType())) {		// 세트상품
					// 세트상품 manageCode 정렬 (optCd ASC)
					Goods option = new Goods();
					option.setArrGoodsCd(item.getItemCd().split(","));
					option.setSizeArr(item.getOptCd().split(","));
					List<Goods> optionList = (ArrayList<Goods>) goodsDao.getOrderGoodsOptionList(option);

					StringBuilder manageCode = new StringBuilder();
					int k = 0;
					for(Goods opt : optionList) {
						if(k++ > 0) manageCode.append("/");
						manageCode.append(opt.getOptCd());
					}

					// 옵션 정보
					sb.append("\t\t<option>\n");
					sb.append("\t\t\t<quantity>").append(item.getGoodsQty()).append("</quantity>\n");	//<!-- 옵션수량-->
					sb.append("\t\t\t<price>").append(item.getOptAddPrice()).append("</price>\n");		//<!-- 옵션금액 -->
					sb.append("\t\t\t<manageCode>").append(manageCode).append("</manageCode>\n");		//<!-- 옵션관리코드 -->

					// 구성상품별 옵션 세팅
					int i = 1;
					for(Goods opt : optionList) {
						// 상품명, 컬러, 사이즈 확인(최대 50자) ==> 20200517 정지혜과장님 확인 :: 상품명=25,OPT1=13,OPT2=12 글자. 넘어갈경우 뒤에 ".." 붙여서 글자수 맞출것.
						// 상품명/컬러/사이즈 이므로 가운데 / 를 위해 24, 12, 12로 진행
						if(opt.getGoodsNm().length() > 24)	{opt.setGoodsNm(opt.getGoodsNm().substring(0, 21) + "..");}
						if(opt.getOptCd2().length() > 12)	{opt.setOptCd2(opt.getOptCd2().substring(0, 9)  + "..");}
						if(opt.getColorNm().length() > 12)	{opt.setColorNm(opt.getColorNm().substring(0, 9) + "..");}

						sb.append("\t\t\t<selectedItem>\n");
						sb.append("\t\t\t\t<type>SELECT</type>\n");								//<!-- 옵션유형 -->
						sb.append("\t\t\t\t<name>구성상품").append(i++).append("</name>\n");		//<!-- 옵션명 -->
						sb.append("\t\t\t\t<value>\n");
						sb.append("\t\t\t\t\t<id>").append(opt.getOptCd()).append("</id>\n");	//<!-- 옵션 -->
						sb.append("\t\t\t\t\t<text>").append(opt.getGoodsNm()).append("/").append(opt.getColorNm()).append("/").append(opt.getOptCd2()).append("</text>\n");//<!-- 옵션명 -->
						sb.append("\t\t\t\t</value>\n");
						sb.append("\t\t\t</selectedItem>\n");
					}

					sb.append("\t\t</option>\n");
				} else if("Y".equals(item.getSelfGoodsYn())) {								// 세트상품 제외 자사상품
					// 옵션 정보
					sb.append("\t\t<option>\n");
					sb.append("\t\t\t<quantity>").append(item.getGoodsQty()).append("</quantity>\n");	//<!-- 옵션수량-->
					sb.append("\t\t\t<price>").append(item.getOptAddPrice()).append("</price>\n");		//<!-- 옵션금액 -->
					sb.append("\t\t\t<manageCode>").append(item.getOptCd()).append("</manageCode>\n");	//<!-- 옵션관리코드 -->

					// 칼라코드
					sb.append("\t\t\t<selectedItem>\n");
					sb.append("\t\t\t\t<type>SELECT</type>\n");//<!-- 옵션유형 -->
					sb.append("\t\t\t\t<name>색상</name>\n");//<!-- 옵션명 -->
					sb.append("\t\t\t\t<value>\n");
					sb.append("\t\t\t\t\t<id>").append(item.getOptCd1()).append("</id>\n");//<!-- 칼라코드 -->
					sb.append("\t\t\t\t\t<text>").append(item.getColorNm()).append("</text>\n");//<!-- 칼라명 -->
					sb.append("\t\t\t\t</value>\n");
					sb.append("\t\t\t</selectedItem>\n");

					// 사이즈코드
					sb.append("\t\t\t<selectedItem>\n");
					sb.append("\t\t\t\t<type>SELECT</type>\n");//<!-- 옵션유형 -->
					sb.append("\t\t\t\t<name>사이즈</name>\n");//<!-- 옵션명 -->
					sb.append("\t\t\t\t<value>\n");
					sb.append("\t\t\t\t\t<id>").append(item.getOptCd2()).append("</id>\n");//<!-- 사이즈코드 -->
					sb.append("\t\t\t\t\t<text>").append(item.getOptCd2()).append("</text>\n");//<!-- 사이즈명 -->
					sb.append("\t\t\t\t</value>\n");
					sb.append("\t\t\t</selectedItem>\n");
					sb.append("\t\t</option>\n");
				} else {																		// 세트상품 제외 입점업체 상품
					// 옵션 정보
					sb.append("\t\t<option>\n");
					sb.append("\t\t\t<quantity>").append(item.getGoodsQty()).append("</quantity>\n");	//<!-- 옵션수량-->
					sb.append("\t\t\t<price>").append(item.getOptAddPrice()).append("</price>\n");		//<!-- 옵션금액 -->
					sb.append("\t\t\t<manageCode>").append(item.getOptCd()).append("</manageCode>\n");	//<!-- 옵션관리코드 -->

					// 칼라코드
					sb.append("\t\t\t<selectedItem>\n");
					sb.append("\t\t\t\t<type>SELECT</type>\n");//<!-- 옵션유형 -->
					sb.append("\t\t\t\t<name>옵션</name>\n");//<!-- 옵션명 -->
					sb.append("\t\t\t\t<value>\n");
					sb.append("\t\t\t\t\t<id>").append(item.getOptCd()).append("</id>\n");//<!-- 칼라코드 -->
					sb.append("\t\t\t\t\t<text>").append(item.getOptCd1()).append("/").append(item.getOptCd2()).append("</text>\n");//<!-- 칼라명 -->
					sb.append("\t\t\t\t</value>\n");
					sb.append("\t\t\t</selectedItem>\n");
					sb.append("\t\t</option>\n");
				}

				// 배송비 판단 후 배송비유형 선택 (추가 기본배송비, 무료배송비 기준 조회후 등록)
				//<!-- 배송정보 -->
				String delvFeeCrite = "CHARGE";
				int delvFee = item.getOrgDelvFee();
				String feePayType = "PREPAYED";
				// 배송비 조건
				if(TscConstants.DelvFeeCrite.NORMAL.value().equals(item.getDelvFeeCrite())) {
					delvFeeCrite = "CONDITIONAL_FREE";		// 조건부 무료(배송비 조건이 무료이거나 배송 방법이 착불일때만 배송비는 0원으로 변경)
				} else if(TscConstants.DelvFeeCrite.FREE.value().equals(item.getDelvFeeCrite())) {
					delvFeeCrite = "FREE";
					feePayType = "FREE";
					delvFee = 0;
				}

				sb.append("\t\t<shippingPolicy>\n");
				sb.append("\t\t\t<groupId>").append(item.getDelvFeeCd()).append("</groupId>\n");		//<!-- 배송비묶음그룹ID -->
				sb.append("\t\t\t<method>DELIVERY</method>\n");											//<!-- 배송방법 : 택배,소포,등기 -->
				sb.append("\t\t\t<feeType>").append(delvFeeCrite).append("</feeType>\n");				//<!-- 배송비유형 : 유료 -->
				sb.append("\t\t\t<feePayType>").append(feePayType).append("</feePayType>\n");			//<!-- 배송비결제방법 : 선불 -->
				sb.append("\t\t\t<feePrice>").append(delvFee).append("</feePrice>\n");					//<!-- 기본배송비 -->

				// 조건부 무료일경우에만 송부
				if(TscConstants.DelvFeeCrite.NORMAL.value().equals(item.getDelvFeeCrite())) {
					sb.append("\t\t\t<conditionalFree>\n");
					sb.append("\t\t\t\t<basePrice>").append(item.getMinOrdAmt()).append("</basePrice>\n");	//<!-- 무료배송비기준 -->
					sb.append("\t\t\t</conditionalFree>\n");
				}

				sb.append("\t\t</shippingPolicy>\n");
				sb.append("\t</product>\n");

				totPrice = totPrice + ((item.getCurrPrice() + item.getOptAddPrice()) * item.getGoodsQty());
			}

			sb.append("</order>");

			log.info("CHECK NAVER PAY SB_LENGTH ::::: \n{}", sb.length());
			log.info("CHECK NAVER PAY SB ::::: \n{}", sb.toString());

			result = sendOrderInfoToNC(sb);

			// 최종 결제 금액 계산
			Order realAmtOrdNo = new Order();
			realAmtOrdNo.setOrdNo(ordNo);

			// 4. 결제 예정 정보 저장
			Payment payment = new Payment();
			payment.setOrdNo(param.getOrdNo());
			payment.setPayMeans(TscConstants.PayMeans.CREDIT_CARD.value());
			payment.setPayAmt(orderDao.getRealPaymentAmt(realAmtOrdNo));
			payment.setPgCpnAmt(0);
			payment.setNpayPntAmt(0);
			payment.setPayGb("O");
			payment.setPayStat(TscConstants.PaymentStat.PAYMENT_WAIT.value());
			payment.setPgGb(TscConstants.PgGb.NAVER_ORDER.value());
			payment.setPgShopId(env.getProperty("naverPay.shop.id"));
			payment.setEscrowYn("N");
			payment.setRegNo(custNo);
			payment.setUpdNo(custNo);
			coreOrderDao.insertPayment(payment);

			if(TscConstants.FrontGb.PC.value().equals(TsfSession.getFrontGb())) {
				result.put("npayOrderUrl", env.getProperty("naverPay.order.pc.url"));
			} else {
				result.put("npayOrderUrl", env.getProperty("naverPay.order.mobile.url"));
			}

			result.put("orderkey", param.getNpayOrdNo());
			result.put("resultNo", result.get("resultNo").toString());

			result.put("state", "sucess");
		} catch(Exception e) {
			result.put("state", "fail");
			result.put("message", "주문실패");

			e.printStackTrace();
		}

		return result;
	}

	private String getCombinationXml(String manageCode, int addPrice, int stockQty, int size) {
		String[] optCd = manageCode.split("/");
		StringBuilder sb = new StringBuilder();
		sb.append("\t\t\t<combination>\n");
		sb.append("\t\t\t\t<manageCode>").append(manageCode).append("</manageCode>\n");
		sb.append("\t\t\t\t<price>").append(addPrice).append("</price>\n");
		sb.append("\t\t\t\t<stockQuantity>").append(stockQty).append("</stockQuantity>\n");
		sb.append("\t\t\t\t<status>true</status>\n");

		// 옵션 옵션조합정보 색상
		for(int i = 0 ; i < size ; i++) {
			sb.append("\t\t\t\t<options>\n");
			sb.append("\t\t\t\t\t<name>구성상품").append(i + 1).append("</name>\n");
			sb.append("\t\t\t\t\t<id>").append(optCd[i]).append("</id>\n");
			sb.append("\t\t\t\t</options>\n");
		}

		sb.append("\t\t\t</combination>\n");

		return sb.toString();
	}

	/**
	 * 네이버페이 주문 정보 송부
	 * @param sb
	 * @author xodud1202
	 * @since 2021. 05. 12
	 */
	private GagaMap sendOrderInfoToNC(StringBuilder sb) throws IOException {
		GagaMap resultMap = new GagaMap();

		// 1.0, 2.0  일때 구분값 처리
		URL _url = new URL(env.getProperty("naverPay.order.api.url"));
		String ENCODING = "UTF-8";

		HttpsURLConnection conn = (HttpsURLConnection)_url.openConnection();

		conn.setDoInput(true);
		conn.setDoOutput(true);
		conn.setUseCaches(false);
		conn.setRequestMethod("POST");
		conn.addRequestProperty("Content-Type", "application/xml; charset=UTF-8");

		// 주문 등록 API 호출
		Writer writer = new OutputStreamWriter(conn.getOutputStream(), ENCODING);
		writer.write(sb.toString());

		writer.flush();
		writer.close();

		int respCode = conn.getResponseCode();
		log.info("CHECK RESP CODE ::::: {}", respCode);

		if (respCode != 200) {
			throw new RuntimeException(String.format("NC Response fail : %d %s", respCode, conn.getResponseMessage()));
		}

		BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

		String[] arr = reader.readLine().split(":");

		log.info("CHECK RESULT ARR ::::: {} / {} / {}", arr[0], arr[1], arr[2]);
		if ("SUCCESS".equals(arr[0])) {
			resultMap.put("state", 		arr[0]);
			resultMap.put("orderKey", 	arr[1]);
			resultMap.put("resultNo", 	arr[2]);
		} else {
			throw new IllegalStateException(String.format("NC Response fail : %d %s", reader.readLine().toString()));
		}

		conn.disconnect();

		return resultMap;
	}

	/*
	 * 쿠키값 가져오기
	 */
	private String getCookieValue(HttpServletRequest request, String name) {
		if (name == null || request == null) {
			return "";
		}

		Cookie[] cookies = request.getCookies();

		if (cookies != null) {
			for (int i = 0; i < cookies.length; i++) {
				if (name.equals(cookies[i].getName())) {
					return cookies[i].getValue();
				}
			}
		}

		return "";
	}

	/**
	 * 네이버페이 상품 정보 생성 및 송부
	 * @param request
	 * @param response
	 * @author xodud1202
	 * @since 2021. 05. 12
	 */
	public void createNpayGoodsXml50(HttpServletRequest request, HttpServletResponse response) throws Exception {
		log.info(":::::::::::::::: CHECK CREATE GOODS XML :::::::::::::::::: ");
		StringBuilder sb = new StringBuilder();
		// http://ldfront.style24.com/pg/create/npay/goodsxml?product%5B0%5D%5Bid%5D=A83F-DP568S&product%5B0%5D%5BoptionManageCodes%5D=14019445-2&supplementSearch=true&optionSearch=true
		// product%5B0%5D%5Bid%5D=A83F-DP568S&product%5B0%5D%5BoptionManageCodes%5D=14019445-2&supplementSearch=true&optionSearch=true
		// http://ldfront.style24.com/pg/create/npay/goodsxml?product%5B0%5D%5Bid%5D=STYS00000143&product%5B0%5D%5BoptionManageCodes%5D=14237291-10/14237321-4/14237322-6&supplementSearch=true&optionSearch=true
		// product%5B0%5D%5Bid%5D=STYS00000143&product%5B0%5D%5BoptionManageCodes%5D=14237291-10/14237321-4/14237322-6&supplementSearch=true&optionSearch=true
		// 이스케이프코드 : %5B = [  ,   %5D = ]

		try {
			String goodsCdStr 				= "";
			String optionManageCodesStr 	= "";
			String optionManageCodes 		= "";
			String queryStr 				= request.getQueryString();
			String[] arr1 					= queryStr.split("product");

			for (int i=0 ; i<arr1.length; i++) {
				String[] arr2 = arr1[i].split("&");

				for (int j=0 ; j<arr2.length ; j++) {
					String[] arr3 = arr2[j].split("=");

					log.info("CHECK ARR1 :::: {}", Arrays.toString(arr1));
					log.info("CHECK ARR2 :::: {}", Arrays.toString(arr2));
					log.info("CHECK ARR3 :::: {}", Arrays.toString(arr3));

					if (arr3.length > 1) {
						if (arr3[0].contains("id")) {
							if ("".equals(goodsCdStr)) {
								goodsCdStr = goodsCdStr + arr3[1];
							} else {
								goodsCdStr = goodsCdStr + "," + arr3[1];
							}
						} else if (arr3[0].contains("optionManageCodes")) {
							if ("".equals(optionManageCodesStr)) {
								optionManageCodesStr = optionManageCodesStr + arr3[1];
								optionManageCodes = optionManageCodes + arr3[1];
							} else {
								optionManageCodesStr = optionManageCodesStr + "," + arr3[1];
								optionManageCodes = optionManageCodes + "/" + arr3[1];
							}
						}
					}
				}
			}

			log.info("CHECK GOODS_CDS :::: {}", goodsCdStr);
			log.info("CHECK MANAGE_CODES_ARR :::: {}", optionManageCodesStr);

			String[] goodsCdArr 			= goodsCdStr.split(",");
			String[] optionManageCodesArr 	= optionManageCodesStr.split(",");

			// 네이버페이 기본정보
			String shopId			= env.getProperty("naverPay.shop.id");				// shopId
			String certificationKey	= env.getProperty("naverPay.certification.key");	// 네이버페이 인증키
			String cpaInflowCode	= getCookieValue(request, "CPAValidator");
			String naverInflowCode	= getCookieValue(request, "NA_CO");
			String saClickId		= getCookieValue(request, "NVADID");
			String domain 			= env.getProperty("domain.front");					// 도메인 주소
			String staticUrl		= "/resources";
			String goodsImgUrl		= env.getProperty("upload.goods.view");				// 상품 이미지 경로
			int totPrice			= 0;												// 전체 주문 금액

			sb.append("<?xml version='1.0' encoding='utf-8'?>\n");
			sb.append("<products>\n");

			for (int i=0; i<goodsCdArr.length; i++) {
				Order item = new Order();
				item.setGoodsCd(goodsCdArr[i]);		// 상품코드
				String optionManageCode = coreOrderService.simpleDecode(optionManageCodesArr[i]);
				item.setOptCd(optionManageCode);	// 상품 옵션

				// 이 포인트에서 세트상품, 일반 상품 분리 조회 필요 (재고 파악 로직이 다름)
				Goods simpleInfo = new Goods();
				simpleInfo.setGoodsCd(item.getGoodsCd());
				simpleInfo = goodsDao.getGoodsSimpleInfo(simpleInfo);

				// 세트상품일 경우
				if(TscConstants.GoodsType.SET.value().equals(simpleInfo.getGoodsType())) {
					// 주문 상품 정보 조회
					Goods goods = new Goods();
					goods.setGoodsCd(item.getGoodsCd());
					goods.setOptCd(item.getOptCd());
					goods.setFrontGb(TsfSession.getFrontGb());
					goods.setSiteCd(TscConstants.Site.STYLE24.value());
					goods.setAdminYn("Y");			// 상품 상태에 관계 없이 조회하기 위함
					goods = goodsDao.getGoodsInfo(goods);

					// 상품 상태 확인
					String goodsStat = "";
					if(TscConstants.GoodsStat.APPR.value().equals(goods.getGoodsStat())) {
						goodsStat = "ON_SALE";		// 판매중
					} else if (TscConstants.GoodsStat.SOLDOUT.value().equals(goods.getGoodsStat())) {
						goodsStat = "SOLD_OUT";		// 품절
					} else {
						goodsStat = "NOT_SALE";		// 구매불가
					}

					// 반송지 정보
					Delivery rtnInfo = goodsDao.getGoodsDeliveryInfo(goods.getGoodsCd());

					sb.append("\t<product>\n");
					sb.append("\t\t<id>").append(item.getGoodsCd()).append("</id>\n");
					sb.append("\t\t<merchantProductId>").append(item.getGoodsCd()).append("</merchantProductId>\n");
					sb.append("\t\t<ecMallProductId>").append(item.getGoodsCd()).append("</ecMallProductId>\n");
					sb.append("\t\t<name>").append(goods.getGoodsNm()).append("</name>\n");
					sb.append("\t\t<status>").append(goodsStat).append("</status>\n");
					sb.append("\t\t<basePrice>").append(goods.getCurrPrice()).append("</basePrice>\n");
					sb.append("\t\t<infoUrl>").append("https:" + domain + "/goods/detail/form?goodsCd=" + goods.getGoodsCd()).append("</infoUrl>\n");
					sb.append("\t\t<imageUrl>").append("https:" + goodsImgUrl + "/" + goods.getSysImgNm()).append("</imageUrl>\n");

					// 12.반품주소
					if (rtnInfo != null && rtnInfo.getRtnLocZipcode() != null && !"".equals(rtnInfo.getRtnLocZipcode())) {
						// 2.1 반품정보
						sb.append("\t\t<returnInfo>\n");
						sb.append("\t\t\t<zipcode>").append(rtnInfo.getRtnLocZipcode()).append("</zipcode>\n");
						sb.append("\t\t\t<address1>").append(rtnInfo.getRtnLocBaseAddr()).append("</address1>\n");
						sb.append("\t\t\t<address2>").append(rtnInfo.getRtnLocDtlAddr()).append("</address2>\n");
						sb.append("\t\t\t<sellername>").append(rtnInfo.getRtnLocNm()).append("</sellername>\n");
						sb.append("\t\t\t<contact1>").append(rtnInfo.getRtnLocTelno()).append("</contact1>\n");
						sb.append("\t\t</returnInfo>\n");

						// 반품배송비, 교환배송비
						sb.append("\t\t<returnShippingFee>").append(goods.getRtnDelvFee()).append("</returnShippingFee>\n");
						sb.append("\t\t<exchangeShippingFee>").append((goods.getRtnDelvFee() * 2)).append("</exchangeShippingFee>\n");
					}

					// 옵션정보 지원여부 true
					sb.append("\t\t<optionSupport>true</optionSupport>\n");

					// 세트상품 정보  getGoodsSetComposeList
					goods.setSiteCd(TscConstants.Site.STYLE24.value());
					Collection<Goods> compsInfoList = goodsDao.getCompsGoodsList(goods);

					// 옵션 정보
					sb.append("\t\t<option>\n");
					int combCnt = 0;		// 옵션 조합 총 수량
					// 옵션 아이템정보 구성상품
					for (Goods comps : compsInfoList) {
						sb.append("\t\t\t<optionItem>\n");
						sb.append("\t\t\t\t<type>SELECT</type>\n");
						sb.append("\t\t\t\t<name>구성상품").append(comps.getRnum()).append("</name>\n");

						// 구성상품별 옵션 정보
						String[] optCds = comps.getOptCd().split(",");
						String[] optCd2s = comps.getOptCd2().split(",");
						String[] colorNms = comps.getColorNm().split(",");
						combCnt *= optCds.length;

						for(int j = 0 ; j < optCds.length ; j++) {
							if(comps.getGoodsNm().length() > 24)	{comps.setGoodsNm(comps.getGoodsNm().substring(0, 21) + "..");}
							if(optCd2s[j].length() > 12)	{optCd2s[j] = optCd2s[j].substring(0, 9)  + "..";}
							if(colorNms[j].length() > 12)	{colorNms[j] = colorNms[j].substring(0, 9) + "..";}

							sb.append("\t\t\t\t<value>\n");
							sb.append("\t\t\t\t\t<id>").append(optCds[j]).append("</id>\n");
							sb.append("\t\t\t\t\t<text>").append(comps.getGoodsNm()).append("/").append(colorNms[j]).append("/").append(optCd2s[j]).append("</text>\n");//<!-- 옵션명 -->
							sb.append("\t\t\t\t</value>\n");
						}

						sb.append("\t\t\t</optionItem>\n");
					}

					// 세트 구성상품 모든 옵션 경우의 수 조회 > 상품코드 오름차순, OPTCD 오름차순으로 정확히 보낼것 > 주문요청된 manageCode가 같아야함.
					for (Goods comps1 : compsInfoList) {
						if(comps1.getRnum() == 1) {
							// 구성상품별 옵션 정보
							String[] goods1optCds = comps1.getOptCd().split(",");
							String[] goods1addPrices = comps1.getItemPrices().split(",");
							String[] goods1stockQty = comps1.getItemStockQty().split(",");

							for(int g1 = 0 ; g1 < goods1optCds.length ; g1++) {
								StringBuilder manageCode = new StringBuilder(goods1optCds[g1]);	// 옵션코드 조합
								int addPrice = Integer.parseInt(goods1addPrices[g1]);		// 추가금액 합계
								int stockQty = Integer.parseInt(goods1stockQty[g1]);		// 상품 주문 최소 재고(구성상품 최소)
								log.info("MAKE new StringBuilder(goods1optCds[g1]) :::: {}", goods1optCds[g1]);
								log.info("MAKE MANAGECODE :::: {}", manageCode);
								if(compsInfoList.size() > 1) {		// 조합 상품 최대치 계산 (세트상품은 최대 5개까지 등록 가능)
									for (Goods comps2 : compsInfoList) {
										if(comps2.getRnum() == 2) {
											// 구성상품별 옵션 정보
											String[] goods2optCds = comps2.getOptCd().split(",");
											String[] goods2addPrices = comps2.getItemPrices().split(",");
											String[] goods2stockQty = comps2.getItemStockQty().split(",");

											// 기존 정보 저장 (다시 돌아올 경우 이전 번호까지의 정보로 리셋하기 위함)
											String manageCodeSave2 = manageCode.toString();
											int addPriceSave2 = Integer.parseInt(goods1addPrices[g1]);
											int stockQtySave2 = Integer.parseInt(goods1stockQty[g1]);

											for(int g2 = 0 ; g2 < goods2optCds.length ; g2++) {
												manageCode = new StringBuilder(manageCodeSave2);		// String 참조변수 인식 방지(사라지지 않음)를 위한 객체 재생성
												manageCode.append("/").append(goods2optCds[g2]);
												addPrice = addPriceSave2 + Integer.parseInt(goods2addPrices[g2]);
												if(stockQtySave2 < Integer.parseInt(goods2stockQty[g2])) stockQty = Integer.parseInt(goods2stockQty[g2]);
												log.info("MAKE new StringBuilder(manageCodeSave2); :::: {}", manageCodeSave2);
												log.info("MAKE MANAGECODE :::: {}", manageCode);

												if(compsInfoList.size() > 2) {        // 조합 상품 최대치 계산 (세트상품은 최대 5개까지 등록 가능)
													for (Goods comps3 : compsInfoList) {
														if (comps3.getRnum() == 3) {
															// 구성상품별 옵션 정보
															String[] goods3optCds = comps3.getOptCd().split(",");
															String[] goods3addPrices = comps3.getItemPrices().split(",");
															String[] goods3stockQty = comps3.getItemStockQty().split(",");

															// 기존 정보 저장 (다시 돌아올 경우 이전 번호까지의 정보로 리셋하기 위함)
															String manageCodeSave3 = manageCode.toString();
															int addPriceSave3 = addPriceSave2;
															int stockQtySave3 = stockQtySave2;

															for(int g3 = 0 ; g3 < goods3optCds.length ; g3++) {
																manageCode = new StringBuilder(manageCodeSave3);		// String 참조변수 인식 방지(사라지지 않음)를 위한 객체 재생성
																manageCode.append("/").append(goods3optCds[g3]);
																addPrice = addPriceSave3 + Integer.parseInt(goods3addPrices[g3]);
																if(stockQtySave3 < Integer.parseInt(goods3stockQty[g3])) stockQty = Integer.parseInt(goods3stockQty[g3]);
																log.info("MAKE new StringBuilder(manageCodeSave3); :::: {}", manageCodeSave3);
																log.info("MAKE MANAGECODE :::: {}", manageCode);

																if(compsInfoList.size() > 3) {        // 조합 상품 최대치 계산 (세트상품은 최대 5개까지 등록 가능)
																	for (Goods comps4 : compsInfoList) {
																		if (comps4.getRnum() == 4) {
																			// 구성상품별 옵션 정보
																			String[] goods4optCds = comps4.getOptCd().split(",");
																			String[] goods4addPrices = comps4.getItemPrices().split(",");
																			String[] goods4stockQty = comps4.getItemStockQty().split(",");

																			// 기존 정보 저장 (다시 돌아올 경우 이전 번호까지의 정보로 리셋하기 위함)
																			String manageCodeSave4 = manageCode.toString();
																			int addPriceSave4 = addPriceSave3;
																			int stockQtySave4 = stockQtySave3;

																			for(int g4 = 0 ; g4 < goods4optCds.length ; g4++) {
																				manageCode = new StringBuilder(manageCodeSave4);		// String 참조변수 인식 방지(사라지지 않음)를 위한 객체 재생성
																				manageCode.append("/").append(goods4optCds[g4]);
																				addPrice = addPriceSave4 + Integer.parseInt(goods4addPrices[g4]);
																				if(stockQtySave4 < Integer.parseInt(goods4stockQty[g4])) stockQty = Integer.parseInt(goods4stockQty[g4]);

																				if(compsInfoList.size() > 4) {        // 조합 상품 최대치 계산 (세트상품은 최대 5개까지 등록 가능)
																					for (Goods comps5 : compsInfoList) {
																						if (comps5.getRnum() == 5) {
																							// 구성상품별 옵션 정보
																							String[] goods5optCds = comps5.getOptCd().split(",");
																							String[] goods5addPrices = comps5.getItemPrices().split(",");
																							String[] goods5stockQty = comps5.getItemStockQty().split(",");

																							// 기존 정보 저장 (다시 돌아올 경우 이전 번호까지의 정보로 리셋하기 위함)
																							String manageCodeSave5 = manageCode.toString();
																							int addPriceSave5 = addPriceSave4;
																							int stockQtySave5 = stockQtySave4;

																							for(int g5 = 0 ; g5 < goods5optCds.length ; g5++) {
																								manageCode = new StringBuilder(manageCodeSave5);        // String 참조변수 인식 방지(사라지지 않음)를 위한 객체 재생성
																								manageCode.append("/").append(goods5optCds[g5]);
																								addPrice = addPriceSave5 + Integer.parseInt(goods5addPrices[g5]);
																								if (stockQtySave5 < Integer.parseInt(goods5stockQty[g5])) stockQty = Integer.parseInt(goods5stockQty[g5]);

																								// 세트상품은 최대 5개이므로 마무리.
																								if (optionManageCodes.equals(manageCode.toString())) {
																									sb.append(getCombinationXml(manageCode.toString(), addPrice, stockQty, compsInfoList.size()));
																								}
																							}
																						}
																					}
																				} else {
																					if (optionManageCodes.equals(manageCode.toString())) {
																						sb.append(getCombinationXml(manageCode.toString(), addPrice, stockQty, compsInfoList.size()));
																					}
																				}
																			}
																		}
																	}
																} else {
																	if (optionManageCodes.equals(manageCode.toString())) {
																		sb.append(getCombinationXml(manageCode.toString(), addPrice, stockQty, compsInfoList.size()));
																	}
																}
															}
														}
													}
												} else {
													if (optionManageCodes.equals(manageCode.toString())) {
														sb.append(getCombinationXml(manageCode.toString(), addPrice, stockQty, compsInfoList.size()));
													}
												}
											}
										}
									}
								} else {
									if (optionManageCodes.equals(manageCode.toString())) {
										sb.append(getCombinationXml(manageCode.toString(), addPrice, stockQty, compsInfoList.size()));
									}
								}
							}
						}
					}

					sb.append("\t\t</option>\n");

					// 10. 배송정보조회
					// 5.2.1 업체별 기본배송비, 무료배송비
					String delvFeeCd = "";
					if("Y".equals(goods.getSelfGoodsYn())) {
						delvFeeCd = "WMS";
					} else {
						delvFeeCd = goods.getDelvFeeCd();
					}
					String delvFeeCrite = "CHARGE";
					int delvFee = goods.getDelvFee();
					String feePayType = "PREPAYED";
					// 배송비 조건
					if(TscConstants.DelvFeeCrite.NORMAL.value().equals(goods.getDelvFeeCrite())) {
						delvFeeCrite = "CONDITIONAL_FREE";		// 조건부 무료(배송비 조건이 무료이거나 배송 방법이 착불일때만 배송비는 0원으로 변경)
					} else if(TscConstants.DelvFeeCrite.FREE.value().equals(goods.getDelvFeeCrite())) {
						delvFeeCrite = "FREE";
						feePayType = "FREE";
						delvFee = 0;
					}

					sb.append("\t\t<shippingPolicy>\n");
					sb.append("\t\t\t<groupId>").append(delvFeeCd).append("</groupId>\n");
					sb.append("\t\t\t<method>").append("DELIVERY").append("</method>\n");
					sb.append("\t\t\t<feeType>").append(delvFeeCrite).append("</feeType>\n");
					sb.append("\t\t\t<feePayType>").append(feePayType).append("</feePayType>\n");
					sb.append("\t\t\t<feePrice>").append(delvFee).append("</feePrice>\n");
					if(!"FREE".equals(delvFeeCrite)) {
						sb.append("\t\t\t<conditionalFree>\n");
						sb.append("\t\t\t\t<basePrice>").append(goods.getMinOrdAmt()).append("</basePrice>\n");
						sb.append("\t\t\t</conditionalFree>\n");
					}

					sb.append("\t\t</shippingPolicy>\n");

					sb.append("\t</product>\n");
				} else {
					// 주문 상품 옵션 정보 조회
					GoodsStock opt = new GoodsStock();
					opt.setGoodsCd(item.getGoodsCd());
					opt.setOptCd(item.getOptCd());
					opt = goodsDao.getGoodsStockInfo(opt);

					// 주문 상품 정보 조회
					Goods goods = new Goods();
					goods.setGoodsCd(item.getGoodsCd());
					goods.setOptCd(item.getOptCd());
					goods.setColorCd(opt.getOptCd1());
					goods.setFrontGb(TsfSession.getFrontGb());
					goods.setSiteCd(TscConstants.Site.STYLE24.value());
					goods.setAdminYn("Y");			// 상품 상태에 관계 없이 조회하기 위함
					goods = goodsDao.getGoodsInfo(goods);

					// 상품 상태 확인
					String goodsStat = "";
					if(TscConstants.GoodsStat.APPR.value().equals(goods.getGoodsStat())) {
						goodsStat = "ON_SALE";		// 판매중
					} else if (TscConstants.GoodsStat.SOLDOUT.value().equals(goods.getGoodsStat())) {
						goodsStat = "SOLD_OUT";		// 품절
					} else {
						goodsStat = "NOT_SALE";		// 구매불가
					}

					// 반송지 정보
					Delivery rtnInfo = goodsDao.getGoodsDeliveryInfo(goods.getGoodsCd());

					sb.append("\t<product>\n");
					sb.append("\t\t<id>").append(goodsCdArr[i]).append("</id>\n");
					sb.append("\t\t<merchantProductId>").append(goodsCdArr[i]).append("</merchantProductId>\n");
					sb.append("\t\t<ecMallProductId>").append(goodsCdArr[i]).append("</ecMallProductId>\n");
					sb.append("\t\t<name>").append(goods.getGoodsNm()).append("</name>\n");
					sb.append("\t\t<status>").append(goodsStat).append("</status>\n");
					sb.append("\t\t<basePrice>").append(goods.getCurrPrice()).append("</basePrice>\n");
					sb.append("\t\t<infoUrl>").append("https:" + domain + "/goods/detail/form?goodsCd=" + goods.getGoodsCd()).append("</infoUrl>\n");
					sb.append("\t\t<imageUrl>").append("https:" + goodsImgUrl + "/" + goods.getSysImgNm()).append("</imageUrl>\n");

					// 12.반품주소
					if (rtnInfo != null && rtnInfo.getRtnLocZipcode() != null && !"".equals(rtnInfo.getRtnLocZipcode())) {
						// 2.1 반품정보
						sb.append("\t\t<returnInfo>\n");
						sb.append("\t\t\t<zipcode>").append(rtnInfo.getRtnLocZipcode()).append("</zipcode>\n");
						sb.append("\t\t\t<address1>").append(rtnInfo.getRtnLocBaseAddr()).append("</address1>\n");
						sb.append("\t\t\t<address2>").append(rtnInfo.getRtnLocDtlAddr()).append("</address2>\n");
						sb.append("\t\t\t<sellername>").append(rtnInfo.getRtnLocNm()).append("</sellername>\n");
						sb.append("\t\t\t<contact1>").append(rtnInfo.getRtnLocTelno()).append("</contact1>\n");
						sb.append("\t\t</returnInfo>\n");

						// 반품배송비, 교환배송비
						sb.append("\t\t<returnShippingFee>").append(goods.getRtnDelvFee()).append("</returnShippingFee>\n");
						sb.append("\t\t<exchangeShippingFee>").append((goods.getRtnDelvFee() * 2)).append("</exchangeShippingFee>\n");
					}

					// 옵션정보 지원여부 true
					sb.append("\t\t<optionSupport>true</optionSupport>\n");

					// 옵션 정보
					sb.append("\t\t<option>\n");

					// 상품 옵션 전체 정보 조회
					List<GoodsStock> optList = (ArrayList<GoodsStock>) goodsDao.getGoodsOptionInfoList(opt);

					String[] colorNmList = new String[optList.size()];
					String[] sizeList = new String[optList.size()];
					int count = 0;

					// 중복제거
					for(GoodsStock optInfo : optList) {
						colorNmList[count] = optInfo.getOptCd1() + "/" + optInfo.getColorNm();
						sizeList[count++] = optInfo.getOptCd2();
					}
					colorNmList = new HashSet<String>(Arrays.asList(colorNmList)).toArray(new String[0]);
					sizeList = new HashSet<String>(Arrays.asList(sizeList)).toArray(new String[0]);

					if("Y".equals(goods.getSelfGoodsYn())) {
						// 자사 일반 상품 정보
						// 옵션 아이템정보 색상
						sb.append("\t\t\t<optionItem>\n");
						sb.append("\t\t\t\t<type>SELECT</type>\n");
						sb.append("\t\t\t\t<name>색상</name>\n");
						for (String color : colorNmList) {
							String[] optCd1Info = color.split("/");
							sb.append("\t\t\t\t<value>\n");
							sb.append("\t\t\t\t\t<id>").append(optCd1Info[0]).append("</id>\n");
							sb.append("\t\t\t\t\t<text>").append(optCd1Info[1]).append("</text>\n");
							sb.append("\t\t\t\t</value>\n");
						}
						sb.append("\t\t\t</optionItem>\n");

						// 옵션 아이템정보 사이즈
						sb.append("\t\t\t<optionItem>\n");
						sb.append("\t\t\t\t<type>SELECT</type>\n");
						sb.append("\t\t\t\t<name>사이즈</name>\n");
						for (String size : sizeList) {
							sb.append("\t\t\t\t<value>\n");
							sb.append("\t\t\t\t\t<id>").append(size).append("</id>\n");
							sb.append("\t\t\t\t\t<text>").append(size).append("</text>\n");
							sb.append("\t\t\t\t</value>\n");
						}
						sb.append("\t\t\t</optionItem>\n");

						// 옵션 옵션조합정보
						for(GoodsStock optInfo : optList) {
							if (optionManageCode.equals(optInfo.getOptCd())) {
								sb.append("\t\t\t<combination>\n");
								sb.append("\t\t\t\t<manageCode>").append(optInfo.getOptCd()).append("</manageCode>\n");
								sb.append("\t\t\t\t<price>").append(optInfo.getAddPrice()).append("</price>\n");
								sb.append("\t\t\t\t<stockQuantity>").append(optInfo.getStockQty()).append("</stockQuantity>\n");
								sb.append("\t\t\t\t<status>true</status>\n");

								// 옵션 옵션조합정보 색상
								sb.append("\t\t\t\t<options>\n");
								sb.append("\t\t\t\t\t<name>색상</name>\n");
								sb.append("\t\t\t\t\t<id>").append(optInfo.getOptCd1()).append("</id>\n");
								sb.append("\t\t\t\t</options>\n");

								// 옵션 옵션조합정보 사이즈
								sb.append("\t\t\t\t<options>\n");
								sb.append("\t\t\t\t\t<name>사이즈</name>\n");
								sb.append("\t\t\t\t\t<id>").append(optInfo.getOptCd2()).append("</id>\n");
								sb.append("\t\t\t\t</options>\n");

								sb.append("\t\t\t</combination>\n");
							}
						}
					} else {// 입점업체 상품 정보
						// 옵션 아이템정보 색상
						sb.append("\t\t\t<optionItem>\n");
						sb.append("\t\t\t\t<type>SELECT</type>\n");
						sb.append("\t\t\t\t<name>옵션</name>\n");
						for(GoodsStock optInfo : optList) {
							sb.append("\t\t\t\t<value>\n");
							sb.append("\t\t\t\t\t<id>").append(optInfo.getOptCd()).append("</id>\n");
							sb.append("\t\t\t\t\t<text>").append(optInfo.getOptCd1()).append("/").append(optInfo.getOptCd2()).append("</text>\n");
							sb.append("\t\t\t\t</value>\n");
						}
						sb.append("\t\t\t</optionItem>\n");

						// 옵션 옵션조합정보
						for(GoodsStock optInfo : optList) {
							if (optionManageCode.equals(optInfo.getOptCd())) {
								sb.append("\t\t\t<combination>\n");
								sb.append("\t\t\t\t<manageCode>").append(optInfo.getOptCd()).append("</manageCode>\n");
								sb.append("\t\t\t\t<price>").append(optInfo.getAddPrice()).append("</price>\n");
								sb.append("\t\t\t\t<stockQuantity>").append(optInfo.getStockQty()).append("</stockQuantity>\n");
								sb.append("\t\t\t\t<status>true</status>\n");
								sb.append("\t\t\t\t<options>\n");
								sb.append("\t\t\t\t\t<name>옵션</name>\n");
								sb.append("\t\t\t\t\t<id>").append(optInfo.getOptCd()).append("</id>\n");
								sb.append("\t\t\t\t</options>\n");
								sb.append("\t\t\t</combination>\n");
							}
						}
					}

					sb.append("\t\t</option>\n");

					// 10. 배송정보조회
					// 5.2.1 업체별 기본배송비, 무료배송비
					String delvFeeCd = "";
					if("Y".equals(goods.getSelfGoodsYn())) {
						delvFeeCd = "WMS";
					} else {
						delvFeeCd = goods.getDelvFeeCd();
					}
					String delvFeeCrite = "CHARGE";
					int delvFee = goods.getDelvFee();
					String feePayType = "PREPAYED";
					// 배송비 조건
					if(TscConstants.DelvFeeCrite.NORMAL.value().equals(goods.getDelvFeeCrite())) {
						delvFeeCrite = "CONDITIONAL_FREE";		// 조건부 무료(배송비 조건이 무료이거나 배송 방법이 착불일때만 배송비는 0원으로 변경)
					} else if(TscConstants.DelvFeeCrite.FREE.value().equals(goods.getDelvFeeCrite())) {
						delvFeeCrite = "FREE";
						feePayType = "FREE";
						delvFee = 0;
					}

					sb.append("\t\t<shippingPolicy>\n");
					sb.append("\t\t\t<groupId>").append(delvFeeCd).append("</groupId>\n");
					sb.append("\t\t\t<method>").append("DELIVERY").append("</method>\n");
					sb.append("\t\t\t<feeType>").append(delvFeeCrite).append("</feeType>\n");
					sb.append("\t\t\t<feePayType>").append(feePayType).append("</feePayType>\n");
					sb.append("\t\t\t<feePrice>").append(delvFee).append("</feePrice>\n");
					if(!"FREE".equals(delvFeeCrite)) {
						sb.append("\t\t\t<conditionalFree>\n");
						sb.append("\t\t\t\t<basePrice>").append(goods.getMinOrdAmt()).append("</basePrice>\n");
						sb.append("\t\t\t</conditionalFree>\n");
					}

					sb.append("\t\t</shippingPolicy>\n");

					sb.append("\t</product>\n");
				}
			}
			sb.append("</products>\n");
			//for end

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			log.info("CHECK CREATE NAVERPAY GOODS XML ::::: \n{}", sb.toString());
			// log.info("CHECK NAVERPAY XML LENGTH ::::: {}", sb.length());
			write(response, sb);
		}
	}

	/**
	 * Write XML Data and flush
	 * @param response - HttpServletResponse
	 * @param result - 결과
	 * @author xodud1202
	 * @since 2021. 05. 13
	 */
	public void write(HttpServletResponse response, StringBuilder result) throws Exception {
		Writer writer = null;

		try {
			response.setContentType("text/xml; charset=utf-8");
			response.setHeader("Cache-Control", "no-cache");

			writer = response.getWriter();
			writer.write(result.toString());
			writer.flush();
		} catch(Exception e) {
			e.printStackTrace();
			throw new IllegalStateException("상품 정보 등록 실패");
		} finally {
			if (writer != null) writer.close();
		}
	}
	
	/**
	 * 장바구니정보 주문번호 이력 등록
	 * @param param
	 * @author xodud1202
	 * @since 2021. 05. 10
	 */
	@Transactional("shopTxnManager")
	public String insertCartHstOrdNo(Order order) {

		// cartsq
		for (int i=0 ; i<order.getCartSqArr().length ; i++) {
			Cart cart = new Cart();
			cart.setOrdNo(order.getOrdNo());
			cart.setCartSq(order.getCartSqArr()[i]);
			cart.setRegNo(order.getCustNo());
			
			// 장바구니 이력등록
			cartDao.insertCartHst(cart);
			cartDao.insertCartDetailHst(cart);
		}

		return "SUCCESS";
	}
	
	/**
	 * 장바구니정보 주문번호 삭제
	 * @param param
	 * @author xodud1202
	 * @since 2021. 05. 10
	 */
	@Transactional("shopTxnManager")
	public String deleteCartOrdNo(Order order) {
		
		// 주문번호 존재할때만 실행
		if (order.getOrdNo() > 0) {
			// 장바구니 이력등록
			Cart cart = new Cart();
			cart.setOrdNo(order.getOrdNo());
			
			// 2021.05.10 주문완료 주문번호로 장바구니정보 삭제
			cartDao.deleteCartOrdNo(cart);
			
			// 2021.05.10 주문완료 주문번호로 장바구니상세정보 삭제
			cartDao.deleteCartDetailOrdNo(cart);
		}

		return "SUCCESS";
	}
	
	/**
	 * 보증보험정보 update
	 * @param param
	 * @author xodud1202
	 * @since 2021. 05. 10
	 */
	@Transactional("shopTxnManager")
	public String updateInsurance(Order order) {
		// 주문번호 존재할때만 실행
		if (order.getOrdNo() > 0) {
			// 보증보험 API 연동위한 정보조회
			Collection<Order> goodsInfoList = orderDao.getGoodsInfoForInsurance(order);
			
			if (goodsInfoList.size() > 0) {
				String[] goodsNameArr 		= new String[goodsInfoList.size()];
				String[] goodsPriceArr 		= new String[goodsInfoList.size()];
				String[] goodsQuantityArr 	= new String[goodsInfoList.size()];
				
				int realOrdAmt 				= 0;
				int index 					= 0;
				
				for (Order goodsInfo : goodsInfoList) {
					goodsNameArr[index] 		= goodsInfo.getGoodsNm();
					goodsPriceArr[index] 		= String.valueOf(goodsInfo.getRealOrdAmt());
					goodsQuantityArr[index] 	= String.valueOf(goodsInfo.getOrdQty());
					
					realOrdAmt = realOrdAmt + goodsInfo.getRealOrdAmt();
					
					if (index == 0) {
						order.setBirthYmd(goodsInfo.getBirthGen());										// 생년월일 + 성별(남자 : 1, 여자 : 2)
						order.setPayMeans(goodsInfo.getPayMeans());										// 무통장입금 or 계좌이체
						order.setBankNm(goodsInfo.getBankNm());											// 은행명  >> PG 송부 후 result에서 값 입력하면됨
						order.setOrdNm(goodsInfo.getOrdNm());											// 주문자명
						order.setVaNo(goodsInfo.getVaNo());												// 가상계좌번호
						order.setOrdPhnno(goodsInfo.getOrdPhnno());										// 주문자전화2 ("-" 포함)
						order.setOrdEmail(goodsInfo.getOrdEmail());										// 주문자이메일
						order.setRecipNm(goodsInfo.getRecipNm());										// 수령인명
						order.setRecipPhnno(goodsInfo.getRecipPhnno());									// 수령인휴대폰번호
						order.setRecipZipcode(goodsInfo.getRecipZipcode());								// 주문자우편번호
						order.setRecipAddr(goodsInfo.getRecipBaseAddr() + goodsInfo.getRecipDtlAddr());	// 주문자주소
						order.setCustNo(order.getCustNo());												// 고객번호
					}
						
					index++;
				}
				
				order.setItemNmArr(goodsNameArr);		// 상품명 배열
				order.setGoodsPriceArr(goodsPriceArr);	// 상품별 가격 배열
				order.setItemQtyArr(goodsQuantityArr);	// 상품별 수량 배열
				order.setOrdNo(order.getOrdNo());		// 주문번호
				order.setRealOrdAmt(realOrdAmt);		// 결제금액
				
				if (TscConstants.PayMeans.ACCOUNT_TRANSFER.value().equals(order.getPayMeans()) || TscConstants.PayMeans.BANK_DEPOSIT.value().equals(order.getPayMeans())) {
					uSafeGuaranteeInsurance(order);
				}
			}
		}

		return "SUCCESS";
	}

	/**
	 * 비회원 주문 여부 정보 조회
	 *
	 * @param Order
	 * @return int
	 * @author card007
	 * @since 2021. 05. 26
	 */
	public int getNoMemberOrderInfo(Order order) {
		return orderDao.getNoMemberOrderInfo(order);
	}
	
	/**
	 * 주문서 계산금액 재계산 로직
	 * @param Order
	 * @return
	 * @author jsh77b
	 * @since 2021. 07. 23
	 */
	@SuppressWarnings("unchecked")
	public String orderAmtValidationCheck(Order order) {
		String resultStr = "SUCCESS";
		
		Order po = new Order();
		
		// 1. 장바구니정보 및 상품쿠폰정보, 장바구니쿠폰정보, 선포인트정보, 포인트정보, 상품권정보
		Collection<Order> orderDetailList = order.getOrderDetailList();
		int [] cartSqArr = new int[orderDetailList.size()];
		int idx = 0;
		for (Order vo : orderDetailList) {
			cartSqArr[idx] = vo.getCartSq();
			idx++;
		}
		
		po.setCartSqArr(cartSqArr);
		po.setCustNo(order.getCustNo());
		
		// 2. 판매가정보, 즉시할인금액, 옵션금액, 다다익선적용금액 정보 조회
		Collection<Order> tmtbGoodsApplyList = cartService.getMoreBetterAmtList(po);
		
		// 5 상품쿠폰, 장바구니쿠폰 목록 조회
		GagaMap goodsCartCpnMap = coreOrderService.getGoodsCartCpnApplyGoodsList(order);
		
		Collection<Order> goodsCpnList 		= (Collection<Order>) goodsCartCpnMap.get("goodsCpnList");
		Collection<Order> cartCpnList 		= (Collection<Order>) goodsCartCpnMap.get("cartCpnList");
		Collection<Order> cartCpnIdList 	= (Collection<Order>) goodsCartCpnMap.get("cartCpnIdList");

		// 6 상품쿠폰 적용된 상품 목록(상품기준)
		Collection<Order> goodsApplyCpnList = coreOrderService.getGoodsCpnApplyList(tmtbGoodsApplyList, goodsCpnList);
		
		// 7. 장바구니쿠폰(장바구니기준 상품목록)
		cartCpnList = coreOrderService.getCartCpnApplyList(tmtbGoodsApplyList, cartCpnList, cartCpnIdList);
		
		int ordAmt = 0;
		
		for (Order od : tmtbGoodsApplyList) {
			// 주문금액설정
			ordAmt = (od.getCurrPrice() + od.getOptAddPrice()) * od.getGoodsQty();
			od.setOrdAmt(ordAmt);
			
			// 상품쿠폰시퀀스, 장바구니쿠폰시퀀스 적용
			for (Order vo : orderDetailList) {
				if (od.getCartSq().equals(vo.getCartSq())) {
					od.setGoodsCpnSq(vo.getGoodsCpnSq());
					od.setCartCpnSq(vo.getCartCpnSq());
					od.setPrePntDcAmtYn(vo.getPrePntDcAmtYn());
					od.setPntDcAmt(vo.getPntDcAmt());
					od.setGfcdUseAmt(vo.getGfcdUseAmt());
				}
			}
		}
		
		// 상품쿠폰 적용 금액
		for (Order od : tmtbGoodsApplyList) {	
			for (Order tmtbGoods : goodsApplyCpnList) {
				if (od.getCartSq().equals(tmtbGoods.getCartSq())) {
					for (Order goodsCpn : tmtbGoods.getGoodsCpnList()) {
						if (od.getGoodsCpnSq() == goodsCpn.getCustCpnSq()) {
							od.setGoodsCpnDcAmt(goodsCpn.getCpnDcAmt());
						}
					}
				}
			}
		}
		
		String dcWay 			= "";
		int dcVal 				= 0;
		int maxDcAmt 			= 0;
		int cartCpnDcSumAmt		= 0;
		int leftAmt				= 0;
		int index				= 1;
		
		// 장바구니쿠폰 적용 금액
		for (Order od : tmtbGoodsApplyList) {
			for (Order cartCpn : cartCpnList) {
				if (od.getCartCpnSq() == cartCpn.getCustCpnSq()) {
					for (int i=0 ; i<cartCpn.getCartCpnCartSqArr().length ; i++) {
						if (od.getCartSq().equals(cartCpn.getCartCpnCartSqArr()[i])) {
							dcWay 		= cartCpn.getDcWay();
							dcVal 		= cartCpn.getDcVal();
							maxDcAmt 	= cartCpn.getMaxDcAmt();
						}
					}
				}
			}
		}
		
		// 상품쿠폰, 장바구니쿠폰 적용 금액
		int ordDcSumAmt 	= 0;
		int ordDcAmt 		= 0;
		
		for (Order od : tmtbGoodsApplyList) {
			// 주문할인금액설정
			ordDcAmt = od.getOrdAmt() - od.getTmtb1DcAmt() - od.getTmtb2DcAmt() - od.getGoodsCpnDcAmt();
			ordDcSumAmt = ordDcSumAmt + ordDcAmt;
			
			// 율할인일때 할인금액 적용
			if ("G240_11".equals(dcWay)) {
				for (Order cartCpn : cartCpnList) {
					if (od.getCartCpnSq() == cartCpn.getCustCpnSq()) {
						for (int i=0 ; i<cartCpn.getCartCpnCartSqArr().length ; i++) {
							if (od.getCartSq().equals(cartCpn.getCartCpnCartSqArr()[i])) {								
								int cartCpnDcAmt = (ordDcAmt * cartCpn.getDcVal()) / 100;
								cartCpnDcSumAmt = cartCpnDcSumAmt + cartCpnDcAmt;
								od.setCartCpnDcAmt(cartCpnDcAmt);
							}
						}
					}
				}
			}
		}
		
		// 2021.04.19 최대금액 체크
		if (maxDcAmt > cartCpnDcSumAmt || maxDcAmt == 0) {
			log.info("장바구니쿠폰 할인 ::: {} ", dcVal);
		} else {
			// 최대값 적용 일때는 금액할인 방식을 적용
			cartCpnDcSumAmt 	= maxDcAmt;
			dcVal				= cartCpnDcSumAmt;
			dcWay 				= "G240_10";
		}
		
		// 금액일때 할인금액 적용
		if ("G240_10".equals(dcWay)) {
			cartCpnDcSumAmt = dcVal;
			leftAmt			= dcVal;
			index 			= 1;
			
			for (Order cartCpn : cartCpnList) {
				for (Order od : tmtbGoodsApplyList) {
					// 장바구니 쿠폰 시퀀스 체크
					if (od.getCartCpnSq() == cartCpn.getCustCpnSq()) {				
						for (int i=0 ; i<cartCpn.getCartCpnCartSqArr().length ; i++) {
							// 장바구니 시퀀스 체크
							if (od.getCartSq().equals(cartCpn.getCartCpnCartSqArr()[i])) {	
								
								// 주문금액 - 할인금액(상품쿠폰할인금액)
								ordDcAmt = od.getOrdAmt() - od.getTmtb1DcAmt() - od.getTmtb2DcAmt() - od.getGoodsCpnDcAmt();
								double tempDiv1 	= (double) ordDcAmt / ordDcSumAmt;
								double tempDiv2 	= (double) tempDiv1 * 100.0;
								double tempDiv 		= (double) Math.round((tempDiv2) * 100.0) / 100.0;
								
								int cartCpnDcAmt	= 0;
						
								if (index == cartCpn.getCartCpnCartSqArr().length) {
									cartCpnDcAmt 	= leftAmt;
								} else {
									double tempCartCpnDcAmt	= (cartCpnDcSumAmt * tempDiv) / 100;
									cartCpnDcAmt 	= (int) tempCartCpnDcAmt;
									leftAmt 		= leftAmt - cartCpnDcAmt;
								}
								
								od.setCartCpnDcAmt(cartCpnDcAmt);
								
								index++;
							}
						}
					}
				}
			}
		}
		
		int cartDcSumAmt = 0;
		
		for (Order od : tmtbGoodsApplyList) {
			log.info("----------------------------------------------------------------------------");
			log.info("cartSq ::: {}"			, od.getCartSq());
			log.info("orgCurrPrice ::: {}"		, od.getOrgCurrPrice());
			log.info("cpn1DcAmt ::: {}"			, od.getOrgCurrPrice() - od.getCurrPrice());
			log.info("optAddPrice ::: {}"		, od.getOptAddPrice());
			log.info("goodsQty ::: {}"			, od.getGoodsQty());
			log.info("ordAmt ::: {}"			, od.getOrdAmt());
			log.info("tmtb1DcAmt ::: {}"		, od.getTmtb1DcAmt());
			log.info("tmtb2DcAmt ::: {}"		, od.getTmtb2DcAmt());
			log.info("prePntDcAmt ::: {}"		, od.getPrePntDcAmt());
			log.info("goodsCpnDcAmt ::: {}"		, od.getGoodsCpnDcAmt());
			log.info("cartCpnDcAmt ::: {}"		, od.getCartCpnDcAmt());
			log.info("pntDcAmt ::: {}"			, od.getPntDcAmt());
			log.info("gfcdUseAmt ::: {}"		, od.getGfcdUseAmt());		
			
			for (Order vo : orderDetailList) {
				if (od.getCartSq().equals(vo.getCartSq())) {
					if (od.getOrdAmt() != vo.getOrdAmt()) {
						resultStr = "주문금액정보가 잘못 되었습니다.";
						return resultStr;
					}
					
					if (od.getTmtb1DcAmt() != vo.getTmtb1DcAmt()) {
						resultStr = "다다익선수량 할인 금액정보가 잘못 되었습니다.";
						return resultStr;
					}
					
					if (od.getTmtb2DcAmt() != vo.getTmtb2DcAmt()) {
						resultStr = "다다익선금액 할인 금액정보가 잘못 되었습니다.";
						return resultStr;
					}
					
					if (od.getGoodsCpnDcAmt() != vo.getGoodsCpnDcAmt()) {
						resultStr = "상품쿠폰 할인 금액정보가 잘못 되었습니다.";
						return resultStr;
					}
					
					/*
					if (od.getCartCpnDcAmt() != vo.getCartCpnDcAmt()) {
						resultStr = "장바구니쿠폰 할인 금액정보가 잘못 되었습니다.";
						return resultStr;
					}
					*/
					
					if ("Y".equals(od.getPrePntDcAmtYn())) {
						if (od.getPrePntDcAmt() != vo.getPrePntDcAmt()) {
							resultStr = "선포인트 할인 금액정보가 잘못 되었습니다.";
							return resultStr;
						}
					}
				}
			}
			
			cartDcSumAmt = cartDcSumAmt + od.getCartCpnDcAmt();
			log.info("----------------------------------------------------------------------------");	
		}
		
		// 2021.10.13 장바구니금액 
		if (order.getCartCpnDcSumAmt() != cartDcSumAmt) {
			resultStr = "장바구니쿠폰 할인 금액정보가 잘못 되었습니다.";
			return resultStr;
		}

		return resultStr;
	}

	/**
	 * 네이버페이 찜하기 정보 전송
	 * @param
	 * @return GagaMap
	 * @author card007
	 * @since 2021. 08. 17
	 */
	public GagaMap sendZzimToNC(Goods goods, HttpServletRequest request, HttpServletResponse response) throws IOException {
		GagaMap result = new GagaMap();
		// 1.0, 2.0  일때 구분값 처리
		URL _url = new URL(env.getProperty("naverPay.zzim.api.url"));
		String ENCODING = "UTF-8";

		HttpsURLConnection conn = (HttpsURLConnection)_url.openConnection();

		conn.setDoInput(true);
		conn.setDoOutput(true);
		conn.setUseCaches(false);
		conn.setRequestMethod("POST");
		conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

		// Protocol 처리
		String hasSsl = env.getProperty("has-ssl");
		String protocol;

		if ("true".equals(hasSsl)) {
			protocol = "https:";
		} else {
			protocol = "http:";
		}

		// 네이버페이 기본정보
		String shopId			= env.getProperty("naverPay.shop.id");											// shopId
		String certificationKey	= env.getProperty("naverPay.certification.key");								// 네이버페이 인증키
		String goodsUrl 		= protocol + env.getProperty("domain.front");									// 상품 경로
		goodsUrl			   += "/goods/detail/form?goodsCd=" + goods.getGoodsCd();
		if ("Y".equals(goods.getSelfGoodsYn())) {
			goodsUrl		   += "&colorCd=" + goods.getColorCd();
		} else {
			goodsUrl		   += "&colorCd=XX";
		}
		String goodsImgUrl		= protocol + env.getProperty("upload.goods.view") + "/" + goods.getSysImgNm();	// 상품 이미지 경로

		// 상품정보 설정
		StringBuilder sb = new StringBuilder();
		_urlEncode(sb, "SHOP_ID", shopId);
		sb.append('&');
		_urlEncode(sb, "CERTI_KEY", certificationKey);
		sb.append('&');
		_urlEncode(sb, "ITEM_ID", goods.getGoodsCd());
		sb.append('&');
		_urlEncode(sb, "ITEM_NAME", goods.getGoodsNm());
		sb.append('&');
		_urlEncode(sb, "ITEM_UPRICE", String.valueOf(goods.getCurrPrice()));
		sb.append('&');
		_urlEncode(sb, "ITEM_IMAGE", goodsImgUrl);
		sb.append('&');
		_urlEncode(sb, "ITEM_URL", goodsUrl);
		sb.append('&');
		_urlEncode(sb, "RESERVE1", "");
		sb.append('&');
		_urlEncode(sb, "RESERVE2", "");
		sb.append('&');
		_urlEncode(sb, "RESERVE3", "");
		sb.append('&');
		_urlEncode(sb, "RESERVE4", "");
		sb.append('&');
		_urlEncode(sb, "RESERVE5", "");

		// 주문 등록 API 호출
		Writer writer = new OutputStreamWriter(conn.getOutputStream(), ENCODING);
		writer.write(sb.toString());

		writer.flush();
		writer.close();

		int respCode = conn.getResponseCode();
		log.info("CHECK RESP CODE ::::: {}", respCode);

		if (respCode != 200) {
			throw new RuntimeException(String.format("NC Response fail : %d %s", respCode, conn.getResponseMessage()));
		}

		BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

		String itemId = reader.readLine();

		if (StringUtils.isNotBlank(itemId)) {
			String popupUrl = env.getProperty("naverPay.zzim.popup.url");
			String mobileUrl = env.getProperty("naverPay.zzim.mobile.url");
			result.put("state", "success");
			result.put("action", popupUrl);
			result.put("actionMobile", mobileUrl);
			result.put("shopId", shopId);
			result.put("itemId", itemId);
		} else {
			throw new IllegalStateException(String.format("NC Response fail : %d %s", reader.readLine().toString()));
		}

		conn.disconnect();

		return result;
	}

	private void _urlEncode(StringBuilder sb, String key, String value) {
		String ENCODING = "UTF-8";
		try {
			sb.append(URLEncoder.encode(key, ENCODING));
			sb.append('=');
			sb.append(URLEncoder.encode(value, ENCODING));
		}
		catch(UnsupportedEncodingException e) {
			//일어나지 않음
			throw new Error(e);
		}
	}
	
	// 2021.10.25 결제실패 등록
	@Transactional("shopTxnManager")
	public void createPaymentFail(String msg, int custNo) {
		Order po = new Order();
		String [] msgArr0 = msg.split("@");
		
		po.setRegNo(custNo);
		
		if (msgArr0.length > 1) {
			for (int i=0 ; i<msgArr0.length ; i++) {
				String [] msgArr1 = msgArr0[i].split("=");
				
				if (msgArr1.length > 1) {
					if ("ordNo".equals(msgArr1[0])) {
						po.setOrdNo(Integer.valueOf(msgArr1[1]));
					}
					else if ("pgGb".equals(msgArr1[0])) {
						po.setPgGb(msgArr1[1]);
					}
					else if ("errMsg".equals(msgArr1[0])) {
						po.setErrMsg(msgArr1[1]);
					}
					else if ("stepNo".equals(msgArr1[0])) {
						po.setStepNo(Integer.valueOf(msgArr1[1]));
					}
				}
			}
		} else {
			po.setErrMsg(msg);
		}
		
		// 결제실패정보등록
		coreOrderDao.createPaymentFail(po);
	}
}
