결제 - 키움결제 적용 1차

This commit is contained in:
이경숙
2026-03-27 18:34:29 +09:00
parent 721e28e4c2
commit 8573a3e7a4
9 changed files with 722 additions and 635 deletions

View File

@@ -2,6 +2,8 @@ package com.wb.domainserver.domain.sopmal.ordr.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wb.domainserver.common.msg.GconeMessageSource;
import com.wb.domainserver.domain.gcone.ordr.ordr.service.BOOrdrLogService;
import com.wb.domainserver.domain.gcone.ordr.pay.vo.BOPayVO;
import com.wb.domainserver.domain.sopmal.ordr.vo.OrdrVO;
import com.wb.domainserver.exception.WnbtRestException;
import com.wb.domainserver.response.WnbtWebClientResponseHandler;
@@ -9,17 +11,23 @@ import com.wb.domainserver.security.authorization.annotation.AuthPolicy;
import com.wb.domainserver.security.authorization.annotation.Policy;
import com.wb.domainserver.util.communicate.RESRC;
import com.wb.domainserver.util.communicate.SendToResrc;
import com.wb.domainserver.util.dataaccess.DataMap;
import com.wb.domainserver.util.string.StringUtil;
import com.wb.domainserver.util.util.Util;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.ArrayList;
import java.util.List;
import java.io.BufferedReader;
import java.net.URLDecoder;
import java.util.*;
@Slf4j
@Controller
@@ -34,6 +42,9 @@ public class OrdrApiController {
@Autowired
private GconeMessageSource messageSource;
@Autowired
private BOOrdrLogService ordrLogService;
private Util utilClass;
/* ####################################
@@ -95,4 +106,135 @@ public class OrdrApiController {
return Integer.parseInt(cleanedCode.toString(), 16);
}
/* ##################################################
사용자 > 결제(키움) > 결제 성공 후 결제값 응답받음
################################################## */
/**
* 키움 결제 연계처리 - 결과통보페이지
* @author 이경숙
*/
@Policy(AuthPolicy.RESTRICTED)
@RequestMapping(value="/kiwoomPayWebhook")
@ResponseBody
public ResponseEntity<String> selectPaymentkiwoomWebhook(HttpServletRequest request) throws Exception {
// 0. 키움에서 온 값 로그 출력 (결제실패에 대한 응답은 없음)
printKiwoomRequest(request);
// 1. 주문 로그 남김 (GC_ORDER_LOG)
BOPayVO payVO = new BOPayVO();
DataMap pgApiLogReqVO = new DataMap();
String orderNo = StringUtil.isNullToString(request.getParameter("ORDERNO"));
String orderNm = StringUtil.isNullToString(request.getParameter("USERNAME"));
String resParam = queryStringToJson(request.getQueryString());
payVO.setPgCmpnyNm("kiwoom"); //pg사명
payVO.setDvCd("01"); //사용자
payVO.setOrderId(orderNo); //주문번호
payVO.setSetlerNm(orderNm); //주문자명
pgApiLogReqVO.put("resParam",resParam); //응답전문
ordrLogService.insertSetleOrderPgLog(payVO, pgApiLogReqVO);
// 2. PG API 로그 남김 (GC_ORDER_PG_API_LOG)
pgApiLogReqVO.put("reqParam", ""); //요청전문
pgApiLogReqVO.put("ordrInnb", orderNo); //주문번호
pgApiLogReqVO.put("sopmalCd", "SK"); //쇼핑몰코드
pgApiLogReqVO.put("pgCmpnyNm", "kiwoom"); //pg사명
pgApiLogReqVO.put("mbrInnb", ""); //회원번호
pgApiLogReqVO.put("resParam", resParam); //응답전문
ordrLogService.insertBOPgApiLogReqRegist(pgApiLogReqVO);
String response = "<html><body><RESULT>SUCCESS</RESULT></body></html>";
return ResponseEntity.ok()
.contentType(MediaType.TEXT_HTML)
.body(response);
}
public static void printKiwoomRequest(HttpServletRequest request) {
try {
System.out.println("========== [KIWOOM REQUEST START] ==========");
// 1. 기본 정보
System.out.println("URL : " + request.getRequestURL());
System.out.println("METHOD : " + request.getMethod());
System.out.println("QUERY : " + request.getQueryString());
System.out.println("REMOTE IP : " + request.getRemoteAddr());
// 2. 파라미터 (가장 중요)
System.out.println("---------- PARAM ----------");
request.setCharacterEncoding("EUC-KR");
request.getParameterMap().forEach((key, values) -> {
System.out.println(key + " = " + Arrays.toString(values));
});
// 3. 헤더
System.out.println("---------- HEADER ----------");
Collections.list(request.getHeaderNames()).forEach(header -> {
System.out.println(header + " = " + request.getHeader(header));
});
// 4. Body (JSON 대응)
System.out.println("---------- BODY ----------");
StringBuilder body = new StringBuilder();
BufferedReader reader = request.getReader();
String line;
while ((line = reader.readLine()) != null) {
body.append(line);
}
System.out.println(body.toString());
System.out.println("========== [KIWOOM REQUEST END] ==========");
} catch (Exception e) {
System.out.println("❌ REQUEST LOG ERROR");
e.printStackTrace();
}
}
public String queryStringToJson(String queryString) throws Exception {
Map<String, String> map = new HashMap<>();
if (queryString != null && !queryString.isEmpty()) {
String[] pairs = queryString.split("&");
for (String pair : pairs) {
String[] keyValue = pair.split("=", 2);
String key = URLDecoder.decode(keyValue[0], "UTF-8");
String value = keyValue.length > 1 ? URLDecoder.decode(keyValue[1], "UTF-8") : "";
map.put(key, value);
}
}
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(map);
}
public Map<String, String> queryStringToMap(String queryString) throws Exception {
Map<String, String> map = new HashMap<>();
if (queryString != null) {
for (String param : queryString.split("&")) {
String[] pair = param.split("=", 2);
String key = URLDecoder.decode(pair[0], "EUC-KR");
String value = pair.length > 1 ? URLDecoder.decode(pair[1], "EUC-KR") : "";
map.put(key, value);
}
}
return map;
}
}

View File

@@ -831,7 +831,9 @@ public class OrdrController {
String pgCmpnyNm = setle.getPgCmpnyNm();
String setleTyCd = setle.getSetleTyCd();
if ("gcpay".equals(pgCmpnyNm)) {
if ("kiwoom".equals(pgCmpnyNm)) {
url = "sopmal/ordr/OrdrReqstKiwoomPayR";
} else if ("gcpay".equals(pgCmpnyNm)) {
url = "sopmal/ordr/OrdrReqstGcpayPayR";
} else if ("kcp".equals(pgCmpnyNm)) {
if ("sopmal_m".equals(deviceType)) {
@@ -1173,19 +1175,6 @@ public class OrdrController {
payVO.setSetlerNm(request.getParameter("buyr_name"));
//에스크로 정보추가
/*payVO.setEscwUsed(request.getParameter("escw_used"));
payVO.setPayMod(request.getParameter("pay_mod"));
payVO.setRcvrName(request.getParameter("rcvr_name"));
payVO.setRcvrTel1(request.getParameter("rcvr_tel1"));
payVO.setRcvrTel2(request.getParameter("rcvr_tel2"));
payVO.setRcvrZipx(request.getParameter("rcvr_zipx"));
payVO.setRcvrAdd1(request.getParameter("rcvr_add1"));
payVO.setRcvrAdd2(request.getParameter("rcvr_add2"));
payVO.setDeliTerm(request.getParameter("deli_term"));
payVO.setBaskCntx(request.getParameter("bask_cntx"));
payVO.setGoodInfo(request.getParameter("good_info"));*/
log.debug("payVO => {} ", new Gson().toJson(payVO));
String resCd = request.getParameter("res_cd");
@@ -1383,6 +1372,101 @@ public class OrdrController {
return "sopmal/ordr/OrdrRspnsTossPayR";
}
/**
* 사용자 > 상품 > 구매/결제 > 회원구매하기 > 키움 결제 정보 등록
* @param model
* @param request
* @return OrdrRspnsKiwoomPayR.jsp
*/
@Policy(AuthPolicy.RESTRICTED)
@RequestMapping(value="/insertKiwoomSetle")
public String insertKiwoomSetle(ModelMap model, HttpServletRequest request) {
BOPayVO payVO = new BOPayVO();
payVO.setOrderId(request.getParameter("orderId"));
payVO.setAmount(request.getParameter("setleAmt"));
payVO.setSopmalCd(request.getParameter("sopmalCd"));
payVO.setMbrInnb(request.getParameter("mbrInnb"));
payVO.setMbrId(request.getParameter("mbrId"));
payVO.setSesionId(request.getParameter("sesionId"));
payVO.setPgCmpnyNm(request.getParameter("pgCmpnyNm"));
payVO.setSetleTyCd(request.getParameter("setleTyCd"));
payVO.setSetlerNm(request.getParameter("ordrrNm"));
String agentId = "";
String jSesionId = "";
String ipAdres = "";
// 쿠키를 가져옴
Cookie[] cookies = request.getCookies();
//agentId 쿠키 있을 경우 가져옴
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("JSESSIONID")) {
jSesionId = cookie.getValue();
payVO.setSessionId(jSesionId);
}
}
}
//gc_agent_id 가져옴
if (CookieUtil.hasAgentCookie(request.getCookies())) {
agentId = CookieUtil.getAgentCookieValue(request.getCookies());
payVO.setAgentId(agentId);
}
Map<String, String> util = new HashMap<>();
util = utilClass.getRequestInfo(request);
ipAdres = util.get("XForwardedFor");
payVO.setIpAdres(ipAdres);
AnonymousUser user = MemberJwtContextHolder.getMemberInfo();
payVO.setMbrNm(user.getMbrNm()); //회원명(관리자명)
if ("01".equals(user.getSysDvCd())) {
payVO.setDvCd("01");
payVO.setSopmalCd(user.getSopmalCd());
payVO.setMbrDvCd(user.getMbrDvCd());
} else {
payVO.setDvCd("02");
}
Map<String, Object> content;
try {
content = service.insertKiwoomSetle(payVO);
} catch (WnbtRestException wre) {
log.info("insertKiwoomSetle : 키움 결제 정보 등록 : 실패 WnbtRestException");
log.error(wre.getMessage(), wre);
content = new HashMap<>() {{
put("status", "1");
put("message", wre.getMessage());
}};
} catch (Exception e) {
log.info("insertKiwoomSetle : 키움 결제 정보 등록 : 실패");
log.error(e.getMessage(), e);
content = new HashMap<>() {{
put("status", "1");
put("message", "키움 결제 정보 등록이 실패하였습니다.\n관리자에게 문의하시기 바랍니다.");
}};
}
if ("0".equals(content.get("status"))) {
commonOrderPostProcess(payVO);
}
model.addAttribute("data", content);
// responseHandler.handleResponse(
// sendToResrc.ofPost(RESRC.GCONEBO, "/gcone/ordr/ordr/insertBOTosspaySetle", payVO),
// model,
// "data"
// );
model.addAttribute("paramVO", payVO);
return "sopmal/ordr/OrdrRspnsKiwoomPayR";
}
/**
* 사용자 > 상품 > 구매/결제 > 회원구매하기 > 주문완료 화면 이동
* @return OrdrComptR.jsp

View File

@@ -703,98 +703,6 @@ public class PayController {
}
/**
* 키움 결제 연계처리 - 결과통보페이지
* @return PayKiwoomSucsC.jsp
* @author 이경숙
*/
@Policy(AuthPolicy.RESTRICTED)
@RequestMapping(value="/kiwoomPayWebhook")
@ResponseBody
public ResponseEntity<String> selectPaymentkiwoomWebhook(HttpServletRequest request) throws Exception {
String resultCode = request.getParameter("RESULTCODE");
String orderNo = request.getParameter("ORDERNO");
String amount = request.getParameter("AMOUNT");
printKiwoomRequest(request);
/* 실제 처리해야 되는 부분
// 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 = "<html><body><RESULT>SUCCESS</RESULT></body></html>";
return ResponseEntity.ok()
.contentType(MediaType.TEXT_HTML)
.body(response);
}
public static void printKiwoomRequest(HttpServletRequest request) {
try {
System.out.println("========== [KIWOOM REQUEST START] ==========");
// 1. 기본 정보
System.out.println("URL : " + request.getRequestURL());
System.out.println("METHOD : " + request.getMethod());
System.out.println("QUERY : " + request.getQueryString());
System.out.println("REMOTE IP : " + request.getRemoteAddr());
// 2. 파라미터 (가장 중요)
System.out.println("---------- PARAM ----------");
request.getParameterMap().forEach((key, values) -> {
System.out.println(key + " = " + Arrays.toString(values));
});
// 3. 헤더
System.out.println("---------- HEADER ----------");
Collections.list(request.getHeaderNames()).forEach(header -> {
System.out.println(header + " = " + request.getHeader(header));
});
// 4. Body (JSON 대응)
System.out.println("---------- BODY ----------");
StringBuilder body = new StringBuilder();
BufferedReader reader = request.getReader();
String line;
while ((line = reader.readLine()) != null) {
body.append(line);
}
System.out.println(body.toString());
System.out.println("========== [KIWOOM REQUEST END] ==========");
} catch (Exception e) {
System.out.println("❌ REQUEST LOG ERROR");
e.printStackTrace();
}
}
/**
* 키움 결제 연계처리 - 성공결과페이지
* @return PayKiwoomSucsC.jsp