package itn.com.cmm.util; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.URL; import java.security.MessageDigest; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import org.apache.commons.codec.binary.Hex; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.springframework.stereotype.Component; import egovframework.rte.fdl.idgnr.EgovIdGnrService; import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper; import itn.com.cmm.LoginVO; import itn.com.cmm.util.MJUtil; import itn.com.utl.fcc.service.EgovStringUtil; import itn.let.mjo.event.service.MjonEventVO; import itn.let.mjo.event.service.impl.MjonEventDAO; import itn.let.mjo.msgdata.service.MjonMsgDataService; import itn.let.mjo.pay.service.MjonPayVO; import itn.let.mjo.pay.service.impl.MjonPayDAO; import itn.let.mjo.tax.service.TaxVO; import itn.let.mjo.tax.service.impl.TaxDAO; import itn.let.sym.site.service.JoinSettingVO; import itn.let.uat.uia.service.impl.MberManageDAO; import itn.let.uss.umt.service.MberManageVO; @Component("nicePayUtil") public class NicePayUtil { @Resource(name = "egovMjonCashIdGnrService") private EgovIdGnrService idgenMjonCashId; @Resource(name = "egovMjonPointIdGnrService") private EgovIdGnrService idgenMjonPointId; @Resource(name = "MjonMsgDataService") private MjonMsgDataService mjonMsgDataService; /** * @param mjonPayVO * @param request * @return * @throws Exception * //nicepay 정상 결제 여부 확인 */ public boolean pgAuth(MjonPayVO mjonPayVO , HttpServletRequest request) throws Exception { //Pg 결제 정상여부 체크 boolean paySuccess = false; /* **************************************************************************************** * <인증 결과 파라미터> **************************************************************************************** */ String authResultCode = (String)request.getParameter("AuthResultCode"); // 인증결과 : 0000(성공) String authResultMsg = (String)request.getParameter("AuthResultMsg"); // 인증결과 메시지 String nextAppURL = (String)request.getParameter("NextAppURL"); // 승인 요청 URL String txTid = (String)request.getParameter("TxTid"); // 거래 ID String authToken = (String)request.getParameter("AuthToken"); // 인증 TOKEN String payMethod = (String)request.getParameter("PayMethod"); // 결제수단 String mid = (String)request.getParameter("MID"); // 상점 아이디 String moid = (String)request.getParameter("Moid"); // 상점 주문번호 String amt = (String)request.getParameter("Amt"); // 결제 금액 String reqReserved = (String)request.getParameter("ReqReserved"); // 상점 예약필드 String netCancelURL = (String)request.getParameter("NetCancelURL"); // 망취소 요청 URL /* **************************************************************************************** * <승인 결과 파라미터 정의> * 샘플페이지에서는 승인 결과 파라미터 중 일부만 예시되어 있으며, * 추가적으로 사용하실 파라미터는 연동메뉴얼을 참고하세요. **************************************************************************************** */ String ResultCode = ""; String ResultMsg = ""; String PayMethod = ""; String GoodsName = ""; String Amt = ""; String TID = ""; String cardCode = ""; // 결제카드사코드 String cardName = ""; // 결제카드사명 String bankCode = ""; // 결제은행코드 String bankName = ""; // 결제은행명 /* **************************************************************************************** * <인증 결과 성공시 승인 진행> **************************************************************************************** */ String resultJsonStr = ""; if(authResultCode.equals("0000")){ /* **************************************************************************************** * <해쉬암호화> (수정하지 마세요) * SHA-256 해쉬암호화는 거래 위변조를 막기위한 방법입니다. **************************************************************************************** */ DataEncrypt sha256Enc = new DataEncrypt(); String merchantKey = "7wnkxZbHvIA7FoCc6jF8IcXU+Wd3sn5BcMHuWJROe53AjRKnC6CistVdVZwrUKCCdaF+dAx230bwHSQ/E29RWA=="; // 운영상점키 //String merchantKey = "EYzu8jGGMfqaDEp76gSckuvnaHHu+bC4opsSN6lHv3b2lurNYkVXrZ7Z1AoqQnXI3eLuaUFyoRNC6FkrzVjceg=="; // 테스트 상점키 String ediDate = getyyyyMMddHHmmss(); String signData = sha256Enc.encrypt(authToken + mid + amt + ediDate + merchantKey); /* **************************************************************************************** * <승인 요청> * 승인에 필요한 데이터 생성 후 server to server 통신을 통해 승인 처리 합니다. **************************************************************************************** */ StringBuffer requestData = new StringBuffer(); requestData.append("TID=").append(txTid).append("&"); requestData.append("AuthToken=").append(authToken).append("&"); requestData.append("MID=").append(mid).append("&"); requestData.append("Amt=").append(amt).append("&"); requestData.append("EdiDate=").append(ediDate).append("&"); requestData.append("SignData=").append(signData); try { resultJsonStr = connectToServer(requestData.toString(), nextAppURL); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } HashMap resultData = new HashMap(); if("9999".equals(resultJsonStr)){ /* ************************************************************************************* * <망취소 요청> * 승인 통신중에 Exception 발생시 망취소 처리를 권고합니다. ************************************************************************************* */ StringBuffer netCancelData = new StringBuffer(); requestData.append("&").append("NetCancel=").append("1"); String cancelResultJsonStr = connectToServer(requestData.toString(), netCancelURL); HashMap cancelResultData = jsonStringToHashMap(cancelResultJsonStr); ResultCode = (String)cancelResultData.get("ResultCode"); ResultMsg = (String)cancelResultData.get("ResultMsg"); }else{ resultData = jsonStringToHashMap(resultJsonStr); ResultCode = (String)resultData.get("ResultCode"); // 결과코드 (정상 결과코드:3001) ResultMsg = (String)resultData.get("ResultMsg"); // 결과메시지 PayMethod = (String)resultData.get("PayMethod"); // 결제수단 GoodsName = (String)resultData.get("GoodsName"); // 상품명 Amt = (String)resultData.get("Amt"); // 결제 금액 TID = (String)resultData.get("TID"); // 거래번호 cardCode = (String)resultData.get("CardCode"); // 결제카드사코드 cardName = (String)resultData.get("CardName"); // 결제카드사명 bankCode = (String)resultData.get("BankCode"); // 결제은행코드 bankName = (String)resultData.get("BankName"); // 결제은행명 /* ************************************************************************************* * <결제 성공 여부 확인> ************************************************************************************* */ if(PayMethod != null){ if(PayMethod.equals("CARD")){ if(ResultCode.equals("3001")) paySuccess = true; // 신용카드(정상 결과코드:3001) }else if(PayMethod.equals("BANK")){ if(ResultCode.equals("4000")) paySuccess = true; // 계좌이체(정상 결과코드:4000) }else if(PayMethod.equals("CELLPHONE")){ if(ResultCode.equals("A000")) paySuccess = true; // 휴대폰(정상 결과코드:A000) }else if(PayMethod.equals("VBANK")){ if(ResultCode.equals("4100")) paySuccess = true; // 가상계좌(정상 결과코드:4100) }else if(PayMethod.equals("SSG_BANK")){ if(ResultCode.equals("0000")) paySuccess = true; // SSG은행계좌(정상 결과코드:0000) }else if(PayMethod.equals("CMS_BANK")){ if(ResultCode.equals("0000")) paySuccess = true; // 계좌간편결제(정상 결과코드:0000) } } } }else{ ResultCode = authResultCode; ResultMsg = authResultMsg; } //PG테이블 변수설정 오류시에도 PG테이블에 값 insert mjonPayVO.setPgStatus("4"); //결제오류 mjonPayVO.setResultCode(authResultCode); mjonPayVO.setResultMsg(ResultMsg); //'결과메시지', mjonPayVO.setTid(txTid); // 거래 ID mjonPayVO.setPayMethod(payMethod); // 결제수단 mjonPayVO.setMid(mid); // 상점 아이디 mjonPayVO.setAmt(amt); // 결제 금액 mjonPayVO.setPgCode("INNOPAY"); //이노페이(강제세팅) LoginVO loginVO = (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser(); String userId = loginVO == null ? "" : EgovStringUtil.isNullToString(loginVO.getId()); // userId = mjonPayVO.getMoid() ; //테스트시 화면에서 전송한 고객사 ID // mjonPayVO.setMoid(idgenPgMoid.getNextStringId()); // 상점 주문번호 결제 완료 후 생성 mjonPayVO.setRegNo(mjonPayVO.getBuyerTel()); // '사업자번호/전화번호', mjonPayVO.setMobile(mjonPayVO.getBuyerTel()); // '사업자번호/전화번호', mjonPayVO.setPhone(mjonPayVO.getBuyerTel()); //연락처 mjonPayVO.setEmail(mjonPayVO.getBuyerEmail()); //이메일 mjonPayVO.setRepName(mjonPayVO.getBuyerName()); //'대표자명', mjonPayVO.setConfirmYn("N"); //'완료여부', mjonPayVO.setUserId(userId); mjonPayVO.setFrstRegisterId(userId); mjonPayVO.setCardCode(cardCode); //결제카드사코드 mjonPayVO.setCardName(cardName); //결제카드사명 mjonPayVO.setBankCode(bankCode); //결제은행코드 mjonPayVO.setBankName(bankName); //결제은행사명 if(!paySuccess) { return false; } //PG테이블 변수 설정-------------------------------------------------------------------------------- if("0000".equals(authResultCode)) { // 인증결과 : 0000(성공) mjonPayVO.setPgStatus("1"); //'결제 상태 - 0:입금대기, 1:결제완료, 4:결제오류, 9:취소완료' mjonPayVO.setResultCode(authResultCode); //결과코드 } return paySuccess ; } //server to server 통신 public String connectToServer(String data, String reqUrl) throws Exception{ HttpURLConnection conn = null; BufferedReader resultReader = null; PrintWriter pw = null; URL url = null; int statusCode = 0; StringBuffer recvBuffer = new StringBuffer(); try{ url = new URL(reqUrl); conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setConnectTimeout(3000); conn.setReadTimeout(5000); conn.setDoOutput(true); pw = new PrintWriter(conn.getOutputStream()); pw.write(data); pw.flush(); statusCode = conn.getResponseCode(); resultReader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "euc-kr")); for(String temp; (temp = resultReader.readLine()) != null;){ recvBuffer.append(temp).append("\n"); } if(!(statusCode == HttpURLConnection.HTTP_OK)){ throw new Exception(); } return recvBuffer.toString().trim(); }catch (Exception e){ return "9999"; }finally{ recvBuffer.setLength(0); try{ if(resultReader != null){ resultReader.close(); } }catch(Exception ex){ resultReader = null; } try{ if(pw != null) { pw.close(); } }catch(Exception ex){ pw = null; } try{ if(conn != null) { conn.disconnect(); } }catch(Exception ex){ conn = null; } } } //JSON String -> HashMap 변환 public static HashMap jsonStringToHashMap(String str) throws Exception{ HashMap dataMap = new HashMap(); JSONParser parser = new JSONParser(); try{ Object obj = parser.parse(str); JSONObject jsonObject = (JSONObject)obj; Iterator keyStr = jsonObject.keySet().iterator(); while(keyStr.hasNext()){ String key = keyStr.next(); Object value = jsonObject.get(key); dataMap.put(key, value); } }catch(Exception e){ } return dataMap; } public final synchronized String getyyyyMMddHHmmss(){ SimpleDateFormat yyyyMMddHHmmss = new SimpleDateFormat("yyyyMMddHHmmss"); return yyyyMMddHHmmss.format(new Date()); } // SHA-256 형식으로 암호화 public class DataEncrypt{ MessageDigest md; String strSRCData = ""; String strENCData = ""; String strOUTData = ""; public DataEncrypt(){ } public String encrypt(String strData){ String passACL = null; MessageDigest md = null; try{ md = MessageDigest.getInstance("SHA-256"); md.reset(); md.update(strData.getBytes()); byte[] raw = md.digest(); passACL = encodeHex(raw); }catch(Exception e){ System.out.print("암호화 에러" + e.toString()); } return passACL; } public String encodeHex(byte [] b){ char [] c = Hex.encodeHex(b); return new String(c); } } // 세금 값 넣기 public MjonPayVO setTexVO(MjonPayVO mjonPayVO) throws Exception{ /* * amt = mjonPayVO.setAmt(amt); // 결제 금액 * userId = mjonPayVO.getMoid() ; //테스트시 화면에서 전송한 고객사 ID * mjonPayVO.setPayMethod(payMethod); // 결제수단 */ String s_amt = mjonPayVO.getAmt(); // 부가세별도 충전금액 s_amt = setCashVatNotIncluded(s_amt); String s_user_id = mjonPayVO.getMoid(); //PG Tax테이블 변수 생성 mjonPayVO.setRcptType("9"); //PG결제는 세금계산서 '발행유형-[PG결제-현금영수증 유형과 동일] 1:소득공제, 2:지출증빙, 9:세금계산서', (확인필요) mjonPayVO.setRegNo(mjonPayVO.getBuyerTel()); // '사업자번호/전화번호', mjonPayVO.setMobile(mjonPayVO.getBuyerTel()); // '사업자번호/전화번호', mjonPayVO.setPhone(mjonPayVO.getBuyerTel()); //연락처 mjonPayVO.setEmail(mjonPayVO.getBuyerEmail()); //이메일 mjonPayVO.setRepName(mjonPayVO.getBuyerName()); //'대표자명', mjonPayVO.setConfirmYn("Y"); //'완료여부', //캐쉬 테이블 변수 생성 mjonPayVO.setCashId(idgenMjonCashId.getNextStringId()) ; mjonPayVO.setPointId(idgenMjonPointId.getNextStringId()) ; mjonPayVO.setCash(Float.parseFloat(s_amt)); //'사용 캐쉬-양수:지급, 음수:소모', mjonPayVO.setOrderId(mjonPayVO.getMoid()); //'주문번호-주문번호가 없으면 관리자 임의 지급', mjonPayVO.setUserId(s_user_id); mjonPayVO.setFrstRegisterId(s_user_id); return mjonPayVO; } // 부가세별도 충전금액 private String setCashVatNotIncluded(String val) { String rtnVal = ""; // 공급대가 = 공급가액(공급대가/11*10) + 부가세(공급대가/11) // 11000 = (11000/11*10 ) + 11000/11 // 공급가액 계산로직 rtnVal = Math.round(Float.parseFloat(val) / 11 * 10) + ""; return rtnVal; } //cash 값 넣기 /** * @param mjonPayVO * @return * @throws Exception * cash table 값 넣기 */ public MjonPayVO setCashVO(MjonPayVO mjonPayVO) throws Exception{ /* * amt = mjonPayVO.setAmt(amt); // 결제 금액 * userId = mjonPayVO.getMoid() ; //테스트시 화면에서 전송한 고객사 ID * mjonPayVO.setPayMethod(payMethod); // 결제수단 */ String s_amt = mjonPayVO.getAmt(); // 부가세별도 충전금액 s_amt = setCashVatNotIncluded(s_amt); String s_user_id = mjonPayVO.getMoid(); //캐쉬 테이블 변수 생성 mjonPayVO.setCashId(idgenMjonCashId.getNextStringId()) ; mjonPayVO.setPointId(idgenMjonPointId.getNextStringId()) ; mjonPayVO.setCash(Float.parseFloat(s_amt)); //'사용 캐쉬-양수:지급, 음수:소모', mjonPayVO.setOrderId(mjonPayVO.getMoid()); //'주문번호-주문번호가 없으면 관리자 임의 지급', mjonPayVO.setUserId(s_user_id); mjonPayVO.setFrstRegisterId(s_user_id); String s_paymethod = mjonPayVO.getPayMethod(); if(s_paymethod.equals("CARD")){ s_paymethod = "신용카드" ; // 신용카드(정상 결과코드:3001) }else if(s_paymethod.equals("BANK")){ s_paymethod = "계좌이체" ; // 계좌이체(정상 결과코드:4000) }else if(s_paymethod.equals("CELLPHONE")){ s_paymethod = "휴대폰" ; // 휴대폰(정상 결과코드:A000) }else if(s_paymethod.equals("VBANK")){ s_paymethod = "가상계좌" ; // 가상계좌(정상 결과코드:4100) }else if(s_paymethod.equals("SSG_BANK")){ s_paymethod = "SSG은행계좌" ; // SSG은행계좌(정상 결과코드:0000) }else if(s_paymethod.equals("CMS_BANK")){ s_paymethod = "계좌간편결제" ; // 계좌간편결제(정상 결과코드:0000) }else { s_paymethod = ""; } String memo = s_paymethod + " " + s_amt + " 충전" ; mjonPayVO.setMemo(memo); //캐쉬메모 return mjonPayVO; } //point 값 넣기 /** * @param mjonPayVO * @return * @throws Exception * point table 값 넣기 */ public MjonPayVO setPointVO(MjonPayVO mjonPayVO) throws Exception{ String s_paymethod = mjonPayVO.getPayMethod(); if(s_paymethod.equals("CARD")){ s_paymethod = "신용카드" ; // 신용카드(정상 결과코드:3001) }else if(s_paymethod.equals("SPAY")){ s_paymethod = "간편결제" ; // 간편결제 }else if(s_paymethod.equals("BANK")){ s_paymethod = "계좌이체" ; // 계좌이체(정상 결과코드:4000) }else if(s_paymethod.equals("CELLPHONE")){ s_paymethod = "휴대폰" ; // 휴대폰(정상 결과코드:A000) }else if(s_paymethod.equals("VBANK")){ s_paymethod = "가상계좌" ; // 가상계좌(정상 결과코드:4100) }else if(s_paymethod.equals("SSG_BANK")){ s_paymethod = "SSG은행계좌" ; // SSG은행계좌(정상 결과코드:0000) }else if(s_paymethod.equals("CMS_BANK")){ s_paymethod = "계좌간편결제" ; // 계좌간편결제(정상 결과코드:0000) }else { s_paymethod = ""; } String s_amt = mjonPayVO.getAmt(); // 부가세별도 충전금액 s_amt = setCashVatNotIncluded(s_amt); //포인트 테이블 변수설정 JoinSettingVO sysJoinSetVO = mjonMsgDataService.selectJoinSettingInfo(); //int point = Math.round( (Float.parseFloat(s_amt)*2/100) ) ; float p_i_re_point = 0; if (sysJoinSetVO != null) { p_i_re_point = sysJoinSetVO.getPointPer(); } int point = Math.round((Float.parseFloat(s_amt)*p_i_re_point/100)) ; mjonPayVO.setPoint(point); String pointMemo = s_paymethod; //포인트 메모 pointMemo = pointMemo + " " + point + " 충전" ; mjonPayVO.setPointMemo(pointMemo); return mjonPayVO; } public MjonPayVO setPayInfo(HttpServletRequest request, MjonPayVO mjonPayVO) throws Exception{ if(!this.pgAuth(mjonPayVO , request)) { mjonPayVO.setPaySuccess(false); return mjonPayVO; } //세금 값 넣기 mjonPayVO = this.setTexVO(mjonPayVO); //cash 값 넣기 mjonPayVO = this.setCashVO(mjonPayVO); //point 값 넣기 mjonPayVO = this.setPointVO(mjonPayVO); return mjonPayVO; } }