package com.style24.core.biz.service;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.security.SignatureException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import com.gagaframework.web.parameter.GagaMap;
import com.google.gson.Gson;
import com.nhncorp.psinfra.toolkit.SimpleCryptLib;
import com.style24.core.biz.checkout.MallServiceLocator;
import com.style24.core.biz.checkout.MallServiceSOAP11BindingStub;
import com.style24.core.biz.checkout.base.AccessCredentialsType;
import com.style24.core.biz.checkout.base.ChangedProductOrderInfo;
import com.style24.core.biz.checkout.base.ClaimRequestReasonType;
import com.style24.core.biz.checkout.base.DeliveryMethodType;
import com.style24.core.biz.checkout.base.HoldbackClassType;
import com.style24.core.biz.checkout.base.HoldbackStatusType;
import com.style24.core.biz.checkout.base.ProductOrderChangeType;
import com.style24.core.biz.checkout.base.ProductOrderInfo;
import com.style24.core.biz.checkout.base.ReturnInfo;
import com.style24.core.biz.checkout.mall.ApproveCancelApplicationRequest;
import com.style24.core.biz.checkout.mall.ApproveCancelApplicationResponse;
import com.style24.core.biz.checkout.mall.ApproveCollectedExchangeRequest;
import com.style24.core.biz.checkout.mall.ApproveCollectedExchangeResponse;
import com.style24.core.biz.checkout.mall.ApproveReturnApplicationRequest;
import com.style24.core.biz.checkout.mall.ApproveReturnApplicationResponse;
import com.style24.core.biz.checkout.mall.CancelSaleRequest;
import com.style24.core.biz.checkout.mall.CancelSaleResponse;
import com.style24.core.biz.checkout.mall.GetChangedProductOrderListRequest;
import com.style24.core.biz.checkout.mall.GetChangedProductOrderListResponse;
import com.style24.core.biz.checkout.mall.GetProductOrderInfoListRequest;
import com.style24.core.biz.checkout.mall.GetProductOrderInfoListResponse;
import com.style24.core.biz.checkout.mall.PlaceProductOrderRequest;
import com.style24.core.biz.checkout.mall.PlaceProductOrderResponse;
import com.style24.core.biz.checkout.mall.ReDeliveryExchangeRequest;
import com.style24.core.biz.checkout.mall.ReDeliveryExchangeResponse;
import com.style24.core.biz.checkout.mall.RejectExchangeRequest;
import com.style24.core.biz.checkout.mall.RejectExchangeResponse;
import com.style24.core.biz.checkout.mall.RejectReturnRequest;
import com.style24.core.biz.checkout.mall.RejectReturnResponse;
import com.style24.core.biz.checkout.mall.ReleaseExchangeHoldRequest;
import com.style24.core.biz.checkout.mall.ReleaseExchangeHoldResponse;
import com.style24.core.biz.checkout.mall.ReleaseReturnHoldRequest;
import com.style24.core.biz.checkout.mall.ReleaseReturnHoldResponse;
import com.style24.core.biz.checkout.mall.RequestReturnRequest;
import com.style24.core.biz.checkout.mall.RequestReturnResponse;
import com.style24.core.biz.checkout.mall.ShipProductOrderRequest;
import com.style24.core.biz.checkout.mall.ShipProductOrderResponse;
import com.style24.core.biz.checkout.mall.WithholdExchangeRequest;
import com.style24.core.biz.checkout.mall.WithholdExchangeResponse;
import com.style24.core.biz.checkout.mall.WithholdReturnRequest;
import com.style24.core.biz.checkout.mall.WithholdReturnResponse;
import com.style24.core.biz.dao.TscNaverPayDao;
import com.style24.core.biz.dao.TscOrderChangeDao;
import com.style24.core.biz.dao.TscOrderDao;
import com.style24.core.biz.dao.TscScmDao;
import com.style24.core.biz.thirdparty.NaverPayApi;
import com.style24.core.support.env.TscConstants;
import com.style24.core.support.message.TscMessageByLocale;
import com.style24.persistence.domain.NaverPay;
import com.style24.persistence.domain.Order;
import com.style24.persistence.domain.OrderChange;
import com.style24.persistence.domain.Payment;

import lombok.extern.slf4j.Slf4j;

/**
 * 네이버페이 Service
 * 
 * @author card007
 * @since 2020. 03. 03
 */
@Service
@Slf4j
public class TscNaverPayService {

	@Autowired
	private Environment env;

	@Autowired
	private TscMessageByLocale message;

	@Autowired
	private NaverPayApi naverPayApi;

	@Autowired
	private TscNaverPayDao naverPayDao;

	@Autowired
	private TscOrderService orderService;

	@Autowired
	private TscOrderChangeService orderChangeService;

	@Autowired
	private TscOrderRefundService orderRefundService;

	@Autowired
	private TscOrderDao orderDao;

	@Autowired
	private TscScmDao scmDao;

	@Autowired
	private TscOrderChangeDao orderChangeDao;

	private String timeStamp;
	private String signature;

	/**
	 * 네이버페이 결제준비 처리
	 * 
	 * @param Order
	 * @return NaverPay
	 * @author card007
	 * @since 2021. 03. 07
	 */
	@Transactional("shopTxnManager")
	public NaverPay naverPaymentReady(Order order) {
		// API 전송 URL 설정
		String paymentReadyUrl = env.getProperty("naverPay.apiUrl") + env.getProperty("naverPay.partnerId") + env.getProperty("naverPay.paymentReadyUrl");

		// Redirect URL 설정
		String hasSsl = env.getProperty("has-ssl");
		String protocol;

		if ("true".equals(hasSsl)) {
			protocol = "https:";
		} else {
			protocol = "http:";
		}
		String redirectUrl = protocol + env.getProperty("domain.front") + env.getProperty("naverPay.paymentRedirectUrl");

		// API 파라메터 설정
		// NaverPay naverPay = new NaverPay();
		// naverPay.setModelVersion("2");
		// naverPay.setMerchantUserKey(order.getCustNo());
		// naverPay.setMerchantPayKey(String.valueOf(order.getOrdNo()));
		// naverPay.setProductName(order.getGoodsNm());
		// naverPay.setProductCount(order.getOrdGoodsQty());
		// naverPay.setTotalPayAmount(order.getPayAmt());
		// naverPay.setTaxScopeAmount(order.getPayAmt());
		// naverPay.setTaxExScopeAmount(0);
		// naverPay.setReturnUrl(redirectUrl);
		
		
		GagaMap naverPay = new GagaMap();
		naverPay.set("modelVersion", "2");
		if (order.getCustNo() > 0) {
			naverPay.set("merchantUserKey", String.valueOf(order.getCustNo()));
		}
		naverPay.set("merchantPayKey", String.valueOf(order.getOrdNo()));
		naverPay.set("productName", order.getGoodsNm());
		naverPay.set("productCount", order.getOrdGoodsQty());
		naverPay.set("totalPayAmount", order.getPayAmt());
		naverPay.set("taxScopeAmount", order.getPayAmt());
		naverPay.set("taxExScopeAmount", 0);
		naverPay.set("returnUrl", redirectUrl);

		// 네이버페이 API 전송
		return naverPayApi.naverPaymentJsonApi(naverPay, paymentReadyUrl);
	}

	/**
	 * 네이버페이 결제승인 처리
	 *
	 * @param Payment
	 * @return Payment
	 * @author card007
	 * @since 2021. 03. 08
	 */
	@Transactional("shopTxnManager")
	public Payment approveNaverPayment(Payment payment) {
		// API 전송 URL 설정
		String approvePaymentUrl = env.getProperty("naverPay.apiUrl") + env.getProperty("naverPay.partnerId") + env.getProperty("naverPay.approvePaymentUrl");

		// API 파라메터 설정
		MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
		params.add("paymentId", payment.getPgTid());

		// 네이버페이 API 전송
		NaverPay naverPay = naverPayApi.naverPaymentApi(params, approvePaymentUrl);

		// 네이버페이 API 전송 결과 처리
		int statusCode = naverPay.getStatusCode();
		payment.setCode(naverPay.getCode());

		// 승인 성공일때 200
		if (statusCode == 200 && "Success".equals(naverPay.getCode())) {
			Integer custNo = 0;

			if (StringUtils.isNotBlank(naverPay.getBody().getDetail().getMerchantUserKey())) {
				custNo = Integer.parseInt(naverPay.getBody().getDetail().getMerchantUserKey());
			}

			payment.setPgTradeNo(naverPay.getBody().getDetail().getPayHistId());
			payment.setPgTid(naverPay.getBody().getDetail().getPaymentId());
			payment.setPgShopId(env.getProperty("naverPay.clientId"));
			payment.setPgShopKey(env.getProperty("naverPay.clientSecret"));
			payment.setPayDt(naverPay.getBody().getDetail().getAdmissionYmdt());
			payment.setPayStat(TscConstants.PaymentStat.PAYMENT_COMPLETE.value());
			payment.setOrdNo(Integer.parseInt(naverPay.getBody().getDetail().getMerchantPayKey()));
			payment.setCustNo(custNo);
			payment.setNaverMethodType(naverPay.getBody().getDetail().getPrimaryPayMeans());
			payment.setPayAmt(naverPay.getBody().getDetail().getTotalPayAmount());
			payment.setNpayPntAmt(naverPay.getBody().getDetail().getNpointPayAmount());

			// 네이버페이 카드결제 시 카드정보 설정
			if ("CARD".equals(naverPay.getBody().getDetail().getPrimaryPayMeans())) {
				payment.setCardCd(naverPay.getBody().getDetail().getCardCorpCode());
				payment.setCardNm(getCardNm(naverPay.getBody().getDetail().getCardCorpCode()));
				payment.setCardType("N");	// 신용카드 결제
				payment.setCardMips(String.valueOf(naverPay.getBody().getDetail().getCardInstCount()));
				payment.setPayMeans(TscConstants.PayMeans.CREDIT_CARD.value());
			} else if ("BANK".equals(naverPay.getBody().getDetail().getPrimaryPayMeans())) {
				payment.setPayMeans(TscConstants.PayMeans.ACCOUNT_TRANSFER.value());
			}

			// 결제금액과 사용포인트금액이 같으면 카카오포인트 결제 처리
			if (naverPay.getBody().getDetail().getTotalPayAmount() == naverPay.getBody().getDetail().getNpointPayAmount()) {
				payment.setPayMeans(TscConstants.PayMeans.NAVER_POINT.value());
			}
		}

		payment.setResCd(naverPay.getCode());
		payment.setResMsg(naverPay.getMessage());
		
		return payment;
	}
	
	private String getCardNm(String cardCode) {
		String result = "";
		String[] codeArr = {"C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CF", "CH"};
		String[] codeNmArr = {"신한", "비씨", "광주", "KB국민", "NH", "롯데", "산업", "삼성", "수협", "씨티", "외환", "우리", "전북", "제주", "하나-외환", "현대"};

		List<String> list = Arrays.asList(codeArr);

		int index = list.indexOf(cardCode);

		if (index >= 0) {
			result = codeNmArr[list.indexOf(cardCode)];
		} else {
			result = cardCode;
		}

		return result; 
	}

	/**
	 * 네이버페이 주문 조회
	 *
	 * @param Payment
	 * @return NaverPay
	 * @author card007
	 * @since 2021. 03. 08
	 */
	@Transactional("shopTxnManager")
	public NaverPay getNaverPaymentOrder(Payment payment) {
		// API 전송 URL 설정
		String paymentOrderUrl = env.getProperty("naverPay.apiUrl") + env.getProperty("naverPay.partnerId") + env.getProperty("naverPay.paymentOrderUrl");

		// API 파라메터 설정
		// NaverPay naverPay = new NaverPay();
		// naverPay.setPaymentId(payment.getPgTid());

		// 기간별 주문 조회 (31일 이내)
		// naverPay.setStartTime(order.getStartTime());
		// naverPay.setEndTime(order.getEndTime());
		// naverPay.setApprovalType(order.getApprovalType());
		// naverPay.setPageNumber(order.getPageNo());
		// naverPay.setRowsPerPage(order.getPageSize());
		
		GagaMap naverPay = new GagaMap();
		naverPay.set("paymentId", payment.getPgTid());

		// 기간별 주문 조회 (31일 이내)
		// naverPay.set("startTime", payment.getStartTime());
		// naverPay.set("endTime", payment.getEndTime);
		// naverPay.set("approvalType", payment.getApprovalType());
		// naverPay.set("pageNumber", payment.getPageNo());
		// naverPay.set("rowsPerPage", payment.getPageSize());

		// 네이버페이 API 전송
		return naverPayApi.naverPaymentJsonApi(naverPay, paymentOrderUrl);
	}

	/**
	 * 네이버페이 결제 취소
	 *
	 * @param Payment
	 * @return Payment
	 * @author card007
	 * @since 2021. 03. 08
	 */
	@Transactional("shopTxnManager")
	public Payment cancelNaverPayment(Payment payment) {
		// API 전송 URL 설정
		String cancelPaymentUrl = env.getProperty("naverPay.apiUrl") + env.getProperty("naverPay.partnerId") + env.getProperty("naverPay.cancelPaymentUrl");

		// API 파라메터 설정
		MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
		params.add("paymentId", payment.getPgTid());
		params.add("cancelReason", payment.getChgReasonNm());
		params.add("cancelAmount", String.valueOf(payment.getPayAmt()));
		params.add("taxScopeAmount", String.valueOf(payment.getPayAmt()));
		params.add("taxExScopeAmount", "0");
		params.add("doCompareRest", "1");
		params.add("expectedRestAmount", String.valueOf(payment.getLeftAmt() - payment.getPayAmt()));

		// 취소 요청자 설정
		String cancelRequester = "2";
		if (StringUtils.isNotBlank(payment.getCancelRequester())) {
			cancelRequester = payment.getCancelRequester();
		}
		params.add("cancelRequester", cancelRequester);

		// 네이버페이 API 전송
		NaverPay naverPay = naverPayApi.naverPaymentApi(params, cancelPaymentUrl);

		// 네이버페이 API 전송 결과 처리
		int statusCode = naverPay.getStatusCode();

		// 승인 성공일때 200
		if (statusCode == 200 && "Success".equals(naverPay.getCode())) {
			payment.setPgGb(TscConstants.PgGb.NAVER.value());
			payment.setPayAmt(payment.getPayAmt() * -1);
			payment.setNpayPntAmt(naverPay.getBody().getNpointCancelAmount() * -1);
			payment.setPgTid(naverPay.getBody().getPaymentId());
			payment.setPgTradeNo(naverPay.getBody().getPayHistId());
			payment.setPgShopId(env.getProperty("naverPay.clientId"));
			payment.setPgShopKey(env.getProperty("naverPay.clientSecret"));
			payment.setCustNo(payment.getCustNo());
			payment.setNaverMethodType(naverPay.getBody().getPrimaryPayMeans());
			payment.setResCd(naverPay.getCode());
			payment.setResMsg(naverPay.getMessage());

			// orderDao.insertPayment(payment);
			orderDao.insertPaymentCancel(payment);
		} else {
			throw new IllegalStateException(naverPay.getMessage());
		}

		

		return payment;
	}

	/**
	 * 네이버페이 결제 데이터 생성
	 *
	 * @param Order
	 * @return Payment
	 * @author card007
	 * @since 2021. 03. 09
	 */
	public Payment setNaverOrderData(NaverPay naverPay) {
		Payment payment = new Payment();
		payment.setReserveId(naverPay.getBody().getReserveId());

		return payment;
	}

	/**
	 * 네이버페이 결제 처리 후 로직 진행 중 에러 발생으로 인한 취소처리
	 *
	 * @param Payment
	 * @author card007
	 * @since 2021. 04. 09
	 */
	public void naverPayRollBack(Payment payment) {
		payment.setPayStat(TscConstants.PaymentStat.DB_FAIL.value());
		payment.setPayGb("E");

		cancelNaverPayment(payment);
	}

	/**
	 * 네이버페이 결제형 구매확정
	 * 
	 * @param Order
	 * @author card007
	 * @since 2021. 09. 23
	 */
	@Transactional("shopTxnManager")
	public Order decideNaverPayOrder(Order order) {
		// API 전송 URL 설정
		String approvePaymentUrl = env.getProperty("naverPay.apiUrl") + env.getProperty("naverPay.partnerId") + env.getProperty("naverPay.decideOrderUrl");

		// API 파라메터 설정
		MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
		params.add("paymentId", order.getPgTid());
		params.add("requester", "2");

		// 네이버페이 API 전송
		NaverPay naverPay = naverPayApi.naverPaymentApi(params, approvePaymentUrl);

		// 네이버페이 API 전송 결과 처리
		int statusCode = naverPay.getStatusCode();
		order.setResultCd(String.valueOf(naverPay.getStatusCode()));
		order.setResultMsg(naverPay.getCode());

		return order;
	}

	/**
	 * 네이버페이 처리 기간 설정
	 * 
	 * @return Order
	 * @author xodud1202
	 * @since 2021. 05. 27
	 */
	public Order setInitData() {
		Order time				= this.getSelectDt();		// 네이버페이 시간 조건 조회 (최근3시간)
		String stdt				= time.getStdt();			// 조회기간 시작
		String eddt				= time.getEddt();			// 조회기간 끝

		// 로컬의 경우 별도 기간을 설정해서 사용
		if("locd".equals(env.getProperty("spring.profiles.active"))) {
			stdt				= "20211008000000";			// 조회기간 시작
			eddt				= "20211008235959";			// 조회기간 끝

			log.info("stdt : eddt ---> " + stdt + " : " + eddt);
		}

		// 조회기간 Date 타입 설정getReviewGoodsOptionList
		Date tmp1				= new SimpleDateFormat("yyyyMMddHHmmss").parse(stdt, new ParsePosition(0));
		Date tmp2				= new SimpleDateFormat("yyyyMMddHHmmss").parse(eddt, new ParsePosition(0));

		Calendar from			= Calendar.getInstance();
		Calendar to				= Calendar.getInstance();

		from.setTime(tmp1);
		to.setTime(tmp2);

		// 조회기간 String 타입 설정
		SimpleDateFormat fmt	= new SimpleDateFormat("yyyyMMddHHmmss");
		stdt					= fmt.format(from.getTime());
		eddt					= fmt.format(to.getTime());

		// 네이버페이 조회기간 설정
		Order naverParams = new Order();
		naverParams.setStdt(stdt);
		naverParams.setEddt(eddt);
		naverParams.setFrom(from);
		naverParams.setTo(to);

		return naverParams;
	}

	/**
	 * 네이버페이 시간 조건 조회 (최근3시간)
	 * @return Order
	 * @author xodud1202
	 * @since  2021. 05. 27
	 */
	public Order getSelectDt() {
		return naverPayDao.getSelectDt();
	}

	/**
	 * 네이버페이 주문 변경 리스트 조회
	 * @param option, from, to
	 * @return
	 * @throws Exception
	 * @author xodud1202
	 * @since  2021. 05. 28
	 */
	@Transactional("shopTxnManager")
	public ChangedProductOrderInfo[] changedProductOrderList(ProductOrderChangeType option, Calendar from, Calendar to, Integer userNo) throws Exception {
		ChangedProductOrderInfo[] result = null;

		String mallId = env.getProperty("naverPay.shop.id");
		String accessLicense = env.getProperty("naverPay.access.license");
		String secretKey = env.getProperty("naverPay.secret.key");

		Security.addProvider(new BouncyCastleProvider());

		AccessCredentialsType accessCredentialsType 	= new AccessCredentialsType();
		MallServiceLocator MSL 							= new MallServiceLocator(env.getProperty("naverPay.port.address"));
		MallServiceSOAP11BindingStub stub 				= new MallServiceSOAP11BindingStub();

		stub = (MallServiceSOAP11BindingStub) MSL.getMallServiceSOAP11Port();

		GetChangedProductOrderListRequest request 		= new GetChangedProductOrderListRequest();
		GetChangedProductOrderListResponse response 	= new GetChangedProductOrderListResponse();

		//서명생성
		generateSignature("GetChangedProductOrderList", secretKey);
		log.info("GetChangedProductOrderList(변경 상품주문 조회) :: timeStamp === " + timeStamp);

		//인증정보
		accessCredentialsType.setAccessLicense(accessLicense);
		accessCredentialsType.setSignature(signature);
		accessCredentialsType.setTimestamp(timeStamp);
		request.setAccessCredentials(accessCredentialsType);

		//GetChangedProductOrderList 파라메터 설정
		request.setDetailLevel("Full");
		request.setVersion(env.getProperty("naverPay.version"));
		request.setRequestID("");
		request.setMallID(mallId);
		request.setInquiryTimeFrom(from);
		request.setInquiryTimeTo(to);
		request.setLastChangedStatusCode(option);

		//GetChangedProductOrderList Response 수신
		response = stub.getChangedProductOrderList(request);

		String resultStr = "";
		if (response.getResponseType() != null) {
			resultStr = response.getResponseType().toUpperCase();
		}

		//결과 출력
		if ("SUCCESS".equals(resultStr)) {
			result = response.getChangedProductOrderInfoList();
			log.info("RESULT STR :::: SUCCESS");
		} else {
			Order fail = new Order();

			log.info("response.getResponseType()) : " + response.getResponseType());
			log.info("option.toString() : " + option.toString());
			log.info("Code : " + response.getError().getCode());
			log.info("Message : " + response.getError().getMessage());
			log.info("Detail : " + response.getError().getDetail());

			fail.setErrorReason("변경상품주문조회 에러");
			fail.setOrdNo(0);
			fail.setOptCd(option.toString());
			fail.setResultCd(response.getError().getCode());
			fail.setResultMsg(response.getError().getMessage());
			fail.setMallCd(mallId);
			fail.setAccessLicense(accessLicense);
			fail.setSecretKey(secretKey);
			fail.setRegNo(userNo);

			orderDao.createNaverPayErrorLog(fail);
		}

		return result;
	}

	/**
	 * 결제 정보 수정
	 * @param changedProductOrderList
	 * @return
	 * @author xodud1202
	 * @since  2021. 05. 28
	 */
	@Transactional("shopTxnManager")
	public Order createOrderInfo(ChangedProductOrderInfo[] changedProductOrderList, Integer userNo) throws Exception {
		String[] productOrderIdList = new String[changedProductOrderList.length];
		String orderStat = TscConstants.OrderDetailStat.PAYMENT_COMPLETE.value();	// 결제완료

		for (int i=0; i<changedProductOrderList.length; i++) {
			productOrderIdList[i] = changedProductOrderList[i].getProductOrderID();
		}

		ProductOrderInfo[] productOrderInfo = productOrderInfoList(productOrderIdList);
		byte[] encryptKey = SimpleCryptLib.generateKey(timeStamp, env.getProperty("naverPay.secret.key"));
		log.info("결제완료 :: timeStamp === " + timeStamp);

		List<Order> naverPayList = new ArrayList<Order>();

		String rcpDtlAddr 	= "";
		String orderNo = "";
		String naverSeq = "";

		if (productOrderInfo != null) {
			for (ProductOrderInfo orderInfo : productOrderInfo) {
				try {
					rcpDtlAddr = "";

					Order naverParams = new Order();
					orderNo = orderInfo.getProductOrder().getMerchantCustomCode1();        // 가맹점 주문번호
					// naverSeq 	= productOrderInfo[i].getProductOrder().getProductOrderID();		// 네이버주문번호순번
					if (StringUtils.isNotBlank(orderNo) && !"0".equals(orderNo)) {
						// TB_ORDER 네이버페이 주문번호 UPDATE
						naverParams.setOrdNo(Integer.parseInt(orderNo));
						naverParams.setOrdNm(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getOrder().getOrdererName()), StandardCharsets.UTF_8));
						naverParams.setOrdPhnno(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getOrder().getOrdererTel1()), StandardCharsets.UTF_8));
						naverParams.setOrdEmail(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getOrder().getOrdererID()), StandardCharsets.UTF_8) + "@naver.com");
						naverParams.setGoodsCd(orderInfo.getProductOrder().getProductID());    // 네이버페이 상품코드
						naverParams.setSiteCd(orderInfo.getProductOrder().getMallID());
						naverParams.setUpdNo(0);
						Collection<Order> dtlList = naverPayDao.getOrdBaseInfo(naverParams);

						// 결제대기상태만 진행
						if (dtlList.size() > 0) {
							naverParams.setNpayOrdNo(orderInfo.getOrder().getOrderID());            // 네이버 주문번호
							orderDao.updateNaverPayOrderNo(naverParams);

							Order orderDtlList = updateNpayOrderDtl(orderInfo, encryptKey, naverParams, userNo);

							// TB_PAYMENT 결제 완료로 변경 및 데이터 수정
							log.info("CHECK orderNo ::::: {}", orderNo);
							Payment payment = new Payment();
							payment.setOrdNo(Integer.parseInt(orderNo));
							payment.setPayStat(TscConstants.PaymentStat.PAYMENT_COMPLETE.value());
							payment.setPgTid(orderInfo.getOrder().getPaymentNumber());
							payment.setPayMeans(orderInfo.getOrder().getPaymentMeans());
							naverPayDao.updateNaverpayPaymentInfo(payment);
						}
					}
				} catch(Exception e) {
					e.printStackTrace();
				}
			}
		}

		return null;
	}

	@Transactional("shopTxnManager")
	public Order updateNpayOrderDtl(ProductOrderInfo productOrderInfo, byte[] encryptKey, Order npayParam, Integer userNo) throws Exception {
		Order order = new Order();
		order.setGoodsCd(productOrderInfo.getProductOrder().getProductID());			// 네이버페이 상품코드
		String npayOrdDtlNo = productOrderInfo.getProductOrder().getProductOrderID();	// 네이버페이 상품주문번호
		order.setOptCd(productOrderInfo.getProductOrder().getOptionManageCode());		// 고유 상품 옵션 번호 (optCd)

		log.info("CHECK GOODS_CD :::: {}", order.getGoodsCd());
		log.info("CHECK NPAY_ORD_DTL_NO :::: {}", npayOrdDtlNo);
		log.info("CHECK OPT_CD :::: {}", order.getOptCd());

		// 옵션정보 존재하지 않으면 return null;
		if(StringUtils.isBlank(order.getOptCd())) return null;
		if(StringUtils.isBlank(npayOrdDtlNo)) return null;

		// 주문정보 조회 (상품타입, 주문상품들 조회)
		order.setNpayOrdDtlNo(npayOrdDtlNo);
		order.setOrdNo(npayParam.getOrdNo());
		order.setNpayOrdNo(npayParam.getNpayOrdNo());
		Collection<Order> orderDtlList = naverPayDao.getOrdBaseInfo(order);
		int ordDtlNo = 0;

		// 같은 상품 중 ordDtlNo 찾기
		for(Order dtl : orderDtlList) {
			// 세트상품일경우
			if(TscConstants.GoodsType.SET.value().equals(dtl.getGoodsType())) {
				if(order.getOptCd().contains("/")) {
					String[] optCds = order.getOptCd().split("/");
					boolean chkItem = true;

					for(String optCd : optCds) {
						dtl.setOptCd(optCd);
						if(naverPayDao.getIsNaverPayItem(dtl) < 1) {
							chkItem = false;
						}
					}

					// 해당 Dtl List에 있는 옵션이 모두 같으면 상품주문번호 저장
					if(chkItem) {
						dtl.setOrdDtlStat(TscConstants.OrderDetailStat.PAYMENT_COMPLETE.value());
						dtl.setNpayOrdDtlNo(order.getNpayOrdDtlNo());
						dtl.setRegNo(userNo);
						dtl.setUpdNo(userNo);
						dtl.setCustNo(userNo);
						dtl.setSellGb("10");
						ordDtlNo = dtl.getOrdDtlNo();
						naverPayDao.updateNpayOrdDtlNo(dtl);
						orderDao.createOrderDetailHst(dtl);
						scmDao.updateOrderDetailItemStat(dtl);

						// 2021.06.25 네이버페이 결제완료 (정산구분값추가)
						dtl.setOrdDtlStat(TscConstants.OrdDtlItemStat.SALE_PAYMENT_COMPLETE.value());
						orderDao.createOrderDetailItemHstFromDtlNo(dtl);

						orderDao.createSellQty(dtl);
					}
				} else if (order.getOptCd().length() > 0) {
					//if(dtl.getOptCd().equals(order.getOptCd())) {
					// 세트상품인데 구성 상품이 하나밖에 없을때. 존재하지 않을것으로 보임.
					dtl.setOptCd(order.getOptCd());
					Collection<Order> item = orderChangeDao.getOrderDetailItem(dtl);

					for(Order itemOne : item) {
						if(itemOne.getOptCd().equals(dtl.getOptCd())) {
							itemOne.setOrdDtlStat(TscConstants.OrderDetailStat.PAYMENT_COMPLETE.value());
							itemOne.setNpayOrdDtlNo(order.getNpayOrdDtlNo());
							itemOne.setRegNo(userNo);
							itemOne.setUpdNo(userNo);
							itemOne.setCustNo(userNo);
							itemOne.setSellGb("10");
							ordDtlNo = itemOne.getOrdDtlNo();
							naverPayDao.updateNpayOrdDtlNo(itemOne);
							orderDao.createOrderDetailHst(itemOne);
							scmDao.updateOrderDetailItemStat(itemOne);

							// 2021.06.25 네이버페이 결제완료 (정산구분값추가)
							itemOne.setOrdDtlStat(TscConstants.OrdDtlItemStat.SALE_PAYMENT_COMPLETE.value());
							orderDao.createOrderDetailItemHstFromDtlNo(itemOne);
							orderDao.createSellQty(itemOne);
						}
					}
					//}
				}
			} else {
				// 일반상품일경우(딜상품도 네이버페이 송부시에는 일반으로 송부함)
				// 네이버페이 수신 옵션 정보 주문 조회 - 세트 상품이 아닐 경우 결과값 1ROW만 나옴
				//if(dtl.getOptCd().equals(order.getOptCd())) {
				dtl.setOptCd(order.getOptCd());
				Collection<Order> item = orderChangeDao.getOrderDetailItem(dtl);

				for (Order itemOne : item) {
					if(itemOne.getOptCd().equals(dtl.getOptCd())) {
						itemOne.setOrdDtlStat(TscConstants.OrderDetailStat.PAYMENT_COMPLETE.value());
						itemOne.setNpayOrdDtlNo(order.getNpayOrdDtlNo());
						itemOne.setRegNo(userNo);
						itemOne.setUpdNo(userNo);
						itemOne.setCustNo(userNo);
						itemOne.setSellGb("10");
						ordDtlNo = itemOne.getOrdDtlNo();
						naverPayDao.updateNpayOrdDtlNo(itemOne);
						orderDao.createOrderDetailHst(itemOne);
						scmDao.updateOrderDetailItemStat(itemOne);

						// 2021.06.25 네이버페이 결제완료 (정산구분값추가)
						itemOne.setOrdDtlStat(TscConstants.OrdDtlItemStat.SALE_PAYMENT_COMPLETE.value());
						orderDao.createOrderDetailItemHstFromDtlNo(itemOne);
						orderDao.createSellQty(itemOne);
					}
				}
				//}
			}
		}

		// 배송지 정보 수정
		if(ordDtlNo > 0) {
			npayParam.setOrdDtlNo(ordDtlNo);
			order.setOrdDtlNo(ordDtlNo);
			order.setRecipNm(new String(SimpleCryptLib.decrypt(encryptKey, productOrderInfo.getProductOrder().getShippingAddress().getName()), StandardCharsets.UTF_8));
			order.setRecipPhnno(new String(SimpleCryptLib.decrypt(encryptKey, productOrderInfo.getProductOrder().getShippingAddress().getTel1()), StandardCharsets.UTF_8));
			order.setRecipZipcode(productOrderInfo.getProductOrder().getShippingAddress().getZipCode().replaceAll("-", ""));
			order.setRecipBaseAddr(new String(SimpleCryptLib.decrypt(encryptKey, productOrderInfo.getProductOrder().getShippingAddress().getBaseAddress()), StandardCharsets.UTF_8));
			order.setRecipDtlAddr(new String(SimpleCryptLib.decrypt(encryptKey, productOrderInfo.getProductOrder().getShippingAddress().getDetailedAddress()), StandardCharsets.UTF_8));
			order.setDelvMemo(productOrderInfo.getProductOrder().getShippingMemo());

			if(StringUtils.isNotBlank(productOrderInfo.getProductOrder().getShippingAddress().getTel2())) {
				order.setRecipTelno(new String(SimpleCryptLib.decrypt(encryptKey, productOrderInfo.getProductOrder().getShippingAddress().getTel2()), StandardCharsets.UTF_8));
			}

			naverPayDao.updateShippingAddressInfo(order);
		}

		order.setRegNo(userNo);
		order.setUpdNo(userNo);
		order.setCustNo(userNo);
		order.setSellGb("10");
		order.setPgGb(TscConstants.PgGb.NAVER_ORDER.value());
		order.setPayMeans(TscConstants.PayMeans.CREDIT_CARD.value());
		//orderService.updateOrderInfo(order);

		return order;
	}

	@Transactional("shopTxnManager")
	public String sendNaverPayOrderCancelConfirm(Order param) {
		// Collection<Order> confirmList = orderChangeDao.getOrderChangeDetailList(param);
		try {
			Security.addProvider(new BouncyCastleProvider());
			AccessCredentialsType accessCredentialsType = new AccessCredentialsType();
			MallServiceLocator MSL = new MallServiceLocator(env.getProperty("naverPay.port.address"));
			MallServiceSOAP11BindingStub stub = new MallServiceSOAP11BindingStub();

			stub = (MallServiceSOAP11BindingStub) MSL.getMallServiceSOAP11Port();

			ApproveCancelApplicationRequest approveCancelApplicationRequest 	= null;
			ApproveCancelApplicationResponse approveCancelApplicationResponse 	= null;

			// 네이버페이 주문상세 정보 가져올  Request , Response 세팅
			GetProductOrderInfoListRequest getProdOrderInfoRequest = new GetProductOrderInfoListRequest();
			GetProductOrderInfoListResponse getProdOrderInfoResponse = new GetProductOrderInfoListResponse();

			//for(Order order : confirmList) {
				//서명생성
				generateSignature("ApproveCancelApplication", env.getProperty("naverPay.secret.key"));
				log.info("ApproveCancelApplication(취소요청승인 데이타 송신) :: timeStamp === " + timeStamp);

				//인증정보
				accessCredentialsType.setAccessLicense(env.getProperty("naverPay.access.license"));
				accessCredentialsType.setSignature(signature);
				accessCredentialsType.setTimestamp(timeStamp);

				approveCancelApplicationRequest = new ApproveCancelApplicationRequest();
				approveCancelApplicationRequest.setAccessCredentials(accessCredentialsType);
				approveCancelApplicationRequest.setDetailLevel("Full");
				approveCancelApplicationRequest.setVersion(env.getProperty("naverPay.version"));
				approveCancelApplicationRequest.setRequestID("");
				approveCancelApplicationRequest.setProductOrderID(param.getNpayOrdDtlNo());

				approveCancelApplicationResponse = stub.approveCancelApplication(approveCancelApplicationRequest);

				String resultStr = "";
				if (approveCancelApplicationResponse.getResponseType() != null) {
					resultStr = approveCancelApplicationResponse.getResponseType().toUpperCase();
				}

				//결과 출력
				if ("SUCCESS".equals(resultStr)) {
					log.info("취소승인 성공 주문번호 ===> " + param.getOrdNo());
					log.info("취소승인 성공 네이버상품주문번호 ===> " + param.getNpayOrdDtlNo());
				} else {
					log.info("취소승인 에러");
					log.info("주문번호 ===> " + param.getOrdNo());
					log.info("네이버주문번호 ===> " + param.getNpayOrdDtlNo());
					log.info("Code : " + approveCancelApplicationResponse.getError().getCode());
					log.info("Message : " + approveCancelApplicationResponse.getError().getMessage());
					log.info("Detail : " + approveCancelApplicationResponse.getError().getDetail());

					Order fail = new Order();
					fail.setErrorReason("취소 완료 주문 정보 송부 에러");
					fail.setOrdNo(param.getOrdNo());
					fail.setOptCd("sendNaverPayOrderCancelConfirm");
					fail.setResultCd(approveCancelApplicationResponse.getError().getCode());
					fail.setResultMsg(approveCancelApplicationResponse.getError().getMessage());
					fail.setMallCd(env.getProperty("naverPay.shop.id"));
					fail.setAccessLicense(env.getProperty("naverPay.access.license"));
					fail.setSecretKey(env.getProperty("naverPay.secret.key"));
					fail.setRegNo(param.getRegNo());

					orderDao.createNaverPayErrorLog(fail);

					return "FAIL";
				}
			//}
		} catch(Exception e) {
			throw new IllegalStateException("네이버페이 취소 완료 송부 실패");
		}

		return "SUCCESS";
	}

	@Transactional("shopTxnManager")
	public GagaMap sendNaverPayDeliveryStartOrder(Order param, String statGb, Integer userNo) {
		//for(Order param : params) {
		GagaMap result = new GagaMap();
			if ("SHIPPING".equals(statGb)) {
				Order order = naverPayDao.getOrderDetailInfoFromOrdDtlNo(param);

				// 네이버 페이 주문일 경우
				if(order != null && TscConstants.PgGb.NAVER_ORDER.value().equals(order.getPgGb())) {
					try {
						Security.addProvider(new BouncyCastleProvider());
						AccessCredentialsType accessCredentialsType = new AccessCredentialsType();
						MallServiceLocator MSL = new MallServiceLocator(env.getProperty("naverPay.port.address"));
						MallServiceSOAP11BindingStub stub = new MallServiceSOAP11BindingStub();

						stub = (MallServiceSOAP11BindingStub) MSL.getMallServiceSOAP11Port();

						ShipProductOrderRequest shipProductOrderRequest 	= null;
						ShipProductOrderResponse shipProductOrderResponse 	= null;

						order.setAccessLicense(env.getProperty("naverPay.access.license"));
						order.setSecretKey(env.getProperty("naverPay.secret.key"));
						order.setMallCd(env.getProperty("naverPay.shop.id"));

						//서명생성
						generateSignature("ShipProductOrder", order.getSecretKey());
						log.info("ShipProductOrder(발송 처리) :: timeStamp === " + timeStamp);

						byte[] encryptKey = SimpleCryptLib.generateKey(timeStamp, order.getSecretKey());

						//인증정보
						accessCredentialsType.setAccessLicense(order.getAccessLicense());
						accessCredentialsType.setSignature(signature);
						accessCredentialsType.setTimestamp(timeStamp);

						shipProductOrderRequest = new ShipProductOrderRequest();
						shipProductOrderRequest.setAccessCredentials(accessCredentialsType);
						shipProductOrderRequest.setDetailLevel("Full");
						shipProductOrderRequest.setVersion(env.getProperty("naverPay.version"));
						shipProductOrderRequest.setRequestID("");
						shipProductOrderRequest.setProductOrderID(String.valueOf(order.getNpayOrdDtlNo()));
						shipProductOrderRequest.setDeliveryMethodCode(DeliveryMethodType.DELIVERY);
						shipProductOrderRequest.setDeliveryCompanyCode(order.getNaverPayShipCompCd());
						shipProductOrderRequest.setTrackingNumber(order.getInvoiceNo());

						Calendar dispatchDate = Calendar.getInstance();
						Date tmp;
						if(StringUtils.isNotBlank(order.getDelvStdt())) {
							tmp = new SimpleDateFormat("yyyyMMddHHmmss").parse(order.getDelvStdt(), new ParsePosition(0));
						} else {
							tmp = new Date();
						}

						dispatchDate.setTime(tmp);
						shipProductOrderRequest.setDispatchDate(dispatchDate);

						shipProductOrderResponse = stub.shipProductOrder(shipProductOrderRequest);

						String resultStr = "";
						if (shipProductOrderResponse.getResponseType() != null) {
							resultStr = shipProductOrderResponse.getResponseType().toUpperCase();
						}

						if ("SUCCESS".equals(shipProductOrderResponse.getResponseType())) {
							log.info("배송처리 성공 주문번호 ===> " + order.getOrdNo());
							log.info("배송처리 성공 네이버상품주문번호 ===> " + order.getNpayOrdDtlNo());
						} else {
							log.info("배송처리 에러");
							log.info("주문번호 ===> " + order.getOrdNo());
							log.info("네이버상품주문번호 ===> " + order.getNpayOrdDtlNo());
							log.info("Code : " + shipProductOrderResponse.getError().getCode());
							log.info("Message : " + shipProductOrderResponse.getError().getMessage());
							log.info("Detail : " + shipProductOrderResponse.getError().getDetail());

							try {
								Order fail = new Order();
								fail.setErrorReason("변경상품주문조회 에러");
								fail.setOrdNo(order.getOrdNo());
								fail.setNpayOrdDtlNo(order.getNpayOrdDtlNo());
								fail.setOptCd("sendNaverPayDeliveryStartOrder");
								fail.setResultCd(shipProductOrderResponse.getError().getCode());
								fail.setResultMsg(shipProductOrderResponse.getError().getMessage());
								fail.setMallCd(order.getMallCd());
								fail.setAccessLicense(order.getAccessLicense());
								fail.setSecretKey(order.getSecretKey());
								fail.setRegNo(userNo);

								orderDao.createNaverPayErrorLog(fail);

								result.setString("status", "FAIL");
								result.setString("message", shipProductOrderResponse.getError().getMessage());
								return result;
							} catch(Exception e) {
								e.printStackTrace();

								result.setString("status", "FAIL");
								result.setString("message", e.getMessage());
								return result;
							}
						}
					} catch (Exception e) {
						e.printStackTrace();

						result.setString("status", "FAIL");
						result.setString("message", e.getMessage());
						return result;
					}
				}
			}
		//}

		result.setString("status", "SUCCESS");
		return result;
	}

	/**
	 * 네이버페이 교환 반려 정보 송부
	 * @param chnge
	 * @param userNo
	 * @author xodud1202
	 * @since  2021. 06. 27
	 */
	@Transactional("shopTxnManager")
	public String sendNaverPayRejectExchange(Order param, int userNo) throws Exception {
		Order change = naverPayDao.getOrderDetailInfoFromOrdDtlNo(param);
		if(change != null && TscConstants.PgGb.NAVER_ORDER.value().equals(change.getPgGb())) {
			try {
				Security.addProvider(new BouncyCastleProvider());
				AccessCredentialsType accessCredentialsType = new AccessCredentialsType();
				MallServiceLocator MSL = new MallServiceLocator(env.getProperty("naverPay.port.address"));
				MallServiceSOAP11BindingStub stub = new MallServiceSOAP11BindingStub();

				stub = (MallServiceSOAP11BindingStub) MSL.getMallServiceSOAP11Port();

				RejectExchangeRequest rejectExchgneRequest 	= null;
				RejectExchangeResponse rejectExchgneResponse 	= null;

				//for (OrderChange change : rejectList) {
				if(TscConstants.PgGb.NAVER_ORDER.value().equals(change.getPgGb())) {
					// 서명생성
					generateSignature("RejectExchange", env.getProperty("naverPay.secret.key"));
					log.info("RejectExchange(교환반려 주문 네이버로 송신) :: timeStamp === " + timeStamp);

					//인증정보
					accessCredentialsType.setAccessLicense(env.getProperty("naverPay.access.license"));
					accessCredentialsType.setSignature(signature);
					accessCredentialsType.setTimestamp(timeStamp);

					rejectExchgneRequest = new RejectExchangeRequest();
					rejectExchgneRequest.setAccessCredentials(accessCredentialsType);
					rejectExchgneRequest.setDetailLevel("Full");
					rejectExchgneRequest.setVersion(env.getProperty("naverPay.version"));
					rejectExchgneRequest.setRequestID("");
					rejectExchgneRequest.setProductOrderID(change.getNpayOrdDtlNo());
					rejectExchgneRequest.setRejectDetailContent("교환반려");

					rejectExchgneResponse = stub.rejectExchange(rejectExchgneRequest);

					String resultStr = "";
					if (rejectExchgneResponse.getResponseType() != null) {
						resultStr = rejectExchgneResponse.getResponseType().toUpperCase();
					}

					if ("SUCCESS".equals(resultStr)) {
						log.info("교환반려 성공 주문번호===>"+change.getOrdNo());
						log.info("교환반려 성공 네이버상품주문번호===>"+change.getNpayOrdDtlNo());
					} else {
						log.info("교환반려 에러");
						log.info("주문번호 ===> " + change.getOrdNo());
						log.info("네이버상품주문번호 ===> " + change.getNpayOrdDtlNo());
						log.info("Code : " + rejectExchgneResponse.getError().getCode());
						log.info("Message : " + rejectExchgneResponse.getError().getMessage());
						log.info("Detail : " + rejectExchgneResponse.getError().getDetail());

						try {
							Order fail = new Order();
							fail.setErrorReason("교환 반려 데이터 송부 에러");
							fail.setOrdNo(change.getOrdNo());
							fail.setNpayOrdDtlNo(change.getNpayOrdDtlNo());
							fail.setOptCd("sendNaverPayRejectExchange");
							fail.setResultCd(rejectExchgneResponse.getError().getCode());
							fail.setResultMsg(rejectExchgneResponse.getError().getMessage());
							fail.setMallCd(env.getProperty("naverPay.shop.id"));
							fail.setAccessLicense(env.getProperty("naverPay.access.license"));
							fail.setSecretKey(env.getProperty("naverPay.secret.key"));
							fail.setRegNo(userNo);

							orderDao.createNaverPayErrorLog(fail);
						} catch(Exception e) {
							e.printStackTrace();
							return "FAIL";
						}
					}
				}
				//}
			} catch (Exception e) {
				e.printStackTrace();
				return "FAIL";
			}
		}

		return "SUCCESS";
	}

	/**
	 * 네이버페이 반품 반려 정보 송부
	 * @param chnge
	 * @param userNo
	 * @author xodud1202
	 * @since  2021. 06. 24
	 */
	@Transactional("shopTxnManager")
	public String sendNaverPayRejectReturn(Order param, int userNo) throws Exception {
		Order change = naverPayDao.getOrderDetailInfoFromOrdDtlNo(param);

		if(change != null && TscConstants.PgGb.NAVER_ORDER.value().equals(change.getPgGb())) {
			Security.addProvider(new BouncyCastleProvider());
			AccessCredentialsType accessCredentialsType = new AccessCredentialsType();
			MallServiceLocator MSL = new MallServiceLocator(env.getProperty("naverPay.port.address"));
			MallServiceSOAP11BindingStub stub = new MallServiceSOAP11BindingStub();

			stub = (MallServiceSOAP11BindingStub) MSL.getMallServiceSOAP11Port();

			RejectReturnRequest rejectReturnRequest = null;
			RejectReturnResponse rejectReturnResponse = null;

			//for (OrderChange change : rejectList) {
			if (TscConstants.PgGb.NAVER_ORDER.value().equals(change.getPgGb())) {
				// 서명생성
				generateSignature("RejectReturn", env.getProperty("naverPay.secret.key"));
				log.info("RejectReturn(반품반려 주문 네이버로 송신) :: timeStamp === " + timeStamp);

				//인증정보
				accessCredentialsType.setAccessLicense(env.getProperty("naverPay.access.license"));
				accessCredentialsType.setSignature(signature);
				accessCredentialsType.setTimestamp(timeStamp);

				rejectReturnRequest = new RejectReturnRequest();
				rejectReturnRequest.setAccessCredentials(accessCredentialsType);
				rejectReturnRequest.setDetailLevel("Full");
				rejectReturnRequest.setVersion(env.getProperty("naverPay.version"));
				rejectReturnRequest.setRequestID("");
				rejectReturnRequest.setProductOrderID(change.getNpayOrdDtlNo());
				rejectReturnRequest.setRejectDetailContent("반품반려");

				rejectReturnResponse = stub.rejectReturn(rejectReturnRequest);

				String resultStr = "";
				if (rejectReturnResponse.getResponseType() != null) {
					resultStr = rejectReturnResponse.getResponseType().toUpperCase();
				}

				if ("SUCCESS".equals(resultStr)) {
					log.info("반품반려 성공 주문번호===>" + change.getOrdNo());
					log.info("반품반려 성공 네이버상품주문번호===>" + change.getNpayOrdDtlNo());
				} else {
					log.info("반품반려 에러");
					log.info("주문번호 ===> " + change.getOrdNo());
					log.info("네이버상품주문번호 ===> " + change.getNpayOrdDtlNo());
					log.info("Code : " + rejectReturnResponse.getError().getCode());
					log.info("Message : " + rejectReturnResponse.getError().getMessage());
					log.info("Detail : " + rejectReturnResponse.getError().getDetail());

					try {
						Order fail = new Order();
						fail.setErrorReason("반품 반려 데이터 송부 에러");
						fail.setOrdNo(change.getOrdNo());
						fail.setNpayOrdDtlNo(change.getNpayOrdDtlNo());
						fail.setOptCd("sendNaverPayRejectReturn");
						fail.setResultCd(rejectReturnResponse.getError().getCode());
						fail.setResultMsg(rejectReturnResponse.getError().getMessage());
						fail.setMallCd(env.getProperty("naverPay.shop.id"));
						fail.setAccessLicense(env.getProperty("naverPay.access.license"));
						fail.setSecretKey(env.getProperty("naverPay.secret.key"));
						fail.setRegNo(userNo);

						orderDao.createNaverPayErrorLog(fail);

						return "FAIL";
					} catch (Exception e) {
						e.printStackTrace();
						return "FAIL";
					}
				}
			}
			//}
		}

		return "SUCCESS";
	}

	@Transactional("shopTxnManager")
	public Order recvExchangeReqOrder(ChangedProductOrderInfo[] changedProductOrderList, int userNo) throws Exception {
		String[] productOrderIdList = new String[changedProductOrderList.length];
		for(int i = 0 ; i < changedProductOrderList.length ; i++) {
			productOrderIdList[i] = changedProductOrderList[i].getProductOrderID();
		}

		ProductOrderInfo[] productOrderInfo = productOrderInfoList(productOrderIdList);

		byte[] encryptKey = SimpleCryptLib.generateKey(timeStamp, env.getProperty("naverPay.secret.key"));

		for(ProductOrderInfo orderInfo : productOrderInfo) {
			// 교환 접수 대상 주문 정보 조회
			Order order = new Order();

			// ordChgSq 묶음 상품 정보 조회
			order.setNpayOrdDtlNo(orderInfo.getProductOrder().getProductOrderID());
			log.info("CHECK orderInfo.getExchangeInfo().getClaimDeliveryFeeProductOrderIds() :::: {}", orderInfo.getExchangeInfo().getClaimDeliveryFeeProductOrderIds());
			if(StringUtils.isNotBlank(orderInfo.getExchangeInfo().getClaimDeliveryFeeProductOrderIds())) {
				order.setClaimNpayOrdDtlNos(orderInfo.getExchangeInfo().getClaimDeliveryFeeProductOrderIds().replaceAll(" ", "").split(","));
			} else {
				String[] npayOrdDtlNos = {orderInfo.getProductOrder().getProductOrderID()};
				order.setClaimNpayOrdDtlNos(npayOrdDtlNos);
			}

			Collection<Order> itemList = naverPayDao.getNotExchangeOrderInfoList(order);

			// 정보가 없을 경우 다음 주문건으로 변경
			if(itemList.size() < 1) continue;

			// 교환 정보 리스트
			List<Order> cancelReqList = new ArrayList<>();

			// 교환 사유 코드
			String changeReasonCode 	= orderInfo.getExchangeInfo().getExchangeReason().getValue();

			// 교환 접수 처리
			OrderChange change = new OrderChange();
			int addDelvFee = 0;
			if(orderInfo.getExchangeInfo().getClaimDeliveryFeeDemandAmount() != null) {
				addDelvFee = orderInfo.getExchangeInfo().getClaimDeliveryFeeDemandAmount();
			}

			log.info("ORD_NO ::::::::: {}", orderInfo.getProductOrder().getMerchantCustomCode1());

			change.setOrdNo(Integer.parseInt(orderInfo.getProductOrder().getMerchantCustomCode1()));	// 주문번호
			change.setAddPayCost(addDelvFee);															// 추가배송비
			change.setWdInvoiceNo(orderInfo.getExchangeInfo().getCollectTrackingNumber());				// 회수송장번호

			if ("COLOR_AND_SIZE".equals(changeReasonCode)) {				// 색상 및 사이즈 변경
				change.setIsCustomer(true);		// 고객 사유 여부
				change.setChgReason(TscConstants.OrderChangeReason.CHANGE_OPTION.value());		// 사이즈 변경
			} else if ("WRONG_ORDER".equals(changeReasonCode)) {			// 다른 상품 잘못 주문
				change.setIsCustomer(true);		// 고객 사유 여부
				change.setChgReason(TscConstants.OrderChangeReason.CHANGE_OPTION.value());		// 사이즈 변경
			} else if ("PRODUCT_UNSATISFIED".equals(changeReasonCode)) {	// 서비스 및 상품 불만족
				change.setIsCustomer(false);	// 고객 사유 여부
				change.setChgReason(TscConstants.OrderChangeReason.INCORRECT_OPTION.value());	// 상품 정보와 상이함 (상품 불만족이 존재하지 않아 상품정보 상이로 지정)
			} else if ("INCORRECT_INFO".equals(changeReasonCode)) {			// 상품정보 상이
				change.setIsCustomer(false);	// 고객 사유 여부
				change.setChgReason(TscConstants.OrderChangeReason.INCORRECT_OPTION.value());	// 상품 정보와 상이함
			} else if ("BROKEN".equals(changeReasonCode)) {					// 상품파손
				change.setIsCustomer(false);	// 고객 사유 여부
				change.setChgReason(TscConstants.OrderChangeReason.BROKEN.value());				// 상품이 파손되어 배송됨
			} else if ("WRONG_DELIVERY".equals(changeReasonCode)) {			// 오배송
				change.setIsCustomer(false);	// 고객 사유 여부
				change.setChgReason(TscConstants.OrderChangeReason.INCORRECT_DELV.value());		// 상품주문과 다른 상품이 배송됨
			} else if ("WRONG_OPTION".equals(changeReasonCode)) {			// 색상 등 다른 상품잘못 배송
				change.setIsCustomer(false);	// 고객 사유 여부
				change.setChgReason(TscConstants.OrderChangeReason.CHANGE_OPTION.value());		// 상품주문과 다른 상품이 배송됨
			} else if ("DROPPED_DELIVERY".equals(changeReasonCode)) {		// 배송누락
				change.setIsCustomer(false);	// 고객 사유 여부
				change.setChgReason(TscConstants.OrderChangeReason.NOT_DELV_ALL.value());		// 일부 상품이 배송되지 않음
			}

			// 직접 반송일 경우 회수지정보 (네이버페이 주문형은 배송지도 동일 적용 (배송지 주소 작성란 없음))
			// 회수 지시에 대한 내용은 모든 금액을 네이버페이에서 처리하기로(21/06/28 - 정지혜K 확인) 하였으나, 회수지시 불가 상품이 있는 경우에 대비하여 처리
			// 교환 요청시
			if(orderInfo.getExchangeInfo().getCollectDeliveryMethod() == null) {
				change.setWdGb("D");
				change.setWdTargetYn("N");

				// 회수자명, 휴대폰번호, 우편번호, 기본주소, 상세주소
				change.setRecipZipcode(orderInfo.getProductOrder().getShippingAddress().getZipCode().replaceAll("-", ""));
				change.setRecipNm(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getProductOrder().getShippingAddress().getName()), StandardCharsets.UTF_8));
				change.setRecipPhnno(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getProductOrder().getShippingAddress().getTel1()), StandardCharsets.UTF_8));
				change.setHypenRecipPhone();
				change.setRecipBaseAddr(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getProductOrder().getShippingAddress().getBaseAddress()), StandardCharsets.UTF_8));
				if(StringUtils.isNotBlank(orderInfo.getProductOrder().getShippingAddress().getZipCode())) {
					change.setRecipZipcode(orderInfo.getProductOrder().getShippingAddress().getZipCode().replaceAll("-", ""));
				}
				if(StringUtils.isNotBlank(orderInfo.getProductOrder().getShippingAddress().getDetailedAddress())) {
					change.setRecipDtlAddr(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getProductOrder().getShippingAddress().getDetailedAddress()), StandardCharsets.UTF_8));
				}
			} else if("RETURN_INDIVIDUAL".equals(orderInfo.getExchangeInfo().getCollectDeliveryMethod().toString())) {
				change.setWdGb("D");
				change.setWdTargetYn("N");

				// 회수자명, 휴대폰번호, 우편번호, 기본주소, 상세주소
				change.setRecipNm(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getProductOrder().getShippingAddress().getName()), StandardCharsets.UTF_8));
				change.setRecipPhnno(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getProductOrder().getShippingAddress().getTel1()), StandardCharsets.UTF_8));
				change.setRecipBaseAddr(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getProductOrder().getShippingAddress().getBaseAddress()), StandardCharsets.UTF_8));
				if(StringUtils.isNotBlank(orderInfo.getProductOrder().getShippingAddress().getZipCode())) {
					change.setRecipZipcode(orderInfo.getProductOrder().getShippingAddress().getZipCode().replaceAll("-", ""));
				}
				if(StringUtils.isNotBlank(orderInfo.getProductOrder().getShippingAddress().getDetailedAddress())) {
					change.setRecipDtlAddr(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getProductOrder().getShippingAddress().getDetailedAddress()), StandardCharsets.UTF_8));
				}
			} else {			// 수거 요청일 경우
				change.setWdGb("W");
				change.setWdTargetYn("N");

				// 회수자명, 휴대폰번호, 우편번호, 기본주소, 상세주소
				change.setRecipNm(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getExchangeInfo().getCollectAddress().getName()), StandardCharsets.UTF_8));
				change.setRecipPhnno(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getExchangeInfo().getCollectAddress().getTel1()), StandardCharsets.UTF_8));
				change.setRecipBaseAddr(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getExchangeInfo().getCollectAddress().getBaseAddress()), StandardCharsets.UTF_8));
				change.setRecipDtlAddr(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getExchangeInfo().getCollectAddress().getDetailedAddress()), StandardCharsets.UTF_8));
				if(StringUtils.isNotBlank(orderInfo.getExchangeInfo().getCollectAddress().getZipCode())) {
					change.setRecipZipcode(orderInfo.getExchangeInfo().getCollectAddress().getZipCode().replaceAll("-", ""));
				}
			}

			// 배송지 정보 (네이버페이 주문형 배송지는 회수지와 동일 적용 (배송지 주소 작성란 없음))
			change.setChgerNm(change.getRecipNm());
			change.setChgerPhnno(change.getRecipPhnno());
			change.setChgerZipcode(change.getRecipZipcode());
			change.setChgerBaseAddr(change.getRecipBaseAddr());
			change.setChgerDtlAddr(change.getRecipDtlAddr());

			log.info("change.getRecipNm() ::::: {}", change.getRecipNm());
			log.info("change.getRecipPhnno() ::::: {}", change.getRecipPhnno());
			log.info("change.getRecipZipcode() ::::: {}", change.getRecipZipcode());
			log.info("change.getRecipBaseAddr() ::::: {}", change.getRecipBaseAddr());
			log.info("change.getRecipDtlAddr() ::::: {}", change.getRecipDtlAddr());
			log.info("CHECK ClaimDeliveryFeeDemandAmount :::: {}", orderInfo.getExchangeInfo().getClaimDeliveryFeeDemandAmount());
			log.info("CHECK ClaimDeliveryFeeProductOrderIds :::: {}", orderInfo.getExchangeInfo().getClaimDeliveryFeeProductOrderIds());
			log.info("CHECK ClaimDeliveryFeePayMethod :::: {}", orderInfo.getExchangeInfo().getClaimDeliveryFeePayMethod());
			log.info("CHECK ClaimDeliveryFeePayMeans :::: {}", orderInfo.getExchangeInfo().getClaimDeliveryFeePayMeans());
			log.info("CHECK CollectDeliveryCompany :::: {}", orderInfo.getExchangeInfo().getCollectDeliveryCompany());
			log.info("CHECK CollectTrackingNumber :::: {}", orderInfo.getExchangeInfo().getCollectTrackingNumber());

			for(Order item : itemList) {
				addDelvFee = 0;
				// 추가 배송비
				if(orderInfo.getExchangeInfo().getClaimDeliveryFeeDemandAmount() != null) {
					addDelvFee = orderInfo.getExchangeInfo().getClaimDeliveryFeeDemandAmount();
				}

				// SELECT 후 필요 데이터
				change.setCustNo(item.getCustNo());														// 회원번호
				change.setSelfGoodsYn(item.getSelfGoodsYn());											// 자사 상품 여부

				Order cancelReq = new Order();
				cancelReq.setOrdDtlNo(item.getOrdDtlNo());												// 주문상세번호
				cancelReq.setOrdDtlItemSq(item.getOrdDtlItemSq());										// 주문상세단품일련번호
				cancelReq.setDelvFeeCd(item.getDelvFeeCd());											// 출고처코드
				cancelReq.setSupplyCompCd(item.getSupplyCompCd());										// 공급업체코드
				cancelReq.setChgQty(item.getOrdQty());													// 교환수량 (네이버페이주문형은 수량부분 취/반/교 없음. 전체수량.)
				cancelReq.setOrdChgOpt(item.getOptCd());												// 교환옵션 (네이버페이주문형은 교환 옵션이 존재하지 않음. 메모를 보고 수정해야함)
				cancelReq.setExcDelvFee(addDelvFee / 2);												// 교환 배송비 (교환배송비는 반품배송비 * 2로 송부되므로 교환/반품 배송비 절반씩 배분)
				cancelReq.setRtnDelvFee(addDelvFee / 2);												// 반품배송비  (교환배송비는 반품배송비 * 2로 송부되므로 교환/반품 배송비 절반씩 배분)

				cancelReqList.add(cancelReq);
			}

			change.setCancelReqList(cancelReqList);;

			// 교환접수 처리
			change.setRegNo(userNo);
			change.setUpdNo(userNo);
			change.setPgGb(TscConstants.PgGb.NAVER_ORDER.value());
			String delvFeeMemo = "";
			if(orderInfo.getExchangeInfo().getClaimDeliveryFeeDemandAmount() != null && orderInfo.getExchangeInfo().getClaimDeliveryFeeDemandAmount() > 0) {
				if(StringUtils.isNotBlank(orderInfo.getExchangeInfo().getClaimDeliveryFeePayMethod()) && orderInfo.getExchangeInfo().getClaimDeliveryFeePayMethod().contains("동봉")) {
					delvFeeMemo = "/배송비동봉 " + orderInfo.getExchangeInfo().getClaimDeliveryFeeDemandAmount();
				} else if(StringUtils.isNotBlank(orderInfo.getExchangeInfo().getClaimDeliveryFeePayMethod()) && orderInfo.getExchangeInfo().getClaimDeliveryFeePayMethod().contains("송금")) {
					delvFeeMemo = "/배송비송금 " + orderInfo.getExchangeInfo().getClaimDeliveryFeeDemandAmount();
				}
			}

			change.setChgMemo("[네이버페이]-교환 " + delvFeeMemo + "/" + orderInfo.getExchangeInfo().getExchangeDetailedReason());					// 교환 상세 사유
			change.setWdTargetYn("N");
			log.info("CHECK CHG_MEMO :::: {}", change.getChgMemo());

			GagaMap result = orderChangeService.exchReq(change);

			// 추가배송비 결제 이력 있으면 TB_PAYMENT 넣고 deliveryFee에 PAY_SQ UPDATE
			if(orderInfo.getExchangeInfo().getClaimDeliveryFeeDemandAmount() != null && orderInfo.getExchangeInfo().getClaimDeliveryFeeDemandAmount() > 0) {
				if (StringUtils.isNotBlank(orderInfo.getExchangeInfo().getClaimDeliveryFeePayMethod()) && orderInfo.getExchangeInfo().getClaimDeliveryFeePayMethod().contains("결제")) {
					if(StringUtils.isNotBlank(orderInfo.getExchangeInfo().getClaimDeliveryFeePayMeans())) {
						Payment payment = new Payment();
						payment.setOrdNo(Integer.parseInt(orderInfo.getProductOrder().getMerchantCustomCode1()));
						payment.setPayMeans(TscConstants.PayMeans.CREDIT_CARD.value());
						payment.setPayAmt(orderInfo.getExchangeInfo().getClaimDeliveryFeeDemandAmount());
						payment.setPayGb("D");
						payment.setPayStat(TscConstants.PaymentStat.PAYMENT_COMPLETE.value());
						payment.setPgGb(TscConstants.PgGb.NAVER_ORDER.value());
						payment.setPgTid(orderInfo.getOrder().getPaymentNumber());
						payment.setPgShopId(env.getProperty("naverPay.shop.id"));
						payment.setOrdChgSq(result.getInt("ordChgSq"));
						payment.setCardPcableYn("Y");
						payment.setEscrowYn("N");
						payment.setRegNo(userNo);
						payment.setUpdNo(userNo);

						orderDao.insertPayment(payment);
						orderDao.updateDeliveryFeePaySq(payment);

						log.info("::::: 네이버페이 교환 추가 배송비 결제 완료 등록 성공");
					}
				}
			}

			log.info("NAPAY_ORD_NO 교환 접수 성공 :::: {}", order.getNpayOrdDtlNo());
		}

		return null;
	}

	@Transactional("shopTxnManager")
	public Order recvReturnReqOrder(ChangedProductOrderInfo[] changedProductOrderList, int userNo) {
		Order result = new Order();
		try {
			String[] productOrderIdList = new String[changedProductOrderList.length];
			for(int i = 0 ; i < changedProductOrderList.length ; i++) {
				productOrderIdList[i] = changedProductOrderList[i].getProductOrderID();
			}

			ProductOrderInfo[] productOrderInfo = productOrderInfoList(productOrderIdList);

			byte[] encryptKey = SimpleCryptLib.generateKey(timeStamp, env.getProperty("naverPay.secret.key"));

			for(ProductOrderInfo orderInfo : productOrderInfo) {
				Order order = new Order();
				order.setOrdNo(Integer.parseInt(orderInfo.getProductOrder().getMerchantCustomCode1()));
				order.setNpayOrdDtlNo(orderInfo.getProductOrder().getProductOrderID());

				log.info("CHECK NPAY_ORD_DTL_NO ::::: {}", order.getNpayOrdDtlNo());

				// ClaimDeliveryFeeProductOrderIds > 네이버 상품주문번호 반품묶음.
				if(orderInfo.getReturnInfo() != null && StringUtils.isNotBlank(orderInfo.getReturnInfo().getClaimDeliveryFeeProductOrderIds())) {
					order.setClaimNpayOrdDtlNos(orderInfo.getReturnInfo().getClaimDeliveryFeeProductOrderIds().replaceAll(" ", "").split(","));
				} else {
					String[] npayOrdDtlNos = {orderInfo.getProductOrder().getProductOrderID()};
					order.setClaimNpayOrdDtlNos(npayOrdDtlNos);
				}

				Collection<Order> list = naverPayDao.getNotReturnOrderInfoList(order);

				int[] ordDtlNoArr, cnclRtnReqQtyArr;
				int custNo = 0;
				String ordNm = "", ordPhnno = "";
				if(list != null && list.size() > 0) {
					ordDtlNoArr = new int[list.size()];
					cnclRtnReqQtyArr = new int[list.size()];

					int i = 0;
					for(Order item : list) {
						ordDtlNoArr[i] = item.getOrdDtlNo();
						cnclRtnReqQtyArr[i] = item.getOrdQty();
						ordNm = item.getOrdNm();
						ordPhnno = item.getOrdPhnno();
						custNo = item.getCustNo();
					}
				} else {
					continue;
				}

				OrderChange change = new OrderChange();
				String changeReasonCode 		= orderInfo.getReturnInfo().getReturnReason().getValue();
				String collectDeliveryMethod;		// 직접반송
				if(orderInfo.getReturnInfo().getCollectDeliveryMethod() != null && !"RETURN_INDIVIDUAL".equals(orderInfo.getReturnInfo().getCollectDeliveryMethod().toString())) {
					collectDeliveryMethod = orderInfo.getReturnInfo().getCollectDeliveryMethod().toString();
					change.setChgerNm(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getReturnInfo().getCollectAddress().getName()), StandardCharsets.UTF_8));
					change.setChgerBaseAddr(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getReturnInfo().getCollectAddress().getBaseAddress()), StandardCharsets.UTF_8));
					change.setChgerPhnno(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getReturnInfo().getCollectAddress().getTel1()), StandardCharsets.UTF_8));
					if (orderInfo.getReturnInfo().getCollectAddress().getZipCode() != null) {
						change.setChgerZipcode(orderInfo.getReturnInfo().getCollectAddress().getZipCode().replaceAll("-", ""));
					}
					if (orderInfo.getReturnInfo().getCollectAddress().getDetailedAddress() != null) {
						change.setChgerDtlAddr(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getReturnInfo().getCollectAddress().getDetailedAddress()), StandardCharsets.UTF_8));
					}
				} else {
					collectDeliveryMethod	= "RETURN_INDIVIDUAL";		// 직접반송
					change.setChgerNm(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getProductOrder().getShippingAddress().getName()), StandardCharsets.UTF_8));
					change.setChgerBaseAddr(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getProductOrder().getShippingAddress().getBaseAddress()), StandardCharsets.UTF_8));
					change.setChgerPhnno(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getProductOrder().getShippingAddress().getTel1()), StandardCharsets.UTF_8));
					if (orderInfo.getProductOrder().getShippingAddress().getZipCode() != null) {
						change.setChgerZipcode(orderInfo.getProductOrder().getShippingAddress().getZipCode().replaceAll("-", ""));
					}
					if(StringUtils.isNotBlank(orderInfo.getProductOrder().getShippingAddress().getDetailedAddress())) {
						change.setChgerDtlAddr(new String(SimpleCryptLib.decrypt(encryptKey, orderInfo.getProductOrder().getShippingAddress().getDetailedAddress()), StandardCharsets.UTF_8));
					}
				}

				change.setOrdNo(order.getOrdNo());
				change.setCustNo(custNo);
				change.setOrdNm(ordNm);
				change.setOrdPhnno(ordPhnno);
				change.setRegNo(userNo);
				change.setUpdNo(userNo);
				change.setPgGb(TscConstants.PgGb.NAVER_ORDER.value());
				change.setChgMemo(orderInfo.getReturnInfo().getReturnDetailedReason());
				change.setWdInvoiceNo(orderInfo.getReturnInfo().getCollectTrackingNumber());
				change.setOrdDtlNoArr(ordDtlNoArr);
				change.setCnclRtnReqQtyArr(cnclRtnReqQtyArr);
				change.setWdTargetYn("N");			// 네이버페이 자체 회수 지시함

				if(orderInfo.getReturnInfo().getClaimDeliveryFeeDemandAmount() != null) {
					change.setAddPayCost(orderInfo.getReturnInfo().getClaimDeliveryFeeDemandAmount());
				}

				// 회수구분
				if ("RETURN_DESIGNATED".equals(collectDeliveryMethod)
						|| "RETURN_DELIVERY".equals(collectDeliveryMethod)) {
					change.setWdGb("W");		// 회수지시
				} else {
					change.setWdGb("D");		// 직접배송
				}

				// 구매의사 취소
				if ("INTENT_CHANGED".equals(changeReasonCode)) {
					change.setIsCustomer(true);
					change.setChgReason(TscConstants.OrderReturnReason.CHANGE_MIND.value());
				}
				// 색상 및 사이즈변경
				else if ("COLOR_AND_SIZE".equals(changeReasonCode)) {
					change.setIsCustomer(true);
					change.setChgReason(TscConstants.OrderReturnReason.CHANGE_MIND.value());
				}
				// 다른 상품 잘못 주문
				else if ("WRONG_ORDER".equals(changeReasonCode)) {
					change.setIsCustomer(true);
					change.setChgReason(TscConstants.OrderReturnReason.CHANGE_MIND.value());
				}
				// 서비스 불만족
				else if ("PRODUCT_UNSATISFIED".equals(changeReasonCode)) {
					change.setIsCustomer(true);
					change.setChgReason(TscConstants.OrderReturnReason.CHANGE_MIND.value());
				}
				// 상품정보 상이
				else if ("INCORRECT_INFO".equals(changeReasonCode)) {
					change.setIsCustomer(false);
					change.setChgReason(TscConstants.OrderReturnReason.INCORRECT_OPTION.value());
				}
				// 상품파손
				else if ("BROKEN".equals(changeReasonCode)) {
					change.setIsCustomer(false);
					change.setChgReason(TscConstants.OrderReturnReason.BROKEN.value());
				}
				// 오배송
				else if ("WRONG_DELIVERY".equals(changeReasonCode)) {
					change.setIsCustomer(false);
					change.setChgReason(TscConstants.OrderReturnReason.INCORRECT_DELV.value());
				}
				// 색상 등 다른 상품잘못 배송
				else if ("WRONG_OPTION".equals(changeReasonCode)) {
					change.setIsCustomer(false);
					change.setChgReason(TscConstants.OrderReturnReason.INCORRECT_DELV.value());
				}
				// 배송지연
				else if ("DELAYED_DELIVERY".equals(changeReasonCode)) {
					change.setIsCustomer(false);
					change.setChgReason(TscConstants.OrderReturnReason.DELAY_DELV.value());
				}
				// 배송누락
				else if("DROPPED_DELIVERY".equals(changeReasonCode)){
					change.setIsCustomer(false);
					change.setChgReason(TscConstants.OrderReturnReason.NOT_DELV_ALL.value());
				}

				GagaMap map = returnReq(change);
			}
		} catch(Exception e) {
			e.printStackTrace();
			throw new IllegalStateException(e.getMessage(), e);
		}
		return result;
	}

	/**
	 * 네이버페이 반품 신청
	 * @param orderChange
	 * @return
	 * @author xodud1202
	 * @since 2021. 07. 29
	 */
	@SuppressWarnings("unchecked")
	@Transactional("shopTxnManager")
	public GagaMap returnReq(OrderChange orderChange) {
		// 2. 환불 사전 정보 조회
		GagaMap refundPreInfo = orderChangeService.getRefundPreInfo(orderChange);
		List<Order> returnReqList = (List<Order>)refundPreInfo.get("cnclReqList");
		String allLastCanYn = refundPreInfo.getString("allLastCanYn");
		String supplyCompCd = refundPreInfo.getString("supplyCompCd");

		// 3. 환불금액계산
		GagaMap result = orderRefundService.cnclRtnRefundAmt(returnReqList);

		// 4. 주문변경 기본정보 설정
		result.set("ordNo", orderChange.getOrdNo());					// 주문번호
		result.setInt("custNo", orderChange.getCustNo());				// 고객번호
		result.set("regNo", orderChange.getRegNo());
		result.set("updNo", orderChange.getUpdNo());
		result.set("pgGb", orderChange.getPgGb());
		// result.set("ordChgSq", orderChange.getOrdChgSq());			// 주문변경번호
		result.set("chgReason", orderChange.getChgReason());			// 변경사유
		result.set("chgMemo", orderChange.getChgMemo());				// 변경메모

		result.set("accountNo", orderChange.getAccountNo());			// 환불계좌번호
		result.set("accountNm", orderChange.getAccountNm());			// 환불계좌예금주명
		result.set("bankCd", orderChange.getBankCd());					// 환불계좌은행코드

		result.setString("allLastCanYn", allLastCanYn);					// 전체 마지막 취소 여부
		result.set("isCustomer", orderChange.getIsCustomer());			// 변경사유 (고객, 회사)
		result.set("wdTargetYn", orderChange.getWdTargetYn());			// 회수지시 요청 여부
		result.set("wdGb", orderChange.getWdGb());						// 회수방법
		result.set("wdInvoiceNo", orderChange.getWdInvoiceNo());		// 회수송장번호

		// 5. 주문변경 회수지정보 추가
		result.set("chgerNm", orderChange.getChgerNm());				// 변경자명
		result.set("chgerEmail", orderChange.getChgerEmail());			// 변경자이메일주소
		result.set("chgerZipcode", orderChange.getChgerZipcode());		// 회수지우편번호
		result.set("chgerBaseAddr", orderChange.getChgerBaseAddr());	// 회수지기본주소
		result.set("chgerDtlAddr", orderChange.getChgerDtlAddr());		// 회수지상세주소
		result.set("chgerPhnno", orderChange.getChgerPhnno());			// 변경자핸드폰번호
		result.set("chgerTelno", orderChange.getChgerTelno());			// 변경자전화번호
		result.set("chgerRtnMemo", orderChange.getChgerRtnMemo());		// 반품메모

		// 6. 주문변경 DB 등록 (TB_ORDER_CHANGE, TB_ORDER_CHANGE_DETAIL, TB_REFUND)
		GagaMap map = orderChangeService.returnRequest(result);

		return map;
	}

	/**
	 * 네이버페이 교환 재배송 데이터 송부
	 * @param chnge
	 * @param userNo
	 * @author xodud1202
	 * @since  2021. 06. 28
	 */
	@Transactional("shopTxnManager")
	public GagaMap sendNaverPayExchangeReDelivery(Order param, int userNo) throws Exception {
		GagaMap result = new GagaMap();
		Order order = naverPayDao.getOrderDetailInfoFromOrdDtlNo(param);

		Security.addProvider(new BouncyCastleProvider());
		AccessCredentialsType accessCredentialsType = new AccessCredentialsType();
		MallServiceLocator MSL = new MallServiceLocator(env.getProperty("naverPay.port.address"));
		MallServiceSOAP11BindingStub stub = new MallServiceSOAP11BindingStub();

		stub = (MallServiceSOAP11BindingStub) MSL.getMallServiceSOAP11Port();

		ReDeliveryExchangeRequest reDeliveryExchangeRequest 	= null;
		ReDeliveryExchangeResponse reDeliveryExchangeResponse 	= null;

		if(order != null && TscConstants.PgGb.NAVER_ORDER.value().equals(order.getPgGb())) {
			// 서명생성
			generateSignature("ReDeliveryExchange", env.getProperty("naverPay.secret.key"));
			log.info("ReDeliveryExchange(교환 재배송 주문 네이버로 송신) :: timeStamp === " + timeStamp);

			//인증정보
			accessCredentialsType.setAccessLicense(env.getProperty("naverPay.access.license"));
			accessCredentialsType.setSignature(signature);
			accessCredentialsType.setTimestamp(timeStamp);

			reDeliveryExchangeRequest = new ReDeliveryExchangeRequest();
			reDeliveryExchangeRequest.setAccessCredentials(accessCredentialsType);
			reDeliveryExchangeRequest.setDetailLevel("Full");
			reDeliveryExchangeRequest.setVersion(env.getProperty("naverPay.version"));
			reDeliveryExchangeRequest.setRequestID("");
			reDeliveryExchangeRequest.setProductOrderID(order.getNpayOrdDtlNo());
			reDeliveryExchangeRequest.setReDeliveryMethodCode(DeliveryMethodType.DELIVERY);
			reDeliveryExchangeRequest.setReDeliveryCompanyCode(order.getNaverPayShipCompCd());
			reDeliveryExchangeRequest.setReDeliveryTrackingNumber(order.getInvoiceNo());

			Calendar dispatchDate = Calendar.getInstance();
			Date tmp;
			if(StringUtils.isNotBlank(order.getDelvStdt())) {
				tmp = new SimpleDateFormat("yyyyMMddHHmmss").parse(order.getDelvStdt(), new ParsePosition(0));
			} else {
				tmp = new Date();
			}

			if ("".equals(order.getDelvStdt())) tmp = new Date();

			dispatchDate.setTime(tmp);

			reDeliveryExchangeResponse = stub.reDeliveryExchange(reDeliveryExchangeRequest);

			String resultStr = "";
			if (reDeliveryExchangeResponse.getResponseType() != null) {
				resultStr = reDeliveryExchangeResponse.getResponseType().toUpperCase();
			}

			if ("SUCCESS".equals(resultStr)) {
				log.info("교환재배송처리처리 성공 주문번호===>"+order.getOrdNo());
				log.info("교환재배송처리처리 성공 네이버상품주문번호===>"+order.getNpayOrdDtlNo());
			} else {
				log.info("교환재배송처리처리 에러");
				log.info("주문번호 ===> " + order.getOrdNo());
				log.info("네이버상품주문번호 ===> " + order.getNpayOrdDtlNo());
				log.info("Code : " + reDeliveryExchangeResponse.getError().getCode());
				log.info("Message : " + reDeliveryExchangeResponse.getError().getMessage());
				log.info("Detail : " + reDeliveryExchangeResponse.getError().getDetail());

				try {
					Order fail = new Order();
					fail.setErrorReason("교환재배송처리처리 데이터 송부 에러");
					fail.setOrdNo(order.getOrdNo());
					fail.setNpayOrdDtlNo(order.getNpayOrdDtlNo());
					fail.setOptCd("sendNaverPayExchangeReDelivery");
					fail.setResultCd(reDeliveryExchangeResponse.getError().getCode());
					fail.setResultMsg(reDeliveryExchangeResponse.getError().getMessage());
					fail.setMallCd(env.getProperty("naverPay.shop.id"));
					fail.setAccessLicense(env.getProperty("naverPay.access.license"));
					fail.setSecretKey(env.getProperty("naverPay.secret.key"));
					fail.setRegNo(userNo);

					orderDao.createNaverPayErrorLog(fail);

					result.setString("status", "FAIL");
					result.setString("message", reDeliveryExchangeResponse.getError().getMessage());
					return result;
				} catch(Exception e) {
					e.printStackTrace();
					
					result.setString("status", "FAIL");
					result.setString("message", e.getMessage());
					return result;
				}
			}
		}

		result.setString("status", "SUCCESS");
		return result;
	}

	/**
	 * 네이버페이 교환 회수 완료 데이터 송부
	 * @param chnge
	 * @param userNo
	 * @author xodud1202
	 * @since  2021. 06. 28
	 */
	@Transactional("shopTxnManager")
	public String sendNaverPayExchangeCollectComplete(Order param, int userNo) throws Exception {
		Order order = naverPayDao.getOrderDetailInfoFromOrdDtlNo(param);

		Security.addProvider(new BouncyCastleProvider());
		AccessCredentialsType accessCredentialsType = new AccessCredentialsType();
		MallServiceLocator MSL = new MallServiceLocator(env.getProperty("naverPay.port.address"));
		MallServiceSOAP11BindingStub stub = new MallServiceSOAP11BindingStub();

		stub = (MallServiceSOAP11BindingStub) MSL.getMallServiceSOAP11Port();

		ApproveCollectedExchangeRequest approveCollectedExchangeRequest 	= null;
		ApproveCollectedExchangeResponse approveCollectedExchangeResponse 	= null;

		if(order != null && TscConstants.PgGb.NAVER_ORDER.value().equals(order.getPgGb())) {
			// 서명생성
			generateSignature("ApproveCollectedExchange", env.getProperty("naverPay.secret.key"));
			log.info("ApproveCollectedExchange(교환 회수 완료 주문 네이버로 송신) :: timeStamp === " + timeStamp);

			//인증정보
			accessCredentialsType.setAccessLicense(env.getProperty("naverPay.access.license"));
			accessCredentialsType.setSignature(signature);
			accessCredentialsType.setTimestamp(timeStamp);

			approveCollectedExchangeRequest = new ApproveCollectedExchangeRequest();
			approveCollectedExchangeRequest.setAccessCredentials(accessCredentialsType);
			approveCollectedExchangeRequest.setDetailLevel("Full");
			approveCollectedExchangeRequest.setVersion(env.getProperty("naverPay.version"));
			approveCollectedExchangeRequest.setRequestID("");
			approveCollectedExchangeRequest.setProductOrderID(order.getNpayOrdDtlNo());

			approveCollectedExchangeResponse = stub.approveCollectedExchange(approveCollectedExchangeRequest);

			String resultStr = "";
			if (approveCollectedExchangeResponse.getResponseType() != null) {
				resultStr = approveCollectedExchangeResponse.getResponseType().toUpperCase();
			}

			if ("SUCCESS".equals(resultStr)) {
				log.info("교환수거완료처리 성공 주문번호===>"+order.getOrdNo());
				log.info("교환수거완료처리 성공 네이버상품주문번호===>"+order.getNpayOrdDtlNo());
			} else {
				log.info("교환수거완료처리 에러");
				log.info("주문번호 ===> " + order.getOrdNo());
				log.info("네이버상품주문번호 ===> " + order.getNpayOrdDtlNo());
				log.info("Code : " + approveCollectedExchangeResponse.getError().getCode());
				log.info("Message : " + approveCollectedExchangeResponse.getError().getMessage());
				log.info("Detail : " + approveCollectedExchangeResponse.getError().getDetail());

				try {
					Order fail = new Order();
					fail.setErrorReason("교환수거완료처리 데이터 송부 에러");
					fail.setOrdNo(order.getOrdNo());
					fail.setNpayOrdDtlNo(order.getNpayOrdDtlNo());
					fail.setOptCd("sendNaverPayExchangeCollectComplete");
					fail.setResultCd(approveCollectedExchangeResponse.getError().getCode());
					fail.setResultMsg(approveCollectedExchangeResponse.getError().getMessage());
					fail.setMallCd(env.getProperty("naverPay.shop.id"));
					fail.setAccessLicense(env.getProperty("naverPay.access.license"));
					fail.setSecretKey(env.getProperty("naverPay.secret.key"));
					fail.setRegNo(userNo);

					orderDao.createNaverPayErrorLog(fail);

					return "FAIL";
				} catch(Exception e) {
					e.printStackTrace();

					return "FAIL";
				}
			}
		}

		return "SUCCESS";
	}

	/**
	 * 네이버페이 품절반품접수 송부
	 * @param chnge
	 * @param userNo
	 * @author xodud1202
	 * @since  2021. 06. 28
	 */
	@Transactional("shopTxnManager")
	public String sendNaverPaySoldoutReturnReq(Order param, int userNo) throws Exception {
		Order order = naverPayDao.getOrderDetailInfoFromOrdDtlNo(param);

		Security.addProvider(new BouncyCastleProvider());
		AccessCredentialsType accessCredentialsType = new AccessCredentialsType();
		MallServiceLocator MSL = new MallServiceLocator(env.getProperty("naverPay.port.address"));
		MallServiceSOAP11BindingStub stub = new MallServiceSOAP11BindingStub();

		stub = (MallServiceSOAP11BindingStub) MSL.getMallServiceSOAP11Port();

		RequestReturnRequest requestReturnRequest 		= null;
		RequestReturnResponse requestReturnResponse 	= null;

		if(order != null && TscConstants.PgGb.NAVER_ORDER.value().equals(order.getPgGb())) {
			// 서명생성
			generateSignature("RequestReturn", env.getProperty("naverPay.secret.key"));
			log.info("RequestReturn(품절반품접수 네이버로 송신) :: timeStamp === " + timeStamp);

			//인증정보
			accessCredentialsType.setAccessLicense(env.getProperty("naverPay.access.license"));
			accessCredentialsType.setSignature(signature);
			accessCredentialsType.setTimestamp(timeStamp);

			requestReturnRequest = new RequestReturnRequest();
			requestReturnRequest.setAccessCredentials(accessCredentialsType);
			requestReturnRequest.setDetailLevel("Full");
			requestReturnRequest.setVersion(env.getProperty("naverPay.version"));
			requestReturnRequest.setRequestID("");
			requestReturnRequest.setProductOrderID(order.getNpayOrdDtlNo());
			requestReturnRequest.setReturnReasonCode(ClaimRequestReasonType.SOLD_OUT);
			requestReturnRequest.setCollectDeliveryMethodCode(DeliveryMethodType.RETURN_INDIVIDUAL);

			requestReturnResponse = stub.requestReturn(requestReturnRequest);

			String resultStr = "";
			if (requestReturnResponse.getResponseType() != null) {
				resultStr = requestReturnResponse.getResponseType().toUpperCase();
			}

			if ("SUCCESS".equals(resultStr)) {
				log.info("품절반품접수 성공 주문번호===>"+order.getOrdNo());
				log.info("품절반품접수 성공 네이버상품주문번호===>"+order.getNpayOrdDtlNo());
			} else {
				log.info("품절반품접수 에러");
				log.info("주문번호 ===> " + order.getOrdNo());
				log.info("네이버상품주문번호 ===> " + order.getNpayOrdDtlNo());
				log.info("Code : " + requestReturnResponse.getError().getCode());
				log.info("Message : " + requestReturnResponse.getError().getMessage());
				log.info("Detail : " + requestReturnResponse.getError().getDetail());

				try {
					Order fail = new Order();
					fail.setErrorReason("품절반품접수 데이터 송부 에러");
					fail.setOrdNo(order.getOrdNo());
					fail.setNpayOrdDtlNo(order.getNpayOrdDtlNo());
					fail.setOptCd("sendNaverPaySoldoutReturnReq");
					fail.setResultCd(requestReturnResponse.getError().getCode());
					fail.setResultMsg(requestReturnResponse.getError().getMessage());
					fail.setMallCd(env.getProperty("naverPay.shop.id"));
					fail.setAccessLicense(env.getProperty("naverPay.access.license"));
					fail.setSecretKey(env.getProperty("naverPay.secret.key"));
					fail.setRegNo(userNo);

					orderDao.createNaverPayErrorLog(fail);

					return "FAIL";
				} catch(Exception e) {
					e.printStackTrace();
					return "FAIL";
				}
			}
		}

		return "SUCCESS";
	}

	/**
	 * 네이버페이 품절취소 데이터 송부
	 * @param chnge
	 * @param userNo
	 * @author xodud1202
	 * @since  2021. 06. 28
	 */
	@Transactional("shopTxnManager")
	public String sendNaverPaySoldoutCancel(Order param, int userNo) throws Exception {
		Order order = naverPayDao.getOrderDetailInfoFromOrdDtlNo(param);		// ordDtlNo 파라미터 송부 할 것.

		Security.addProvider(new BouncyCastleProvider());
		AccessCredentialsType accessCredentialsType = new AccessCredentialsType();
		MallServiceLocator MSL = new MallServiceLocator(env.getProperty("naverPay.port.address"));
		MallServiceSOAP11BindingStub stub = new MallServiceSOAP11BindingStub();

		stub = (MallServiceSOAP11BindingStub) MSL.getMallServiceSOAP11Port();

		CancelSaleRequest cancelSaleRequest = null;
		CancelSaleResponse cancelSaleResponse = null;
		ApproveCancelApplicationRequest approveCancelApplicationRequest = null;
		ApproveCancelApplicationResponse approveCancelApplicationResponse = null;

		if(order != null && TscConstants.PgGb.NAVER_ORDER.value().equals(order.getPgGb())) {
			// 서명생성
			generateSignature("CancelSale", env.getProperty("naverPay.secret.key"));
			log.info("CancelSale(품절취소) :: timeStamp === " + timeStamp);

			//인증정보
			accessCredentialsType.setAccessLicense(env.getProperty("naverPay.access.license"));
			accessCredentialsType.setSignature(signature);
			accessCredentialsType.setTimestamp(timeStamp);

			cancelSaleRequest = new CancelSaleRequest();
			cancelSaleRequest.setAccessCredentials(accessCredentialsType);
			cancelSaleRequest.setDetailLevel("Full");
			cancelSaleRequest.setVersion(env.getProperty("naverPay.version"));
			cancelSaleRequest.setRequestID("");
			cancelSaleRequest.setProductOrderID(order.getNpayOrdDtlNo());
			cancelSaleRequest.setCancelReasonCode(ClaimRequestReasonType.SOLD_OUT);

			cancelSaleResponse = stub.cancelSale(cancelSaleRequest);

			String resultStr = "";
			if (cancelSaleResponse.getResponseType() != null) {
				resultStr = cancelSaleResponse.getResponseType().toUpperCase();
			}

			if ("SUCCESS".equals(resultStr)) {
				log.info("품절취소 성공 주문번호===>"+order.getOrdNo());
				log.info("품절취소 성공 네이버상품주문번호===>"+order.getNpayOrdDtlNo());
			} else {
				log.info("품절취소 에러");
				log.info("주문번호 ===> " + order.getOrdNo());
				log.info("네이버상품주문번호 ===> " + order.getNpayOrdDtlNo());
				log.info("Code : " + cancelSaleResponse.getError().getCode());
				log.info("Message : " + cancelSaleResponse.getError().getMessage());
				log.info("Detail : " + cancelSaleResponse.getError().getDetail());

				try {
					Order fail = new Order();
					fail.setErrorReason("품절취소 데이터 송부 에러");
					fail.setOrdNo(order.getOrdNo());
					fail.setNpayOrdDtlNo(order.getNpayOrdDtlNo());
					fail.setOptCd("sendNaverPaySoldoutCancel");
					fail.setResultCd(cancelSaleResponse.getError().getCode());
					fail.setResultMsg(cancelSaleResponse.getError().getMessage());
					fail.setMallCd(env.getProperty("naverPay.shop.id"));
					fail.setAccessLicense(env.getProperty("naverPay.access.license"));
					fail.setSecretKey(env.getProperty("naverPay.secret.key"));
					fail.setRegNo(userNo);

					orderDao.createNaverPayErrorLog(fail);
					return "FAIL";
				} catch(Exception e) {
					e.printStackTrace();
					return "FAIL";
				}
			}

			/* 취소 요청 승인 > CANCELSALE이 취소함.
			// 서명생성
			generateSignature("CancelSale", env.getProperty("naverPay.secret.key"));
			log.info("CancelSale(품절취소) :: timeStamp === " + timeStamp);

			//인증정보
			accessCredentialsType.setAccessLicense(env.getProperty("naverPay.access.license"));
			accessCredentialsType.setSignature(signature);
			accessCredentialsType.setTimestamp(timeStamp);

			approveCancelApplicationRequest = new ApproveCancelApplicationRequest();
			approveCancelApplicationRequest.setAccessCredentials(accessCredentialsType);
			approveCancelApplicationRequest.setDetailLevel("Full");
			approveCancelApplicationRequest.setVersion(env.getProperty("naverPay.version"));
			approveCancelApplicationRequest.setRequestID("");
			approveCancelApplicationRequest.setProductOrderID(order.getNpayOrdDtlNo());
			approveCancelApplicationRequest.setEtcFeeDemandAmount(0);

			approveCancelApplicationResponse = stub.approveCancelApplication(approveCancelApplicationRequest);

			resultStr = "";
			if (approveCancelApplicationResponse.getResponseType() != null) {
				resultStr = approveCancelApplicationResponse.getResponseType().toUpperCase();
			}

			if ("SUCCESS".equals(resultStr)) {
				log.info("품절취소승인 성공 주문번호===>"+order.getOrdNo());
				log.info("품절취소승인 성공 네이버상품주문번호===>"+order.getNpayOrdDtlNo());
			} else {
				log.info("품절취소승인 에러");
				log.info("주문번호 ===> " + order.getOrdNo());
				log.info("네이버상품주문번호 ===> " + order.getNpayOrdDtlNo());
				log.info("Code : " + approveCancelApplicationResponse.getError().getCode());
				log.info("Message : " + approveCancelApplicationResponse.getError().getMessage());
				log.info("Detail : " + approveCancelApplicationResponse.getError().getDetail());

				try {
					Order fail = new Order();
					fail.setErrorReason("품절취소승인 데이터 송부 에러");
					fail.setOrdNo(order.getOrdNo());
					fail.setNpayOrdDtlNo(order.getNpayOrdDtlNo());
					fail.setOptCd("sendNaverPaySoldoutCancel");
					fail.setResultCd(approveCancelApplicationResponse.getError().getCode());
					fail.setResultMsg(approveCancelApplicationResponse.getError().getMessage());
					fail.setMallCd(env.getProperty("naverPay.shop.id"));
					fail.setAccessLicense(env.getProperty("naverPay.access.license"));
					fail.setSecretKey(env.getProperty("naverPay.secret.key"));
					fail.setRegNo(userNo);

					orderDao.createNaverPayErrorLog(fail);
				} catch(Exception e) {
					e.printStackTrace();
				}
			}*/
		}

		return "SUCCESS";
	}

	/**
	 * 네이버페이 반품 완료 정보 송부
	 * @param chnge
	 * @param userNo
	 * @author xodud1202
	 * @since  2021. 06. 27
	 */
	@Transactional("shopTxnManager")
	public String sendNaverPayReturnComplete(Order param, int userNo) throws Exception {
		// Collection<OrderChange> successList = orderChangeDao.approveCancelRequestInfo(param);
		Order change = naverPayDao.getOrderDetailInfoFromOrdDtlNo(param);
		if(change != null && TscConstants.PgGb.NAVER_ORDER.value().equals(change.getPgGb())) {
			Security.addProvider(new BouncyCastleProvider());
			AccessCredentialsType accessCredentialsType = new AccessCredentialsType();
			MallServiceLocator MSL = new MallServiceLocator(env.getProperty("naverPay.port.address"));
			MallServiceSOAP11BindingStub stub = new MallServiceSOAP11BindingStub();

			stub = (MallServiceSOAP11BindingStub) MSL.getMallServiceSOAP11Port();

			ApproveReturnApplicationRequest returnCompleteRequest = null;
			ApproveReturnApplicationResponse returnCompleteResponse = null;

			ReleaseReturnHoldRequest releaseReturnHoldRequest = null;
			ReleaseReturnHoldResponse releaseReturnHoldResponse = null;

			// 반품배송비 결제방법 보류해제 예외 방법
			String passRfdDelPayType = "환불금에서 차감";

			// 반품승인 하기 전 반품배송비결제방법을 확인하여
			// 보류가 걸려있으면 보류를 해제한다. (환불금에서차감 제외)
			//for(OrderChange change : successList) {
			String resultStr = "";
			String[] productOrderIdList = new String[]{change.getNpayOrdDtlNo()};

			// 상품주문상태 조회
			ProductOrderInfo[] productOrderInfo = productOrderInfoList(productOrderIdList);

			if (productOrderInfo != null && productOrderInfo.length > 0) {
				ReturnInfo returnInfo = productOrderInfo[0].getReturnInfo();
				String returnPayType = "";        // 반품배송비 결제방법

				HoldbackStatusType returnHoldStatus = null;

				if (returnInfo != null) {
					if (returnInfo.getHoldbackStatus() != null) {
						returnHoldStatus = returnInfo.getHoldbackStatus();                // 보류 상태 코드
					}

					// 반품배송비 오류 추가
					if (returnInfo.getClaimDeliveryFeePayMethod() != null) {
						returnPayType = returnInfo.getClaimDeliveryFeePayMethod();        // 반품배송비 결제방법
					}
				}

				// if ((returnPayType != null && !returnPayType.equals("")) && (returnHoldStatus.toString() != null && !returnHoldStatus.equals(""))) {
					// 보류중이고 환불금 차감 형식이 아니면 보류해제 처리
					// if ("HOLDBACK".equals(returnHoldStatus.toString()) && !passRfdDelPayType.equals(returnPayType)) {
				
				// 2021.10.08 card007 보류중이면 보류해제 처리로 변경
				if ("HOLDBACK".equals(returnHoldStatus.toString())) {
					param.setRegNo(userNo);
					this.nPayReleaseReturnHold(param);
				}
				// }
			}
			//}

			//for (OrderChange change : successList) {
			// 서명생성
			generateSignature("ApproveReturnApplication", env.getProperty("naverPay.secret.key"));
			log.info("ApproveReturnApplication(반품완료 주문 네이버로 송신) :: timeStamp === " + timeStamp);

			//인증정보
			accessCredentialsType.setAccessLicense(env.getProperty("naverPay.access.license"));
			accessCredentialsType.setSignature(signature);
			accessCredentialsType.setTimestamp(timeStamp);

			returnCompleteRequest = new ApproveReturnApplicationRequest();
			returnCompleteRequest.setAccessCredentials(accessCredentialsType);
			returnCompleteRequest.setDetailLevel("Full");
			returnCompleteRequest.setVersion(env.getProperty("naverPay.version"));
			returnCompleteRequest.setRequestID("");
			returnCompleteRequest.setProductOrderID(change.getNpayOrdDtlNo());
			returnCompleteRequest.setEtcFeeDemandAmount(0);    // 기타 비용 청구 금액

			returnCompleteResponse = stub.approveReturnApplication(returnCompleteRequest);

			resultStr = "";
			if (returnCompleteResponse.getResponseType() != null) {
				resultStr = returnCompleteResponse.getResponseType().toUpperCase();
			}

			if ("SUCCESS".equals(resultStr)) {
				log.info("반품승인 성공 주문번호===>" + change.getOrdNo());
				log.info("반품승인 성공 네이버상품주문번호===>" + change.getNpayOrdDtlNo());
			} else {
				log.info("반품승인 에러");
				log.info("주문번호 ===> " + change.getOrdNo());
				log.info("네이버상품주문번호 ===> " + change.getNpayOrdDtlNo());
				log.info("Code : " + returnCompleteResponse.getError().getCode());
				log.info("Message : " + returnCompleteResponse.getError().getMessage());
				log.info("Detail : " + returnCompleteResponse.getError().getDetail());

				try {
					Order fail = new Order();
					fail.setErrorReason("반품 완료 데이터 송부 에러");
					fail.setOrdNo(change.getOrdNo());
					fail.setNpayOrdDtlNo(change.getNpayOrdDtlNo());
					fail.setOptCd("sendNaverPayReturnComplete");
					fail.setResultCd(returnCompleteResponse.getError().getCode());
					fail.setResultMsg(returnCompleteResponse.getError().getMessage());
					fail.setMallCd(env.getProperty("naverPay.shop.id"));
					fail.setAccessLicense(env.getProperty("naverPay.access.license"));
					fail.setSecretKey(env.getProperty("naverPay.secret.key"));
					fail.setRegNo(userNo);

					orderDao.createNaverPayErrorLog(fail);

					return "FAIL";
				} catch (Exception e) {
					e.printStackTrace();
					return "FAIL";
				}
			}
			//}
		}

		return "SUCCESS";
	}

	/**
	 * 서명생성
	 * @param operationName
	 * @param secreKey
	 * @author xodud1202
	 * @since  2021. 05. 28
	 */
	private void generateSignature(String operationName, String secretKey) {
		timeStamp = SimpleCryptLib.getTimestamp();

		String data = timeStamp + env.getProperty("naverPay.service.name") + operationName;

		try {
			signature = SimpleCryptLib.generateSign(data, secretKey);
		} catch (SignatureException e) {
			log.error(e.getMessage()); //서명정보 실패
		}
	}

	/**
	 * 주문상세 정보 조회
	 * @param productOrderIdList
	 * @return
	 * @author xodud1202
	 * @since  2021. 05. 28
	 */
	@Transactional("shopTxnManager")
	public ProductOrderInfo[] productOrderInfoList(String[] productOrderIdList) {
		ProductOrderInfo[] result =  null;
		try {
			if (productOrderIdList != null) {
				Security.addProvider(new BouncyCastleProvider());
				AccessCredentialsType accessCredentialsType = new AccessCredentialsType();
				MallServiceLocator MSL = new MallServiceLocator(env.getProperty("naverPay.port.address"));
				MallServiceSOAP11BindingStub stub = new MallServiceSOAP11BindingStub();
				stub = (MallServiceSOAP11BindingStub) MSL.getMallServiceSOAP11Port();
				GetProductOrderInfoListRequest request = new GetProductOrderInfoListRequest();
				GetProductOrderInfoListResponse response = new GetProductOrderInfoListResponse();

				//서명생성
				generateSignature("GetProductOrderInfoList", env.getProperty("naverPay.secret.key"));
				log.info("GetProductOrderInfoList(상품주문 내역 상세 조회) :: timeStamp === " + timeStamp);

				//인증정보
				accessCredentialsType.setAccessLicense(env.getProperty("naverPay.access.license"));
				accessCredentialsType.setSignature(signature);
				accessCredentialsType.setTimestamp(timeStamp);

				request.setAccessCredentials(accessCredentialsType);
				request.setDetailLevel("Full");
				request.setVersion(env.getProperty("naverPay.version"));
				request.setRequestID("");
				request.setProductOrderIDList(productOrderIdList);

				//GetChangedProductOrderList Response 수신
				response = stub.getProductOrderInfoList(request);

				String resultStr = "";
				if (response.getResponseType() != null) {
					resultStr = response.getResponseType().toUpperCase();
				}

				//결과 출력
				if ("SUCCESS".equals(resultStr)) {
					result = response.getProductOrderInfoList();
				} else {
					log.info("상품주문내역조회 에러");
					log.info("Code    : " + response.getError().getCode());
					log.info("Message : " + response.getError().getMessage());
					log.info("Detail  : " + response.getError().getDetail());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		log.info("***** productOrderInfoList end *****");

		return result;
	}

	/**
	 * 네이버페이 주문형 배송준비중 주문 정보 조회
	 * @param params
	 * @return Order
	 * @author xodud1202
	 * @since  2021. 05. 28
	 */
	@Transactional("shopTxnManager")
	public Order sendNaverPayReadyDeliveryOrder(Collection<Order> params, Integer userNo) throws Exception {
		Order result = new Order();
		try {
			Security.addProvider(new BouncyCastleProvider());
			AccessCredentialsType accessCredentialsType = new AccessCredentialsType();
			MallServiceLocator MSL = new MallServiceLocator(env.getProperty("naverPay.port.address"));
			MallServiceSOAP11BindingStub stub = new MallServiceSOAP11BindingStub();

			stub = (MallServiceSOAP11BindingStub) MSL.getMallServiceSOAP11Port();

			PlaceProductOrderRequest placeProductOrderRequest 	= null;
			PlaceProductOrderResponse placeProductOrderResponse = null;

			String rcpNm 		= "";
			String rcpTel 		= "";
			String rcpFixAddr 	= "";
			String rcpDtlAddr 	= "";
			String rcpZipCode 	= "";

			int i = 0 ;
			for(Order param : params) {
				param.setAccessLicense(env.getProperty("naverPay.access.license"));
				param.setSecretKey(env.getProperty("naverPay.secret.key"));
				param.setMallCd(env.getProperty("naverPay.shop.id"));

				generateSignature("PlaceProductOrder", param.getSecretKey());

				byte[] encryptKey = SimpleCryptLib.generateKey(timeStamp, param.getSecretKey());

				accessCredentialsType.setAccessLicense(param.getAccessLicense());
				accessCredentialsType.setSignature(signature);
				accessCredentialsType.setTimestamp(timeStamp);

				placeProductOrderRequest = new PlaceProductOrderRequest();
				placeProductOrderRequest.setAccessCredentials(accessCredentialsType);
				placeProductOrderRequest.setDetailLevel("Full");
				placeProductOrderRequest.setVersion(env.getProperty("naverPay.version"));
				placeProductOrderRequest.setRequestID("");
				placeProductOrderRequest.setProductOrderID(String.valueOf(param.getNpayOrdDtlNo()));

				placeProductOrderResponse = stub.placeProductOrder(placeProductOrderRequest);

				String resultStr = "";
				if (placeProductOrderResponse.getResponseType() != null) {
					resultStr = placeProductOrderResponse.getResponseType().toUpperCase();
				}

				//결과 출력
				if ("SUCCESS".equals(resultStr)) {
					//네이버페이에서 배송지 정보가 변경됐으면 주소를 변경해준다.
					if (placeProductOrderResponse.getIsReceiverAddressChanged() != null
							&& placeProductOrderResponse.getIsReceiverAddressChanged()) {

						String[] productOrderIdList = {String.valueOf(param.getNpayOrdDtlNo())};
						ProductOrderInfo[] productOrderInfo = productOrderInfoList(productOrderIdList);

						if(productOrderInfo != null){
							// TEST MALL_ID
							if("istyle24".equals(env.getProperty("naverPay.shop.id"))) {
								// 개발반영
								rcpNm 		= productOrderInfo[0].getProductOrder().getShippingAddress().getName();
								rcpTel 		= productOrderInfo[0].getProductOrder().getShippingAddress().getTel1();
								rcpFixAddr 	= productOrderInfo[0].getProductOrder().getShippingAddress().getBaseAddress();

								if (productOrderInfo[0].getProductOrder().getShippingAddress().getDetailedAddress() != null) {
									rcpDtlAddr = productOrderInfo[0].getProductOrder().getShippingAddress().getDetailedAddress();
								}
							} else {		// 운영 MALL_ID (istyle2424)
								//운영반영시 변경
								rcpNm 		= new String(SimpleCryptLib.decrypt(encryptKey,  productOrderInfo[i].getProductOrder().getShippingAddress().getName()), StandardCharsets.UTF_8);
								rcpTel 		= new String(SimpleCryptLib.decrypt(encryptKey,  productOrderInfo[i].getProductOrder().getShippingAddress().getTel1()), StandardCharsets.UTF_8);
								rcpFixAddr 	= new String(SimpleCryptLib.decrypt(encryptKey,  productOrderInfo[0].getProductOrder().getShippingAddress().getBaseAddress()), StandardCharsets.UTF_8);

								if (productOrderInfo[0].getProductOrder().getShippingAddress().getDetailedAddress() != null) {
									rcpDtlAddr = new String(SimpleCryptLib.decrypt(encryptKey,  productOrderInfo[0].getProductOrder().getShippingAddress().getDetailedAddress()), StandardCharsets.UTF_8);
								}
							}

							rcpZipCode = productOrderInfo[0].getProductOrder().getShippingAddress().getZipCode().replaceAll("-", "");

							Order addr = new Order();
							addr.setOrdDtlNo(param.getOrdDtlNo());
							addr.setRecipNm(rcpNm);
							addr.setRecipPhnno(rcpTel);
							addr.setRecipZipcode(rcpZipCode);
							addr.setRecipBaseAddr(rcpFixAddr);
							addr.setRecipDtlAddr(rcpDtlAddr);
							addr.setDelvMemo(productOrderInfo[i].getProductOrder().getShippingMemo());

							naverPayDao.updateShippingAddressInfo(addr);
						}
					}
				} else {
					log.info("배송준비중 송신 에러");
					log.info("주문번호 ===> " + param.getOrdNo());
					log.info("네이버상품주문번호 ===> " + param.getNpayOrdDtlNo());
					log.info("Code : " + placeProductOrderResponse.getError().getCode());
					log.info("Message : " + placeProductOrderResponse.getError().getMessage());
					log.info("Detail : " + placeProductOrderResponse.getError().getDetail());

					Order fail = new Order();
					fail.setErrorReason("배송준비중 송신 에러");
					fail.setOptCd("sendNaverPayReadyDeliveryOrder");
					fail.setOrdNo(param.getOrdNo());
					fail.setNpayOrdDtlNo(param.getNpayOrdDtlNo());
					fail.setResultCd(placeProductOrderResponse.getError().getCode());
					fail.setResultMsg(placeProductOrderResponse.getError().getMessage());
					fail.setMallCd(param.getMallCd());
					fail.setAccessLicense(param.getAccessLicense());
					fail.setSecretKey(param.getSecretKey());
					fail.setRegNo(userNo);
					try {
						orderDao.createNaverPayErrorLog(fail);
					} catch(Exception e) {
						e.printStackTrace();
					}
				}
				i++;
			}
		} catch (Exception e) {
			log.error("placeProductOrder() error: {} \n {}", e.getMessage(), e);
			throw new IllegalStateException(e.getMessage(), e);
		}
		return result;
	}

	@Transactional("shopTxnManager")
	public Order cancelReqOrderInfo(ChangedProductOrderInfo[] changedProductOrderList, int userNo) throws Exception {
		Order result = new Order();
		log.info("주문취소가 요청 된 건수 = " + changedProductOrderList.length);
		// 어드민 주문취소에 필요한 인자 세팅
		String cancelQty 		= "";
		String companyMngIdx 	= "";
		String localShipIdx 	= "";
		String soldoutCancelYn 	= "";
		List<String> tempProductOrderIdList = new ArrayList<String>();

		Order po = new Order();
		for(ChangedProductOrderInfo orderInfo : changedProductOrderList) {
			po.setNpayOrdDtlNo(orderInfo.getProductOrderID());
			po.setPgGb(TscConstants.PgGb.NAVER_ORDER.value());
			Order detailInfo = naverPayDao.getProductOrderIdInfo(po);
			if(detailInfo != null && detailInfo.getOrdDtlNo() != null && detailInfo.getOrdDtlNo() > 0) {
				tempProductOrderIdList.add(orderInfo.getProductOrderID());
			}
		}

		String[] productOrderIdList = tempProductOrderIdList.toArray(new String[tempProductOrderIdList.size()]);
		ProductOrderInfo[] productOrderInfo = productOrderInfoList(productOrderIdList);

		int isChk, isChk2;
		Order orderInfo;
		if (productOrderInfo != null) {
			for (ProductOrderInfo info : productOrderInfo) {
				Order param = new Order();
				param.setOrdNo(Integer.parseInt(info.getProductOrder().getMerchantCustomCode1()));        // 주문번호
				param.setNpayOrdDtlNo(info.getProductOrder().getProductOrderID());        // 상품주문번호

				// 취소신청, 완료 정보 확인 (네이버페이 주문형은 수량취소 안되는것으로 확인)
				param.setPgGb(TscConstants.PgGb.NAVER_ORDER.value());
				isChk = naverPayDao.getOrdDtlCancelCheck(param);

				// 취소 반려된 데이터인지 확인
				param.setChgGb("COMPANION");        // 반려일 경우
				isChk2 = naverPayDao.getOrdDtlCancelCheck(param);

				// 취소 불가능한 상태인지 확인
				orderInfo = naverPayDao.getProductOrderIdInfo(param);

				if (isChk > 0) {
					log.info("이미 취소완료된 주문입니다.(ordNo) : " + param.getOrdNo() + " , (npayOrdDtlNo) : " + param.getNpayOrdDtlNo());
				} else if (isChk2 > 0) {
					log.info("이미 취소반려된 주문입니다.(ordNo) : " + param.getOrdNo() + " , (npayOrdDtlNo) : " + param.getNpayOrdDtlNo());
				} else if (!TscConstants.OrderDetailStat.PAYMENT_COMPLETE.value().equals(orderInfo.getOrdDtlStat()) && !TscConstants.OrderDetailStat.GOODS_PREPARE.value().equals(orderInfo.getOrdDtlStat()) && !TscConstants.OrderDetailStat.DELIVERY_PREPARE.value().equals(orderInfo.getOrdDtlStat())) {
					log.info("취소 불가능한 상태입니다.(ordNo) : " + param.getOrdNo() + " , (npayOrdDtlNo) : " + param.getNpayOrdDtlNo());
				} else {
					String changeReasonCd = info.getCancelInfo().getCancelReason().getValue();
					param.setChgMemo(info.getCancelInfo().getCancelDetailedReason());

					if("PRODUCT_UNSATISFIED".equals(changeReasonCd)) {
						// 단순변심 (네이버 : 서비스 및 상품 불만족)
						param.setChgReason(TscConstants.OrderCancelReason.CHANGE_CUSTOMER.value());
					} else if("DELAYED_DELIVERY".equals(changeReasonCd)) {
						// 배송 지연
						param.setChgReason(TscConstants.OrderCancelReason.DELAY_ORDER.value());
					} else if ("SOLD_OUT".equals(changeReasonCd)) {
						// 품절 취소
						param.setChgReason(TscConstants.OrderCancelReason.SOLDOUT_CANCEL.value());
					} else if ("INTENT_CHANGED".equals(changeReasonCd)) {
						// 구매 의사 취소
						param.setChgReason(TscConstants.OrderCancelReason.CHANGE_CUSTOMER.value());
					} else if ("COLOR_AND_SIZE".equals(changeReasonCd)) {
						// 색상 및 사이즈 변경
						param.setChgReason(TscConstants.OrderCancelReason.CHANGE_CUSTOMER.value());
					} else if ("WRONG_ORDER".equals(changeReasonCd)) {
						// 다른 상품 잘못 주문
						param.setChgReason(TscConstants.OrderCancelReason.CHANGE_CUSTOMER.value());
					} else if ("INCORRECT_INFO".equals(changeReasonCd)) {
						// 상품정보 상이
						param.setChgReason(TscConstants.OrderCancelReason.INCORRECT_INFO.value());
					} else {
						// 사유 확인 불가 (기타 - 추후 네이버페이 자체 사유 추가에 대비)
						param.setChgReason(TscConstants.OrderCancelReason.ETC.value());
					}

					param.setGoodsCd(info.getProductOrder().getProductID());
					param.setOptCd(info.getProductOrder().getProductOption());

					int[] dtlNoArr = {orderInfo.getOrdDtlNo()};            // 주문상세번호
					int[] cnclQtyArr = {orderInfo.getOrdQty()};            // 취소수량 네이버페이 주문형은 수량 취소 없음. 주문 수량을 취소수량으로 전달

					OrderChange change = new OrderChange();
					change.setOrdNo(param.getOrdNo());
					change.setChgGb(TscConstants.OrderChangeGb.CANCEL.value());        // 주문취소
					change.setChgReason(param.getChgReason());                        // 취소사유
					change.setChgMemo(param.getChgMemo());                            // 취소사유 메모
					change.setUserNo(userNo);                                            // 배치는 0
					change.setOrdDtlNoArr(dtlNoArr);                                // 주문상세번호배열
					change.setCnclRtnReqQtyArr(cnclQtyArr);                            // 취소수량배열
					orderChangeService.cancelRequest(change);                        // 취소접수처리
				}
			}
		}

		return result;
	}

	/**
	 * 네이버페이 주문형 배송준비중 주문 정보 조회
	 * @param time
	 * @return Collection
	 * @author xodud1202
	 * @since  2021. 06. 14
	 */
	public Collection<Order> getReadyDeliveryList(Order time) {
		time.setPgGb(TscConstants.PgGb.NAVER_ORDER.value());
		time.setOrdDtlStat(TscConstants.OrderDetailStat.DELIVERY_PREPARE.value());
		return naverPayDao.getReadyDeliveryList(time);
	}

	public String sendScmServerForNaverpay(String urlQueryString) {
		try {
			// TSIT 서버에서만 SSL 미적용.
			String protocol = "";
			if ("tsit".equals(env.getProperty("spring.profiles.active")) || "locd".equals(env.getProperty("spring.profiles.active"))) {
				protocol = "http:";
			} else {
				protocol = "https:";
			}
			log.info("SEND SCM URL ::::: {}", protocol + env.getProperty("domain.scm") + urlQueryString);
			URL url = new URL(protocol + env.getProperty("domain.scm") + urlQueryString);
			HttpURLConnection urlCon = (HttpURLConnection) url.openConnection();
			urlCon.setUseCaches(false);
			urlCon.setDoOutput(true);
			urlCon.setRequestMethod("GET");
			urlCon.setDoInput(true);

			/*BufferedReader reader = new BufferedReader(new InputStreamReader(urlCon.getInputStream()));*/

			// 응답 내용(BODY) 구하기
			try (InputStream in = urlCon.getInputStream();
				 ByteArrayOutputStream out = new ByteArrayOutputStream()) {
				byte[] buf = new byte[1024 * 8];
				int length = 0;
				while ((length = in.read(buf)) != -1) {
					out.write(buf, 0, length);
				}
				log.info("NAVERPAY RESULT MESSAGE ::::: " + out.toString("UTF-8"));

				if (!"SUCCESS".equals(out.toString("UTF-8"))) {
					Gson gson = new Gson();
					GagaMap rtn = new GagaMap();

					try {
						rtn = gson.fromJson(out.toString("UTF-8"), GagaMap.class);
					} catch (Exception e) {
						return "네이버페이 송부 실패";
					}

					log.info("status >>> {}", rtn.getString("status"));
					log.info("message >>> {}", rtn.getString("message"));
					if (!"SUCCESS".equals(rtn.getString("status"))) {
						return rtn.getString("message");
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			urlCon.disconnect();
		} catch (Exception e) {
			return "네이버페이 송부 실패";
		}

		return "SUCCESS";
	}

	public Order getOrderDetailInfoFromOrdDtlNo(Order param) {
		return naverPayDao.getOrderDetailInfoFromOrdDtlNo(param);
	}

	/**
	 * 네이버페이 주문형 교환보류 요청
	 * 
	 * @param OrderChange
	 * @return int
	 * @author card007
	 * @since 2021. 10. 05
	 */
	@Transactional("shopTxnManager")
	public int nPayExchangeHold(Order order) {
		Order info 				= naverPayDao.getOrderDetailInfoFromOrdDtlNo(order);
		String npayOrdDtlNo 	= info.getNpayOrdDtlNo();
		String pgGb 			= info.getPgGb();
		Integer ordNo 			= info.getOrdNo();
		Integer regNo			= order.getRegNo();

		try {
			Security.addProvider(new BouncyCastleProvider());
			AccessCredentialsType accessCredentialsType = new AccessCredentialsType();
			MallServiceLocator MSL = new MallServiceLocator(env.getProperty("naverPay.port.address"));
			MallServiceSOAP11BindingStub stub = (MallServiceSOAP11BindingStub)MSL.getMallServiceSOAP11Port();

			WithholdExchangeRequest withholdExchangeRequest = new WithholdExchangeRequest();
			WithholdExchangeResponse withholdExchangeResponse = new WithholdExchangeResponse();

			if (order != null && TscConstants.PgGb.NAVER_ORDER.value().equals(pgGb)) {
				// 서명생성
				generateSignature("WithholdExchange", env.getProperty("naverPay.secret.key"));
				log.info("WithholdExchange(교환보류 네이버로 송신) :: timeStamp === " + timeStamp);

				//인증정보
				accessCredentialsType.setAccessLicense(env.getProperty("naverPay.access.license"));
				accessCredentialsType.setSignature(signature);
				accessCredentialsType.setTimestamp(timeStamp);

				withholdExchangeRequest.setAccessCredentials(accessCredentialsType);
				withholdExchangeRequest.setDetailLevel("Full");
				withholdExchangeRequest.setVersion(env.getProperty("naverPay.version"));
				withholdExchangeRequest.setRequestID("");
				withholdExchangeRequest.setProductOrderID(npayOrdDtlNo);					// 상품 주문 번호
				withholdExchangeRequest.setExchangeHoldCode(HoldbackClassType.ETC);			// 교환 보류 타입 코드
				withholdExchangeRequest.setExchangeHoldDetailContent("기타사유");				// 교환 보류 상세 사유
				// withholdExchangeRequest.setEtcFeeDemandAmount(0);							// 기타 교환 비용


				withholdExchangeResponse = stub.withholdExchange(withholdExchangeRequest);

				String resultStr = "";
				if (withholdExchangeResponse.getResponseType() != null) {
					resultStr = withholdExchangeResponse.getResponseType().toUpperCase();
				}

				if ("SUCCESS".equals(resultStr)) {
					log.info("교환보류 성공 주문번호===>" + ordNo);
					log.info("교환보류 성공 네이버상품주문번호===>" + npayOrdDtlNo);
				} else {
					log.info("교환보류 에러");
					log.info("주문번호 ===>" + ordNo);
					log.info("네이버상품주문번호 ===> " + npayOrdDtlNo);
					log.info("Code : " + withholdExchangeResponse.getError().getCode());
					log.info("Message : " + withholdExchangeResponse.getError().getMessage());
					log.info("Detail : " + withholdExchangeResponse.getError().getDetail());

					Order fail = new Order();
					fail.setErrorReason("교환보류 데이터 송부 에러");
					fail.setOrdNo(ordNo);
					fail.setNpayOrdDtlNo(npayOrdDtlNo);
					fail.setOptCd("WithholdExchange");
					fail.setResultCd(withholdExchangeResponse.getError().getCode());
					fail.setResultMsg(withholdExchangeResponse.getError().getMessage());
					fail.setMallCd(env.getProperty("naverPay.shop.id"));
					fail.setAccessLicense(env.getProperty("naverPay.access.license"));
					fail.setSecretKey(env.getProperty("naverPay.secret.key"));
					fail.setRegNo(regNo);

					orderDao.createNaverPayErrorLog(fail);

					return 0;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}

		return 1;
	}

	/**
	 * 네이버페이 주문형 교환보류 해제 요청
	 *
	 * @param OrderChange
	 * @return int
	 * @author card007
	 * @since 2021. 10. 05
	 */
	@Transactional("shopTxnManager")
	public int nPayReleaseExchangeHold(Order order) {
		Order info 				= naverPayDao.getOrderDetailInfoFromOrdDtlNo(order);
		String npayOrdDtlNo 	= info.getNpayOrdDtlNo();
		String pgGb 			= info.getPgGb();
		Integer ordNo 			= info.getOrdNo();
		Integer regNo			= order.getRegNo();

		try {
			Security.addProvider(new BouncyCastleProvider());
			AccessCredentialsType accessCredentialsType = new AccessCredentialsType();
			MallServiceLocator MSL = new MallServiceLocator(env.getProperty("naverPay.port.address"));
			MallServiceSOAP11BindingStub stub = (MallServiceSOAP11BindingStub)MSL.getMallServiceSOAP11Port();

			ReleaseExchangeHoldRequest releaseExchangeHoldRequest = new ReleaseExchangeHoldRequest();
			ReleaseExchangeHoldResponse releaseExchangeHoldResponse = new ReleaseExchangeHoldResponse();

			if (order != null && TscConstants.PgGb.NAVER_ORDER.value().equals(pgGb)) {
				// 서명생성
				generateSignature("ReleaseExchangeHold", env.getProperty("naverPay.secret.key"));
				log.info("ReleaseExchangeHold(교환보류 해제 네이버로 송신) :: timeStamp === " + timeStamp);

				//인증정보
				accessCredentialsType.setAccessLicense(env.getProperty("naverPay.access.license"));
				accessCredentialsType.setSignature(signature);
				accessCredentialsType.setTimestamp(timeStamp);

				releaseExchangeHoldRequest.setAccessCredentials(accessCredentialsType);
				releaseExchangeHoldRequest.setDetailLevel("Full");
				releaseExchangeHoldRequest.setVersion(env.getProperty("naverPay.version"));
				releaseExchangeHoldRequest.setRequestID("");
				releaseExchangeHoldRequest.setProductOrderID(npayOrdDtlNo);					// 상품 주문 번호

				releaseExchangeHoldResponse = stub.releaseExchangeHold(releaseExchangeHoldRequest);

				String resultStr = "";
				if (releaseExchangeHoldResponse.getResponseType() != null) {
					resultStr = releaseExchangeHoldResponse.getResponseType().toUpperCase();
				}

				if ("SUCCESS".equals(resultStr)) {
					log.info("교환보류 해제 성공 주문번호===>" + ordNo);
					log.info("교환보류 해제 성공 네이버상품주문번호===>" + npayOrdDtlNo);
				} else {
					log.info("교환보류 해제 에러");
					log.info("주문번호 ===>" + ordNo);
					log.info("네이버상품주문번호 ===> " + npayOrdDtlNo);
					log.info("Code : " + releaseExchangeHoldResponse.getError().getCode());
					log.info("Message : " + releaseExchangeHoldResponse.getError().getMessage());
					log.info("Detail : " + releaseExchangeHoldResponse.getError().getDetail());

					Order fail = new Order();
					fail.setErrorReason("교환보류 해제 데이터 송부 에러");
					fail.setOrdNo(ordNo);
					fail.setNpayOrdDtlNo(npayOrdDtlNo);
					fail.setOptCd("ReleaseExchangeHold");
					fail.setResultCd(releaseExchangeHoldResponse.getError().getCode());
					fail.setResultMsg(releaseExchangeHoldResponse.getError().getMessage());
					fail.setMallCd(env.getProperty("naverPay.shop.id"));
					fail.setAccessLicense(env.getProperty("naverPay.access.license"));
					fail.setSecretKey(env.getProperty("naverPay.secret.key"));
					fail.setRegNo(regNo);

					orderDao.createNaverPayErrorLog(fail);

					return 0;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}

		return 1;
	}

	/**
	 * 네이버페이 주문형 반품보류 요청
	 *
	 * @param OrderChange
	 * @return int
	 * @author card007
	 * @since 2021. 10. 05
	 */
	@Transactional("shopTxnManager")
	public int nPayReturnHold(Order order) {
		Order info 				= naverPayDao.getOrderDetailInfoFromOrdDtlNo(order);
		String npayOrdDtlNo 	= info.getNpayOrdDtlNo();
		String pgGb 			= info.getPgGb();
		Integer ordNo 			= info.getOrdNo();
		Integer regNo			= order.getRegNo();

		try {
			Security.addProvider(new BouncyCastleProvider());
			AccessCredentialsType accessCredentialsType = new AccessCredentialsType();
			MallServiceLocator MSL = new MallServiceLocator(env.getProperty("naverPay.port.address"));
			MallServiceSOAP11BindingStub stub = (MallServiceSOAP11BindingStub)MSL.getMallServiceSOAP11Port();

			WithholdReturnRequest withholdReturnRequest = new WithholdReturnRequest();
			WithholdReturnResponse withholdReturnResponse = new WithholdReturnResponse();

			if (order != null && TscConstants.PgGb.NAVER_ORDER.value().equals(pgGb)) {
				// 서명생성
				generateSignature("WithholdReturn", env.getProperty("naverPay.secret.key"));
				log.info("WithholdReturn(교환보류 네이버로 송신) :: timeStamp === " + timeStamp);

				//인증정보
				accessCredentialsType.setAccessLicense(env.getProperty("naverPay.access.license"));
				accessCredentialsType.setSignature(signature);
				accessCredentialsType.setTimestamp(timeStamp);

				withholdReturnRequest.setAccessCredentials(accessCredentialsType);
				withholdReturnRequest.setDetailLevel("Full");
				withholdReturnRequest.setVersion(env.getProperty("naverPay.version"));
				withholdReturnRequest.setRequestID("");
				withholdReturnRequest.setProductOrderID(npayOrdDtlNo);						// 상품 주문 번호
				withholdReturnRequest.setReturnHoldCode(HoldbackClassType.ETC);				// 반품 보류 타입 코드
				withholdReturnRequest.setReturnHoldDetailContent("기타사유");					// 반품 보류 상세 사유
				// withholdReturnRequest.setEtcFeeDemandAmount(0);							// 기타 교환 비용


				withholdReturnResponse = stub.withholdReturn(withholdReturnRequest);

				String resultStr = "";
				if (withholdReturnResponse.getResponseType() != null) {
					resultStr = withholdReturnResponse.getResponseType().toUpperCase();
				}

				if ("SUCCESS".equals(resultStr)) {
					log.info("반품보류 성공 주문번호===>" + ordNo);
					log.info("반품보류 성공 네이버상품주문번호===>" + npayOrdDtlNo);
				} else {
					log.info("반품보류 에러");
					log.info("주문번호 ===>" + ordNo);
					log.info("네이버상품주문번호 ===> " + npayOrdDtlNo);
					log.info("Code : " + withholdReturnResponse.getError().getCode());
					log.info("Message : " + withholdReturnResponse.getError().getMessage());
					log.info("Detail : " + withholdReturnResponse.getError().getDetail());

					Order fail = new Order();
					fail.setErrorReason("반품보류 데이터 송부 에러");
					fail.setOrdNo(ordNo);
					fail.setNpayOrdDtlNo(npayOrdDtlNo);
					fail.setOptCd("WithholdReturn");
					fail.setResultCd(withholdReturnResponse.getError().getCode());
					fail.setResultMsg(withholdReturnResponse.getError().getMessage());
					fail.setMallCd(env.getProperty("naverPay.shop.id"));
					fail.setAccessLicense(env.getProperty("naverPay.access.license"));
					fail.setSecretKey(env.getProperty("naverPay.secret.key"));
					fail.setRegNo(regNo);

					orderDao.createNaverPayErrorLog(fail);

					return 0;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}

		return 1;
	}

	/**
	 * 네이버페이 주문형 반품보류 해제 요청
	 *
	 * @param OrderChange
	 * @return int
	 * @author card007
	 * @since 2021. 10. 08
	 */
	@Transactional("shopTxnManager")
	public int nPayReleaseReturnHold(Order order) {
		Order info 				= naverPayDao.getOrderDetailInfoFromOrdDtlNo(order);
		String npayOrdDtlNo 	= info.getNpayOrdDtlNo();
		String pgGb 			= info.getPgGb();
		Integer ordNo 			= info.getOrdNo();
		Integer regNo			= order.getRegNo();

		try {
			Security.addProvider(new BouncyCastleProvider());
			AccessCredentialsType accessCredentialsType = new AccessCredentialsType();
			MallServiceLocator MSL = new MallServiceLocator(env.getProperty("naverPay.port.address"));
			MallServiceSOAP11BindingStub stub = (MallServiceSOAP11BindingStub)MSL.getMallServiceSOAP11Port();

			ReleaseReturnHoldRequest releaseReturnHoldRequest = new ReleaseReturnHoldRequest();
			ReleaseReturnHoldResponse releaseReturnHoldResponse = new ReleaseReturnHoldResponse();

			if (order != null && TscConstants.PgGb.NAVER_ORDER.value().equals(pgGb)) {
				// 서명생성
				generateSignature("ReleaseReturnHold", env.getProperty("naverPay.secret.key"));
				log.info("ReleaseReturnHold(반품보류 해제 네이버로 송신) :: timeStamp === " + timeStamp);

				//인증정보
				accessCredentialsType.setAccessLicense(env.getProperty("naverPay.access.license"));
				accessCredentialsType.setSignature(signature);
				accessCredentialsType.setTimestamp(timeStamp);

				releaseReturnHoldRequest.setAccessCredentials(accessCredentialsType);
				releaseReturnHoldRequest.setDetailLevel("Full");
				releaseReturnHoldRequest.setVersion(env.getProperty("naverPay.version"));
				releaseReturnHoldRequest.setRequestID("");
				releaseReturnHoldRequest.setProductOrderID(npayOrdDtlNo);					// 상품 주문 번호

				releaseReturnHoldResponse = stub.releaseReturnHold(releaseReturnHoldRequest);

				String resultStr = "";
				if (releaseReturnHoldResponse.getResponseType() != null) {
					resultStr = releaseReturnHoldResponse.getResponseType().toUpperCase();
				}

				if ("SUCCESS".equals(resultStr)) {
					log.info("반품보류 해제 성공 주문번호===>" + ordNo);
					log.info("반품보류 해제 성공 네이버상품주문번호===>" + npayOrdDtlNo);
				} else {
					log.info("반품보류 해제 에러");
					log.info("주문번호 ===>" + ordNo);
					log.info("네이버상품주문번호 ===> " + npayOrdDtlNo);
					log.info("Code : " + releaseReturnHoldResponse.getError().getCode());
					log.info("Message : " + releaseReturnHoldResponse.getError().getMessage());
					log.info("Detail : " + releaseReturnHoldResponse.getError().getDetail());

					Order fail = new Order();
					fail.setErrorReason("반품보류 해제 데이터 송부 에러");
					fail.setOrdNo(ordNo);
					fail.setNpayOrdDtlNo(npayOrdDtlNo);
					fail.setOptCd("ReleaseReturnHold");
					fail.setResultCd(releaseReturnHoldResponse.getError().getCode());
					fail.setResultMsg(releaseReturnHoldResponse.getError().getMessage());
					fail.setMallCd(env.getProperty("naverPay.shop.id"));
					fail.setAccessLicense(env.getProperty("naverPay.access.license"));
					fail.setSecretKey(env.getProperty("naverPay.secret.key"));
					fail.setRegNo(regNo);

					orderDao.createNaverPayErrorLog(fail);

					return 0;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}

		return 1;
	}

	/**
	 * 네이버페이 주문형 반품/교환 보류 여부 수정
	 * 
	 * @param Order
	 * @return int
	 * @author card007
	 * @since 2021. 10. 05
	 */
	public int updateNaverPayChangeHold(Order order) {
		return naverPayDao.updateNaverPayChangeHold(order);
	}
}
