package com.style24.core.biz.service;

import java.lang.reflect.Field;
import java.nio.charset.Charset;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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

import com.gagaframework.web.parameter.GagaMap;
import com.kcp.J_PP_CLI_N;
import com.style24.core.biz.dao.TscOrderDao;
import com.style24.core.support.env.TscConstants;
import com.style24.persistence.domain.CustAccount;
import com.style24.persistence.domain.GiftCard;
import com.style24.persistence.domain.Order;
import com.style24.persistence.domain.Payment;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class TscKcpService {
	@Autowired
	private Environment env;

	@Autowired
	private TscOrderDao orderDao;

	public String f_get_parm(String val) {
		if ( val == null ) val = "";
		return  val;
	}

	public Payment kcpPayRequest(Payment param, HttpServletRequest request, HttpServletResponse response) throws Exception {
		Payment result = new Payment();

		// 01. characterEncoding EUC-KR 세팅
		request.setCharacterEncoding("euc-kr");

		if (!"POST".equals(request.getMethod())) {
			throw new IllegalArgumentException("잘못된 경로로 접속하셨습니다.");
		}

		String pgOrdNo = request.getParameter("ordr_idxx");
		if(pgOrdNo.contains("C")) {
			int orgChgSq = Integer.parseInt(pgOrdNo.replaceAll("C", ""));
			Order tmp = new Order();
			tmp.setOrdChgSq(orgChgSq);
			result.setOrdNo(orderDao.getOrdChgSqToOrdNo(tmp).getOrdNo());
			result.setOrdChgSq(orgChgSq);
		} else {
			result.setOrdNo(Integer.parseInt(pgOrdNo));
		}

		// 02. 지불 요청 정보 설정
		// result.setOrdNo(request.getParameter("ordr_idxx"));
		result.setPgGb(param.getPgGb());
		result.setPayMeans(param.getPayMeans());
		result.setReqTx(request.getParameter("req_tx"));
		result.setTranCd(request.getParameter("tran_cd"));
		result.setUsePayMethod(request.getParameter("use_pay_method"));
		result.setPgShopId(env.getProperty("pg.kcp.site.cd"));
		result.setPgShopKey(env.getProperty("pg.kcp.site.key"));
		result.setPayStat(TscConstants.PaymentStat.PAYMENT_COMPLETE.value());

		// 03. 인스턴스 생성 및 초기화(변경 불가) (결제에 필요한 인스턴스를 생성하고 초기화 합니다.)
		J_PP_CLI_N c_PayPlus = new J_PP_CLI_N();
		c_PayPlus.mf_init("", env.getProperty("pg.kcp.gw.url"), env.getProperty("pg.kcp.gw.port"), Integer.parseInt(env.getProperty("pg.kcp.tx.mode")), env.getProperty("pg.kcp.log.dir"));
		c_PayPlus.mf_init_set();

		// 04-1. 승인 요청 정보 설정
		if ("pay".equals(result.getReqTx())){
			c_PayPlus.mf_set_enc_data(f_get_parm(request.getParameter("enc_data" )), f_get_parm(request.getParameter("enc_info")));

			/* 1원은 실제로 업체에서 결제하셔야 될 원 금액을 넣어주셔야 합니다. 결제금액 유효성 검증 */
			int ordr_data_set_no = c_PayPlus.mf_add_set("ordr_data");
			c_PayPlus.mf_set_us(ordr_data_set_no, "ordr_mony", request.getParameter("good_mny"));
		}

		// 05. 실행
		if (result.getTranCd().length() > 0) {			
			c_PayPlus.mf_do_tx(result.getPgShopId(), result.getPgShopKey(), result.getTranCd(), "", pgOrdNo, env.getProperty("pg.kcp.log.level"), "1");
		} else {
			c_PayPlus.m_res_cd  = "9562";
			c_PayPlus.m_res_msg = "연동 오류|tran_cd값이 설정되지 않았습니다.";
		}

		log.info("CHECK KCP RESULT :::: {}", c_PayPlus.getRecvObj().toString());

		result.setResCd(c_PayPlus.m_res_cd);		// 결과 코드
		result.setResMsg(c_PayPlus.m_res_msg);		// 결과 메시지

		// 06. 승인 결과 값 추출
		if ("pay".equals(result.getReqTx())) {
			if ("0000".equals(result.getResCd())) {
				result.setPgTid(c_PayPlus.mf_get_res("tno"));							// KCP 거래 고유 번호
				//result.setPntIssue(c_PayPlus.mf_get_res("pnt_issue"));					// 결제 포인트사 코드
				result.setPayAmt(Integer.parseInt(c_PayPlus.mf_get_res("amount")));		// KCP 실제 거래 금액
				result.setPgCpnAmt(c_PayPlus.mf_get_res("coupon_mny").isEmpty() ? 0 : Integer.parseInt(c_PayPlus.mf_get_res("coupon_mny")));    // 쿠폰 할인금액
				result.setPgGb(TscConstants.PgGb.KCP.value());

				if ("100000000000".equals(result.getUsePayMethod())) {
					// 06-1. 신용카드 승인 결과 처리
					result.setCardCd(c_PayPlus.mf_get_res("card_cd"));			// 카드명. 결제수단이 "30:신용카드"일 때 사용. PG사에서 받은 값
					result.setCardNm(c_PayPlus.mf_get_res("card_name"));			// 카드명. 결제수단이 "30:신용카드"일 때 사용. PG사에서 받은 값
					result.setPayDt(c_PayPlus.mf_get_res("app_time"));			// 승인 시간
					result.setPgTradeNo(c_PayPlus.mf_get_res("app_no"));			// PG거래번호(승인번호)
					result.setCardMips(c_PayPlus.mf_get_res("quota"));			// 할부개월수
					//noinf = c_PayPlus.mf_get_res("noinf"); // 무이자 여부
					result.setCardPcableYn(c_PayPlus.mf_get_res("partcanc_yn"));	// 부분취소 가능유무
					// N : 신용카드, Y : 체크카드, G 기프트카드 (기프트카드는 어떻게 입력해야할지 ?)
					// result.setCardType("0".equals(c_PayPlus.mf_get_res("card_bin_type_02")) ? "N" : "Y");		>> 사용안함. 20210419
					result.setPayMeans(TscConstants.PayMeans.CREDIT_CARD.value());
				} else if ("010000000000".equals(result.getUsePayMethod())) {
					// 06-2. 실시간 계좌이체 승인 결과 처리
					result.setPayDt(c_PayPlus.mf_get_res("app_time"));			// 승인 시간
					result.setCashAuthNo(c_PayPlus.mf_get_res("cash_authno"));	// 현금영수증 승인번호
					result.setCashTradeNo(c_PayPlus.mf_get_res("cash_no"));		// 현금영수증 거래번호
					result.setVaBank(c_PayPlus.mf_get_res("bank_code").replaceAll("BK", ""));	// 입금 은행 코드(공통코드 G940)
					result.setBankNm(c_PayPlus.mf_get_res("bank_name"));			// 은행명 (보증보험에서 사용)
					result.setPayMeans(TscConstants.PayMeans.ACCOUNT_TRANSFER.value());
				} else if ("001000000000".equals(result.getUsePayMethod())) {
					// 06-3. 가상계좌 승인 결과 처리 (현금영수증은 입금완료 noti에서 입력)
					result.setVaNm(c_PayPlus.mf_get_res("va_name"));					// 입금할 계좌 예금주
					result.setVaNo(c_PayPlus.mf_get_res("account"));					// 입금할 계좌 번호
					result.setVaBank(c_PayPlus.mf_get_res("bankcode").replaceAll("BK", ""));	// 입금 은행 코드(공통코드 G940)
					result.setVaDeadline(c_PayPlus.mf_get_res("va_date"));			// 가상계좌 입금마감시간
					result.setBankNm(c_PayPlus.mf_get_res("bankname"));			// 은행명 (보증보험에서 사용)
					result.setPayStat(TscConstants.PaymentStat.DEPOSIT_BEFORE_BANKING.value());	// 결제대기
					result.setPayMeans(TscConstants.PayMeans.BANK_DEPOSIT.value());
				} else if ("000010000000".equals(result.getUsePayMethod())) {
					// 06-4. 휴대폰 승인 결과 처리
					result.setPayDt(c_PayPlus.mf_get_res("hp_app_time"));		// 승인시간
					result.setTelecom(c_PayPlus.mf_get_res("commid"));			// 통신사코드
					result.setPayMeans(TscConstants.PayMeans.CELL_PHONE.value());
				}

				// PC 버전 페이코 확인
				if(StringUtils.isNotBlank(param.getPgGb()) && TscConstants.PgGb.PAYCO.value().equals(param.getPgGb())) {
					result.setPgGb(TscConstants.PgGb.PAYCO.value());
					result.setPayMeans(TscConstants.PayMeans.CREDIT_CARD.value());
				}

				// 모바일버전 페이코 확인
				if(!TscConstants.FrontGb.PC.value().equals(param.getFrontGb())) {
					String pgGb = request.getParameter("param_opt_1");
					if(StringUtils.isNotBlank(pgGb) && TscConstants.PgGb.PAYCO.value().equals(pgGb)) {
						result.setPgGb(TscConstants.PgGb.PAYCO.value());
						result.setPayMeans(TscConstants.PayMeans.CREDIT_CARD.value());
					}
				}

				String shopUserId = String.valueOf(c_PayPlus.getRecvObj().get("shop_user_id"));
				log.info("CHECK SHOP_USER_ID ::::: {}", shopUserId);
				if(StringUtils.isNotBlank(shopUserId) && !"null".equals(shopUserId)) {
					result.setCustNo(Integer.parseInt(shopUserId));
					result.setRegNo(Integer.parseInt(shopUserId));
					result.setUpdNo(Integer.parseInt(shopUserId));
				}
			} else {
				log.error("KCP ERROR RESULT :::: {}, {}", result.getResCd(), result.getResMsg());
				throw new IllegalArgumentException("결제 실패하였습니다.");
			}
		}

		return result;
	}

	public Payment setKcpOrderData(Order order) {
		if(order.getOrdChgSq() != null && order.getOrdChgSq() > 0) {
			order.setPgOrdNo("C" + order.getOrdChgSq());
		} else {
			order.setPgOrdNo(String.valueOf(order.getOrdNo()));
		}

		Payment payment = new Payment();
		// KCP 주문요청 공통 데이터
		payment.setReqTx("pay");						// 필수 (주문시 only "pay")
		payment.setOrdrIdxx(order.getPgOrdNo());		// 필수
		payment.setGoodName(order.getGoodsNm());		// 필수
		payment.setGoodMny(order.getPayAmt());			// 필수
		payment.setBuyrName(order.getOrdNm());			// 필수
		payment.setBuyrMail(order.getOrdEmail());		// 선택
		payment.setBuyrTel1(order.getOrdTelno());		// 선택, 일반 전화번호
		payment.setBuyrTel2(order.getOrdPhnno());		// 필수, 휴대폰번호
		payment.setShopUserId(order.getCustNo());		// 필수, 쇼핑몰회원ID (CUST_NO)
		payment.setCustNo(order.getCustNo());
		// KCP 공통 변경되지 않는 값
		payment.setSiteCd(env.getProperty("pg.kcp.site.cd"));		// 상점코드
		payment.setSiteName(env.getProperty("pg.kcp.site.name"));	// 상점 이름 (영문 작성 권장)
		payment.setModuleType(env.getProperty("pg.kcp.module.type"));
		payment.setGoodExpr("0");									// 제공 기간 설정 0:일회성 1:기간설정(ex 1:2012010120120131)

		if(TscConstants.FrontGb.PC.value().equals(order.getFrontGb())) {
			payment.setCurrency("WON");						// 필수, 원화 : WON, 달러 : USD
			if(TscConstants.PgGb.PAYCO.value().equals(order.getPgGb())) {	// 페이코
				payment.setPaycoDirect("Y");				// 페이코 직접 호출
				payment.setPayMthod( "100000000000");		// 직접 호출시 필요 데이터
				payment.setPayMethod("100000000000");		// 카드
			} else if(order.getPayMeans() != null && TscConstants.PayMeans.CREDIT_CARD.value().equals(order.getPayMeans())) {		// KCP 카드
				payment.setPayMethod("100000000000");		// 카드
				payment.setQuotaopt(12);					// 최대 할부 개월 수
			} else if(order.getPayMeans() != null && TscConstants.PayMeans.BANK_DEPOSIT.value().equals(order.getPayMeans())) {		// KCP 가상계좌(무통장입금)
				payment.setPayMethod("001000000000");		// 가상계좌
				payment.setVcntExpireTerm(2);				// 무통장입금 유효기간
			} else if(order.getPayMeans() != null && TscConstants.PayMeans.ACCOUNT_TRANSFER.value().equals(order.getPayMeans())) {	// KCP 계좌이체(실시간계좌이체)
				payment.setPayMethod("010000000000");		// 계좌이체
			} else if(order.getPayMeans() != null && TscConstants.PayMeans.CELL_PHONE.value().equals(order.getPayMeans())) {		// KCP 휴대폰결제
				payment.setPayMethod("000010000000");		// 휴대폰결제
			}
		} else {
			payment.setCurrency("410");						// 필수, 원화 : 410
			if(TscConstants.PgGb.PAYCO.value().equals(order.getPgGb())) {	// 페이코
				payment.setPaycoDirect("Y");				// 페이코 직접 호출
				payment.setPayMthod("CARD");				// 직접 호출시 필요 데이터
				payment.setPayMethod("CARD");				// 카드
				payment.setActionResult("card");			// 카드
			} else if(order.getPayMeans() != null && TscConstants.PayMeans.CREDIT_CARD.value().equals(order.getPayMeans())) {		// KCP 카드
				payment.setPayMethod("CARD");				// 카드
				payment.setActionResult("card");			// 카드
				payment.setQuotaopt(12);					// 최대 할부 개월 수
			} else if(order.getPayMeans() != null && TscConstants.PayMeans.BANK_DEPOSIT.value().equals(order.getPayMeans())) {		// KCP 가상계좌(무통장입금)
				payment.setPayMethod("VCNT");				// 가상계좌
				payment.setActionResult("vcnt");			// 가상계좌
				payment.setVcntExpireTerm(3);				// 무통장입금 유효기간
			} else if(order.getPayMeans() != null && TscConstants.PayMeans.ACCOUNT_TRANSFER.value().equals(order.getPayMeans())) {	// KCP 계좌이체(실시간계좌이체)
				payment.setPayMethod("BANK");				// 계좌이체
				payment.setActionResult("acnt");			// 계좌이체
				payment.setAppUrl(env.getProperty("pg.kcp.app.url"));			// KCP IOS 실시간계좌이체 송부 APP URL
			} else if(order.getPayMeans() != null && TscConstants.PayMeans.CELL_PHONE.value().equals(order.getPayMeans())) {		// KCP 휴대폰결제
				payment.setPayMethod("MOBX");				// 휴대폰결제
				payment.setActionResult("mobx");			// 휴대폰결제
			}
		}

		payment.setOrgOrdNo(order.getOrdNo());

		return payment;
	}

	/**
	 * KCP 취소 (pgTid, regNo, updNo)
	 * ** 주문 로직 진행 중 에러로 인한 취소
	 * result.setPayStat(TscConstants.PaymentStat.DB_FAIL.value());
	 * result.setPayGb("E");	// O:주문시결제, D:배송시결제, E:에러(강제 결제 태울 때 또는 에러일 때)
	 * result.setModType("STSC");
	 * result.setModDesc("가맹점 결과 처리 오류 - 가맹점에서 취소 요청");
	 *
	 * ** 전체취소 필요 정보
	 * param.setPayStat(TscConstants.PaymentStat.PAYMENT_CANCEL.value());
	 * param.setPayGb("O");				// O:주문시결제, D:배송시결제, E:에러(강제 결제 태울 때 또는 에러일 때)
	 * param.setModType("STSC");		// 전체취소
	 * param.setModDesc("가맹점 취소 - 전체 취소");
	 *
	 * ** 부분취소 필요 정보
	 * param.setPayStat(TscConstants.PaymentStat.PAYMENT_CANCEL.value());
	 * param.setPayGb("O");				// O:주문시결제, D:배송시결제, E:에러(강제 결제 태울 때 또는 에러일 때)
	 * param.setModType("STPC");
	 * param.setModDesc("가맹점 취소 - 부분 취소");
	 * param.setLeftAmt(100000);		// 취소 전 잔여금액
	 * param.setPartCancelAmt(30000);	// 부분취소금액
	 *
	 * ** 무통장입금 입금 후 전체 취소 (전체취소 필요 정보에서 아래 정보 추가)
	 * param.setModType("STHD");			// 전체환불
	 * param.setBankCd("88");				// 계좌은행(공통코드G940). 결제수단이 "20:무통장입금일" 때 사용
	 * param.setAccountNm("테스터");		// 환불계좌 예금주명
	 * param.setAccountNo("110111111111");	// 환불계좌번호
	 *
	 * ** 무통장입금 입금 후 부분 취소 (부분취소 필요 정보에서 아래 정보 추가)
	 * param.setModType("STPD");			// 부분환불
	 * param.setBankCd("88");				// 계좌은행(공통코드G940). 결제수단이 "20:무통장입금일" 때 사용
	 * param.setAccountNm("테스터");		// 환불계좌 예금주명
	 * param.setAccountNo("110111111111")	// 환불계좌번호
	 *
	 * @param param
	 * @param request
	 */
	@Transactional("shopTxnManager")
	public void kcpCancel(Payment param) {
		int ordChgSq = param.getOrdChgSq();
		// try {	request.setCharacterEncoding("euc-kr");	} catch(Exception e) {e.printStackTrace();}

		// 일반 취소의 모듈 실행 mf_do_tx 에는 값이 안들어가고, 무통장입금 환불계좌 취소에는 custIp가 들어가도록 되어있어 계좌취소용 변수 따로 사용
		HttpServletRequest request;
		String cust_ip = "";
		String custIp = "";
		if(StringUtils.isEmpty(param.getBatchYn()) || !"Y".equals(param.getBatchYn())) {
			request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
			cust_ip = request.getRemoteAddr();

			if("STHD".equals(param.getModType()) || "STPD".equals(param.getModType())) {
				custIp = request.getRemoteAddr();
			}
		}

		J_PP_CLI_N c_PayPlus = new J_PP_CLI_N();
		Payment payment = new Payment();

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

		int mod_data_set_no = c_PayPlus.mf_add_set("mod_data");
		c_PayPlus.mf_set_us(mod_data_set_no, "tno"		, param.getPgTid());						// KCP 원거래 거래번호
		c_PayPlus.mf_set_us(mod_data_set_no, "mod_type"	, param.getModType());						// 전체취소 STSC / 부분취소 STPC
		c_PayPlus.mf_set_us(mod_data_set_no, "mod_ip"	, f_get_parm(cust_ip));						// 변경 요청자 IP
		c_PayPlus.mf_set_us(mod_data_set_no, "mod_desc"	, param.getModDesc());						// 변경 사유

		if("STPC".equals(param.getModType())) {
			c_PayPlus.mf_set_us( mod_data_set_no, "mod_mny", param.getPartCancelAmt() + "");		// 취소요청금액
			c_PayPlus.mf_set_us( mod_data_set_no, "rem_mny", param.getLeftAmt() + "");				// 취소가능잔액
		} else if("STHD".equals(param.getModType())) {
			// 파일 인코딩 EUC-KR 변경
			setFileEncoding("EUC-KR");
			c_PayPlus.mf_set_us( mod_data_set_no, "mod_sub_type", "MDSC00");						// 변경 유형
			c_PayPlus.mf_set_us( mod_data_set_no, "mod_comp_type", "MDCP01");						// 변경 유형
			c_PayPlus.mf_set_us( mod_data_set_no, "mod_bankcode", "BK" + param.getBankCd());		// 환불 요청 은행 코드
			c_PayPlus.mf_set_us( mod_data_set_no, "mod_account", param.getAccountNo());				// 환불 요청 계좌
			c_PayPlus.mf_set_us( mod_data_set_no, "mod_depositor", param.getAccountNm());			// 환불 요청 계좌주명
		} else if("STPD".equals(param.getModType())) {
			// 파일 인코딩 EUC-KR 변경
			setFileEncoding("EUC-KR");
			c_PayPlus.mf_set_us( mod_data_set_no, "mod_sub_type", "MDSC03");						// 변경 유형
			c_PayPlus.mf_set_us( mod_data_set_no, "mod_comp_type", "MDCP01");						// 변경 유형
			c_PayPlus.mf_set_us( mod_data_set_no, "mod_mny", param.getPartCancelAmt() + "");		// 취소요청금액
			c_PayPlus.mf_set_us( mod_data_set_no, "rem_mny", param.getLeftAmt() + "");				// 취소가능잔액
			c_PayPlus.mf_set_us( mod_data_set_no, "mod_bankcode", "BK" + param.getBankCd());		// 환불 요청 은행 코드
			c_PayPlus.mf_set_us( mod_data_set_no, "mod_account", param.getAccountNo());				// 환불 요청 계좌
			c_PayPlus.mf_set_us( mod_data_set_no, "mod_depositor", param.getAccountNm());			// 환불 요청 계좌주명
		}

		param.setTranCd("00200000");
		c_PayPlus.mf_do_tx(env.getProperty("pg.kcp.site.cd"), env.getProperty("pg.kcp.site.key"), param.getTranCd(), custIp, "", env.getProperty("pg.kcp.log.level"), "1");

		if (!"UTF-8".equals(System.getProperty("file.encoding"))) {
			setFileEncoding("UTF-8");
		}

		log.info("CHECK KCP PG RESULT ::::: {}", c_PayPlus.getRecvObj().toString());

		if("0000".equals(c_PayPlus.m_res_cd)) {
			try {
				// 주문 결제 정보 조회
				payment = orderDao.getKcpOrderPaymentInfo(param);

				payment.setResCd(c_PayPlus.m_res_cd);												// 결과 코드
				payment.setResMsg(c_PayPlus.m_res_msg);												// 결과 메시지
				payment.setPgCpnAmt(c_PayPlus.mf_get_res("coupon_mny").isEmpty() ? 0 : Integer.parseInt(c_PayPlus.mf_get_res("coupon_mny")));

				if ("STSC".equals(param.getModType()) || "STHD".equals(param.getModType())) {
					payment.setPayAmt(-payment.getPayAmt());										// 전체 취소는 결제 금액 전체
				} else if ("STPD".equals(param.getModType())) {
					payment.setPayAmt(param.getPartCancelAmt() * -1);								// 무통장입금 부분 취소는 취소 요청 금액
				} else {
					payment.setPayAmt(-(Integer.parseInt(c_PayPlus.mf_get_res("panc_mod_mny"))));	// 부분 취소는 취소된 금액
				}

				if ("E".equals(param.getPayGb())) {													// 결제완료 로직 진행 중 에러 발생시
					param.setPgTradeNo(c_PayPlus.mf_get_res("tno"));
					param.setPayAmt(payment.getPayAmt());
					orderDao.insertPayment(param);
				} else {																			// 일반 취소 작업
					payment.setRegNo(param.getRegNo() == null ? 0 : param.getRegNo());
					payment.setUpdNo(param.getUpdNo() == null ? 0 : param.getUpdNo());
					payment.setPayGb(param.getPayGb());
					payment.setOrdChgSq(ordChgSq);
					payment.setPayStat(param.getPayStat());
					payment.setPgTradeNo(c_PayPlus.mf_get_res("tno"));								// 환불 요청건의 KCP 거래번호

					orderDao.insertPaymentCancel(payment);
					param.setPaySq(payment.getPaySq());
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			if ("bos".equals(env.getProperty("server.site.name"))) {
				throw new IllegalArgumentException(c_PayPlus.m_res_msg);
			} else {
				throw new IllegalArgumentException("결제 취소 실패하였습니다.");
			}
		}
	}


	/**
	 * KCP 계좌인증 처리
	 *
	 * @param custAccount
	 * @result GagaMap - 결과 값
	 * @author card007
	 * @since 2021. 03. 17
	 */
	public GagaMap checkAccount(CustAccount custAccount) {
		GagaMap result = new GagaMap();

		// KCP Profile 별 정보
		String pgUrl = env.getProperty("pg.kcp.gw.url");
		String pgPort = env.getProperty("pg.kcp.gw.port");
		String siteCd = env.getProperty("pg.kcp.site.cd");
		String siteKey = env.getProperty("pg.kcp.site.key");

		// KCP 운영 정보
		// 계좌인증 개발서버는 무조건 인증성공으로 처리되어 운영서버 정보로 설정
		// 개발서버 정보로 변경 시 하기 변수 주석처리 진행
		pgUrl = "paygw.kcp.co.kr";
		pgPort = "8090";
		siteCd = "U3476";
		siteKey = "4aVa--.Xz8Fc78nwYPsrmmY__";

		String tranCd = "00100000";
		// 파일 인코딩 EUC-KR 변경
		setFileEncoding("EUC-KR");
		J_PP_CLI_N c_PayPlus = new J_PP_CLI_N();
		c_PayPlus.mf_init( "", pgUrl, pgPort, 0, env.getProperty("pg.kcp.log.dir") );
		c_PayPlus.mf_init_set();

		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
		String custIp = request.getRemoteAddr();
		String ordNo = String.valueOf(custAccount.getOrdNo());
		String bankCode = custAccount.getBankCd();
		String accountNo = custAccount.getAccountNo();
		String accountNm = custAccount.getAccountNm();

		if (StringUtils.isEmpty(ordNo)) {
			ordNo = "0";
		}

		int payx_data_set;
		int common_data_set;

		payx_data_set = c_PayPlus.mf_add_set("payx_data");
		common_data_set = c_PayPlus.mf_add_set("common");

		c_PayPlus.mf_set_us(common_data_set, "amount", "0");
		c_PayPlus.mf_set_us(common_data_set, "cust_ip", custIp);
		c_PayPlus.mf_set_us(common_data_set, "escw_mod", "N");

		c_PayPlus.mf_add_rs(payx_data_set, common_data_set);

		// 주문 정보
		int ordr_data_set = c_PayPlus.mf_add_set("ordr_data");

		c_PayPlus.mf_set_us(ordr_data_set, "ordr_idxx", ordNo);

		// 계좌 정보
		int acnt_data_set = c_PayPlus.mf_add_set("bank");
		c_PayPlus.mf_set_us(acnt_data_set, "bk_owner_nm", accountNm);					// 예금주명
		c_PayPlus.mf_set_us(acnt_data_set, "bk_txtype", "74200000");					// 지불 타입 (계좌 인증)
		c_PayPlus.mf_set_us(acnt_data_set, "bk_code", bankCode);						// 은행 코드
		c_PayPlus.mf_set_us(acnt_data_set, "bk_account_no", accountNo);					// 발급 계좌
		c_PayPlus.mf_add_rs(payx_data_set, acnt_data_set);

		c_PayPlus.mf_do_tx(siteCd, siteKey, tranCd, custIp, ordNo, "3", "1" );

		// 파일 인코딩 UTF-8 변경
		setFileEncoding("UTF-8");

		log.info("CHECK KCP PG RESULT ::::: {}", c_PayPlus.getRecvObj().toString());

		result.set("resCd", c_PayPlus.m_res_cd);										// 결과 메시지
		result.set("resMsg", c_PayPlus.m_res_msg);										// 결과 메시지
		result.set("res_en_msg", c_PayPlus.getRecvMsgOfKey("res_en_msg"));				// 결과 메시지(영문)

		return result;
	}

	/**
	 * KCP 현금영수증 취소 신청 API
	 * param.setModType("STSQ");	// 요청 구분 (STSQ : 조회, STSC : 전체취소, STPC : 부분취소) >> 조회는 사용 안함 > result 안받음. 사용시 result 추가활것.
	 * param.setOrdNo(100);			// 주문번호
	 * param.setUsGfcdAmt(3000);	// 취소 요청 금액
	 * param.getAmt(30000);			// 잔여금액
	 * param.getTradeNo();			// 현금영수증 거래번호
	 * param.getTradeTime();		// 거래일시
	 * 
	 * @param GiftCard
	 * @author xodud1202
	 * @since 2021. 04. 23
	 */
	@Transactional("shopTxnManager")
	public GiftCard kcpCashReceiptCancel(GiftCard param) {
		GiftCard result = new GiftCard();
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
		String cust_ip = request.getRemoteAddr();
		String reqTx = "mod";		// 현금영수증 취소 or 조회 요청
		String txCd = "07030000";	// 현금영수증 조회 요청

		// 현금영수증 정보 조회
		// GiftCard receiptInfo = orderDao.getGiftCardReceiptInfo(param);

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

		int     mod_data_set_no ;

		mod_data_set_no = c_PayPlus.mf_add_set( "mod_data" ) ;

		// 요청 구분
		if("STSQ".equals(param.getModType())) {
			txCd = "07030000" ;     // 조회 요청
		} else {
			txCd = "07020000" ;     // 취소 요청
		}

		// 부분 취소
		if("STPC".equals(param.getModType())) {
			c_PayPlus.mf_set_us( mod_data_set_no, "mod_mny"  , String.valueOf(param.getUsGfcdAmt()));	// 부분취소 요청 금액
			c_PayPlus.mf_set_us( mod_data_set_no, "rem_mny"  , String.valueOf(param.getAmt()));			// 잔여금액 (부분취소 이전에 남은 금액)
		}

		c_PayPlus.mf_set_us( mod_data_set_no, "mod_type"  , param.getModType()) ;
		c_PayPlus.mf_set_us( mod_data_set_no, "mod_value" , param.getTradeNo()) ;
		c_PayPlus.mf_set_us( mod_data_set_no, "mod_gubn"  , "MG01"  ) ;
		c_PayPlus.mf_set_us( mod_data_set_no, "trad_time" , param.getTradeTime()) ;

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

		log.info("CHECK CASH MOD RESULT ::::: {}", c_PayPlus.getRecvObj().toString());

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

				// 성공시 TB_GIFTCARD_RECEIPT AMT UPDATE
				orderDao.updateGiftCardReceipt(result);
			}

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

		return result;
	}

	/**
	 * 파일 인코딩 설정
	 * JDK 1.9에서는 작동 안하는것 같음
	 * @param encoding - EUC-KR, UTF-8
	 * @author jsshin
	 * @since 2021. 06. 21
	 */
	private void setFileEncoding(String encoding) {
		log.info("file.encoding Before: {}", System.getProperty("file.encoding"));
		System.setProperty("file.encoding", encoding);
		Field charset;
		try {
			charset = Charset.class.getDeclaredField("defaultCharset");
			charset.setAccessible(true);
			charset.set(null, null);
		} catch (NoSuchFieldException e1) {
			e1.printStackTrace();
		} catch (SecurityException e1) {
			e1.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		log.info("file.encoding After: {}", System.getProperty("file.encoding"));
	}

}

