+++ src/main/java/itn/let/mjo/pay/service/MjonPayTossService.java
... | ... | @@ -0,0 +1,23 @@ |
| 1 | +package itn.let.mjo.pay.service; | |
| 2 | + | |
| 3 | +import itn.com.cmm.LoginVO; | |
| 4 | + | |
| 5 | +import java.io.IOException; | |
| 6 | +import java.util.List; | |
| 7 | +import java.util.Map; | |
| 8 | + | |
| 9 | +public interface MjonPayTossService { | |
| 10 | + Map<String, Object> processTossConfirm(String paymentKey, String orderId, String amount, LoginVO loginVO) throws Exception; | |
| 11 | + | |
| 12 | +// public int selectBLineMberCnt(String mberId) throws Exception; | |
| 13 | +// | |
| 14 | +// public int insertPrePayInfo(MjonPrePayVO mjonPrePayVO) throws Exception; | |
| 15 | +// | |
| 16 | +// public List<MjonPrePayVO> selectPrePayList(MjonPrePayVO mjonPrePayVO) throws Exception; | |
| 17 | +// | |
| 18 | +// public int deletePrePayInfo(MjonPrePayVO mjonPrePayVO) throws Exception; | |
| 19 | +// | |
| 20 | +// public MjonPrePayVO selectPrePayInfo(MjonPrePayVO mjonPrePayVO) throws Exception; | |
| 21 | +// | |
| 22 | +// public int updatePrePayModify(MjonPrePayVO mjonPrePayVO) throws Exception; | |
| 23 | +} |
--- src/main/java/itn/let/mjo/pay/service/MjonPayVO.java
+++ src/main/java/itn/let/mjo/pay/service/MjonPayVO.java
... | ... | @@ -246,6 +246,6 @@ |
| 246 | 246 |
private String managerNm; // 담당자명 |
| 247 | 247 |
private String prePaymentYn; // 선불결제여부 N:후불제고객 |
| 248 | 248 |
private String dept; // 회원종류 p:개인 c:기업 |
| 249 |
- |
|
| 250 |
- |
|
| 249 |
+ |
|
| 250 |
+ |
|
| 251 | 251 |
} |
+++ src/main/java/itn/let/mjo/pay/service/impl/MjonPayTossServiceImpl.java
... | ... | @@ -0,0 +1,232 @@ |
| 1 | +package itn.let.mjo.pay.service.impl; | |
| 2 | + | |
| 3 | +import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl; | |
| 4 | +import itn.com.cmm.LoginVO; | |
| 5 | +import itn.let.mjo.pay.service.MjonPayTossService; | |
| 6 | + | |
| 7 | +import javax.annotation.Resource; | |
| 8 | +import java.io.*; | |
| 9 | +import java.util.Map; | |
| 10 | + | |
| 11 | +import itn.let.mjo.pay.service.MjonPayVO; | |
| 12 | +import itn.let.uat.uia.service.impl.MberManageDAO; | |
| 13 | +import itn.let.uss.umt.service.MberManageVO; | |
| 14 | +import org.springframework.stereotype.Service; | |
| 15 | + | |
| 16 | +import java.nio.charset.StandardCharsets; | |
| 17 | +import java.util.*; | |
| 18 | + | |
| 19 | +import java.net.HttpURLConnection; | |
| 20 | +import java.net.URL; | |
| 21 | +import java.util.Base64; | |
| 22 | +import java.util.HashMap; | |
| 23 | + | |
| 24 | +import org.json.JSONObject; | |
| 25 | + | |
| 26 | +@Service("mjonPayTossService") | |
| 27 | +public class MjonPayTossServiceImpl extends EgovAbstractServiceImpl implements MjonPayTossService { | |
| 28 | + | |
| 29 | + @Resource(name="mjonPrePayDAO") | |
| 30 | + private MjonPrePayDAO mjonPrePayDAO; | |
| 31 | + | |
| 32 | + @Resource(name="mjonPayDAO") | |
| 33 | + private MjonPayDAO mjonPayDAO; | |
| 34 | + | |
| 35 | + /** mberManageDAO */ | |
| 36 | + @Resource(name="mberManageDAO") | |
| 37 | + private MberManageDAO mberManageDAO; | |
| 38 | + | |
| 39 | + /** | |
| 40 | + * 토스페이먼츠 결제 승인 및 내역 저장 | |
| 41 | + * @param paymentKey 토스 결제 고유 키 | |
| 42 | + * @param orderId 상점 주문번호 (MOID) | |
| 43 | + * @param amount 결제 금액 | |
| 44 | + * @param loginVO 로그인 사용자 정보 | |
| 45 | + * @return 처리 결과 Map | |
| 46 | + */ | |
| 47 | + @Override | |
| 48 | + public Map<String, Object> processTossConfirm(String paymentKey, String orderId, String amount, LoginVO loginVO) throws Exception { | |
| 49 | + | |
| 50 | + // 1. 토스 승인 API 호출 설정 | |
| 51 | + String secretKey = "test_gsk_GjLJoQ1aVZ5nzl22xOql3w6KYe2R:"; // 시크릿 키 (뒤에 콜론 필수) | |
| 52 | + String encodedKey = Base64.getEncoder().encodeToString(secretKey.getBytes(StandardCharsets.UTF_8)); | |
| 53 | + | |
| 54 | + URL url = new URL("https://api.tosspayments.com/v1/payments/confirm"); | |
| 55 | + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); | |
| 56 | + connection.setRequestMethod("POST"); | |
| 57 | + connection.setRequestProperty("Authorization", "Basic " + encodedKey); | |
| 58 | + connection.setRequestProperty("Content-Type", "application/json"); | |
| 59 | + connection.setDoOutput(true); | |
| 60 | + | |
| 61 | + // API 요청 바디 생성 (JSON 형식) | |
| 62 | + String jsonBody = String.format("{\"paymentKey\":\"%s\",\"orderId\":\"%s\",\"amount\":%s}", | |
| 63 | + paymentKey, orderId, amount); | |
| 64 | + | |
| 65 | + try (OutputStream os = connection.getOutputStream()) { | |
| 66 | + os.write(jsonBody.getBytes(StandardCharsets.UTF_8)); | |
| 67 | + } | |
| 68 | + | |
| 69 | + // 2. 응답 수신 처리 | |
| 70 | + int responseCode = connection.getResponseCode(); | |
| 71 | + InputStream responseStream = (responseCode == 200) ? connection.getInputStream() : connection.getErrorStream(); | |
| 72 | + | |
| 73 | + StringBuilder resBuilder = new StringBuilder(); | |
| 74 | + try (BufferedReader reader = new BufferedReader(new InputStreamReader(responseStream, StandardCharsets.UTF_8))) { | |
| 75 | + String line; | |
| 76 | + while ((line = reader.readLine()) != null) { | |
| 77 | + resBuilder.append(line); | |
| 78 | + } | |
| 79 | + } | |
| 80 | + | |
| 81 | + if (responseCode != 200) { | |
| 82 | + throw new Exception("토스 결제 승인 실패: " + resBuilder.toString()); | |
| 83 | + } | |
| 84 | + | |
| 85 | + // 3. 응답 데이터 파싱 및 mj_pg 테이블 매핑 | |
| 86 | + JSONObject resObj = new JSONObject(resBuilder.toString()); | |
| 87 | + String method = resObj.getString("method"); // 결제수단 (카드, 가상계좌 등) | |
| 88 | + | |
| 89 | + // 회원 정보 상세 조회 (연락처 등 매핑용) | |
| 90 | + MberManageVO mberManageVO = mberManageDAO.selectMber(loginVO.getId()); | |
| 91 | + | |
| 92 | + // 기존 쿼리의 parameterClass인 VO 객체 생성 및 값 세팅 | |
| 93 | + MjonPayVO payVO = new MjonPayVO(); | |
| 94 | + | |
| 95 | + // [공통 정보 세팅] | |
| 96 | + payVO.setMoid(orderId); // #moid# (idgen으로 생성된 PK) | |
| 97 | + payVO.setPgCode("TOSS"); // #pgCode# | |
| 98 | + payVO.setTid(resObj.getString("paymentKey")); // #tid# | |
| 99 | + payVO.setAmt(String.valueOf(resObj.getLong("totalAmount"))); // #amt# | |
| 100 | + payVO.setGoodsName(resObj.getString("orderName")); // #goodsName# | |
| 101 | + payVO.setMid(resObj.optString("mId")); // #mid# (상점ID 추가) | |
| 102 | + | |
| 103 | + // 고객 정보 매핑 (연락처/이메일 누락 방지) | |
| 104 | + payVO.setUserId(loginVO.getId()); // #userId# | |
| 105 | + payVO.setEmail(mberManageVO.getMberEmailAdres()); // #email# | |
| 106 | + payVO.setPhone(mberManageVO.getMoblphonNo()); // #phone# | |
| 107 | + payVO.setMobile(mberManageVO.getMoblphonNo()); // #mobile# | |
| 108 | + payVO.setBuyerName(loginVO.getName()); // #buyerName# | |
| 109 | + | |
| 110 | + payVO.setResultCode("0000"); // #resultCode# | |
| 111 | + payVO.setResultMsg("정상처리 되었습니다."); // #resultMsg# | |
| 112 | + payVO.setAfterPayYn("N"); // #afterPayYn# (선불 고정) | |
| 113 | + | |
| 114 | + // CASH(공급가액) 계산: 부가세 제외 금액 | |
| 115 | + long totalAmt = resObj.getLong("totalAmount"); | |
| 116 | + long cashAmount = resObj.optLong("suppliedAmount", Math.round(totalAmt / 1.1)); | |
| 117 | + payVO.setCash(Double.parseDouble(String.valueOf(cashAmount))); // #cash# | |
| 118 | + | |
| 119 | + // 4. 결제 수단별 상세 분기 처리 | |
| 120 | + if ("가상계좌".equals(method)) { | |
| 121 | + JSONObject vAccount = resObj.getJSONObject("virtualAccount"); | |
| 122 | + String bankCode = vAccount.getString("bankCode"); | |
| 123 | + | |
| 124 | + payVO.setPayMethod("VBANK"); // #payMethod# | |
| 125 | + payVO.setPgStatus("0"); // #pgStatus# (0: 입금 대기) | |
| 126 | + payVO.setVbankNum(vAccount.getString("accountNumber")); // #vbankNum# | |
| 127 | + payVO.setVbankCode(vAccount.getString("bankCode")); // #vbankCode# | |
| 128 | + | |
| 129 | + // --- 은행 코드 -> 한글명 변환 --- | |
| 130 | + String bankName = ""; | |
| 131 | + switch (bankCode) { | |
| 132 | + case "20": bankName = "우리은행"; break; | |
| 133 | + case "88": bankName = "신한은행"; break; | |
| 134 | + case "11": bankName = "농협"; break; | |
| 135 | + case "04": bankName = "국민은행"; break; | |
| 136 | + case "03": bankName = "기업은행"; break; | |
| 137 | + case "81": bankName = "하나은행"; break; | |
| 138 | + case "07": bankName = "수협"; break; | |
| 139 | + case "31": bankName = "대구은행"; break; | |
| 140 | + case "32": bankName = "부산은행"; break; | |
| 141 | + case "34": bankName = "광주은행"; break; | |
| 142 | + case "37": bankName = "전북은행"; break; | |
| 143 | + case "39": bankName = "경남은행"; break; | |
| 144 | + case "71": bankName = "우체국"; break; | |
| 145 | + case "23": bankName = "SC제일"; break; | |
| 146 | + case "45": bankName = "새마을금고"; break; | |
| 147 | + case "48": bankName = "신협"; break; | |
| 148 | + case "02": bankName = "산업은행"; break; | |
| 149 | + case "90": bankName = "카카오뱅크"; break; | |
| 150 | + case "92": bankName = "토스뱅크"; break; | |
| 151 | + case "89": bankName = "케이뱅크"; break; | |
| 152 | + default: bankName = "기타은행(" + bankCode + ")"; break; | |
| 153 | + } | |
| 154 | + payVO.setVbankName(bankName); | |
| 155 | + | |
| 156 | + // 입금 기한 가공 (YYYYMMDD 형식) | |
| 157 | + String dueDate = vAccount.getString("dueDate").substring(0, 10).replace("-", ""); | |
| 158 | + payVO.setVbankExpDate(dueDate); // #vbankExpDate# | |
| 159 | + | |
| 160 | + } else if ("카드".equals(method)) { | |
| 161 | + JSONObject card = resObj.getJSONObject("card"); | |
| 162 | + payVO.setPayMethod("CARD"); // #payMethod# | |
| 163 | + payVO.setPgStatus("1"); // #pgStatus# (1: 결제 완료)String issuerCode = card.getString("issuerCode"); | |
| 164 | + String issuerCode = card.getString("issuerCode"); | |
| 165 | + payVO.setCardCode(issuerCode); // #cardCode# | |
| 166 | + | |
| 167 | + | |
| 168 | + // --- 카드사 코드 -> 한글명 변환 시작 --- | |
| 169 | + String cardName = ""; | |
| 170 | + switch (issuerCode) { | |
| 171 | + case "36": cardName = "씨티"; break; | |
| 172 | + case "31": cardName = "삼성"; break; | |
| 173 | + case "61": cardName = "현대"; break; | |
| 174 | + case "11": cardName = "농협"; break; | |
| 175 | + case "91": cardName = "카카오뱅크"; break; | |
| 176 | + case "26": cardName = "비씨"; break; | |
| 177 | + case "21": cardName = "하나"; break; | |
| 178 | + case "41": cardName = "신한"; break; | |
| 179 | + case "51": cardName = "롯데"; break; | |
| 180 | + case "15": cardName = "우리"; break; | |
| 181 | + case "01": cardName = "외환"; break; | |
| 182 | + case "12": cardName = "수협"; break; | |
| 183 | + case "46": cardName = "광주"; break; | |
| 184 | + case "33": cardName = "전북"; break; | |
| 185 | + case "62": cardName = "제주"; break; | |
| 186 | + case "35": cardName = "KDB산업"; break; | |
| 187 | + default: cardName = "기타카드(" + issuerCode + ")"; break; | |
| 188 | + } | |
| 189 | + payVO.setCardName(cardName); // #cardName#에 한글명 세팅 | |
| 190 | + | |
| 191 | + } else if ("간편결제".equals(method)) { | |
| 192 | + JSONObject easyPay = resObj.getJSONObject("easyPay"); | |
| 193 | + String provider = easyPay.getString("provider"); | |
| 194 | + | |
| 195 | + payVO.setPayMethod("SPAY"); // #payMethod# | |
| 196 | + payVO.setPgStatus("1"); | |
| 197 | + payVO.setSpayMethod("M"); // #spayMethod# | |
| 198 | + payVO.setCardName(provider); // #cardName# | |
| 199 | + | |
| 200 | + // 기존 SPAY_DIV 코드 매핑 + 토스페이(TOS) 추가 | |
| 201 | + if ("카카오페이".equals(provider)) { | |
| 202 | + payVO.setSpayDiv("KKO"); | |
| 203 | + } else if ("네이버페이".equals(provider)) { | |
| 204 | + payVO.setSpayDiv("NAV"); | |
| 205 | + } else if ("토스페이".equals(provider)) { | |
| 206 | + payVO.setSpayDiv("TOS"); // 요청하신 토스페이 코드 추가 | |
| 207 | + } | |
| 208 | + } | |
| 209 | + | |
| 210 | + // 5. DB INSERT 실행 | |
| 211 | + mjonPayDAO.insertMjPg(payVO); | |
| 212 | + | |
| 213 | + // 컨트롤러 응답용 결과 Map 구성 | |
| 214 | + Map<String, Object> result = new HashMap<>(); | |
| 215 | + result.put("PG_STATUS", payVO.getPgStatus()); | |
| 216 | + result.put("MOID", payVO.getMoid()); | |
| 217 | + result.put("VBANK_NUM", payVO.getVbankNum()); | |
| 218 | + result.put("VBANK_NAME", payVO.getVbankName()); | |
| 219 | + result.put("VBANK_EXP_DATE", payVO.getVbankExpDate()); | |
| 220 | + result.put("AMT", payVO.getAmt()); | |
| 221 | + | |
| 222 | + return result; | |
| 223 | + } | |
| 224 | + | |
| 225 | + /** | |
| 226 | + * 입금 대기 중인 가상계좌 조회 (PayView용) | |
| 227 | + */ | |
| 228 | +/* @Override | |
| 229 | + public Map<String, Object> selectWaitingVBank(String userId) throws Exception { | |
| 230 | + return mjonPayDAO.selectWaitingVBank(userId); | |
| 231 | + }*/ | |
| 232 | +} |
+++ src/main/java/itn/let/mjo/pay/web/MjonPayTossController.java
... | ... | @@ -0,0 +1,130 @@ |
| 1 | +package itn.let.mjo.pay.web; | |
| 2 | + | |
| 3 | +import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper; | |
| 4 | +import itn.com.cmm.LoginVO; | |
| 5 | +import itn.let.mjo.mjocommon.MjonCommon; | |
| 6 | +import itn.let.mjo.msgcampain.service.MjonCandidateService; | |
| 7 | +import itn.let.mjo.pay.service.MjonPayService; | |
| 8 | +import itn.let.mjo.pay.service.MjonPayTossService; | |
| 9 | +import itn.let.mjo.payva.service.VacsVactService; | |
| 10 | +import itn.let.sym.grd.service.MberGrdService; | |
| 11 | +import itn.let.sym.site.service.EgovSiteManagerService; | |
| 12 | +import itn.let.uss.umt.service.EgovMberManageService; | |
| 13 | +import itn.let.uss.umt.service.EgovUserManageService; | |
| 14 | +import itn.let.utl.user.service.MjonNoticeSendUtil; | |
| 15 | +import org.slf4j.Logger; | |
| 16 | +import org.slf4j.LoggerFactory; | |
| 17 | +import org.springframework.beans.factory.annotation.Value; | |
| 18 | +import org.springframework.stereotype.Controller; | |
| 19 | +import org.springframework.web.bind.annotation.RequestMapping; | |
| 20 | +import org.springframework.web.servlet.mvc.support.RedirectAttributes; | |
| 21 | + | |
| 22 | +import javax.annotation.Resource; | |
| 23 | +import javax.servlet.http.HttpServletRequest; | |
| 24 | +import java.util.Map; | |
| 25 | + | |
| 26 | +@Controller | |
| 27 | +public class MjonPayTossController { | |
| 28 | + private static final Logger LOGGER = LoggerFactory.getLogger(MjonPayController.class); | |
| 29 | + | |
| 30 | + @Resource(name = "mjonPayService") | |
| 31 | + private MjonPayService mjonPayService; | |
| 32 | + | |
| 33 | + @Resource(name = "mberManageService") | |
| 34 | + private EgovMberManageService mberManageService; | |
| 35 | + | |
| 36 | + @Resource(name = "mjonCandidateService") | |
| 37 | + private MjonCandidateService mjonCandidateService; | |
| 38 | + | |
| 39 | + //전용계좌 서비스 | |
| 40 | + @Resource(name = "vacsVactService") | |
| 41 | + private VacsVactService vacsVactService; | |
| 42 | + | |
| 43 | + /** userManageService */ | |
| 44 | + @Resource(name = "userManageService") | |
| 45 | + private EgovUserManageService userManageService; | |
| 46 | + | |
| 47 | + /** 사이트 설정 */ | |
| 48 | + @Resource(name = "egovSiteManagerService") | |
| 49 | + EgovSiteManagerService egovSiteManagerService; | |
| 50 | + | |
| 51 | + /** 알림전송 Util */ | |
| 52 | + @Resource(name = "mjonNoticeSendUtil") | |
| 53 | + private MjonNoticeSendUtil mjonNoticeSendUtil; | |
| 54 | + | |
| 55 | + @Resource(name="MjonCommon") | |
| 56 | + private MjonCommon mjonCommon; | |
| 57 | + | |
| 58 | + @Resource(name = "mberGrdService") | |
| 59 | + MberGrdService mberGrdService; | |
| 60 | + @Resource(name = "mjonPayTossService") | |
| 61 | + MjonPayTossService mjonPayTossService; | |
| 62 | + | |
| 63 | + /** KG 모빌리언스 설정 */ | |
| 64 | + // CARD | |
| 65 | + @Value("#{globalSettings['Globals.pay.kgm.card.cnSvcid']}") | |
| 66 | + private String globalCnSvcid; | |
| 67 | + @Value("#{globalSettings['Globals.pay.kgm.card.payMode']}") | |
| 68 | + private String globalCnPayMode; | |
| 69 | + | |
| 70 | + // BANK | |
| 71 | + @Value("#{globalSettings['Globals.pay.kgm.bank.raSvcid']}") | |
| 72 | + private String globalRaSvcid; | |
| 73 | + @Value("#{globalSettings['Globals.pay.kgm.bank.payMode']}") | |
| 74 | + private String globalRaPayMode; | |
| 75 | + | |
| 76 | + // MOBILE | |
| 77 | + @Value("#{globalSettings['Globals.pay.kgm.mobile.mcSvcid']}") | |
| 78 | + private String globalMcSvcid; | |
| 79 | + @Value("#{globalSettings['Globals.pay.kgm.mobile.payMode']}") | |
| 80 | + private String globalMcPayMode; | |
| 81 | + | |
| 82 | + @RequestMapping(value = "/web/member/pay/tossSuccess.do") | |
| 83 | + public String tossSuccess(HttpServletRequest request | |
| 84 | + , RedirectAttributes redirectAttributes) throws Exception { | |
| 85 | + | |
| 86 | + LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated() ? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser() : null; | |
| 87 | + if(loginVO == null) return "redirect:/web/user/login/login.do"; | |
| 88 | + | |
| 89 | + // 파라미터 수신 | |
| 90 | + String paymentKey = request.getParameter("paymentKey"); | |
| 91 | + String orderId = request.getParameter("orderId"); | |
| 92 | + String amount = request.getParameter("amount"); | |
| 93 | + | |
| 94 | + try { | |
| 95 | + // 비즈니스 로직 호출 | |
| 96 | + Map<String, Object> result = mjonPayTossService.processTossConfirm(paymentKey, orderId, amount, loginVO); | |
| 97 | + | |
| 98 | + // 가상계좌일 경우 화면에 띄울 데이터 전달 | |
| 99 | + if ("0".equals(result.get("PG_STATUS"))) { | |
| 100 | + redirectAttributes.addFlashAttribute("vbankInfo", result); | |
| 101 | + redirectAttributes.addFlashAttribute("isVbankIssued", "Y"); | |
| 102 | + return "redirect:/web/member/pay/PayView.do"; // 결제뷰로 이동 | |
| 103 | + } | |
| 104 | + | |
| 105 | + return "redirect:/web/member/pay/PayList.do"; // 일반 결제는 리스트로 이동 | |
| 106 | + | |
| 107 | + } catch (Exception e) { | |
| 108 | + redirectAttributes.addFlashAttribute("message", e.getMessage()); | |
| 109 | + return "redirect:/web/member/pay/tossFail.do"; | |
| 110 | + } | |
| 111 | + } | |
| 112 | + | |
| 113 | + | |
| 114 | + @RequestMapping(value = "/web/member/pay/tossFail.do") | |
| 115 | + public String tossFail(HttpServletRequest request, RedirectAttributes redirectAttributes) throws Exception { | |
| 116 | + | |
| 117 | + String code = request.getParameter("code"); | |
| 118 | + String message = request.getParameter("message"); | |
| 119 | + | |
| 120 | + // 로그 기록 | |
| 121 | + LOGGER.error("결제 실패 원인: [{}] {}", code, message); | |
| 122 | + | |
| 123 | + // 다시 결제 화면으로 보낼 때 실패 메시지를 전달 | |
| 124 | + // FlashAttribute는 리다이렉트 후 한 번만 유지되는 데이터입니다. | |
| 125 | + redirectAttributes.addFlashAttribute("payErrorMsg", message); | |
| 126 | + redirectAttributes.addFlashAttribute("payErrorCode", code); | |
| 127 | + | |
| 128 | + return "redirect:/web/member/pay/PayView.do"; | |
| 129 | + } | |
| 130 | +} |
--- src/main/java/itn/let/mjo/pay/web/MjonPayV2Controller.java
+++ src/main/java/itn/let/mjo/pay/web/MjonPayV2Controller.java
... | ... | @@ -1,22 +1,26 @@ |
| 1 | 1 |
package itn.let.mjo.pay.web; |
| 2 | 2 |
|
| 3 |
+import java.io.BufferedReader; |
|
| 4 |
+import java.io.InputStream; |
|
| 5 |
+import java.io.InputStreamReader; |
|
| 6 |
+import java.io.OutputStream; |
|
| 7 |
+import java.net.HttpURLConnection; |
|
| 8 |
+import java.net.URL; |
|
| 9 |
+import java.nio.charset.StandardCharsets; |
|
| 3 | 10 |
import java.text.SimpleDateFormat; |
| 4 |
-import java.util.ArrayList; |
|
| 5 |
-import java.util.Arrays; |
|
| 6 |
-import java.util.Calendar; |
|
| 7 |
-import java.util.Date; |
|
| 8 |
-import java.util.List; |
|
| 9 |
-import java.util.Random; |
|
| 11 |
+import java.util.*; |
|
| 10 | 12 |
|
| 11 | 13 |
import javax.annotation.Resource; |
| 12 | 14 |
import javax.servlet.http.HttpServletRequest; |
| 13 | 15 |
import javax.servlet.http.HttpServletResponse; |
| 14 | 16 |
import javax.servlet.http.HttpSession; |
| 15 | 17 |
|
| 18 |
+import org.json.JSONObject; |
|
| 16 | 19 |
import org.slf4j.Logger; |
| 17 | 20 |
import org.slf4j.LoggerFactory; |
| 18 | 21 |
import org.springframework.beans.factory.annotation.Value; |
| 19 | 22 |
import org.springframework.stereotype.Controller; |
| 23 |
+import org.springframework.ui.Model; |
|
| 20 | 24 |
import org.springframework.ui.ModelMap; |
| 21 | 25 |
import org.springframework.web.bind.annotation.ModelAttribute; |
| 22 | 26 |
import org.springframework.web.bind.annotation.RequestMapping; |
... | ... | @@ -1877,5 +1881,6 @@ |
| 1877 | 1881 |
|
| 1878 | 1882 |
return rtnVal; |
| 1879 | 1883 |
} |
| 1880 |
- |
|
| 1884 |
+ |
|
| 1885 |
+ |
|
| 1881 | 1886 |
} |
--- src/main/webapp/WEB-INF/jsp/web/pay/PayView.jsp
+++ src/main/webapp/WEB-INF/jsp/web/pay/PayView.jsp
... | ... | @@ -21,6 +21,16 @@ |
| 21 | 21 |
let paymentMethodWidget; |
| 22 | 22 |
|
| 23 | 23 |
$(document).ready(function(){
|
| 24 |
+ |
|
| 25 |
+ // 서버에서 보낸 payErrorMsg가 있는지 확인 |
|
| 26 |
+ var errorMsg = "${payErrorMsg}";
|
|
| 27 |
+ |
|
| 28 |
+ if (errorMsg && errorMsg !== "") {
|
|
| 29 |
+ // 사용자에게 익숙한 alert 띄우기 |
|
| 30 |
+ alert("결제에 실패하였습니다.\n사유: " + errorMsg);
|
|
| 31 |
+ } |
|
| 32 |
+ |
|
| 33 |
+ |
|
| 24 | 34 |
setPriceMake(); |
| 25 | 35 |
// 다음 결제시 결제수단 SELECT (필요 시 유지) |
| 26 | 36 |
// getNextPayMethod(); |
... | ... | @@ -92,15 +102,24 @@ |
| 92 | 102 |
alert("최소 충전금액 5천원 이상 선택해주세요.");
|
| 93 | 103 |
return false; |
| 94 | 104 |
} |
| 105 |
+ // const paymentMethodsWidget = paymentWidget.renderPaymentMethods(); |
|
| 106 |
+ // const selectedPaymentMethod = paymentMethodsWidget.getSelectedPaymentMethod(); |
|
| 107 |
+ // console.log('paymentMethodsWidget : ', paymentMethodsWidget);
|
|
| 108 |
+ // console.log('selectedPaymentMethod : ', selectedPaymentMethod);
|
|
| 95 | 109 |
|
| 96 | 110 |
// 토스페이먼츠 결제창 바로 호출 |
| 97 | 111 |
paymentWidget.requestPayment({
|
| 98 | 112 |
orderId: 'ORDER_' + new Date().getTime(), // 고유한 상점 주문번호 생성 |
| 99 | 113 |
orderName: '문자온 충전 ' + lastPrice + '원', |
| 100 | 114 |
successUrl: window.location.origin + '/web/member/pay/tossSuccess.do', // 결제 성공 시 이동할 URL (백엔드 컨트롤러 생성 필요) |
| 115 |
+ // paymentType=NORMAL |
|
| 116 |
+ // &orderId=ORDER_1778047452906 |
|
| 117 |
+ // &paymentKey=tmunj2026050615041659Zv9 |
|
| 118 |
+ // &amount=55000 |
|
| 101 | 119 |
failUrl: window.location.origin + '/web/member/pay/tossFail.do', // 결제 실패 시 이동할 URL (백엔드 컨트롤러 생성 필요) |
| 102 |
- customerEmail: 'hoyoung.lee@gmail.com', // 필요시 로그인한 사용자의 이메일 매핑 |
|
| 103 |
- customerName: '이호영' // 필요시 로그인한 사용자의 이름 매핑 |
|
| 120 |
+ customerEmail: $('#mberEmailAdres').val(), // 필요시 로그인한 사용자의 이메일 매핑
|
|
| 121 |
+ customerName: $('#mberNm').val(), // 필요시 로그인한 사용자의 이름 매핑
|
|
| 122 |
+ customerMobilePhone: $('#moblphonNo').val()
|
|
| 104 | 123 |
}).catch(function (error) {
|
| 105 | 124 |
if (error.code === 'USER_CANCEL') {
|
| 106 | 125 |
alert('결제를 취소하셨습니다.');
|
... | ... | @@ -159,6 +178,9 @@ |
| 159 | 178 |
<input type="hidden" id="payMethod" name="payMethod" /> |
| 160 | 179 |
<input type="hidden" id="accMsg" name="accMsg" /> |
| 161 | 180 |
<input type="hidden" id="sendCnt" name="sendCnt" value="<c:out value='${resultMsgInfo.sendCnt}'/>" />
|
| 181 |
+ <input type="hidden" id="mberEmailAdres" value="<c:out value='${mberManageVO.mberEmailAdres}'/>" />
|
|
| 182 |
+ <input type="hidden" id="moblphonNo" value="<c:out value='${mberManageVO.moblphonNo}'/>" />
|
|
| 183 |
+ <input type="hidden" id="mberNm" value="<c:out value='${mberManageVO.mberNm}'/>" />
|
|
| 162 | 184 |
<!-- content 영역 --> |
| 163 | 185 |
<div class="inner"> |
| 164 | 186 |
<!-- send top --> |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?