From b0b9ae46be0fd56a3ea2477ee9274b9813ec65b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EA=B2=BD=EC=88=99?= Date: Mon, 23 Mar 2026 16:04:25 +0900 Subject: [PATCH] =?UTF-8?q?=ED=82=A4=EC=9B=80=EA=B2=B0=EC=A0=9C=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gcone/ordr/pay/service/BOPayService.java | 85 ++++ .../domain/gcone/ordr/pay/vo/BOPayVO.java | 3 + .../sopmal/ordr/controller/PayController.java | 164 ++++++- .../views/sopmal/ordr/PayKiwoomPay2C.jsp | 51 ++ .../views/sopmal/ordr/PayKiwoomPayC.jsp | 446 ++++++++++++++++++ .../views/sopmal/ordr/PayKiwoomSucsC.jsp | 56 +++ 6 files changed, 802 insertions(+), 3 deletions(-) create mode 100644 src/main/webapp/WEB-INF/views/sopmal/ordr/PayKiwoomPay2C.jsp create mode 100644 src/main/webapp/WEB-INF/views/sopmal/ordr/PayKiwoomPayC.jsp create mode 100644 src/main/webapp/WEB-INF/views/sopmal/ordr/PayKiwoomSucsC.jsp diff --git a/src/main/java/com/wb/domainserver/domain/gcone/ordr/pay/service/BOPayService.java b/src/main/java/com/wb/domainserver/domain/gcone/ordr/pay/service/BOPayService.java index 7b0b1b94..5ef3cbb7 100644 --- a/src/main/java/com/wb/domainserver/domain/gcone/ordr/pay/service/BOPayService.java +++ b/src/main/java/com/wb/domainserver/domain/gcone/ordr/pay/service/BOPayService.java @@ -32,6 +32,7 @@ import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder; import org.bouncycastle.operator.InputDecryptorProvider; import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; import org.json.simple.JSONObject; +import org.json.simple.JSONValue; import org.json.simple.parser.JSONParser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -1468,10 +1469,94 @@ public class BOPayService{ } + /* ============================================================================== */ + /* = 여기서 부터 Kiwoom + /* = -------------------------------------------------------------------------- = */ + + /** + * Kiwoom 결제 + * @param BOPayVO + */ + public Map insertKiwoomPay(BOPayVO payVO) throws Exception { + + //관련 키값 DB 조회 + /*DataMap resultMap = selectPayLink(payVO.getSopmalCd()); + String reSetleAmt = StringUtil.isNullToString(selectRlSetleAmt(payVO.getSopmalCd(),payVO.getOrderId())); + reSetleAmt = reSetleAmt.isEmpty()? "10" : reSetleAmt; //0원은 정상거래로 인정되어서 10원으로 지정함*/ + + log.info("insertKiwoomPay step1 "); + + String cpId = f_get_parm( payVO.getCpId()); + String payMethod = f_get_parm( payVO.getPayMethod()); + String orderNo = f_get_parm( payVO.getOrderId()); + String type = f_get_parm( payVO.getType()); + String amount = f_get_parm( payVO.getAmount()); + + JSONObject jsonObj = new JSONObject(); + jsonObj.put("CPID", cpId); + jsonObj.put("PAYMETHOD", payMethod); + jsonObj.put("ORDERNO", orderNo); + jsonObj.put("TYPE", type); + jsonObj.put("AMOUNT", amount); + + log.info("insertKiwoomPay step2 ::: {}", jsonObj); + //결제등록 요청시 실결제값(good_mny) + /*String payType = getPayMethod(payVO.getPayMethod()); + jsonReq.put("ordr_mony", reSetleAmt); // ** 결제금액 유효성 검증 ** + jsonReq.put("pay_type", payType); // ** 결제수단 유효성 검증 ** + jsonReq.put("ordr_no", payVO.getOrderId()); // ** 주문번호검증 ** + */ + String kiwoom_ENC = ""; + try { + String url = "https://apitest.kiwoompay.co.kr/pay/hash"; + URL goUrl = new URL(url); + HttpURLConnection con = (HttpURLConnection) goUrl.openConnection(); + con.setRequestMethod("POST"); + con.setRequestProperty("Content-Type", "application/json"); + con.setUseCaches(false); + con.setDoOutput(true); + con.setDoInput(true); + + OutputStream os = con.getOutputStream(); + os.write((jsonObj.toString()).getBytes("euc-kr")); + os.flush(); + os.close(); + + int responseCode = con.getResponseCode(); + + if (responseCode == 200) { + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuffer response1 = new StringBuffer(); + + while ((inputLine = in.readLine()) != null) { + response1.append(inputLine); + } + in.close(); + + JSONObject jObj = (JSONObject) JSONValue.parse(response1.toString()); + kiwoom_ENC = (String) jObj.get("KIWOOM_ENC"); + + log.info("insertKiwoomPay step3 ::: {}", jObj); + } + con.disconnect(); + } catch (Exception e) { + e.printStackTrace(); + } + + JSONObject resultObj = new JSONObject(); + resultObj.put("KIWOOM_ENC", kiwoom_ENC); + + log.info("insertKiwoomPay step4 ::: {}", resultObj.get("KIWOOM_ENC")); + + return new HashMap<>() {{ + put("response", resultObj.toString()); + }}; + } diff --git a/src/main/java/com/wb/domainserver/domain/gcone/ordr/pay/vo/BOPayVO.java b/src/main/java/com/wb/domainserver/domain/gcone/ordr/pay/vo/BOPayVO.java index 9db9b8d7..6773282d 100644 --- a/src/main/java/com/wb/domainserver/domain/gcone/ordr/pay/vo/BOPayVO.java +++ b/src/main/java/com/wb/domainserver/domain/gcone/ordr/pay/vo/BOPayVO.java @@ -292,6 +292,9 @@ public class BOPayVO extends AbstractVO { /** 테스트 여부 - 테스트용 */ private String testAt; + /** 키움 - 상점ID */ + private String cpId; + // cookie /** 에이전트 ID */ diff --git a/src/main/java/com/wb/domainserver/domain/sopmal/ordr/controller/PayController.java b/src/main/java/com/wb/domainserver/domain/sopmal/ordr/controller/PayController.java index 2f1a423a..7923f90a 100644 --- a/src/main/java/com/wb/domainserver/domain/sopmal/ordr/controller/PayController.java +++ b/src/main/java/com/wb/domainserver/domain/sopmal/ordr/controller/PayController.java @@ -22,9 +22,7 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.*; import com.fasterxml.jackson.databind.ObjectMapper; import com.wb.domainserver.domain.sopmal.ordr.vo.PayVO; @@ -630,4 +628,164 @@ public class PayController { return message; } + + /* ********************************************* + * 키움결제 + ********************************************* */ + + /** + * 키움 결제 화면 + * @return PayKiwoomSucsC.jsp + * @author 이경숙 + */ + @Policy(AuthPolicy.RESTRICTED) + @RequestMapping(value="/selectKiwoomSimple") + public String selectKiwoonPay(ModelMap model) throws Exception { + log.debug("selectKiwoonPay = {}"); + return "sopmal/ordr/PayKiwoomPayC"; + } + + @Policy(AuthPolicy.RESTRICTED) + @RequestMapping(value="/selectKiwoomSimple2") + public String selectKiwoonPay2(ModelMap model) throws Exception { + log.debug("selectKiwoonPay = {}"); + return "sopmal/ordr/PayKiwoomPay2C"; + } + + + /** + * 키움 결제 연계 전 getEnc 값 받아오기 + * @return PayKiwoomSucsC.jsp + * @author 이경숙 + */ + @Policy(AuthPolicy.RESTRICTED) + @ResponseBody + @RequestMapping(value="/kiwoomPayGetEnc") + public Map selectKiwoomGetEnc(HttpServletRequest request) throws Exception { + + BOPayVO payVO = new BOPayVO(); + + log.debug("kiwoomPayGetEnc = {}"); + + payVO.setCpId(request.getParameter("CPID")); + payVO.setPayMethod(request.getParameter("PAYMETHOD")); + payVO.setOrderId(request.getParameter("ORDERNO")); + payVO.setType(request.getParameter("TYPE")); + payVO.setAmount(request.getParameter("AMOUNT")); + + Map message; + String sopmalCd = payVO.getSopmalCd(); + try { + message = service.insertKiwoomPay(payVO); + + } catch (Exception e) { + message = new HashMap<>() {{ + put("response", "결제를 실패하였습니다.\n관리자에게 문의하시기 바랍니다."); + }}; + } + + + log.info("insertKiwoomPay step5 ::: {}", message.get("KIWOOM_ENC")); + + //model.addAttribute("message", message); + //return "sopmal/ordr/PayKiwoomSucsC"; + + return message; + } + + + + /** + * 키움 결제 연계처리 - 결과통보페이지 + * @return PayKiwoomSucsC.jsp + * @author 이경숙 + */ + @Policy(AuthPolicy.RESTRICTED) + @RequestMapping(value="/kiwoomPayWebhook") + @ResponseBody + public ResponseEntity selectPaymentkiwoomWebhook(HttpServletRequest request) throws Exception { + + String resultCode = request.getParameter("RESULTCODE"); + String orderNo = request.getParameter("ORDERNO"); + String amount = request.getParameter("AMOUNT"); + + System.out.println("콜백 수신"); + System.out.println("RESULTCODE = " + resultCode); + System.out.println("ORDERNO = " + orderNo); + System.out.println("AMOUNT = " + amount); + + /* 실제 처리해야 되는 부분 + // 1. 주문 조회 + Order order = orderService.find(orderNo); + + // 2. 중복 방지 + if ("PAID".equals(order.getStatus())) return "OK"; + + // 3. 금액 검증 + if (!order.getAmount().equals(Integer.parseInt(amount))) { + order.setStatus("FAIL"); + return "OK"; + } + + // 4. 성공 처리 + if ("0000".equals(resultCode)) { + order.setStatus("PAID"); + } else { + order.setStatus("FAIL"); + } + + orderService.save(order); +*/ + String response = "SUCCESS"; + + return ResponseEntity.ok() + .contentType(MediaType.TEXT_HTML) + .body(response); + } + + + /** + * 키움 결제 연계처리 - 성공결과페이지 + * @return PayKiwoomSucsC.jsp + * @author 이경숙 + */ + @Policy(AuthPolicy.RESTRICTED) + @RequestMapping(value="/kiwoomPaySuccss") + public String confirmPaymentkiwoom(HttpServletRequest request, ModelMap model) throws Exception { + + BOPayVO payVO = new BOPayVO(); + + payVO.setCode(request.getParameter("RESULTCODE")); + payVO.setOrderId(request.getParameter("ORDERNO")); + payVO.setAmount(request.getParameter("AMOUNT")); + payVO.setPayMethod(request.getParameter("PAYMETHOD")); + + Map message = new HashMap<>(); + /*String sopmalCd = payVO.getSopmalCd(); + try { + message = service.insertKcpPay(payVO); + + } catch (Exception e) { + message = new HashMap<>() {{ + put("response", "결제를 실패하였습니다.\n관리자에게 문의하시기 바랍니다."); + }}; + }*/ + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("code", payVO.getCode()); + jsonObject.put("orderId", payVO.getOrderId()); + jsonObject.put("amount", payVO.getAmount()); + jsonObject.put("payMethod", payVO.getPayMethod()); + message.put("response",jsonObject.toString()); + + model.addAttribute("message", message); +// responseHandler.handleResponse( +// sendToResrc.ofPost(RESRC.GCONEBO, "/gcone/ordr/pay/kcpPayProc", payVO), +// model, +// "message" +// ); + + return "sopmal/ordr/PayKiwoomSucsC"; + } + } diff --git a/src/main/webapp/WEB-INF/views/sopmal/ordr/PayKiwoomPay2C.jsp b/src/main/webapp/WEB-INF/views/sopmal/ordr/PayKiwoomPay2C.jsp new file mode 100644 index 00000000..9a11ba43 --- /dev/null +++ b/src/main/webapp/WEB-INF/views/sopmal/ordr/PayKiwoomPay2C.jsp @@ -0,0 +1,51 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> +<%@ taglib prefix="ui" uri="http://www.winbit.kr/ctl/ui"%> +<%@ taglib prefix="f" uri="/WEB-INF/tlds/f.tld"%> + +<%-- + Class Name : PayKiwoomPayC.jsp + Description : 키움 결제창 + Modification Information + + 수정일 수정자 수정내용 + ------- -------- --------------------------- + 2026-03-18 이경숙 최초 생성 +--%> + + + + + + + + + + + diff --git a/src/main/webapp/WEB-INF/views/sopmal/ordr/PayKiwoomPayC.jsp b/src/main/webapp/WEB-INF/views/sopmal/ordr/PayKiwoomPayC.jsp new file mode 100644 index 00000000..d1b591d9 --- /dev/null +++ b/src/main/webapp/WEB-INF/views/sopmal/ordr/PayKiwoomPayC.jsp @@ -0,0 +1,446 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> +<%@ taglib prefix="ui" uri="http://www.winbit.kr/ctl/ui"%> +<%@ taglib prefix="f" uri="/WEB-INF/tlds/f.tld"%> + +<%-- + Class Name : PayKiwoomPayC.jsp + Description : 키움 결제창 + Modification Information + + 수정일 수정자 수정내용 + ------- -------- --------------------------- + 2026-03-18 이경숙 최초 생성 +--%> + + + + + 통합LINK(보안 결제 창) + + + + + + + + + + + + +
+ + + + + + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
----------공통항목(필수)
파라미터값설명
서버서버환경
TYPE결제방식(P:PC/M:모바일/W:웹뷰)
PAYMETHOD결제수단
CPID상점아이디
ORDERNO주문번호
PRODUCTTYPE상품구분(1: 디지털, 2: 실물)
AMOUNT결제금액
PRODUCTNAME상품명
PRODUCTCODE상품코드
USERID고객 ID
----------공통항목(선택)
KIWOOM_ENC보안 기능
EMAIL고객 이메일
USERNAME고객명
RESERVEDINDEX1예약항목
RESERVEDINDEX2예약항목
RESERVEDSTRING예약스트링
HOMEURL결제 성공 후, 이동할 URL(결제 창에서 이동)
DIRECTRESULTFLAG키움페이 결제 완료 창 없이 HOMEURL로 바로 이동(Y/N)
SET_LOGO결제 창 하단 상점로고 URL
----------웹뷰결제창(필수)
HOMEURL공통항목(선택)에 있음결제 성공 후, 이동할 URL(결제 창에서 이동)
CLOSEURL결제 창에서 취소 누를 시 이동할 URL
FAILURL결제실패 후, 확인버튼 입력 시 이동할 URL
APPURL인증완료 후 돌아갈 앱의 URL(CARD(K), BANK 필수)
----------신용카드(필수)
TAXFREECD과세/비과세여부(00: 과세, 01: 비과세, 02: 복합과세)
TELNO2비과세 대상금액(TAXFREECD가 02인 경우에만 필수전송)
----------신용카드(조건부 필수)
BILLTYPECARD(K)-SUGI, CARD(K)-BATCH, MOBILE-BATCH인 경우 필수 과금 유형(1: 일반, 2: 월자동, 14:카드월자동, 13:수기일반, 18:수기비인증)
CERTTYPECARD(K)-SUGI인 경우 필수(00:카드번호/유효기간)(11:카드번호/유효기간/생년월일/비밀번호앞2자리)
AUTOINFOFLAGCARD(K)-BATCH인 경우 필수 AUTOKEY 전송방식(A~D타입 메뉴얼참고)
----------신용카드(선택)
CPQUOTACARD, CARD-SUGI인 경우 최대 할부 개월 수(구분자 “ : “) (일시불~12개월 예: 0:2:3:4~~~:12)
CARDQUOTACARD, CARD-SUGI인 경우 카드사별 할부 개월 수(예시 : CCBC-0:2:3:4:5:6^CCNH-0:2:3)
QUOTAOPTCARDK, CARDK-SUGI인 경우 최대 할부 개월 수 (일시불~12개월 예: 12)
CARDLISTCARD(K)인 경우 결제 창 카드사 노출 값(구분자 “ : “)(카드사코드는 매뉴얼 하단참고)
HIDECARDLISTCARD(K)인 경우 결제 창 카드사 숨김 값(구분자 “ : “)(카드사코드는 매뉴얼 하단참고)
SKIP_YN카드사 인증창 바로 이동 Y/N(CARDLIST에 하나의 카드사 코드만)
ENG_FLAGCARDK인 경우 영문 결제창 사용여부 Y/N
OPTIONPARAMSCARD-BATCH인 경우 CARDCODE를 값에 추가하여 AUTOKEY 전송방식 변경 (추가 옵션)
----------휴대폰(선택)
MOBILECOMPANYLISTMOBILE,MOBILE-BATCH 결제 창 통신사만 노출 값(구분자 “ , “)통신사 코드: SKT/KTF/LGT/CJH/KCT
FIXTELNO휴대폰 번호 고정 입력
----------가상계좌(선택)
DEPOSITENDDATE입금만료일(YYYYMMDD24MISS)(미지정 기본값 7일)
VTAXFREECD과세여부(00:과세 / 01:비과세 / 02:복합) RESERVEDSTIRNG : 비과세 대상금액 ^[비과세금액] 형식, 복합일 경우에만 사용
BANKCODE은행코드(제한하는 경우에만)
----------현금영수증(선택)
CASHRECEIPTFLAG현금영수증 발행여부(1:발행, 0:미발행)
CASHRECEIPTUSE현금영수증 발행용도(1:소득공제, 2:지출증빙, 9:미발행)
CASHRECEIPTINFO현금영수증 발행정보(휴대폰번호, 사업자번호)
----------카카오페이(선택)
FREE_AMT결제금액 중 비과세 금액
CASHRECEIPTFLAG + + 현금영수증 발행여부(Y:발행, N:미발행)는 카카오페이 현금영수증 발행은 구분하여 사용바랍니다.
PAYTYPE결제방식 CARD, MONEY(카드, 카카오머니)
USEKAKAOY/N(신용카드, 카카오 모두 사용시 신용카드 결제 창에서 카카오 표기 여부)
+ +
+ + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/views/sopmal/ordr/PayKiwoomSucsC.jsp b/src/main/webapp/WEB-INF/views/sopmal/ordr/PayKiwoomSucsC.jsp new file mode 100644 index 00000000..c508714f --- /dev/null +++ b/src/main/webapp/WEB-INF/views/sopmal/ordr/PayKiwoomSucsC.jsp @@ -0,0 +1,56 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> +<%@ taglib prefix="ui" uri="http://www.winbit.kr/ctl/ui"%> +<%@ taglib prefix="f" uri="/WEB-INF/tlds/f.tld"%> + +<%-- + Class Name : PayKiwoomSucsC.jsp + Description : 키움 결과창 + Modification Information + + 수정일 수정자 수정내용 + ------- -------- --------------------------- + 2026-03-23 이경숙 최초 생성 +--%> + + + + 결제 성공 + + + + + + + +
+ +

결제 성공

+

결과 데이터 :

+

orderName :

+

method :

+

금액 :

+

메세지 :

+

결과코드 :

+ +

+ +