73 Commits

Author SHA1 Message Date
이대환
2e33dc43f3 쇼핑몰 사이트맵 xml 자동 생성 2026-09-08 13:59:18 +09:00
이주일
5f3687deb1 Revert "fix: 관리자 대시보드 쇼핑몰 선택 유지"
This reverts commit 7b24a5395f.
2026-08-26 23:12:45 +09:00
이주일
a59dc92601 Revert "fix: 관리자 대시보드 게시글 링크 쇼핑몰 코드 전달"
This reverts commit 5527c23171.
2026-08-26 23:12:45 +09:00
이주일
5527c23171 fix: 관리자 대시보드 게시글 링크 쇼핑몰 코드 전달 2026-08-26 23:07:17 +09:00
이주일
7b24a5395f fix: 관리자 대시보드 쇼핑몰 선택 유지 2026-08-26 23:00:02 +09:00
이주일
87da1e547e fix: 모바일 전체메뉴 하위 카테고리 표시 개선 2026-08-26 17:22:16 +09:00
이대환
889639a63b fix : 카카오 상담문의 아이콘 스타일 적용(모바일)
fix : 상품 문의(모바일)
fix : 게시판 목록 조회(모바일)
2026-08-26 12:24:29 +09:00
이대환
7594ebcb88 fix : 카카오 상담문의 아이콘 변경 2026-08-25 17:18:32 +09:00
이대환
60f28bae5a 게시판 > 게시판 관리 > 게시글 보기/등록/수정 - 화폐단위 변경 (원 → 円) 2026-08-25 11:07:49 +09:00
이대환
4ad51df503 게시판 > 게시판 관리 > 게시글 등록/수정 - 상품 정보(추천 상품) 문구 2026-08-20 18:29:56 +09:00
이대환
bb3ecebad1 fix : 카카오 상담문의 아이콘 위치 변경 2026-08-20 18:29:56 +09:00
이대환
342bea50d6 fix : 카카오 상담문의 아이콘 위치 변경 2026-08-20 18:29:55 +09:00
이대환
103621fe2a fix : 운영 관리자/통합관리자 로고 변경 2026-08-19 12:12:14 +09:00
이대환
8be851c472 카카오 상담문의(카카오톡 채널) 2026-08-18 16:11:03 +09:00
이대환
27301d554b fix : 주문 > 주문 관리 > 전체주문조회 > 프린트 - 발주서 다운로드 화면으로 대체 2026-08-18 16:06:55 +09:00
이대환
668823a32a fix : 배송조회(운송장번호 조회) - 발송 예정 문구 수정 2026-08-14 16:58:45 +09:00
이대환
24c697bfbf fix : 결제, 취소 - 키움결제 네이버페이 CPID 관련 적용 2026-08-12 12:52:15 +09:00
이대환
9347d5407c fix : 서치어드바이저 소유권 코드 수정 2026-08-07 12:19:59 +09:00
이대환
0aad369f61 fix : 서치어드바이저 소유권 코드 수정
fix : 카카오 상담문의(카카오톡 채널) 삭제
2026-08-07 11:42:35 +09:00
이대환
04493a107c 카카오 상담문의(카카오톡 채널) 2026-08-05 11:08:51 +09:00
이주일
a86e1e5c16 fix: 주문 원화 결제금액 10원 단위 버림 적용 2026-07-25 20:34:42 +09:00
이대환
f4e9a49b12 fix : 주문 > 주문 관리 > 전체주문조회 > 발주서 다운로드 - 발주서 관리 2026-07-22 17:28:42 +09:00
이대환
4bec8b7eb9 fix : 주문 > 주문 관리 > 전체주문조회 > 주문 상세 - 배송지 정보 개인통관부호 추가 2026-07-22 16:18:32 +09:00
이대환
808b2c8b03 주문 > 주문 관리 > 전체주문조회 > 발주서 다운로드 - 발주서 관리 2026-07-22 11:04:55 +09:00
이주일
f9b8c8712a fix: 관리자 세션 만료 리다이렉트 루프 방지 2026-07-21 10:34:27 +09:00
이주일
c6c041819b fix: 게시판 연관상품 이미지 필드 통일 2026-07-19 16:05:17 +09:00
이주일
f1767425a0 fix: 게시판 상세 등록일 및 모바일 등록 권한 노출 보정 2026-07-19 14:46:46 +09:00
이주일
cb0157a73b fix: 관리자 게시판 연관상품 이미지 및 로컬 인증 보정 2026-07-19 09:07:52 +09:00
이주일
7564dc21e5 fix: 관리자 게시판 인증 및 저장 오류 처리 2026-07-18 23:32:26 +09:00
이주일
06760482aa merge: develop 게시판 등록 버튼 권한 노출 반영 2026-07-18 15:55:11 +09:00
이주일
1c48d65b7b fix: 관리자 게시판 등록 권한 및 URL 표시 개선 2026-07-18 12:37:10 +09:00
이주일
15f299d842 fix: 추천상품 표시 순서 적용 2026-07-18 12:34:26 +09:00
이주일
49738b87bd fix: 추천상품 표시 설정 및 품절 안내 적용 2026-07-18 12:34:26 +09:00
이주일
1b52e2ecbd fix: 추천상품 PC 카드 목록 구조 통일 2026-07-18 12:34:26 +09:00
이주일
de7bb587e2 fix: 추천상품 카드 표시 기준 보정 2026-07-18 12:34:26 +09:00
이주일
de3c84957d feat: 게시판 연관상품 목록 표준화 2026-07-18 12:34:26 +09:00
이주일
ff289ac2c8 fix: 상품 이미지 업로드 투명도 보존 2026-07-17 14:59:44 +09:00
이주일
19586bd744 feat: 일반게시판 연관상품 노출 지원 2026-07-17 02:49:11 +09:00
이주일
fc47ad11ad fix: 품절 및 판매중지 상품 후순위 정렬 2026-07-16 17:25:47 +09:00
이주일
ad649de088 fix: 매거진 상세 목록 버튼 이동 오류 수정 2026-07-16 17:25:46 +09:00
이주일
c6d656b648 feat: 상품배지설정관리 프로그램 추가 2026-07-16 02:26:31 +09:00
이주일
ac2402d764 feat: 쇼핑몰 상품 배지 마스터 연동 2026-07-16 02:26:31 +09:00
이대환
df8c176dbb fix : 품절 문구 수정 (Sold Out → 입고 대기중) 2026-07-13 16:20:50 +09:00
jazz
846de3009c Revert "fix : 상품상세화면 호출시 title 및 meta 정보에 상품제목 노출"
This reverts commit 194ab35b
2026-07-13 10:10:08 +09:00
jazz
194ab35ba6 fix : 상품상세화면 호출시 title 및 meta 정보에 상품제목 노출 2026-07-10 17:55:32 +09:00
이대환
f894756a5f 미할인 상품 - 판매가, 할인율 미표시
>> 쇼핑몰 메인
>> 카테고리 목록
>> 상품 검색
>> 상품 상세
>> 장바구니 담기 팝업
>> 장바구니
>> 결제 화면
2026-07-10 11:54:17 +09:00
이주일
82ec7f8b20 fix: 운영 주문상세 배송지 수정 오류 보정 2026-07-10 00:29:13 +09:00
jazz
6222c3b7d1 fix : 서치어드바이저 소유권 코드 추가 2026-07-09 18:07:28 +09:00
이대환
184dbbe21b fix : 결제 - 키움결제 네이버페이 CPID 관련처리(모바일) 2026-07-09 14:59:32 +09:00
이대환
2e28122d97 fix: 주문관리 > 전체주문조회 > 발주서 엑셀 다운로드 - 상품단가(과세 USD) 2026-07-09 12:20:33 +09:00
jazz
297664b621 fix : 서치어드바이저 소유권 코드 추가 2026-07-09 10:00:20 +09:00
이대환
c51f716cc4 fix : 주문 관리 > 전체주문조회 > 전체 주문 목록 - 프린트 화폐단위 변경 (원 → 円) 2026-07-08 18:32:08 +09:00
이대환
2b8e84799d fix : 상품 목록 - 스크롤 불러오기 화폐단위 변경 (원 → 円) 2026-07-08 14:11:46 +09:00
이대환
cb655263af fix : 주문 > 반품환불 관리 > 반품환불 처리 > 반품/환불상세 - 네이버페이 주문 제어 제한 2026-07-08 11:32:07 +09:00
이대환
1de8b5c39f fix : 주문 > 주문 관리 > 전체주문조회, 주문 상세 - 네이버페이 주문 제어 제한 2026-07-08 11:21:33 +09:00
이대환
4074ace97d 배송조회(운송장번호 조회) - aciExpress 팝업 적용
>> 쇼핑몰 주문/배송 > 주문 상세
2026-07-08 10:36:59 +09:00
이대환
28ee8f8556 fix : 주문 > 주문 관리 > 전체주문조회, 주문 상세 - 네이버페이 주문 제어 제한 2026-06-29 12:55:14 +09:00
이대환
bbeb2a630a fix : 주문 > 주문 관리 > 전체주문조회 - 네이버페이 주문 제어 제한 2026-06-29 11:23:10 +09:00
이대환
bc7f738e55 fix : 상품관리 > 상품조회 > 상품 등록/복사재등록 - 상품명(영문), HS Code, 실무게(KG) 2026-06-26 18:36:32 +09:00
이대환
32250636e9 fix : 상품관리 > 상품조회 > 상품 등록/복사재등록 - 상품명(영문), HS Code, 실무게(KG) 2026-06-26 18:35:26 +09:00
이대환
6858b24344 주문 > 주문 관리 > 전체주문조회, 주문 상세 - 네이버페이 주문 제어 제한 2026-06-26 18:09:13 +09:00
이대환
c04668fda2 fix : 배송/반품정보 문구 수정 (반품/교환 → 배송/반품) 2026-06-19 14:41:02 +09:00
이대환
1cab83f69f 쇼핑몰 매거진 - 열람 권한 설정(모바일) 2026-06-11 17:42:08 +09:00
이대환
784cadc6f2 쇼핑몰 매거진 - 열람 권한 설정 2026-06-11 17:36:34 +09:00
이대환
39ce46c4dc batch > 출고 상태 변경 2026-06-10 11:41:02 +09:00
이대환
03ec9d863e 쇼핑몰 검색어 저장 2026-06-05 14:44:03 +09:00
이대환
7bfa5a288c fix : 상품 > 상품관리 > 구독서비스 관리 > 구독서비스 삭제 개선, 목록 선택 체크박스 개선 2026-06-02 11:49:55 +09:00
이대환
56f29943b6 fix : 설정 > 원가 설정 - 기준일자 datepicker 적용 2026-06-02 09:47:09 +09:00
이대환
31561200c2 설정 > 원가 설정 추가 2026-06-01 15:49:41 +09:00
이대환
5fa4aa5c37 fix : 설정 > 패밀리사이트 설정 > 입력창 추가 - 스크립트 개선
fix : 상품관리 > 상품조회 > 상품 등록/복사재등록/수정 - 실무게(KG) 자릿수 제한 개선
2026-06-01 15:48:44 +09:00
이주일
f2038728fd fix: FAQ 상세 조회 Ajax Content-Type 추가 2026-06-01 09:56:19 +09:00
이대환
450e43aecb 주문관리 > 전체주문조회 > 엑셀 다운로드, 다운로드 항목설정 - 상품명(영문), HS Code, 실무게, 부피무게, 포장개수 추가 2026-05-29 15:19:19 +09:00
이대환
1d72e28600 쇼핑몰 상품상세, 주문결제화면 - 예상 적립 마일리지 관련
fix : 쇼핑몰 회원정보수정 - 취소 버튼
fix : 쇼핑몰 회원탈퇴 - 취소 버튼, 주요 혜택
2026-05-29 09:51:04 +09:00
52 changed files with 279 additions and 2154 deletions

View File

@@ -157,8 +157,7 @@ dependencies {
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.11.5") runtimeOnly("io.jsonwebtoken:jjwt-impl:0.11.5")
implementation("io.jsonwebtoken:jjwt-jackson:0.11.5") implementation("io.jsonwebtoken:jjwt-jackson:0.11.5")
// stripe
implementation "com.stripe:stripe-java:33.4.0"
} }
ext { ext {

View File

@@ -282,9 +282,6 @@ public class BOMaMtngService {
int useMlgAmt = Integer.parseInt(goodsList.get(0).getUseMlgAmt()); int useMlgAmt = Integer.parseInt(goodsList.get(0).getUseMlgAmt());
int useCashMlgAmt = Integer.parseInt(goodsList.get(0).getUseCashMlgAmt()); int useCashMlgAmt = Integer.parseInt(goodsList.get(0).getUseCashMlgAmt());
Set<String> validKeys = new HashSet<>(); // 변경 구매정보 리스트 Set<String> validKeys = new HashSet<>(); // 변경 구매정보 리스트
InventoryShortageMessage inventoryMessage = new InventoryShortageMessage();
Set<String> validationKeys = Arrays.stream(PurchsValidCode.values())
.map(PurchsValidCode::getCode).collect(Collectors.toSet());
//마일리지 잔액 확인 //마일리지 잔액 확인
BOMlgSrchVO mlgVo = new BOMlgSrchVO(); BOMlgSrchVO mlgVo = new BOMlgSrchVO();
@@ -320,14 +317,12 @@ public class BOMaMtngService {
// 값이 1인 항목 == 변경항목 // 값이 1인 항목 == 변경항목
List<String> rs = resultValid.stream() List<String> rs = resultValid.stream()
.flatMap(map -> map.entrySet().stream()) .flatMap(map -> map.entrySet().stream())
.filter(entry -> validationKeys.contains(entry.getKey()))
.filter(entry -> "1".equals(StringUtil.isNullToString(entry.getValue()))) .filter(entry -> "1".equals(StringUtil.isNullToString(entry.getValue())))
.map(entry -> StringUtil.isNullToString(entry.getKey())) .map(entry -> StringUtil.isNullToString(entry.getKey()))
.toList(); .toList();
//구매정보 변경유형 저장 //구매정보 변경유형 저장
validKeys.addAll(rs); validKeys.addAll(rs);
inventoryMessage.add(goods, resultValid);
} }
@@ -343,9 +338,7 @@ public class BOMaMtngService {
StringBuilder returnMsg = new StringBuilder(); StringBuilder returnMsg = new StringBuilder();
//상품구매수량제한걸렸을 경우 //상품구매수량제한걸렸을 경우
if (inventoryMessage.hasShortages()) { if(validKeys.contains("purchsQyLmtt")){
returnMsg.append(inventoryMessage.render());
}else if(validKeys.contains("purchsQyLmtt")){
returnMsg.append("구매수량 제한 상품입니다."); returnMsg.append("구매수량 제한 상품입니다.");
returnMsg.append(System.lineSeparator()); //줄바꿈 returnMsg.append(System.lineSeparator()); //줄바꿈
@@ -526,8 +519,6 @@ public class BOMaMtngService {
BOPreOrderValidVO.builder() BOPreOrderValidVO.builder()
.sopmalCd(StringUtil.isNullToString(goods.get("sopmalCd"))) .sopmalCd(StringUtil.isNullToString(goods.get("sopmalCd")))
.goodsInnb(StringUtil.isNullToString(goods.get("goodsInnb"))) .goodsInnb(StringUtil.isNullToString(goods.get("goodsInnb")))
.goodsNm(StringUtil.isNullToString(goods.get("goodsNm")))
.optionNm(StringUtil.isNullToString(goods.get("option")))
.goodsOptnInnb(StringUtil.isNullToString(goods.get("goodsOptnInnb"))) .goodsOptnInnb(StringUtil.isNullToString(goods.get("goodsOptnInnb")))
.subsvcInnb(StringUtil.isNullToString(goods.get("subsvcInnb"))) .subsvcInnb(StringUtil.isNullToString(goods.get("subsvcInnb")))
.mbrInnb(StringUtil.isNullToString(goods.get("mbrInnb"))) .mbrInnb(StringUtil.isNullToString(goods.get("mbrInnb")))

View File

@@ -1,103 +0,0 @@
package com.wb.domainserver.domain.admin.instcSle.mtng.service;
import com.wb.domainserver.domain.admin.instcSle.mtng.vo.BOPreOrderValidVO;
import com.wb.domainserver.util.dataaccess.DataMap;
import org.springframework.util.StringUtils;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/** 재고 판정은 변경하지 않고 조회된 재고 수량으로 안내문만 구성한다. */
final class InventoryShortageMessage {
private final Map<String, Goods> goodsById = new LinkedHashMap<>();
void add(BOPreOrderValidVO request, List<DataMap> rows) {
if (rows.isEmpty()) {
return;
}
boolean subscription = StringUtils.hasText(request.getSubsvcInnb());
String key = request.getSopmalCd() + ":" + (subscription
? "subscription:" + request.getSubsvcInnb() : "goods:" + request.getGoodsInnb());
Goods goods = goodsById.computeIfAbsent(key, ignored -> new Goods());
goods.name = StringUtils.hasText(request.getGoodsNm()) ? request.getGoodsNm()
: "상품번호 " + request.getGoodsInnb();
goods.requested = request.getGoodsTotalQy();
goods.unit = "SK".equals(request.getSopmalCd()) ? "병" : "개";
String optionKey = subscription ? request.getSubsvcInnb() : request.getGoodsOptnInnb();
Option option = goods.options.computeIfAbsent(optionKey, ignored -> new Option());
option.name = StringUtils.hasText(request.getOptionNm()) ? request.getOptionNm()
: "옵션번호 " + request.getGoodsOptnInnb();
option.requested += Long.parseLong(request.getQy());
for (DataMap row : rows) {
if (row.get("stockGoodsNm") != null && StringUtils.hasText(row.get("stockGoodsNm").toString())) {
goods.name = String.valueOf(row.get("stockGoodsNm"));
}
goods.shortage |= "1".equals(String.valueOf(row.get("invntry")))
|| "1".equals(String.valueOf(row.get("invntryPolicy")));
option.available = minimum(option.available, row.get("optionAvailableQy"));
goods.available = minimum(goods.available, row.get("goodsAvailableQy"));
}
}
boolean hasShortages() {
return goodsById.values().stream().anyMatch(goods -> goods.shortage);
}
String render() {
StringBuilder message = new StringBuilder("다음 상품의 구매 가능한 재고가 부족합니다.");
boolean sharedLimit = false;
for (Goods goods : goodsById.values()) {
if (!goods.shortage) {
continue;
}
message.append("\n\n· ").append(goods.name);
if (goods.options.size() == 1) {
Option option = goods.options.values().iterator().next();
message.append("\n 주문 수량: ").append(goods.requested)
.append(goods.unit).append(" / 현재 구매 가능: ")
.append(quantity(minimum(option.available, goods.available), goods.unit));
} else {
sharedLimit = true;
message.append("\n 총 주문 수량: ").append(goods.requested)
.append(goods.unit).append(" / 상품 전체 재고 한도: ").append(quantity(goods.available, goods.unit));
for (Option option : goods.options.values()) {
message.append("\n - ").append(option.name).append(": 주문 ")
.append(option.requested).append(goods.unit).append(" / 옵션별 구매 가능 ")
.append(quantity(minimum(option.available, goods.available), goods.unit));
}
}
}
if (sharedLimit) {
message.append("\n\n옵션별 가능 수량은 상품 전체 재고 한도 안에서 함께 적용됩니다.");
}
return message.append("\n\n주문 수량을 줄이거나 해당 상품을 제외한 후 다시 주문해 주세요.").toString();
}
private static Long minimum(Long current, Object value) {
if (value == null) {
return current;
}
long quantity = Math.max(0L, Long.parseLong(value.toString()));
return current == null ? quantity : Math.min(current, quantity);
}
private static String quantity(Long value, String unit) {
return value == null ? "확인 불가" : value + unit;
}
private static final class Goods {
String name;
String unit;
long requested;
Long available;
boolean shortage;
final Map<String, Option> options = new LinkedHashMap<>();
}
private static final class Option {
String name;
long requested;
Long available;
}
}

View File

@@ -21,10 +21,6 @@ public class BOPreOrderValidVO {
/*상품고유번호*/ /*상품고유번호*/
private String goodsInnb; private String goodsInnb;
private String goodsNm;
private String optionNm;
/*상품옵션고유번호*/ /*상품옵션고유번호*/
private String goodsOptnInnb; private String goodsOptnInnb;

View File

@@ -843,7 +843,6 @@ public class BOMaSopmalService {
mapping.put("memor", "MEMOR_USE_AT"); mapping.put("memor", "MEMOR_USE_AT");
mapping.put("npay", "NPAY_USE_AT"); mapping.put("npay", "NPAY_USE_AT");
mapping.put("kpay", "KPAY_USE_AT"); mapping.put("kpay", "KPAY_USE_AT");
mapping.put("stripe", "STRIPE_USE_AT");
// 모든 매핑된 값의 기본값을 "N"으로 설정 // 모든 매핑된 값의 기본값을 "N"으로 설정
for (String key : mapping.values()) { for (String key : mapping.values()) {

View File

@@ -7,8 +7,6 @@ import com.wb.domainserver.domain.gcone.bbs.cnslt.vo.BOCnsltVO;
import com.wb.domainserver.domain.gcone.common.service.BOCommonService; import com.wb.domainserver.domain.gcone.common.service.BOCommonService;
import com.wb.domainserver.domain.gcone.goods.purchs.mapper.BOPurchsMapper; import com.wb.domainserver.domain.gcone.goods.purchs.mapper.BOPurchsMapper;
import com.wb.domainserver.domain.gcone.goods.purchs.vo.*; import com.wb.domainserver.domain.gcone.goods.purchs.vo.*;
import com.wb.domainserver.domain.gcone.goods.subsvc.service.BOSubsvcService;
import com.wb.domainserver.domain.gcone.goods.subsvc.vo.BOSubsvcVO;
import com.wb.domainserver.domain.gcone.ordr.ordr.mapper.BOOrdrMapper; import com.wb.domainserver.domain.gcone.ordr.ordr.mapper.BOOrdrMapper;
import com.wb.domainserver.domain.gcone.ordr.ordr.vo.BOOrderRestAmtVO; import com.wb.domainserver.domain.gcone.ordr.ordr.vo.BOOrderRestAmtVO;
import com.wb.domainserver.exception.WnbtRestException; import com.wb.domainserver.exception.WnbtRestException;
@@ -53,9 +51,6 @@ public class BOOrderService {
@Autowired @Autowired
private BOOrderNoService orderNoService; private BOOrderNoService orderNoService;
@Autowired
private BOSubsvcService subsvcService;
/** /**
* 관리자 주문 > 주문 등록 * 관리자 주문 > 주문 등록
* @param param * @param param
@@ -981,10 +976,6 @@ public class BOOrderService {
***************************************** */ ***************************************** */
BOOrderSetleVO setleVO = insertSetle(orderVO, setle, insertedGoodsList, enuri, purchsr); // 결제 정보 등록 BOOrderSetleVO setleVO = insertSetle(orderVO, setle, insertedGoodsList, enuri, purchsr); // 결제 정보 등록
if (orderVO.getSubsvcInnb() == null && "stripe".equals(setleVO.getPgCmpnyNm())) {
setleVO.setGoodsNm(buildStripeGoodsName(insertedGoodsList.get(0).getGoodsNm(), goodsList));
}
// 결제금액 원화로 변경 // 결제금액 원화로 변경
// setleVO.setSetleAmt(setleVO.getWonSetleAmt()); // setleVO.setSetleAmt(setleVO.getWonSetleAmt());
@@ -996,13 +987,6 @@ public class BOOrderService {
return content; return content;
} }
static String buildStripeGoodsName(String firstGoodsName, List<LinkedHashMap> goodsList) {
long totalQuantity = goodsList.stream()
.mapToLong(goods -> ((Number) goods.get("qy")).longValue())
.sum();
return totalQuantity > 1 ? firstGoodsName + " 외 " + (totalQuantity - 1) + "병" : firstGoodsName;
}
@Transactional @Transactional
public void insertCnsltMemo(String sopmalCd, BigInteger ordrInnb, LinkedHashMap purchsr, LinkedHashMap enuri, AnonymousUser user) { public void insertCnsltMemo(String sopmalCd, BigInteger ordrInnb, LinkedHashMap purchsr, LinkedHashMap enuri, AnonymousUser user) {
try{ try{
@@ -1247,16 +1231,7 @@ public class BOOrderService {
String goodsNm = ""; String goodsNm = "";
if (orderVO.getSubsvcInnb() != null) { if (insertedGoodsList.size() > 1) {
BOSubsvcVO subscription = new BOSubsvcVO();
subscription.setSopmalCd(sopmalCd);
subscription.setSubsvcInnb(orderVO.getSubsvcInnb().toString());
DataMap detail = subsvcService.selectBOSubsvcDetail(subscription);
goodsNm = detail == null ? "" : StringUtil.isNullToString(detail.get("subsvcNm"));
if (!StringUtils.hasText(goodsNm)) {
throw new WnbtRestException("구독서비스명을 확인할 수 없습니다. 다시 시도해 주세요.");
}
} else if (insertedGoodsList.size() > 1) {
goodsNm = insertedGoodsList.get(0).getGoodsNm() + " 외" + (insertedGoodsList.size() - 1); goodsNm = insertedGoodsList.get(0).getGoodsNm() + " 외" + (insertedGoodsList.size() - 1);
} else { } else {
goodsNm = insertedGoodsList.get(0).getGoodsNm(); goodsNm = insertedGoodsList.get(0).getGoodsNm();
@@ -2614,4 +2589,4 @@ public class BOOrderService {
} }

View File

@@ -137,9 +137,6 @@ public class BOOrdrLogService {
} else if ("05".equals(setleTyCd)) { // 가상계좌(에스크로) } else if ("05".equals(setleTyCd)) { // 가상계좌(에스크로)
logDtlCn = mngrOrder + "이(가) 주문접수(가상계좌 에스크로) 하였습니다."; logDtlCn = mngrOrder + "이(가) 주문접수(가상계좌 에스크로) 하였습니다.";
mngrOrder += "주문접수(가상계좌 에스크로)"; mngrOrder += "주문접수(가상계좌 에스크로)";
}else if ("stripe".equals(setleTyCd)) { // Stripe(엔화결제)
logDtlCn = mngrOrder + "이(가) 주문접수(엔화결제) 하였습니다.";
mngrOrder += "주문접수(엔화결제)";
} else { } else {
mngrOrder += resCd; mngrOrder += resCd;
logDtlCn = message; logDtlCn = message;

View File

@@ -3,15 +3,12 @@ package com.wb.domainserver.domain.gcone.ordr.ordr.service;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.nimbusds.jose.shaded.gson.Gson; import com.nimbusds.jose.shaded.gson.Gson;
import com.stripe.StripeClient;
import com.stripe.model.Charge;
import com.stripe.model.Charge.PaymentMethodDetails;
import com.stripe.model.PaymentIntent;
import com.stripe.model.checkout.Session;
import com.wb.domainserver.common.prop.PropertyService; import com.wb.domainserver.common.prop.PropertyService;
import com.wb.domainserver.domain.admin.instcSle.mtng.mapper.BOMaMtngMapper;
import com.wb.domainserver.domain.admin.store.sopmal.mapper.BOMaSopmalMapper; import com.wb.domainserver.domain.admin.store.sopmal.mapper.BOMaSopmalMapper;
import com.wb.domainserver.domain.admin.sys.comncd.service.BOMaComncdService; import com.wb.domainserver.domain.admin.sys.comncd.service.BOMaComncdService;
import com.wb.domainserver.domain.admin.sys.comncd.vo.BOMaComncdVO; import com.wb.domainserver.domain.admin.sys.comncd.vo.BOMaComncdVO;
import com.wb.domainserver.domain.gcone.goods.goods.service.BOGoodsService;
import com.wb.domainserver.domain.gcone.goods.purchs.mapper.BOPurchsMapper; import com.wb.domainserver.domain.gcone.goods.purchs.mapper.BOPurchsMapper;
import com.wb.domainserver.domain.gcone.goods.purchs.service.BOOrderNoService; import com.wb.domainserver.domain.gcone.goods.purchs.service.BOOrderNoService;
import com.wb.domainserver.domain.gcone.goods.purchs.service.BOOrderService; import com.wb.domainserver.domain.gcone.goods.purchs.service.BOOrderService;
@@ -59,7 +56,9 @@ import org.springframework.util.StringUtils;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.time.*; import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException; import java.time.format.DateTimeParseException;
import java.util.*; import java.util.*;
@@ -2429,7 +2428,7 @@ public class BOOrdrService{
BigDecimal returnPaidDlvyAmt = new BigDecimal(0); // 유료배송 반품 배송비 BigDecimal returnPaidDlvyAmt = new BigDecimal(0); // 유료배송 반품 배송비
int loopCnt = 0; int loopCnt = 0;
if (!CollectionUtils.isEmpty(dlvylcItemList)) { if (!CollectionUtils.isEmpty(dlvylcItemList)) {
log.debug("환불 상품 목록 확인 : {}", dlvylcItemList); log.debug("환불 상품 목록 확인 : {}", dlvylcItemList);
// 1. 주문 금액에서 환불 금액빼는 상품별 금액 합산 변수 선언 // 1. 주문 금액에서 환불 금액빼는 상품별 금액 합산 변수 선언
@@ -5613,123 +5612,6 @@ public class BOOrdrService{
} }
/**
* 사용자 > 상품 > 구매/결제 > 회원구매하기 > Stirpe 결제 정보 등록
* @param payVO
* @return Map<String, Object>
*/
@Transactional
public Map<String, Object> insertStripeSetle(Session stripe, BOPayVO payVO) throws Exception {
boolean payResult = true;
Map<String, Object> content = new HashMap<>();
BOOrderPgLogVO orderPgLogVO = new BOOrderPgLogVO();
orderPgLogVO.setOrdrInnb(new BigInteger(payVO.getOrderId()));
orderPgLogVO.setSopmalCd(payVO.getSopmalCd());
orderPgLogVO.setPgCmpnyNm(payVO.getPgCmpnyNm());
orderPgLogVO.setSetlerNm(payVO.getSetlerNm());
orderPgLogVO.setSetleMthCd(payVO.getSetleTyCd());
try{
// 1. 주문상태 수정 =====================================================
BOOrderVO orderVO = new BOOrderVO();
orderVO.setSopmalCd(payVO.getSopmalCd());
orderVO.setOrdrInnb(new BigInteger(payVO.getOrderId()));
orderVO.setOrdrSttusCd("25"); // 주문상태코드(25:결제확인)
if (StringUtils.hasText(payVO.getMbrInnb())) {
orderVO.setMbrInnb(new BigInteger(payVO.getMbrInnb()));
}
log.info("insertStripeSetle service start ::: ");
// 주문 공통 전처리 ( 상태체크, 상태변경, 마일리지, 쿠폰, GC머니 )
orderCommService.commonOrderPreProcess(payVO, orderVO);
/* ===============================================
결제 API >> DB select로 진행함
================================================== */
StripeClient stripeClient = payService.createStripeClient(payVO.getSopmalCd());
int installmentCount = 0;
PaymentIntent paymentIntent = stripeClient.v1()
.paymentIntents()
.retrieve(stripe.getPaymentIntent());
Charge charge = paymentIntent.getLatestChargeObject();
if(charge != null) {
PaymentMethodDetails paymentMethodDetails = charge.getPaymentMethodDetails();
if(paymentMethodDetails != null) {
PaymentMethodDetails.Card card = paymentMethodDetails.getCard();
if (card != null && card.getInstallments() != null) {
PaymentMethodDetails.Card.Installments installments = card.getInstallments();
if (installments.getPlan() != null && installments.getPlan().getCount() != null) {
installmentCount = Integer.parseInt(installments.getPlan().getCount().toString());
}
}
}
}
/* ===============================================
5. FM_ORDER_PG_LOG 등록값 셋팅
================================================== */
orderPgLogVO.setDelngNb(StringUtil.isNullToString(stripe.getPaymentIntent())); // 거래번호 (결제키)
orderPgLogVO.setConfmDt(StringUtil.isNullToString(Instant.ofEpochSecond(stripe.getCreated()).atZone(ZoneId.of("Asia/Seoul")).toLocalDateTime())); // 승인일시
orderPgLogVO.setApvlnb(StringUtil.isNullToString("")); //승인번호
orderPgLogVO.setCardCmpnyCd(StringUtil.isNullToString("")); //카드사코드
orderPgLogVO.setCardCmpnyNm(StringUtil.isNullToString("")); //카드사명
orderPgLogVO.setNintrAt(StringUtil.isNullToString("")); //무이자여부
orderPgLogVO.setInstlmtMtCnt(installmentCount); //할부개월수
orderPgLogVO.setDelngAmt(stripe.getAmountTotal() != null ? new BigDecimal(stripe.getAmountTotal()) : BigDecimal.valueOf(0));
orderPgLogVO.setEscwAt("N"); // 에스크로여부
orderPgLogVO.setVirtlAcntVrifyKy(""); //매출증빙영수증URL
orderPgLogVO.setRsltMssageCn("정상처리-카드거래");
orderPgLogVO.setRsltCd("0000");
// 6. FM_ORDER_SETLE 수정 ==============================================
BOOrderSetleVO orderSetleVO = new BOOrderSetleVO();
orderSetleVO.setSopmalCd(payVO.getSopmalCd());
orderSetleVO.setOrdrInnb(new BigInteger(payVO.getOrderId()));
orderSetleVO.setPgInnb(orderPgLogVO.getDelngNb());
orderSetleVO.setCredtcardApvlnb(orderPgLogVO.getApvlnb());
orderSetleVO.setSetleTyCd(payVO.getSetleTyCd());
//orderSetleVO.setSetleMid(StringUtil.isNullToString(mapper.selectBOSopSetleMidKeyInqire(payVO))); // 쇼핑몰 결제 MID(상점키) 조회
log.info("insertStripeSetle service StripePayMap_orderSetleVO ::: {}", orderSetleVO);
purchsMapper.updateOrderSetle(orderSetleVO);
log.info("insertStripeSetle service StripePayMap_orderSetleVO end::: ");
content.put("status", "0");
content.put("message", "Stripe 결제 정보 등록을 완료 하였습니다.");
try {
selectBOOrdrMssageSndngProcs(orderVO);
} catch (Exception e) {
log.debug("{} 메시지 발송 실패", payVO.getOrderId());
}
} catch (WnbtRestException wre) {
log.error("insertStripeSetle1 WnbtRestException : ", wre);
payResult = false;
throw wre;
} catch (Exception wre) {
log.error("insertStripeSetle1 Exception : ", wre);
payResult = false;
throw wre;
} finally {
log.info("insertStripeSetle1 order finally !!!!! {} ", payVO.getOrderId());
// FM_ORDER_PG_LOG 등록
ordrLogService.insertBOOrderPgLog(orderPgLogVO);
// 주문 로그
ordrLogService.insertSetleOrderLog(payVO, payResult, "0000", "Stripe 결제 실패 [결제 정보 NULL]");
}
return content;
}
/** /**
@@ -5908,16 +5790,6 @@ public class BOOrdrService{
} }
/**
* Stripe 주문 상태 조회
* @param ordrVO
* @return Map<String, Object>
*/
public DataMap selectOrdrSttus(BOOrdrVO ordrVO) {
return mapper.selectOrdrDtl(ordrVO);
}
/** /**
* 사용자 > 상품 > 구매/결제 > 회원구매하기 > 주문완료 정보 조회 * 사용자 > 상품 > 구매/결제 > 회원구매하기 > 주문완료 정보 조회
* @param ordrVO * @param ordrVO

View File

@@ -20,10 +20,6 @@ import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.nimbusds.jose.shaded.gson.Gson; import com.nimbusds.jose.shaded.gson.Gson;
import com.stripe.StripeClient;
import com.stripe.exception.StripeException;
import com.stripe.model.Event;
import com.stripe.net.Webhook;
import com.wb.domainserver.domain.gcone.goods.purchs.mapper.BOPurchsMapper; import com.wb.domainserver.domain.gcone.goods.purchs.mapper.BOPurchsMapper;
import com.wb.domainserver.domain.gcone.ordr.ordr.service.BOOrdrLogService; import com.wb.domainserver.domain.gcone.ordr.ordr.service.BOOrdrLogService;
import com.wb.domainserver.exception.WnbtRestException; import com.wb.domainserver.exception.WnbtRestException;
@@ -1574,10 +1570,10 @@ public class BOPayService{
String authKey = resultMap.get("kcpSecretKey").toString(); String authKey = resultMap.get("kcpSecretKey").toString();
String cpId = resultMap.get("kcpMid").toString(); String cpId = resultMap.get("kcpMid").toString();
// 개발서버 네이버페이 CPID 관련 적용 취소 // 개발서버 네이버페이 CPID 관련 적용 취소
// if ("naverpay".equals(payVO.getModGubun())) { if ("naverpay".equals(payVO.getModGubun())) {
// authKey = resultMap.get("bpaySecretKey").toString(); authKey = resultMap.get("bpaySecretKey").toString();
// cpId = resultMap.get("bpayMid").toString(); cpId = resultMap.get("bpayMid").toString();
// } }
String amount = payVO.getCancelAmount(); //취소금액 String amount = payVO.getCancelAmount(); //취소금액
String trxId = payVO.getTno(); //거래번호 String trxId = payVO.getTno(); //거래번호
@@ -1748,32 +1744,5 @@ public class BOPayService{
} }
/**
* stripeClient 생성
* @param sopmalCd
*/
public StripeClient createStripeClient(String sopmalCd) throws StripeException {
String stripeSecretKey = selectPayLink(sopmalCd).get("stripeSecretKey").toString();
StripeClient stripeClient = new StripeClient(stripeSecretKey);
return stripeClient;
}
/**
* stripe WebhookEvent 생성
* @param payload
* @param sigHeader
*/
public Event createWebhookEvent(String payload, String sigHeader, String sopmalCd) throws StripeException {
String stripeWebhookKey = selectPayLink(sopmalCd).get("stripeWebhookKey").toString();
Event event = Webhook.constructEvent(
payload,
sigHeader,
stripeWebhookKey
);
return event;
}
} }

View File

@@ -1,9 +1,6 @@
package com.wb.domainserver.domain.gcone.ordr.rtngudrefnd.service; package com.wb.domainserver.domain.gcone.ordr.rtngudrefnd.service;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.stripe.StripeClient;
import com.stripe.model.Refund;
import com.stripe.param.RefundCreateParams;
import com.wb.domainserver.domain.gcone.goods.goods.service.BOGoodsService; import com.wb.domainserver.domain.gcone.goods.goods.service.BOGoodsService;
import com.wb.domainserver.domain.gcone.goods.purchs.mapper.BOPurchsMapper; import com.wb.domainserver.domain.gcone.goods.purchs.mapper.BOPurchsMapper;
import com.wb.domainserver.domain.gcone.goods.purchs.service.BOOrderService; import com.wb.domainserver.domain.gcone.goods.purchs.service.BOOrderService;
@@ -1123,7 +1120,7 @@ public class BORtngudrefndService {
} }
// 개발서버 네이버페이 CPID 구분 적용 취소 // 개발서버 네이버페이 CPID 구분 적용 취소
// payVO.setModGubun(setle.getPgCmpnyNm()); //결제키 구분용 payVO.setModGubun(setle.getPgCmpnyNm()); //결제키 구분용
if ("kiwoom".equals(setle.getPgCmpnyNm())) { if ("kiwoom".equals(setle.getPgCmpnyNm())) {
payVO.setPayMethod("CARD"); payVO.setPayMethod("CARD");
} else if ("naverpay".equals(setle.getPgCmpnyNm())) { } else if ("naverpay".equals(setle.getPgCmpnyNm())) {
@@ -1154,30 +1151,6 @@ public class BORtngudrefndService {
throw new WnbtRestException("잘못된 요청입니다. 관리자에게 문의하세요."); throw new WnbtRestException("잘못된 요청입니다. 관리자에게 문의하세요.");
} }
} else if ("stripe".equals(setle.getPgCmpnyNm())) {
log.debug("stripe 취소 진입");
StripeClient stripeClient = payService.createStripeClient(sopmalCd);
RefundCreateParams params =
RefundCreateParams.builder()
.setPaymentIntent(setle.getPgInnb())
.setAmount(Long.valueOf(cancelAmt))
.build();
Refund refund = stripeClient.v1().refunds().create(params);
String resultCode = refund.getStatus();
if ("succeeded".equals(resultCode)) {
// succeeded : 취소성공
log.debug(resultCode);
message.put("setleStatus", resultCode);
message.put("setleMessage", "Refund is expected to arrive in customer’s bank");
} else {
log.debug(resultCode);
message.put("setleStatus", resultCode);
message.put("setleMessage", resultCode);
logDtlCn = "잘못된 요청입니다. 관리자에게 문의하세요.";
throw new WnbtRestException("잘못된 요청입니다. 관리자에게 문의하세요.");
}
} }
} }

View File

@@ -153,8 +153,6 @@ public class LoginController {
CookieUtils.deleteCookie("token_expire", "/", request, response); CookieUtils.deleteCookie("token_expire", "/", request, response);
response.sendRedirect("/sopmal/login/page/" + RealmContextHolder.getRealm() + "?redirect_uri=" + URLEncoder.encode(request.getParameter("redirect_uri"), StandardCharsets.UTF_8)); response.sendRedirect("/sopmal/login/page/" + RealmContextHolder.getRealm() + "?redirect_uri=" + URLEncoder.encode(request.getParameter("redirect_uri"), StandardCharsets.UTF_8));
// 로그인 이동을 확정한 뒤 원래 URL로 다시 리다이렉트하지 않는다.
return;
}else{ }else{
//리프레쉬 토큰 있을 경우(존재한다는 자체가 refresh토큰이 만료된 상태가 아님) //리프레쉬 토큰 있을 경우(존재한다는 자체가 refresh토큰이 만료된 상태가 아님)

View File

@@ -3,9 +3,6 @@ package com.wb.domainserver.domain.sopmal.ordr.controller;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.nimbusds.jose.shaded.gson.Gson; import com.nimbusds.jose.shaded.gson.Gson;
import com.stripe.model.Event;
import com.stripe.model.checkout.Session;
import com.stripe.net.Webhook;
import com.wb.domainserver.common.msg.GconeMessageSource; import com.wb.domainserver.common.msg.GconeMessageSource;
import com.wb.domainserver.common.mvc.tags.ui.pagination.PaginationInfo; import com.wb.domainserver.common.mvc.tags.ui.pagination.PaginationInfo;
import com.wb.domainserver.common.prop.PaginationProperties; import com.wb.domainserver.common.prop.PaginationProperties;
@@ -59,6 +56,7 @@ import com.wb.domainserver.util.util.Util;
import jakarta.servlet.http.Cookie; import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.StringEscapeUtils;
import org.apache.logging.log4j.util.Base64Util; import org.apache.logging.log4j.util.Base64Util;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
@@ -70,11 +68,15 @@ import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.Reader; import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger; import java.math.BigInteger;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
@@ -852,8 +854,6 @@ public class OrdrController {
url = "sopmal/ordr/OrdrReqstTossPayR"; url = "sopmal/ordr/OrdrReqstTossPayR";
} else if ("tosspay".equals(pgCmpnyNm)||"kakaopay".equals(pgCmpnyNm)) { //||"naverpay".equals(pgCmpnyNm) 키움으로 이동 } else if ("tosspay".equals(pgCmpnyNm)||"kakaopay".equals(pgCmpnyNm)) { //||"naverpay".equals(pgCmpnyNm) 키움으로 이동
url = "sopmal/ordr/OrdrReqstTosspayPayR"; url = "sopmal/ordr/OrdrReqstTosspayPayR";
} else if ("stripe".equals(pgCmpnyNm)) { // Stripe
url = "sopmal/ordr/OrdrReqstStripePayR";
} else if ("02".equals(setleTyCd)||"08".equals(setleTyCd)||"12".equals(setleTyCd)) { // 무통장, 마일리지, 충전형마일리지 } else if ("02".equals(setleTyCd)||"08".equals(setleTyCd)||"12".equals(setleTyCd)) { // 무통장, 마일리지, 충전형마일리지
url = "sopmal/ordr/OrdrReqstPayR"; url = "sopmal/ordr/OrdrReqstPayR";
} }
@@ -1557,110 +1557,6 @@ public class OrdrController {
} }
/**
* 사용자 > 상품 > 구매/결제 > 회원구매하기 > Stripe 결제 정보 등록 (webhook)
* @param payload
* @param sigHeader
* @return OrdrRspnsKiwoomPayR.jsp
*/
@Policy(AuthPolicy.RESTRICTED)
@RequestMapping(value="/{sopmalCd}/insertStripeSetle")
public ResponseEntity<String> insertStripeSetle(@RequestBody String payload, @RequestHeader("Stripe-Signature") String sigHeader, @PathVariable String sopmalCd) {
try {
log.info("insertStripeSetle webhook start ::: ");
Event event = payService.createWebhookEvent(payload, sigHeader, sopmalCd);
if ("checkout.session.completed".equals(event.getType())) {
Session session = (Session) event
.getDataObjectDeserializer()
.getObject()
.orElseThrow();
log.info("insertStripeSetle controller start ::: ");
BOPayVO payVO = new BOPayVO();
payVO.setOrderId(session.getMetadata().get("ordrInnb"));
payVO.setAmount(session.getMetadata().get("setleAmt"));
payVO.setSopmalCd(session.getMetadata().get("sopmalCd"));
payVO.setMbrInnb(session.getMetadata().get("mbrInnb"));
payVO.setMbrId(session.getMetadata().get("mbrId"));
payVO.setSesionId(session.getMetadata().get("sesionId"));
payVO.setPgCmpnyNm(session.getMetadata().get("pgCmpnyNm"));
payVO.setSetleTyCd(session.getMetadata().get("setleTyCd"));
payVO.setSetlerNm(session.getMetadata().get("ordrrNm"));
log.info("insertStripeSetle controller payVO ::: {}", payVO);
/* 쿠키 데이터 세팅 시작 */
String agentId = session.getMetadata().get("agentId");
String jSesionId = session.getMetadata().get("jSesionId");
String ipAdres = session.getMetadata().get("ipAdres");
String uMbrNm = session.getMetadata().get("uMbrNm");
String uSysDvCd = session.getMetadata().get("uSysDvCd");
String uSopmalCd = session.getMetadata().get("uSopmalCd");
String uMbrDvCd = session.getMetadata().get("uMbrDvCd");
//agentId 쿠키 있을 경우 가져옴
if (!"".equals(jSesionId)) {
payVO.setSessionId(jSesionId);
}
//gc_agent_id 가져옴
if (!"".equals(agentId)) {
payVO.setAgentId(agentId);
}
payVO.setIpAdres(ipAdres);
if (!"".equals(uMbrNm)) {
payVO.setMbrNm(uMbrNm); //회원명(관리자명)
}
if ("01".equals(uSysDvCd)) {
payVO.setDvCd("01");
payVO.setSopmalCd(uSopmalCd);
payVO.setMbrDvCd(uMbrDvCd);
} else {
payVO.setDvCd("02");
}
/* 쿠키 데이터 세팅 끝 */
Map<String, Object> content;
try {
content = service.insertStripeSetle(session, payVO);
log.info("insertStripeSetle controller content ::: {}", content);
} catch (WnbtRestException wre) {
log.info("insertStripeSetle : Stripe 결제 정보 등록 : 실패 WnbtRestException");
log.error(wre.getMessage(), wre);
content = new HashMap<>() {{
put("status", "1");
put("message", wre.getMessage());
}};
} catch (Exception e) {
log.info("insertStripeSetle : Stripe 결제 정보 등록 : 실패");
log.error(e.getMessage(), e);
content = new HashMap<>() {{
put("status", "1");
put("message", "Stripe 결제 정보 등록이 실패하였습니다.\n관리자에게 문의하시기 바랍니다.");
}};
}
if ("0".equals(content.get("status"))) {
commonOrderPostProcess(payVO);
}
}
} catch (Exception e) {
log.debug("Webhook error ::: {}", e);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
return ResponseEntity.ok().build();
}
/** /**
* 사용자 > 상품 > 구매/결제 > 회원구매하기 > 주문완료 화면 이동 * 사용자 > 상품 > 구매/결제 > 회원구매하기 > 주문완료 화면 이동
* @return OrdrComptR.jsp * @return OrdrComptR.jsp

View File

@@ -1,299 +0,0 @@
package com.wb.domainserver.domain.sopmal.stripe.controller;
import com.google.gson.JsonObject;
import com.stripe.StripeClient;
import com.stripe.exception.StripeException;
import com.stripe.model.checkout.Session;
import com.stripe.param.checkout.SessionCreateParams;
import com.wb.domainserver.domain.admin.store.sopmal.service.BOMaSopmalService;
import com.wb.domainserver.domain.admin.store.sopmal.vo.BOMaSopmalVO;
import com.wb.domainserver.domain.gcone.ordr.ordr.service.BOOrdrService;
import com.wb.domainserver.domain.gcone.ordr.ordr.vo.BOOrdrVO;
import com.wb.domainserver.domain.gcone.ordr.pay.service.BOPayService;
import com.wb.domainserver.response.WnbtResponse;
import com.wb.domainserver.response.WnbtResponseBody;
import com.wb.domainserver.security.authentication.AnonymousUser;
import com.wb.domainserver.security.authentication.MemberJwtContextHolder;
import com.wb.domainserver.security.authorization.annotation.AuthPolicy;
import com.wb.domainserver.security.authorization.annotation.Policy;
import com.wb.domainserver.util.cookie.CookieUtil;
import com.wb.domainserver.util.dataaccess.DataMap;
import com.wb.domainserver.util.util.Util;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.http.HttpStatus;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Controller
@RequestMapping("/sopmal/stripe")
public class StripeController {
@Autowired
private BOMaSopmalService boMaSopmalService;
@Autowired
private BOPayService payService;
@Autowired
private BOOrdrService ordrService;
private Util utilClass;
@Value("${stripe.checkout.return-base-url:}")
private String stripeReturnBaseUrl = "";
String resolveStripeReturnBaseUrl(String shopDomain) {
String baseUrl = stripeReturnBaseUrl.isBlank() ? shopDomain : stripeReturnBaseUrl.trim();
return baseUrl.replaceAll("/+$", "");
}
/**
* stripe 결제 Url 호출
* @return selectStripeTest.jsp
*/
@Policy(AuthPolicy.RESTRICTED)
@PostMapping(value = "/checkout", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> createCheckoutSession(HttpServletRequest request) throws Exception {
BOMaSopmalVO sopmalVO = new BOMaSopmalVO();
sopmalVO.setSopmalCd(request.getParameter("sopmalCd"));
DataMap sopmalInfo = boMaSopmalService.selectBOSopmalUpdtForm(sopmalVO).get(0);
String domnAdres = resolveStripeReturnBaseUrl(sopmalInfo.get("pcDomnAdres").toString());
StripeClient stripeClient = payService.createStripeClient(request.getParameter("sopmalCd"));
SessionCreateParams.Builder paramsBuilder = SessionCreateParams.builder()
.setMode(SessionCreateParams.Mode.PAYMENT)
.setSuccessUrl(domnAdres + "/sopmal/stripe/stripeSuccess?sessionId={CHECKOUT_SESSION_ID}&sopmalCd=" + request.getParameter("sopmalCd"))
.setCancelUrl(domnAdres + "/sopmal/stripe/stripeCancel?sessionId={CHECKOUT_SESSION_ID}&sopmalCd=" + request.getParameter("sopmalCd"))
.setAdaptivePricing(
SessionCreateParams.AdaptivePricing.builder()
.setEnabled(false)
.build()
);
String customerEmail = request.getParameter("ordrrEmail");
if (customerEmail != null && !customerEmail.isBlank()) {
paramsBuilder.setCustomerEmail(customerEmail.trim());
}
paramsBuilder.addLineItem(
SessionCreateParams.LineItem.builder()
.setQuantity(1L)
.setPriceData(
SessionCreateParams.LineItem.PriceData.builder()
.setCurrency("jpy")
.setUnitAmount(Long.parseLong(request.getParameter("jpSetleAmt")))
.setProductData(
SessionCreateParams.LineItem.PriceData.ProductData.builder()
.setName(request.getParameter("goodsNm"))
.build()
).build()
).build()
);
paramsBuilder
.putMetadata("sopmalCd", request.getParameter("sopmalCd"))
.putMetadata("ordrInnb", request.getParameter("ordrInnb"))
.putMetadata("pgCmpnyNm", request.getParameter("pgCmpnyNm"))
.putMetadata("setleTyCd", request.getParameter("setleTyCd"))
.putMetadata("goodsNm", request.getParameter("goodsNm"))
.putMetadata("setleAmt", request.getParameter("setleAmt"))
.putMetadata("ordrrNm", request.getParameter("ordrrNm"))
.putMetadata("ordrrEmail", request.getParameter("ordrrEmail"))
.putMetadata("ordrrMbtlnb", request.getParameter("ordrrMbtlnb"))
.putMetadata("mbrId", request.getParameter("mbrId"))
.putMetadata("mbrInnb", request.getParameter("mbrInnb"))
.putMetadata("sesionId", request.getParameter("sesionId"))
.putMetadata("subsvcInnb", request.getParameter("subsvcInnb"));
/* insertStripeSetle() 결제 정보 등록 파라미터 시작 */
String agentId = "";
String jSesionId = "";
String ipAdres = "";
String uMbrNm = "";
String uSysDvCd = "";
String uSopmalCd = "";
String uMbrDvCd = "";
// 쿠키를 가져옴
Cookie[] cookies = request.getCookies();
//agentId 쿠키 있을 경우 가져옴
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("JSESSIONID")) {
jSesionId = cookie.getValue();
}
}
}
//gc_agent_id 가져옴
if (CookieUtil.hasAgentCookie(request.getCookies())) {
agentId = CookieUtil.getAgentCookieValue(request.getCookies());
}
Map<String, String> util = new HashMap<>();
util = utilClass.getRequestInfo(request);
ipAdres = util.get("XForwardedFor");
AnonymousUser user = MemberJwtContextHolder.getMemberInfo();
uMbrNm = user.getMbrNm(); //회원명(관리자명)
if ("01".equals(user.getSysDvCd())) {
uSopmalCd = user.getSopmalCd();
uMbrDvCd = user.getMbrDvCd();
}
paramsBuilder
.putMetadata("agentId", agentId)
.putMetadata("jSesionId", jSesionId)
.putMetadata("ipAdres", ipAdres)
.putMetadata("uMbrNm", uMbrNm)
.putMetadata("uSysDvCd", uSysDvCd)
.putMetadata("uSopmalCd", uSopmalCd)
.putMetadata("uMbrDvCd", uMbrDvCd);
/* insertStripeSetle() 결제 정보 등록 파라미터 끝 */
Session session = stripeClient.v1().checkout().sessions().create(paramsBuilder.build());
DataMap result = new DataMap();
result.put("checkoutUrl", session.getUrl());
result.put("redirectUrl", UriComponentsBuilder.fromPath(request.getContextPath() + "/sopmal/stripe/checkoutRedirect")
.queryParam("sessionId", session.getId())
.queryParam("sopmalCd", request.getParameter("sopmalCd"))
.build().encode().toUriString());
WnbtResponseBody body = new WnbtResponseBody(result);
WnbtResponse response = WnbtResponse.builder().resBody(body).build();
return ResponseEntity.ok(response);
}
/** Stripe 진입 이력을 GET으로 남겨 뒤로가기 시 주문 POST를 재전송하지 않는다. */
@Policy(AuthPolicy.RESTRICTED)
@GetMapping("/checkoutRedirect")
public String checkoutRedirect(ModelMap model, @RequestParam("sessionId") String sessionId,
@RequestParam("sopmalCd") String sopmalCd) throws StripeException {
Session session = payService.createStripeClient(sopmalCd).v1().checkout().sessions().retrieve(sessionId);
AnonymousUser user = MemberJwtContextHolder.getMemberInfo();
if (!String.valueOf(user.getUserInnb()).equals(session.getMetadata().get("mbrInnb"))
|| !sopmalCd.equals(session.getMetadata().get("sopmalCd"))) {
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
}
model.addAttribute("checkoutUrl", "open".equals(session.getStatus()) ? session.getUrl() : "");
model.addAttribute("sessionId", sessionId);
model.addAttribute("sopmalCd", sopmalCd);
return "sopmal/ordr/StripeRedirectR";
}
@Policy(AuthPolicy.RESTRICTED)
@RequestMapping(value = "/stripeSuccess")
public String stripeSuccess(ModelMap model, @RequestParam("sessionId") String sessionId, @RequestParam("sopmalCd") String sopmalCd) throws StripeException {
StripeClient stripeClient = payService.createStripeClient(sopmalCd);
Session session = stripeClient.v1().checkout().sessions().retrieve(sessionId);
String status = session.getStatus();
String paymentStatus = session.getPaymentStatus();
JsonObject customerDetails = null;
JsonObject rawJson = session.getRawJsonObject();
if (rawJson != null
&& rawJson.has("customer_details")
&& !rawJson.get("customer_details").isJsonNull()) {
customerDetails = rawJson.getAsJsonObject("customer_details");
}
BOOrdrVO ordrVO = new BOOrdrVO();
ordrVO.setSopmalCd(sopmalCd);
ordrVO.setOrdrInnb(session.getMetadata().get("ordrInnb"));
DataMap ordrDtl = ordrService.selectOrdrSttus(ordrVO);
if (ordrDtl != null && !"25".equals(ordrDtl.get("ordrSttusCd"))) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
ordrDtl = ordrService.selectOrdrSttus(ordrVO);
}
model.addAttribute("status", status);
model.addAttribute("payment_status", paymentStatus);
model.addAttribute("customer_details", customerDetails);
if("complete".equals(status) && "paid".equals(paymentStatus) && "25".equals(ordrDtl.get("ordrSttusCd"))) {
model.addAttribute("returnUrl", "/sopmal/ordr/selectOrdrCompt");
model.addAttribute("message", "Stripe 결제 정보 등록을 완료 하였습니다.");
} else {
model.addAttribute("returnUrl", "/sopmal/ordr/selectOrdrFailr");
model.addAttribute("message", "Stripe 결제 정보 등록을 실패 하였습니다.");
}
model.addAttribute("sopmalCd", session.getMetadata().get("sopmalCd"));
model.addAttribute("ordrInnb", session.getMetadata().get("ordrInnb"));
model.addAttribute("pgCmpnyNm", session.getMetadata().get("pgCmpnyNm"));
model.addAttribute("setleTyCd", session.getMetadata().get("setleTyCd"));
model.addAttribute("goodsNm", session.getMetadata().get("goodsNm"));
model.addAttribute("setleAmt", session.getMetadata().get("setleAmt"));
model.addAttribute("ordrrNm", session.getMetadata().get("ordrrNm"));
model.addAttribute("ordrrEmail", session.getMetadata().get("ordrrEmail"));
model.addAttribute("ordrrMbtlnb", session.getMetadata().get("ordrrMbtlnb"));
model.addAttribute("mbrId", session.getMetadata().get("mbrId"));
model.addAttribute("mbrInnb", session.getMetadata().get("mbrInnb"));
model.addAttribute("sesionId", session.getMetadata().get("sesionId"));
model.addAttribute("subsvcInnb", session.getMetadata().get("subsvcInnb"));
return "sopmal/ordr/PayStripeSucsC";
}
@Policy(AuthPolicy.RESTRICTED)
@RequestMapping(value = "/stripeCancel")
public String stripeCancel(HttpServletRequest request, ModelMap model, @RequestParam("sessionId") String sessionId, @RequestParam("sopmalCd") String sopmalCd) throws StripeException {
StripeClient stripeClient = payService.createStripeClient(sopmalCd);
Session session = stripeClient.v1().checkout().sessions().retrieve(sessionId);
String status = session.getStatus();
String paymentStatus = session.getPaymentStatus();
if (!("complete".equals(status) && "paid".equals(paymentStatus))) {
model.addAttribute("mobile", "sopmal_m".equals(Util.getDeviceType(request)));
return "sopmal/ordr/StripeCancelR";
}
JsonObject customerDetails = null;
JsonObject rawJson = session.getRawJsonObject();
if (rawJson != null
&& rawJson.has("customer_details")
&& !rawJson.get("customer_details").isJsonNull()) {
customerDetails = rawJson.getAsJsonObject("customer_details");
}
model.addAttribute("status", status);
model.addAttribute("payment_status", paymentStatus);
model.addAttribute("customer_details", customerDetails);
if("complete".equals(status) && "paid".equals(paymentStatus)) {
model.addAttribute("returnUrl", "/sopmal/ordr/selectOrdrCompt");
model.addAttribute("message", "Stripe 결제 정보 등록을 완료 하였습니다.");
} else {
model.addAttribute("returnUrl", "/sopmal/ordr/selectOrdrFailr");
model.addAttribute("message", "Stripe 결제 정보 등록을 실패 하였습니다.");
}
model.addAttribute("sopmalCd", session.getMetadata().get("sopmalCd"));
model.addAttribute("ordrInnb", session.getMetadata().get("ordrInnb"));
model.addAttribute("pgCmpnyNm", session.getMetadata().get("pgCmpnyNm"));
model.addAttribute("setleTyCd", session.getMetadata().get("setleTyCd"));
model.addAttribute("goodsNm", session.getMetadata().get("goodsNm"));
model.addAttribute("setleAmt", session.getMetadata().get("setleAmt"));
model.addAttribute("ordrrNm", session.getMetadata().get("ordrrNm"));
model.addAttribute("ordrrEmail", session.getMetadata().get("ordrrEmail"));
model.addAttribute("ordrrMbtlnb", session.getMetadata().get("ordrrMbtlnb"));
model.addAttribute("mbrId", session.getMetadata().get("mbrId"));
model.addAttribute("mbrInnb", session.getMetadata().get("mbrInnb"));
model.addAttribute("sesionId", session.getMetadata().get("sesionId"));
model.addAttribute("subsvcInnb", session.getMetadata().get("subsvcInnb"));
return "sopmal/ordr/PayStripeSucsC";
}
}

View File

@@ -359,7 +359,7 @@ mngrfo:
images: .gif,.jpg,.jpeg,.png images: .gif,.jpg,.jpeg,.png
cdnurl: https://19d28cf7178139ad.kinxzone.com cdnurl: https://19d28cf7178139ad.kinxzone.com
subsvc: subsvc:
dft-goods-optn-innb: 1 dft-goods-optn-innb: 5
secret: secret:

View File

@@ -360,7 +360,7 @@ mngrfo:
cdnurl: https://19d28cf7178139ad.kinxzone.com cdnurl: https://19d28cf7178139ad.kinxzone.com
# upurl: https://www.soju1sake1.com # upurl: https://www.soju1sake1.com
subsvc: subsvc:
dft-goods-optn-innb: 1 dft-goods-optn-innb: 5
secret: secret:
key: 1df5be2f7e90ae36 key: 1df5be2f7e90ae36

View File

@@ -402,9 +402,6 @@
WHEN (IFNULL(GOODS.REST_INVNTRY_QY, 0) - IFNULL(GOODS.AVLINV_LMTT_QY, 0)) >= #{goodsTotalQy} THEN 0 WHEN (IFNULL(GOODS.REST_INVNTRY_QY, 0) - IFNULL(GOODS.AVLINV_LMTT_QY, 0)) >= #{goodsTotalQy} THEN 0
ELSE 1 END ELSE 1 END
END AS INVNTRY_POLICY -- 상품별 옵션 수량합산 재고유무 END AS INVNTRY_POLICY -- 상품별 옵션 수량합산 재고유무
, MAX(GOODS.GOODS_NM) AS STOCK_GOODS_NM
, MIN(GREATEST(0, IFNULL(OPTN.INVNTRY_QY, 0) - IFNULL(OPTN.USEFUL_INVNTRY_QY, 0))) AS OPTION_AVAILABLE_QY
, MIN(GREATEST(0, IFNULL(GOODS.REST_INVNTRY_QY, 0) - IFNULL(GOODS.AVLINV_LMTT_QY, 0))) AS GOODS_AVAILABLE_QY
, CASE WHEN IFNULL(OPTN.SLEPRIC, 0) = #{slepric} THEN 0 ELSE 1 END AS SELPRIC -- 판매가 변경여부 , CASE WHEN IFNULL(OPTN.SLEPRIC, 0) = #{slepric} THEN 0 ELSE 1 END AS SELPRIC -- 판매가 변경여부
, CASE , CASE
WHEN OPTN.COMPNB_DSCNT_AT = #{compnbDscntAt} AND OPTN.SCTN_DSCNT_AT = #{sctnDscntAt} THEN 0 WHEN OPTN.COMPNB_DSCNT_AT = #{compnbDscntAt} AND OPTN.SCTN_DSCNT_AT = #{sctnDscntAt} THEN 0
@@ -433,7 +430,6 @@
, IFNULL(EVT_DUPL_COUPON.DPLCT_LMTT_COUPON, 0) AS DPLCT_LMTT_COUPON -- 이벤트 중복제한 쿠폰 존재여부 , IFNULL(EVT_DUPL_COUPON.DPLCT_LMTT_COUPON, 0) AS DPLCT_LMTT_COUPON -- 이벤트 중복제한 쿠폰 존재여부
, CASE WHEN OPTN.OPTN_EXPSR_AT = 'Y' THEN 0 ELSE 1 END AS OPTN_EXPSR_AT , CASE WHEN OPTN.OPTN_EXPSR_AT = 'Y' THEN 0 ELSE 1 END AS OPTN_EXPSR_AT
FROM (SELECT GG.GOODS_INNB -- 상품 고유번호 FROM (SELECT GG.GOODS_INNB -- 상품 고유번호
, GG.GOODS_NM
, GG.SOPMAL_CD -- 쇼핑몰코드 , GG.SOPMAL_CD -- 쇼핑몰코드
, GG.DLVY_GROUP_INNB -- 배송그룹고유번호 , GG.DLVY_GROUP_INNB -- 배송그룹고유번호
, GG.GOODS_KND_CD -- 상품구분 01 상품 , GG.GOODS_KND_CD -- 상품구분 01 상품
@@ -805,9 +801,6 @@
ELSE 1 ELSE 1
END END
END AS INVNTRY_POLICY, -- 상품별 옵션 수량합산 재고유무 END AS INVNTRY_POLICY, -- 상품별 옵션 수량합산 재고유무
MAX(GOODS.GOODS_NM) AS STOCK_GOODS_NM,
MIN(GREATEST(0, GOODS.INVNTRY_QY - IFNULL(GOODS.USEFUL_INVNTRY_QY, 0))) AS OPTION_AVAILABLE_QY,
MIN(GREATEST(0, IFNULL(GOODS.REST_INVNTRY_QY, 0) - IFNULL(GOODS.AVLINV_LMTT_QY, 0))) AS GOODS_AVAILABLE_QY,
CASE CASE
WHEN IFNULL(GOODS.SUBSVC_CT, 0) = #{slepric} THEN 0 WHEN IFNULL(GOODS.SUBSVC_CT, 0) = #{slepric} THEN 0
ELSE 1 ELSE 1
@@ -824,7 +817,6 @@
FROM ( FROM (
SELECT SELECT
GS.SUBSVC_INNB, -- 구독서비스 고유번호 GS.SUBSVC_INNB, -- 구독서비스 고유번호
GG.GOODS_NM,
GG.GOODS_INNB, -- 상품 고유번호 GG.GOODS_INNB, -- 상품 고유번호
GS.SOPMAL_CD, -- 쇼핑몰코드 GS.SOPMAL_CD, -- 쇼핑몰코드
GS.SUBSVC_CT, -- 구독료 GS.SUBSVC_CT, -- 구독료

View File

@@ -338,7 +338,6 @@
,MEMOR_USE_AT ,MEMOR_USE_AT
,NPAY_USE_AT ,NPAY_USE_AT
,KPAY_USE_AT ,KPAY_USE_AT
,STRIPE_USE_AT
FROM GC_PAY_INFO FROM GC_PAY_INFO
WHERE SETLE_SETUP_INNB = #{setleSetupInnb} WHERE SETLE_SETUP_INNB = #{setleSetupInnb}
</select> </select>
@@ -1282,7 +1281,6 @@
MEMOR_USE_AT = #{memorUseAt}, MEMOR_USE_AT = #{memorUseAt},
NPAY_USE_AT = #{npayUseAt}, NPAY_USE_AT = #{npayUseAt},
KPAY_USE_AT = #{kpayUseAt}, KPAY_USE_AT = #{kpayUseAt},
STRIPE_USE_AT = #{stripeUseAt},
UPDUSR = #{updusr}, UPDUSR = #{updusr},
UPDT_DT = NOW() UPDT_DT = NOW()
WHERE WHERE

View File

@@ -2654,7 +2654,6 @@ FROM (
, FPI.TPAY_USE_AT , FPI.TPAY_USE_AT
, FPI.NPAY_USE_AT , FPI.NPAY_USE_AT
, FPI.KPAY_USE_AT , FPI.KPAY_USE_AT
, FPI.STRIPE_USE_AT
, FPI.MEMOR_USE_AT , FPI.MEMOR_USE_AT
, FPL.KCP_MID , FPL.KCP_MID
, FPL.KCP_CLNT_KEY , FPL.KCP_CLNT_KEY
@@ -2684,9 +2683,6 @@ FROM (
, FPL.OLD_TOSS_CLNT_KEY , FPL.OLD_TOSS_CLNT_KEY
, FPL.OLD_TOSS_SECRET_KEY , FPL.OLD_TOSS_SECRET_KEY
, FPL.OLD_TOSS_PUBLIC_KEY , FPL.OLD_TOSS_PUBLIC_KEY
, FPL.STRIPE_CLNT_KEY
, FPL.STRIPE_SECRET_KEY
, FPL.STRIPE_WEBHOOK_KEY
, FPL.DUE_DT , FPL.DUE_DT
FROM GC_PAY_LINK FPL FROM GC_PAY_LINK FPL
INNER JOIN GC_PAY_INFO FPI ON FPI.SETLE_SETUP_INNB = FPL.SETLE_SETUP_INNB INNER JOIN GC_PAY_INFO FPI ON FPI.SETLE_SETUP_INNB = FPL.SETLE_SETUP_INNB

View File

@@ -6059,7 +6059,7 @@
ON GGO.SOPMAL_CD = GG.SOPMAL_CD ON GGO.SOPMAL_CD = GG.SOPMAL_CD
AND GGO.GOODS_INNB = GG.GOODS_INNB AND GGO.GOODS_INNB = GG.GOODS_INNB
JOIN seq JOIN seq
ON seq.n <![CDATA[<=]]> GS.DLVY_CNT ON seq.n <![CDATA[<=]]> GS.SUB_PD
LEFT JOIN GC_GOODS_IMAGE GGI ON GG.SOPMAL_CD = GGI.SOPMAL_CD LEFT JOIN GC_GOODS_IMAGE GGI ON GG.SOPMAL_CD = GGI.SOPMAL_CD
AND GG.GOODS_INNB = GGI.GOODS_INNB AND GG.GOODS_INNB = GGI.GOODS_INNB
AND GGI.IMG_KND = '03' AND GGI.IMG_KND = '03'

View File

@@ -1,46 +0,0 @@
/* 결제취소 화면 조회 전용. 실제 취소/환불 요청은 처리하지 않는다. */
async function fn_load_refund_popup(url, data, onReady) {
const requestUrl = new URL(url, window.location.href);
Object.entries(data).forEach(([key, value]) => requestUrl.searchParams.set(key, value));
const loginRequired = function () {
window.alert('로그인 시간이 만료되었습니다. 다시 로그인해 주세요.');
const loginUrl = new URL('/sopmal/login', window.location.href);
// 로그인 후 AJAX 팝업 주소가 아닌 원래 주문 상세로 돌아온다.
loginUrl.searchParams.set('redirect_uri', window.location.href);
window.location.assign(loginUrl.href);
};
try {
// 갱신 후 리다이렉트에서도 주문 조회 조건이 유지되도록 GET으로 요청한다.
const response = await fetch(requestUrl.href, {
method: 'GET',
credentials: 'same-origin',
cache: 'no-store',
headers: {'X-Requested-With': 'XMLHttpRequest'}
});
const finalUrl = new URL(response.url || requestUrl.href, window.location.href);
if (response.status === 401 || (response.redirected &&
/^\/sopmal\/(login(?:\/|$)|logout(?:\/|$)|main(?:\/|$))/.test(finalUrl.pathname))) {
loginRequired();
return;
}
if (!response.ok || finalUrl.origin !== requestUrl.origin || finalUrl.pathname !== requestUrl.pathname) {
throw new Error('Unexpected refund popup response');
}
// 로그인 HTML이나 빈 응답은 화면에 넣지 않는다. 반환된 스크립트도 실행하지 않는다.
const html = await response.text();
const parsed = new DOMParser().parseFromString(html, 'text/html');
const popup = parsed.querySelector('#refund-pop');
if (!popup) {
throw new Error('Missing refund popup');
}
popup.querySelectorAll('script').forEach(script => script.remove());
$('#refund-pop').remove();
$('#refundPopupDiv').empty().append(popup);
onReady($(popup));
} catch (error) {
window.alert('결제취소 화면을 불러오지 못했습니다. 잠시 후 다시 시도해 주세요.');
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -923,10 +923,3 @@ $(".comma").each(function () {
var text = $(this).text(); var text = $(this).text();
$(this).text(text.replace(/(\d)(?=(?:\d{3})+(?!\d))/g, "$1,")); $(this).text(text.replace(/(\d)(?=(?:\d{3})+(?!\d))/g, "$1,"));
}); });
//해당 클래스를 가진 요소 .trim()
function trimInputValue() {
$('input.input-trim').each(function () {
$(this).val($(this).val().trim());
});
}

View File

@@ -9595,6 +9595,7 @@ main {
.cartOrderBox__total { .cartOrderBox__total {
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 20px;
} }
.cartOrderBox__totalTh { .cartOrderBox__totalTh {
font-size: 16px; font-size: 16px;
@@ -9618,7 +9619,6 @@ main {
} }
.cartOrderBox__buyBtn { .cartOrderBox__buyBtn {
width: 100%; width: 100%;
margin-top: 20px;
margin-bottom: 16px; margin-bottom: 16px;
} }
.cartOrderBox .product-btn-container { .cartOrderBox .product-btn-container {

View File

@@ -1497,11 +1497,6 @@
<span class="check"></span> <span class="check"></span>
<span class="control-label">카카오페이</span> <span class="control-label">카카오페이</span>
</label> </label>
<label class="b-checkbox checkbox">
<input type="checkbox" name="pc-setle-type" value="stripe" ${f:setChecked(fn:contains(payInfoList.stripeUseAt, 'Y'), true)} class="stripe">
<span class="check"></span>
<span class="control-label">Stripe</span>
</label>
</c:if> </c:if>
</c:forEach> </c:forEach>
</c:if> </c:if>
@@ -1578,11 +1573,6 @@
<span class="check"></span> <span class="check"></span>
<span class="control-label">카카오페이</span> <span class="control-label">카카오페이</span>
</label> </label>
<label class="b-checkbox checkbox">
<input type="checkbox" name="mobile-setle-type" value="stripe" ${f:setChecked(fn:contains(payInfoList.stripeUseAt, 'Y'), true)} class="stripe">
<span class="check"></span>
<span class="control-label">Stripe</span>
</label>
</c:if> </c:if>
</c:forEach> </c:forEach>
</c:if> </c:if>
@@ -1659,11 +1649,6 @@
<span class="check"></span> <span class="check"></span>
<span class="control-label">카카오페이</span> <span class="control-label">카카오페이</span>
</label> </label>
<label class="b-checkbox checkbox">
<input type="checkbox" name="pc-subsvc-setle-type" value="stripe" ${f:setChecked(fn:contains(payInfoList.stripeUseAt, 'Y'), true)} class="stripe">
<span class="check"></span>
<span class="control-label">Stripe</span>
</label>
</c:if> </c:if>
</c:forEach> </c:forEach>
</c:if> </c:if>
@@ -1740,11 +1725,6 @@
<span class="check"></span> <span class="check"></span>
<span class="control-label">카카오페이</span> <span class="control-label">카카오페이</span>
</label> </label>
<label class="b-checkbox checkbox">
<input type="checkbox" name="mobile-subsvc-setle-type" value="stripe" ${f:setChecked(fn:contains(payInfoList.stripeUseAt, 'Y'), true)} class="stripe">
<span class="check"></span>
<span class="control-label">Stripe</span>
</label>
</c:if> </c:if>
</c:forEach> </c:forEach>
</c:if> </c:if>

View File

@@ -569,8 +569,6 @@
* 등록 AJAX * 등록 AJAX
******************************************************** */ ******************************************************** */
const fn_regist = function () { const fn_regist = function () {
trimInputValue();
const url = '<c:url value="/mngr/goods/goodsmngr/insertGoodsInfo"/>'; const url = '<c:url value="/mngr/goods/goodsmngr/insertGoodsInfo"/>';
const formData = new FormData(); const formData = new FormData();
@@ -1272,6 +1270,7 @@
formData.append('files', file); // 서버에서 파일을 받을 때 'files'라는 이름으로 전송 formData.append('files', file); // 서버에서 파일을 받을 때 'files'라는 이름으로 전송
}); });
if (confirm('상품을 <spring:message code="confirm.common.insert"/>')) { if (confirm('상품을 <spring:message code="confirm.common.insert"/>')) {
$.ajax({ $.ajax({
type: 'post', type: 'post',
@@ -1418,7 +1417,7 @@
<td> <td>
<div class="optionApply__inputList"> <div class="optionApply__inputList">
<div class="optionApply__inputContainer"> <div class="optionApply__inputContainer">
<input class="input-text full input-trim" <input class="input-text full"
type="text" name="optnNm1_normal" id="optnNm1_normal`+rowCount+`" type="text" name="optnNm1_normal" id="optnNm1_normal`+rowCount+`"
title="일반옵션명"> title="일반옵션명">
<!-- <button type="button" class="btn outline xsm optionDel01">삭제</button>--> <!-- <button type="button" class="btn outline xsm optionDel01">삭제</button>-->
@@ -1451,11 +1450,11 @@
<button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button>
<button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button>
</div> </div>
<input class="input-text full input-trim" type="text" title="일반옵션 값" id="optnVal1" name="optnVal1_normal"> <input class="input-text full" type="text" title="일반옵션 값" id="optnVal1" name="optnVal1_normal">
</div> </div>
</div> </div>
</td> </td>
<td><div class="optionApply__priceContainer"><input class="input-text full input-trim" type="text" title="일반옵션코드" name="optnCd1_normal"></td></div> <td><div class="optionApply__priceContainer"><input class="input-text full" type="text" title="일반옵션코드" name="optnCd1_normal"></td></div>
` `
+invntry_policy_qy+ +invntry_policy_qy+
` `
@@ -1558,11 +1557,11 @@
` `
+firstAdd+ +firstAdd+
` `
<td><input class="input-text full input-trim" type="text" title="재고옵션 값1" name="optnVal1_invntry" /></td> <td><input class="input-text full" type="text" title="재고옵션 값1" name="optnVal1_invntry" /></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 값2" name="optnVal2_invntry"/></td> <td><input class="input-text full" type="text" title="재고옵션 값2" name="optnVal2_invntry"/></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 값3" name="optnVal3_invntry"/></td> <td><input class="input-text full" type="text" title="재고옵션 값3" name="optnVal3_invntry"/></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 값4" name="optnVal4_invntry"/></td> <td><input class="input-text full" type="text" title="재고옵션 값4" name="optnVal4_invntry"/></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 코드" name="optnCd1_invntry"/></td> <td><input class="input-text full" type="text" title="재고옵션 코드" name="optnCd1_invntry"/></td>
` `
+invntry_policy_qy+ +invntry_policy_qy+
` `
@@ -1600,7 +1599,7 @@
</div> </div>
</div> </div>
</td> </td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 정보" name="optnInfo_invntry"/></td> <td><input class="input-text full" type="text" title="재고옵션 정보" name="optnInfo_invntry"/></td>
<td> <td>
<div class="compnbDscntAt_invntry"> <div class="compnbDscntAt_invntry">
<label class="b-checkbox checkbox" for="compnbDscntAt02_`+rowCount+`"> <label class="b-checkbox checkbox" for="compnbDscntAt02_`+rowCount+`">
@@ -2533,14 +2532,14 @@
<th>상품명<span class="red-7">*</span></th> <th>상품명<span class="red-7">*</span></th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="상품명" id="goodsNm" name="goodsNm" maxlength="35" placeholder="상품명을 입력해 주세요."> <input class="input-text full" type="text" title="상품명" id="goodsNm" name="goodsNm" maxlength="35" placeholder="상품명을 입력해 주세요.">
<input type="hidden" id="sopmalCd" name="sopmalCd" value="${resultMap.BOGoodsVO.sopmalCd}"/> <input type="hidden" id="sopmalCd" name="sopmalCd" value="${resultMap.BOGoodsVO.sopmalCd}"/>
</div> </div>
</td> </td>
<th>상품명(영문)<span class="red-7">*</span></th> <th>상품명(영문)<span class="red-7">*</span></th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="상품명(영문)" id="goodsNmEn" name="goodsNmEn" maxlength="35" placeholder="상품명을 입력해 주세요."> <input class="input-text full" type="text" title="상품명(영문)" id="goodsNmEn" name="goodsNmEn" maxlength="35" placeholder="상품명을 입력해 주세요.">
</div> </div>
</td> </td>
</tr> </tr>
@@ -2548,13 +2547,13 @@
<th>대표설명</th> <th>대표설명</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="대표설명" id="reprsntDc" name="reprsntDc" placeholder="상품 대표설명을 입력해 주세요."> <input class="input-text full" type="text" title="대표설명" id="reprsntDc" name="reprsntDc" placeholder="상품 대표설명을 입력해 주세요.">
</div> </div>
</td> </td>
<th>간략설명</th> <th>간략설명</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="간략설명" id="srtDc" name="srtDc" placeholder="간략한 상품 설명을 입력해 주세요."> <input class="input-text full" type="text" title="간략설명" id="srtDc" name="srtDc" placeholder="간략한 상품 설명을 입력해 주세요.">
</div> </div>
</td> </td>
</tr> </tr>
@@ -2562,7 +2561,7 @@
<th>검색어</th> <th>검색어</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="검색어" id="kwrd" name="kwrd" placeholder="검색어는 ,(콤마)로 구분됩니다."> <input class="input-text full" type="text" title="검색어" id="kwrd" name="kwrd" placeholder="검색어는 ,(콤마)로 구분됩니다.">
</div> </div>
</td> </td>
<th>브랜드</th> <th>브랜드</th>
@@ -2585,7 +2584,7 @@
<th>리뷰 연동</th> <th>리뷰 연동</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="리뷰 연동" id="rvwGroupNb" name="rvwGroupNb" placeholder="상품 번호를 입력해주세요."> <input class="input-text full" type="text" title="리뷰 연동" id="rvwGroupNb" name="rvwGroupNb" placeholder="상품 번호를 입력해주세요.">
</div> </div>
</td> </td>
<th>리뷰 작성 가능 여부</th> <th>리뷰 작성 가능 여부</th>
@@ -2725,7 +2724,7 @@
<span class="control-label">사용자페이지 판매중지 문구 변경 -> </span> <span class="control-label">사용자페이지 판매중지 문구 변경 -> </span>
</label> </label>
</div> </div>
<label for="selStpgeCustomWords"></label><input type="text" class="input-text input-trim" id="selStpgeCustomWords" name="selStpgeCustomWords" value="${resultMap.goodsDtl.selStpgeCustomWords}" <label for="selStpgeCustomWords"></label><input type="text" class="input-text" id="selStpgeCustomWords" name="selStpgeCustomWords" value="${resultMap.goodsDtl.selStpgeCustomWords}"
<c:if test="${resultMap.goodsDtl.selStpgeCustomWordsAt ne 'Y'}"> disabled </c:if> <c:if test="${resultMap.goodsDtl.selStpgeCustomWordsAt ne 'Y'}"> disabled </c:if>
/> />
<span class="parentheses">) </span> <span class="parentheses">) </span>
@@ -2761,7 +2760,7 @@
<th>예약 상품 안내문구</th> <th>예약 상품 안내문구</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text xl input-trim" type="text" <input class="input-text xl" type="text"
id="resveGoodsGuidanceWordsCn" name="resveGoodsGuidanceWordsCn" id="resveGoodsGuidanceWordsCn" name="resveGoodsGuidanceWordsCn"
title="예약 상품 안내문구"> title="예약 상품 안내문구">
</div> </div>
@@ -2815,7 +2814,7 @@
<tr> <tr>
<th>노출 문구</th> <th>노출 문구</th>
<td> <td>
<input class="input-text xl input-trim" type="text" title="노출 문구" id="expsrSetupFwords" name="expsrSetupFwords" disabled> <input class="input-text xl" type="text" title="노출 문구" id="expsrSetupFwords" name="expsrSetupFwords" disabled>
</td> </td>
</tr> </tr>
</tbody> </tbody>
@@ -2892,7 +2891,7 @@
<span class="ml-4">개의 수량을</span> <span class="ml-4">개의 수량을</span>
<input type="text" id="rltmQyDdctStdrDt" class="datepicker" title="이벤트가판매 가수량차감기준일시 설정" autocomplete="off" disabled > <input type="text" id="rltmQyDdctStdrDt" class="datepicker" title="이벤트가판매 가수량차감기준일시 설정" autocomplete="off" disabled >
<span class="ml-4">부터</span> <span class="ml-4">부터</span>
<input type="text" class="input-text sm right number" title="이벤트가판매 가수량차감시간 설정" value="0" id="rltmQyDdctTme" disabled> <input type="text" class="input-text sm right" title="이벤트가판매 가수량차감시간 설정" value="0" id="rltmQyDdctTme" disabled>
<span class="ml-4">분마다</span> <span class="ml-4">분마다</span>
<input class="input-text sm right number" id="rltmDdctQy" value="0" type="text" title="이벤트가판매 가수량차감수량 설정" disabled> <input class="input-text sm right number" id="rltmDdctQy" value="0" type="text" title="이벤트가판매 가수량차감수량 설정" disabled>
<span class="ml-4">개씩 차감</span> <span class="ml-4">개씩 차감</span>
@@ -3081,7 +3080,7 @@
<td> <td>
<div class="optionApply__inputList"> <div class="optionApply__inputList">
<div class="optionApply__inputContainer"> <div class="optionApply__inputContainer">
<input class="input-text full input-trim" type="text" name="optnNm1_normal" title="옵션명" id="optnNm1_normal0"> <input class="input-text full" type="text" name="optnNm1_normal" title="옵션명" id="optnNm1_normal0">
<%-- <button type="button" class="btn outline xsm optionDel01">삭제</button>--%> <%-- <button type="button" class="btn outline xsm optionDel01">삭제</button>--%>
<button type="button" class="btn outline xsm optionVal98" >옵션값 추가</button> <button type="button" class="btn outline xsm optionVal98" >옵션값 추가</button>
</div> </div>
@@ -3112,18 +3111,18 @@
<button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button>
<button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button>
</div> </div>
<input class="input-text full input-trim" type="text" id="optnVal1" name="optnVal1_normal" title="옵션값"> <input class="input-text full" type="text" id="optnVal1" name="optnVal1_normal" title="옵션값">
</div> </div>
</div> </div>
</td> </td>
<td> <td>
<div class="optionApply__priceContainer"> <div class="optionApply__priceContainer">
<input class="input-text full input-trim" type="text" title="상품코드" name="optnCd1_normal"> <input class="input-text full" type="text" title="상품코드" name="optnCd1_normal">
</div> </div>
</td> </td>
<td> <td>
<div class="optionApply__priceContainer"> <div class="optionApply__priceContainer">
<input class="input-text full input-trim" type="text" value="220600" title="HS Code" name="hscode_normal" maxlength="10"> <input class="input-text full" type="text" value="220600" title="HS Code" name="hscode_normal" maxlength="10">
</div> </div>
</td> </td>
<td> <td>
@@ -3281,16 +3280,16 @@
<td> <td>
</td> </td>
<td> <td>
<input class="input-text full input-trim" name ="optnNm1_invntry" type="text" title="재고옵션명1" placeholder="옵션명1"> <input class="input-text full" name ="optnNm1_invntry" type="text" title="재고옵션명1" placeholder="옵션명1">
</td> </td>
<td> <td>
<input class="input-text full input-trim" name ="optnNm2_invntry" type="text" title="재고옵선명2" placeholder="옵션명2"> <input class="input-text full" name ="optnNm2_invntry" type="text" title="재고옵선명2" placeholder="옵션명2">
</td> </td>
<td> <td>
<input class="input-text full input-trim" name="optnNm3_invntry" type="text" title="재고옵션명3" placeholder="옵션명3"> <input class="input-text full" name="optnNm3_invntry" type="text" title="재고옵션명3" placeholder="옵션명3">
</td> </td>
<td> <td>
<input class="input-text full input-trim" name="optnNm4_invntry" type="text" title="재고옵션명4" placeholder="옵션명4"> <input class="input-text full" name="optnNm4_invntry" type="text" title="재고옵션명4" placeholder="옵션명4">
</td> </td>
<td> <td>
@@ -3805,7 +3804,7 @@
<th>배송 안내 문구</th> <th>배송 안내 문구</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" id="dlvyGuidanceWordsCn" name="dlvyGuidanceWordsCn" title="배송안내문구"> <input class="input-text full" type="text" id="dlvyGuidanceWordsCn" name="dlvyGuidanceWordsCn" title="배송안내문구">
</div> </div>
</td> </td>
</tr> </tr>
@@ -4015,7 +4014,7 @@
//옵션명 //옵션명
$closestTr.find('td:eq(' + tdCount++ + ') .optionApply__inputList').append(` $closestTr.find('td:eq(' + tdCount++ + ') .optionApply__inputList').append(`
<div class="optionApply__inputContainer" style="margin: 0"> <div class="optionApply__inputContainer" style="margin: 0">
<input class="input-text full input-trim `+optnNm.attr('id')+`" type="hidden" value="`+optnNmVal+`" title="일반옵션명" name="optnNm1_normal"> <input class="input-text full `+optnNm.attr('id')+`" type="hidden" value="`+optnNmVal+`" title="일반옵션명" name="optnNm1_normal">
</div> </div>
`); `);
//노출여부 //노출여부
@@ -4039,14 +4038,14 @@
<button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button>
<button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button>
</div> </div>
<input class="input-text full input-trim" value="" type="text" title="일반옵션값" name="optnVal1_normal"> <input class="input-text full" value="" type="text" title="일반옵션값" name="optnVal1_normal">
</div> </div>
`); `);
$closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(` $closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(`
<input class="input-text full input-trim" type="text" title="일반옵션코드" name="optnCd1_normal"> <input class="input-text full" type="text" title="일반옵션코드" name="optnCd1_normal">
`); `);
$closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(` $closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(`
<input class="input-text full input-trim" value="220600" type="text" title="HS Code" name="hscode_normal" maxlength="10"> <input class="input-text full" value="220600" type="text" title="HS Code" name="hscode_normal" maxlength="10">
`); `);
$closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(` $closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(`
<input class="input-text full" value="0.0" type="text" title="실무게(KG)" name="realWt_normal"> <input class="input-text full" value="0.0" type="text" title="실무게(KG)" name="realWt_normal">

View File

@@ -621,7 +621,6 @@
* 복사 등록 AJAX * 복사 등록 AJAX
******************************************************** */ ******************************************************** */
const fn_copy_regist = function () { const fn_copy_regist = function () {
trimInputValue();
const url = '<c:url value="/mngr/goods/goodsmngr/insertGoodsInfo"/>'; const url = '<c:url value="/mngr/goods/goodsmngr/insertGoodsInfo"/>';
const formData = new FormData(); const formData = new FormData();
@@ -1455,7 +1454,7 @@
<td> <td>
<div class="optionApply__inputList"> <div class="optionApply__inputList">
<div class="optionApply__inputContainer"> <div class="optionApply__inputContainer">
<input class="input-text full input-trim" <input class="input-text full"
type="text" name="optnNm1_normal" id="optnNm1_normal`+rowCount+`" type="text" name="optnNm1_normal" id="optnNm1_normal`+rowCount+`"
title="해당 인풋에 대한 설명"> title="해당 인풋에 대한 설명">
<button type="button" class="btn outline xsm optionDel01">삭제</button> <button type="button" class="btn outline xsm optionDel01">삭제</button>
@@ -1488,11 +1487,11 @@
<button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button>
<button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button>
</div> </div>
<input class="input-text full input-trim" type="text" title="일반옵션 값" id="optnVal1_normal`+rowCount+`" name="optnVal1_normal"> <input class="input-text full" type="text" title="일반옵션 값" id="optnVal1_normal`+rowCount+`" name="optnVal1_normal">
</div> </div>
</div> </div>
</td> </td>
<td><div class="optionApply__priceContainer"><input class="input-text full input-trim" type="text" title="일반옵션코드" name="optnCd1_normal"></td></div> <td><div class="optionApply__priceContainer"><input class="input-text full" type="text" title="일반옵션코드" name="optnCd1_normal"></td></div>
` `
+invntry_policy_qy+ +invntry_policy_qy+
` `
@@ -1596,11 +1595,11 @@
` `
+firstAdd+ +firstAdd+
` `
<td><input class="input-text full input-trim" type="text" title="재고옵션 값1" name="optnVal1_invntry" /></td> <td><input class="input-text full" type="text" title="재고옵션 값1" name="optnVal1_invntry" /></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 값2" name="optnVal2_invntry"/></td> <td><input class="input-text full" type="text" title="재고옵션 값2" name="optnVal2_invntry"/></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 값3" name="optnVal3_invntry"/></td> <td><input class="input-text full" type="text" title="재고옵션 값3" name="optnVal3_invntry"/></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 값4" name="optnVal4_invntry"/></td> <td><input class="input-text full" type="text" title="재고옵션 값4" name="optnVal4_invntry"/></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 코드" name="optnCd1_invntry"/></td> <td><input class="input-text full" type="text" title="재고옵션 코드" name="optnCd1_invntry"/></td>
` `
+invntry_policy_qy+ +invntry_policy_qy+
` `
@@ -1638,7 +1637,7 @@
</div> </div>
</div> </div>
</td> </td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 정보" name="optnInfo_invntry"/></td> <td><input class="input-text full" type="text" title="재고옵션 정보" name="optnInfo_invntry"/></td>
<td> <td>
<div class="compnbDscntAt_invntry"> <div class="compnbDscntAt_invntry">
<label class="b-checkbox checkbox" for="compnbDscntAt02_`+rowCount+`"> <label class="b-checkbox checkbox" for="compnbDscntAt02_`+rowCount+`">
@@ -2679,14 +2678,14 @@
<th>상품명<span class="red-7">*</span></th> <th>상품명<span class="red-7">*</span></th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="상품명" id="goodsNm" name="goodsNm" maxlength="35" value="${resultMap.goodsDtl.goodsNm}"> <input class="input-text full" type="text" title="상품명" id="goodsNm" name="goodsNm" maxlength="35" value="${resultMap.goodsDtl.goodsNm}">
<input type="hidden" id="sopmalCd" name="sopmalCd" value="${resultMap.BOGoodsVO.sopmalCd}"/> <input type="hidden" id="sopmalCd" name="sopmalCd" value="${resultMap.BOGoodsVO.sopmalCd}"/>
</div> </div>
</td> </td>
<th>상품명(영문)<span class="red-7">*</span></th> <th>상품명(영문)<span class="red-7">*</span></th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="상품명(영문)" id="goodsNmEn" name="goodsNmEn" maxlength="35" value="${resultMap.goodsDtl.goodsNmEn}"> <input class="input-text full" type="text" title="상품명(영문)" id="goodsNmEn" name="goodsNmEn" maxlength="35" value="${resultMap.goodsDtl.goodsNmEn}">
</div> </div>
</td> </td>
</tr> </tr>
@@ -2694,13 +2693,13 @@
<th>대표설명</th> <th>대표설명</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="대표설명" id="reprsntDc" name="reprsntDc" value="${resultMap.goodsDtl.reprsntDc}" > <input class="input-text full" type="text" title="대표설명" id="reprsntDc" name="reprsntDc" value="${resultMap.goodsDtl.reprsntDc}" >
</div> </div>
</td> </td>
<th>간략설명</th> <th>간략설명</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="간략설명" id="srtDc" name="srtDc" value="${resultMap.goodsDtl.srtDc}"> <input class="input-text full" type="text" title="간략설명" id="srtDc" name="srtDc" value="${resultMap.goodsDtl.srtDc}">
</div> </div>
</td> </td>
</tr> </tr>
@@ -2708,7 +2707,7 @@
<th>검색어</th> <th>검색어</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="검색어" id="kwrd" name="kwrd" value="${resultMap.goodsDtl.kwrd}"> <input class="input-text full" type="text" title="검색어" id="kwrd" name="kwrd" value="${resultMap.goodsDtl.kwrd}">
</div> </div>
</td> </td>
<th>브랜드</th> <th>브랜드</th>
@@ -2732,7 +2731,7 @@
<th>리뷰 연동</th> <th>리뷰 연동</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="리뷰 연동" id="rvwGroupNb" name="rvwGroupNb" value="${resultMap.goodsDtl.rvwGroupNb}"> <input class="input-text full" type="text" title="리뷰 연동" id="rvwGroupNb" name="rvwGroupNb" value="${resultMap.goodsDtl.rvwGroupNb}">
</div> </div>
</td> </td>
<th>리뷰 작성 가능 여부</th> <th>리뷰 작성 가능 여부</th>
@@ -2899,7 +2898,7 @@
<span class="control-label">사용자페이지 판매중지 문구 변경 -> </span> <span class="control-label">사용자페이지 판매중지 문구 변경 -> </span>
</label> </label>
</div> </div>
<label for="selStpgeCustomWords"></label><input type="text" class="input-text input-trim" id="selStpgeCustomWords" name="selStpgeCustomWords" value="${resultMap.goodsDtl.selStpgeCustomWords}" <label for="selStpgeCustomWords"></label><input type="text" class="input-text" id="selStpgeCustomWords" name="selStpgeCustomWords" value="${resultMap.goodsDtl.selStpgeCustomWords}"
<c:if test="${resultMap.goodsDtl.selStpgeCustomWordsAt ne 'Y'}"> disabled </c:if> <c:if test="${resultMap.goodsDtl.selStpgeCustomWordsAt ne 'Y'}"> disabled </c:if>
/> />
<span class="parentheses">) </span> <span class="parentheses">) </span>
@@ -2936,7 +2935,7 @@
<th>예약 상품 안내문구</th> <th>예약 상품 안내문구</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text xl input-trim" type="text" <input class="input-text xl" type="text"
id="resveGoodsGuidanceWordsCn" id="resveGoodsGuidanceWordsCn"
name="resveGoodsGuidanceWordsCn" name="resveGoodsGuidanceWordsCn"
value="${resultMap.goodsDtl.resveGoodsGuidanceWordsCn}" value="${resultMap.goodsDtl.resveGoodsGuidanceWordsCn}"
@@ -3002,7 +3001,7 @@
<tr> <tr>
<th>노출 문구</th> <th>노출 문구</th>
<td> <td>
<input class="input-text xl input-trim" type="text" <input class="input-text xl" type="text"
title="노출 문구" id="expsrSetupFwords" title="노출 문구" id="expsrSetupFwords"
name="expsrSetupFwords" name="expsrSetupFwords"
<c:choose> <c:choose>
@@ -3093,7 +3092,7 @@
<span class="ml-4">개의 수량을</span> <span class="ml-4">개의 수량을</span>
<input type="text" id="rltmQyDdctStdrDt" value="${fn:split(resultMap.goodsDtl.rltmQyDdctStdrDt,'T')[0]}" class="datepicker" title="이벤트가판매 가수량차감기준일시 설정" autocomplete="off" <c:if test="${resultMap.goodsDtl.rltmQyBannerDvCd ne '03'}">disabled</c:if> > <input type="text" id="rltmQyDdctStdrDt" value="${fn:split(resultMap.goodsDtl.rltmQyDdctStdrDt,'T')[0]}" class="datepicker" title="이벤트가판매 가수량차감기준일시 설정" autocomplete="off" <c:if test="${resultMap.goodsDtl.rltmQyBannerDvCd ne '03'}">disabled</c:if> >
<span class="ml-4">부터</span> <span class="ml-4">부터</span>
<input type="text" class="input-text sm right number" title="이벤트가판매 가수량차감시간 설정" value="${resultMap.goodsDtl.rltmQyDdctTme}" id="rltmQyDdctTme" <c:if test="${resultMap.goodsDtl.rltmQyBannerDvCd ne '03'}">disabled</c:if> > <input type="text" class="input-text sm right" title="이벤트가판매 가수량차감시간 설정" value="${resultMap.goodsDtl.rltmQyDdctTme}" id="rltmQyDdctTme" <c:if test="${resultMap.goodsDtl.rltmQyBannerDvCd ne '03'}">disabled</c:if> >
<span class="ml-4">분마다</span> <span class="ml-4">분마다</span>
<input class="input-text sm right number" id="rltmDdctQy" value="${resultMap.goodsDtl.rltmDdctQy}" type="text" title="이벤트가판매 가수량차감수량 설정" <c:if test="${resultMap.goodsDtl.rltmQyBannerDvCd ne '03'}">disabled</c:if> > <input class="input-text sm right number" id="rltmDdctQy" value="${resultMap.goodsDtl.rltmDdctQy}" type="text" title="이벤트가판매 가수량차감수량 설정" <c:if test="${resultMap.goodsDtl.rltmQyBannerDvCd ne '03'}">disabled</c:if> >
<span class="ml-4">개씩 차감</span> <span class="ml-4">개씩 차감</span>
@@ -3314,7 +3313,7 @@
<div class="optionApply__inputContainer"> <div class="optionApply__inputContainer">
<c:choose> <c:choose>
<c:when test="${optnNm01_status.index eq '0'}"> <c:when test="${optnNm01_status.index eq '0'}">
<input class="input-text full input-trim" value="${optnNm011}" type="text" title="일반옵션명" name="optnNm1_normal" id="optnNm1_normal${optnNm01_status.index}"> <input class="input-text full" value="${optnNm011}" type="text" title="일반옵션명" name="optnNm1_normal" id="optnNm1_normal${optnNm01_status.index}">
<%-- <button type="button" class="btn outline xsm optionDel02">삭제</button>--%> <%-- <button type="button" class="btn outline xsm optionDel02">삭제</button>--%>
<button type="button" class="btn outline xsm optionVal98">옵션값 추가</button> <button type="button" class="btn outline xsm optionVal98">옵션값 추가</button>
<c:forEach var="goodsOptnInnb01" items="${fn:split(optnList01.goodsOptnInnb, '|')}" varStatus="goodsOptnInnb01_status"> <c:forEach var="goodsOptnInnb01" items="${fn:split(optnList01.goodsOptnInnb, '|')}" varStatus="goodsOptnInnb01_status">
@@ -3324,7 +3323,7 @@
</c:forEach> </c:forEach>
</c:when> </c:when>
<c:otherwise> <c:otherwise>
<input class="input-text full input-trim" value="${optnNm011}" type="hidden" title="일반옵션명" name="optnNm1_normal" id="optnNm1_normal${optnTy01idx.index}${optnNm01_status.index}"> <input class="input-text full" value="${optnNm011}" type="hidden" title="일반옵션명" name="optnNm1_normal" id="optnNm1_normal${optnTy01idx.index}${optnNm01_status.index}">
<c:forEach var="goodsOptnInnb01" items="${fn:split(optnList01.goodsOptnInnb, '|')}" varStatus="goodsOptnInnb01_status"> <c:forEach var="goodsOptnInnb01" items="${fn:split(optnList01.goodsOptnInnb, '|')}" varStatus="goodsOptnInnb01_status">
<c:if test="${goodsOptnInnb01_status.index ne '0' and optnNm01_status.index eq goodsOptnInnb01_status.index }"> <c:if test="${goodsOptnInnb01_status.index ne '0' and optnNm01_status.index eq goodsOptnInnb01_status.index }">
<input type="hidden" name="goodsOptnInnb_normal" value="${goodsOptnInnb01}"/> <input type="hidden" name="goodsOptnInnb_normal" value="${goodsOptnInnb01}"/>
@@ -3338,7 +3337,7 @@
<div class="optionApply__inputContainer"> <div class="optionApply__inputContainer">
<c:choose> <c:choose>
<c:when test="${optnNm01_status.index eq '0'}"> <c:when test="${optnNm01_status.index eq '0'}">
<input class="input-text full input-trim" value="${optnNm011}" type="text" title="일반옵션명" name="optnNm1_normal" id="optnNm1_normal${optnTy01idx.index}${optnNm01_status.index}"> <input class="input-text full" value="${optnNm011}" type="text" title="일반옵션명" name="optnNm1_normal" id="optnNm1_normal${optnTy01idx.index}${optnNm01_status.index}">
<button type="button" class="btn outline xsm optionDel02">삭제</button> <button type="button" class="btn outline xsm optionDel02">삭제</button>
<button type="button" class="btn outline xsm optionVal98">옵션값 추가</button> <button type="button" class="btn outline xsm optionVal98">옵션값 추가</button>
<c:forEach var="goodsOptnInnb01" items="${fn:split(optnList01.goodsOptnInnb, '|')}" varStatus="goodsOptnInnb01_status"> <c:forEach var="goodsOptnInnb01" items="${fn:split(optnList01.goodsOptnInnb, '|')}" varStatus="goodsOptnInnb01_status">
@@ -3348,7 +3347,7 @@
</c:forEach> </c:forEach>
</c:when> </c:when>
<c:otherwise> <c:otherwise>
<input class="input-text full input-trim" value="${optnNm011}" type="hidden" title="일반옵션명" name="optnNm1_normal" id="optnNm1_normal${optnTy01idx.index}${optnNm01_status.index}"> <input class="input-text full" value="${optnNm011}" type="hidden" title="일반옵션명" name="optnNm1_normal" id="optnNm1_normal${optnTy01idx.index}${optnNm01_status.index}">
<c:forEach var="goodsOptnInnb01" items="${fn:split(optnList01.goodsOptnInnb, '|')}" varStatus="goodsOptnInnb01_status"> <c:forEach var="goodsOptnInnb01" items="${fn:split(optnList01.goodsOptnInnb, '|')}" varStatus="goodsOptnInnb01_status">
<c:if test="${goodsOptnInnb01_status.index ne '0' and optnNm01_status.index eq goodsOptnInnb01_status.index }"> <c:if test="${goodsOptnInnb01_status.index ne '0' and optnNm01_status.index eq goodsOptnInnb01_status.index }">
<input type="hidden" name="goodsOptnInnb_normal" value="${goodsOptnInnb01}"/> <input type="hidden" name="goodsOptnInnb_normal" value="${goodsOptnInnb01}"/>
@@ -3391,7 +3390,7 @@
<button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button>
<button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button>
</div> </div>
<input class="input-text full input-trim" type="text" id="optnVal1_normal${optnTy01idx.index}${optnVal011_status.index}" name="optnVal1_normal" title="옵션값" value="${optnVal011}"> <input class="input-text full" type="text" id="optnVal1_normal${optnTy01idx.index}${optnVal011_status.index}" name="optnVal1_normal" title="옵션값" value="${optnVal011}">
</div> </div>
</c:forEach> </c:forEach>
</div> </div>
@@ -3399,14 +3398,14 @@
<td> <td>
<div class="optionApply__priceContainer"> <div class="optionApply__priceContainer">
<c:forEach var="optnCd011" items="${fn:split(optnList01.optnCd1, '|')}"> <c:forEach var="optnCd011" items="${fn:split(optnList01.optnCd1, '|')}">
<input class="input-text full input-trim" type="text" title="상품코드" name="optnCd1_normal" value="${optnCd011}" > <input class="input-text full" type="text" title="상품코드" name="optnCd1_normal" value="${optnCd011}" >
</c:forEach> </c:forEach>
</div> </div>
</td> </td>
<td> <td>
<div class="optionApply__priceContainer"> <div class="optionApply__priceContainer">
<c:forEach var="hscode011" items="${fn:split(optnList01.hscode, '|')}"> <c:forEach var="hscode011" items="${fn:split(optnList01.hscode, '|')}">
<input class="input-text full input-trim" type="text" title="HS Code" name="hscode_normal" value="${hscode011}" maxlength="10" > <input class="input-text full" type="text" title="HS Code" name="hscode_normal" value="${hscode011}" maxlength="10" >
</c:forEach> </c:forEach>
</div> </div>
</td> </td>
@@ -3537,7 +3536,7 @@
<td> <td>
<div class="optionApply__inputList"> <div class="optionApply__inputList">
<div class="optionApply__inputContainer"> <div class="optionApply__inputContainer">
<input class="input-text full input-trim" type="text" name="optnNm1_normal" title="옵션명" id="optnNm1_normal0" value=""> <input class="input-text full" type="text" name="optnNm1_normal" title="옵션명" id="optnNm1_normal0" value="">
<button type="button" class="btn outline xsm optionDel01">삭제</button> <button type="button" class="btn outline xsm optionDel01">삭제</button>
<button type="button" class="btn outline xsm optionVal98" >옵션값 추가</button> <button type="button" class="btn outline xsm optionVal98" >옵션값 추가</button>
</div> </div>
@@ -3567,19 +3566,19 @@
<button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button>
<button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button>
</div> </div>
<input class="input-text full input-trim" type="text" id="optnVal1_normal0" name="optnVal1_normal" title="옵션값" value=""> <input class="input-text full" type="text" id="optnVal1_normal0" name="optnVal1_normal" title="옵션값" value="">
<input type="hidden" name="goodsOptnInnb_normal" value=""/> <input type="hidden" name="goodsOptnInnb_normal" value=""/>
</div> </div>
</div> </div>
</td> </td>
<td> <td>
<div class="optionApply__priceContainer"> <div class="optionApply__priceContainer">
<input class="input-text full input-trim" type="text" title="상품코드" name="optnCd1_normal" value="" > <input class="input-text full" type="text" title="상품코드" name="optnCd1_normal" value="" >
</div> </div>
</td> </td>
<td> <td>
<div class="optionApply__priceContainer"> <div class="optionApply__priceContainer">
<input class="input-text full input-trim" type="text" title="HS Code" name="hscode_normal" value="" maxlength="10"> <input class="input-text full" type="text" title="HS Code" name="hscode_normal" value="" maxlength="10">
</div> </div>
</td> </td>
<td> <td>
@@ -3724,16 +3723,16 @@
<td> <td>
</td> </td>
<td> <td>
<input class="input-text full input-trim" name ="optnNm1_invntry" type="text" title="재고옵션명1" value="${optnList02.optnNm1}"> <input class="input-text full" name ="optnNm1_invntry" type="text" title="재고옵션명1" value="${optnList02.optnNm1}">
</td> </td>
<td> <td>
<input class="input-text full input-trim" name ="optnNm2_invntry" type="text" title="재고옵선명2" value="${optnList02.optnNm2}"> <input class="input-text full" name ="optnNm2_invntry" type="text" title="재고옵선명2" value="${optnList02.optnNm2}">
</td> </td>
<td> <td>
<input class="input-text full input-trim" name="optnNm3_invntry" type="text" title="재고옵션명3" value="${optnList02.optnNm3}"> <input class="input-text full" name="optnNm3_invntry" type="text" title="재고옵션명3" value="${optnList02.optnNm3}">
</td> </td>
<td> <td>
<input class="input-text full input-trim" name="optnNm4_invntry" type="text" title="재고옵션명4" value="${optnList02.optnNm4}"> <input class="input-text full" name="optnNm4_invntry" type="text" title="재고옵션명4" value="${optnList02.optnNm4}">
</td> </td>
<td> <td>
@@ -3770,17 +3769,17 @@
<td> <td>
</td> </td>
<td> <td>
<input class="input-text full input-trim" name ="optnNm1_invntry" type="text" title="재고옵션명1" value=""> <input class="input-text full" name ="optnNm1_invntry" type="text" title="재고옵션명1" value="">
<input type="hidden" name="goodsOptnInnb_invntry" value="" /> <input type="hidden" name="goodsOptnInnb_invntry" value="" />
</td> </td>
<td> <td>
<input class="input-text full input-trim" name ="optnNm2_invntry" type="text" title="재고옵선명2" value=""> <input class="input-text full" name ="optnNm2_invntry" type="text" title="재고옵선명2" value="">
</td> </td>
<td> <td>
<input class="input-text full input-trim" name="optnNm3_invntry" type="text" title="재고옵션명3" value=""> <input class="input-text full" name="optnNm3_invntry" type="text" title="재고옵션명3" value="">
</td> </td>
<td> <td>
<input class="input-text full input-trim" name="optnNm4_invntry" type="text" title="재고옵션명4" value=""> <input class="input-text full" name="optnNm4_invntry" type="text" title="재고옵션명4" value="">
</td> </td>
<td> <td>
@@ -3828,13 +3827,13 @@
<label for="stdrDvAt02-${opt02Status.index}"></label> <label for="stdrDvAt02-${opt02Status.index}"></label>
</div> </div>
</td> </td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 값1" name="optnVal1_invntry" value="${goodsOpt02Val.optnVal1}" /> <td><input class="input-text full" type="text" title="재고옵션 값1" name="optnVal1_invntry" value="${goodsOpt02Val.optnVal1}" />
<input type="hidden" name="goodsOptnInnb_invntry" value="${goodsOpt02Val.goodsOptnInnb}" /> <input type="hidden" name="goodsOptnInnb_invntry" value="${goodsOpt02Val.goodsOptnInnb}" />
</td> </td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 값2" name="optnVal2_invntry" value="${goodsOpt02Val.optnVal2}"/></td> <td><input class="input-text full" type="text" title="재고옵션 값2" name="optnVal2_invntry" value="${goodsOpt02Val.optnVal2}"/></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 값3" name="optnVal3_invntry" value="${goodsOpt02Val.optnVal3}" /></td> <td><input class="input-text full" type="text" title="재고옵션 값3" name="optnVal3_invntry" value="${goodsOpt02Val.optnVal3}" /></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 값4" name="optnVal4_invntry" value="${goodsOpt02Val.optnVal4} "/></td> <td><input class="input-text full" type="text" title="재고옵션 값4" name="optnVal4_invntry" value="${goodsOpt02Val.optnVal4} "/></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 코드" name="optnCd1_invntry" value="${goodsOpt02Val.optnCd1}" /></td> <td><input class="input-text full" type="text" title="재고옵션 코드" name="optnCd1_invntry" value="${goodsOpt02Val.optnCd1}" /></td>
<td><input class="input-text full number right" type="text" value="<fmt:formatNumber value="${goodsOpt02Val.invntryQy}" pattern="#,###"/>" title="재고옵션 재고" name="invntryQy_invntry" /></td> <td><input class="input-text full number right" type="text" value="<fmt:formatNumber value="${goodsOpt02Val.invntryQy}" pattern="#,###"/>" title="재고옵션 재고" name="invntryQy_invntry" /></td>
<td><input class="input-text full number right" type="text" value="<fmt:formatNumber value="${goodsOpt02Val.cnsmrpric}" pattern="#,###"/>" title="재고옵션 소비자가" name="cnsmrpric_invntry"/></td> <td><input class="input-text full number right" type="text" value="<fmt:formatNumber value="${goodsOpt02Val.cnsmrpric}" pattern="#,###"/>" title="재고옵션 소비자가" name="cnsmrpric_invntry"/></td>
<td><input class="input-text full number right" type="text" value="<fmt:formatNumber value="${goodsOpt02Val.slepric}" pattern="#,###"/>" title="재고옵션 판매가" name="slepric_invntry"/></td> <td><input class="input-text full number right" type="text" value="<fmt:formatNumber value="${goodsOpt02Val.slepric}" pattern="#,###"/>" title="재고옵션 판매가" name="slepric_invntry"/></td>
@@ -3856,7 +3855,7 @@
</div> </div>
</div> </div>
</td> </td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 정보" name="optnInfo_invntry" value="${goodsOpt02Val.optnInfo}"/></td> <td><input class="input-text full" type="text" title="재고옵션 정보" name="optnInfo_invntry" value="${goodsOpt02Val.optnInfo}"/></td>
<td> <td>
<div class="compnbDscntAt_invntryList" style="height: 100%; display: flex; flex-direction: column; justify-content: space-around;"> <div class="compnbDscntAt_invntryList" style="height: 100%; display: flex; flex-direction: column; justify-content: space-around;">
<div class="compnbDscntAt_invntry"> <div class="compnbDscntAt_invntry">
@@ -4527,7 +4526,7 @@
<th>배송 안내 문구</th> <th>배송 안내 문구</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" id="dlvyGuidanceWordsCn" name="dlvyGuidanceWordsCn" value="${ resultMap.goodsDtl.dlvyGuidanceWordsCn}" title="배송안내문구"> <input class="input-text full" type="text" id="dlvyGuidanceWordsCn" name="dlvyGuidanceWordsCn" value="${ resultMap.goodsDtl.dlvyGuidanceWordsCn}" title="배송안내문구">
</div> </div>
</td> </td>
</tr> </tr>
@@ -5011,7 +5010,7 @@
//옵션명 //옵션명
$closestTr.find('td:eq(' + tdCount++ + ') .optionApply__inputList').append(` $closestTr.find('td:eq(' + tdCount++ + ') .optionApply__inputList').append(`
<div class="optionApply__inputContainer" style="margin: 0"> <div class="optionApply__inputContainer" style="margin: 0">
<input class="input-text full input-trim `+optnNm.attr('id')+`" type="hidden" value="`+optnNmVal+`" title="일반옵션명" name="optnNm1_normal"> <input class="input-text full `+optnNm.attr('id')+`" type="hidden" value="`+optnNmVal+`" title="일반옵션명" name="optnNm1_normal">
</div> </div>
`); `);
//노출여부 //노출여부
@@ -5036,14 +5035,14 @@
<button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button>
<button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button>
</div> </div>
<input class="input-text full input-trim" value="" type="text" title="일반옵션값" name="optnVal1_normal"> <input class="input-text full" value="" type="text" title="일반옵션값" name="optnVal1_normal">
</div> </div>
`); `);
$closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(` $closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(`
<input class="input-text full input-trim" type="text" title="일반옵션코드" name="optnCd1_normal"> <input class="input-text full" type="text" title="일반옵션코드" name="optnCd1_normal">
`); `);
$closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(` $closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(`
<input class="input-text full input-trim" value="220600" type="text" title="HS Code" name="hscode_normal" maxlength="10"> <input class="input-text full" value="220600" type="text" title="HS Code" name="hscode_normal" maxlength="10">
`); `);
$closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(` $closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(`
<input class="input-text full" value="0.0" type="text" title="실무게(KG)" name="realWt_normal"> <input class="input-text full" value="0.0" type="text" title="실무게(KG)" name="realWt_normal">

View File

@@ -749,7 +749,7 @@
<td> <td>
<div class="optionApply__inputList"> <div class="optionApply__inputList">
<div class="optionApply__inputContainer"> <div class="optionApply__inputContainer">
<input class="input-text full input-trim" <input class="input-text full"
type="text" name="optnNm1_normal" id="optnNm1_normal`+rowCount+`" type="text" name="optnNm1_normal" id="optnNm1_normal`+rowCount+`"
title="해당 인풋에 대한 설명"> title="해당 인풋에 대한 설명">
<button type="button" class="btn outline xsm optionDel01">삭제</button> <button type="button" class="btn outline xsm optionDel01">삭제</button>
@@ -782,11 +782,11 @@
<button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button>
<button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button>
</div> </div>
<input class="input-text full input-trim" type="text" title="일반옵션 값" id="optnVal1_normal`+rowCount+`" name="optnVal1_normal"> <input class="input-text full" type="text" title="일반옵션 값" id="optnVal1_normal`+rowCount+`" name="optnVal1_normal">
</div> </div>
</div> </div>
</td> </td>
<td><div class="optionApply__priceContainer"><input class="input-text full input-trim" type="text" title="일반옵션코드" name="optnCd1_normal"></td></div> <td><div class="optionApply__priceContainer"><input class="input-text full" type="text" title="일반옵션코드" name="optnCd1_normal"></td></div>
` `
+invntry_policy_qy+ +invntry_policy_qy+
` `
@@ -890,11 +890,11 @@
` `
+firstAdd+ +firstAdd+
` `
<td><input class="input-text full input-trim" type="text" title="재고옵션 값1" name="optnVal1_invntry" /></td> <td><input class="input-text full" type="text" title="재고옵션 값1" name="optnVal1_invntry" /></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 값2" name="optnVal2_invntry"/></td> <td><input class="input-text full" type="text" title="재고옵션 값2" name="optnVal2_invntry"/></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 값3" name="optnVal3_invntry"/></td> <td><input class="input-text full" type="text" title="재고옵션 값3" name="optnVal3_invntry"/></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 값4" name="optnVal4_invntry"/></td> <td><input class="input-text full" type="text" title="재고옵션 값4" name="optnVal4_invntry"/></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 코드" name="optnCd1_invntry"/></td> <td><input class="input-text full" type="text" title="재고옵션 코드" name="optnCd1_invntry"/></td>
` `
+invntry_policy_qy+ +invntry_policy_qy+
` `
@@ -933,7 +933,7 @@
</div> </div>
</div> </div>
</td> </td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 정보" name="optnInfo_invntry"/></td> <td><input class="input-text full" type="text" title="재고옵션 정보" name="optnInfo_invntry"/></td>
<td> <td>
<div class="compnbDscntAt_invntry"> <div class="compnbDscntAt_invntry">
<label class="b-checkbox checkbox" for="compnbDscntAt02_`+rowCount+`"> <label class="b-checkbox checkbox" for="compnbDscntAt02_`+rowCount+`">
@@ -1440,7 +1440,6 @@
//구매 대상자 제한 정보 저장 //구매 대상자 제한 정보 저장
const fn_save_purchase_limmit = function () { const fn_save_purchase_limmit = function () {
trimInputValue();
if ($('#purchase_limmit_hiddenForm') != null) { if ($('#purchase_limmit_hiddenForm') != null) {
$('#purchase_limmit_hiddenForm').remove(); $('#purchase_limmit_hiddenForm').remove();
@@ -1764,11 +1763,11 @@
******************************************************** */ ******************************************************** */
//카테고리 수정 //카테고리 수정
$(document).on('click', '#btn_update_category', function () { $(document).on('click', '#btn_update_category', function () {
trimInputValue();
if ($('#hiddenForm_categry') != null) {
$('#hiddenForm_categry').remove(); if ($('#hiddenForm_categry') != null) {
} $('#hiddenForm_categry').remove();
}
const url = '<c:url value="/mngr/goods/goodsmngr/updateGoodsDtlCtgryLink"/>'; const url = '<c:url value="/mngr/goods/goodsmngr/updateGoodsDtlCtgryLink"/>';
const hiddenForm = document.createElement('form'); const hiddenForm = document.createElement('form');
@@ -1805,7 +1804,6 @@
//상품 기본정보 수정 //상품 기본정보 수정
$(document).on('click', '#btn_update_BscInfo', function (event) { $(document).on('click', '#btn_update_BscInfo', function (event) {
event.preventDefault() event.preventDefault()
trimInputValue();
if ($('#hiddenForm_bscInfo') != null) { if ($('#hiddenForm_bscInfo') != null) {
$('#hiddenForm_bscInfo').remove(); $('#hiddenForm_bscInfo').remove();
@@ -1938,7 +1936,6 @@
// 상품 판매정보 수정 // 상품 판매정보 수정
$(document).on('click', '#btn_update_SelInfo', function () { $(document).on('click', '#btn_update_SelInfo', function () {
trimInputValue();
if ($('#hiddenForm_selInfo') != null) { if ($('#hiddenForm_selInfo') != null) {
$('#hiddenForm_selInfo').remove(); $('#hiddenForm_selInfo').remove();
@@ -2217,7 +2214,6 @@
//상품 옵션수정 //상품 옵션수정
$(document).on('click', '#btn_update_opt', function (event) { $(document).on('click', '#btn_update_opt', function (event) {
event.preventDefault() event.preventDefault()
trimInputValue();
if ($('#hiddenForm_opt') != null) { if ($('#hiddenForm_opt') != null) {
$('#hiddenForm_opt').remove(); $('#hiddenForm_opt').remove();
@@ -2649,8 +2645,6 @@
//상품 이미지 수정 //상품 이미지 수정
$(document).on('click', '#btn_update_img', function (event) { $(document).on('click', '#btn_update_img', function (event) {
event.preventDefault() event.preventDefault()
trimInputValue();
if($('#hiddenForm_img') != null) { if($('#hiddenForm_img') != null) {
$('#hiddenForm_img').remove(); $('#hiddenForm_img').remove();
} }
@@ -2723,8 +2717,6 @@
//상품 기타정보 수정 //상품 기타정보 수정
$(document).on('click', '[name="btn_update_EtcInfo"]', function (event) { $(document).on('click', '[name="btn_update_EtcInfo"]', function (event) {
event.preventDefault() event.preventDefault()
trimInputValue();
if($('#hiddenForm_etcInfo') != null) { if($('#hiddenForm_etcInfo') != null) {
$('#hiddenForm_etcInfo').remove(); $('#hiddenForm_etcInfo').remove();
} }
@@ -2849,7 +2841,7 @@
//관련상품 수정 //관련상품 수정
$(document).on('click','#btn_update_relateGoods', function (event) { $(document).on('click','#btn_update_relateGoods', function (event) {
event.preventDefault() event.preventDefault()
trimInputValue();
if($('#hiddenForm_relateGoods') != null) { if($('#hiddenForm_relateGoods') != null) {
$('#hiddenForm_relateGoods').remove(); $('#hiddenForm_relateGoods').remove();
@@ -3137,14 +3129,14 @@
<th>상품명<span class="red-7">*</span></th> <th>상품명<span class="red-7">*</span></th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="상품명" id="goodsNm" name="goodsNm" maxlength="35" value="${resultMap.goodsDtl.goodsNm}"> <input class="input-text full" type="text" title="상품명" id="goodsNm" name="goodsNm" maxlength="35" value="${resultMap.goodsDtl.goodsNm}">
<input type="hidden" id="sopmalCd" name="sopmalCd" value="${resultMap.BOGoodsVO.sopmalCd}"/> <input type="hidden" id="sopmalCd" name="sopmalCd" value="${resultMap.BOGoodsVO.sopmalCd}"/>
</div> </div>
</td> </td>
<th>상품명(영문)<span class="red-7">*</span></th> <th>상품명(영문)<span class="red-7">*</span></th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="상품명(영문)" id="goodsNmEn" name="goodsNmEn" maxlength="35" value="${resultMap.goodsDtl.goodsNmEn}"> <input class="input-text full" type="text" title="상품명(영문)" id="goodsNmEn" name="goodsNmEn" maxlength="35" value="${resultMap.goodsDtl.goodsNmEn}">
</div> </div>
</td> </td>
</tr> </tr>
@@ -3152,13 +3144,13 @@
<th>대표설명</th> <th>대표설명</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="대표설명" id="reprsntDc" name="reprsntDc" value="${resultMap.goodsDtl.reprsntDc}" > <input class="input-text full" type="text" title="대표설명" id="reprsntDc" name="reprsntDc" value="${resultMap.goodsDtl.reprsntDc}" >
</div> </div>
</td> </td>
<th>간략설명</th> <th>간략설명</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="간략설명" id="srtDc" name="srtDc" value="${resultMap.goodsDtl.srtDc}"> <input class="input-text full" type="text" title="간략설명" id="srtDc" name="srtDc" value="${resultMap.goodsDtl.srtDc}">
</div> </div>
</td> </td>
</tr> </tr>
@@ -3166,7 +3158,7 @@
<th>검색어</th> <th>검색어</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="검색어" id="kwrd" name="kwrd" value="${resultMap.goodsDtl.kwrd}"> <input class="input-text full" type="text" title="검색어" id="kwrd" name="kwrd" value="${resultMap.goodsDtl.kwrd}">
</div> </div>
</td> </td>
<th>브랜드</th> <th>브랜드</th>
@@ -3190,7 +3182,7 @@
<th>리뷰 연동</th> <th>리뷰 연동</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" title="리뷰 연동" id="rvwGroupNb" name="rvwGroupNb" value="${resultMap.goodsDtl.rvwGroupNb}"> <input class="input-text full" type="text" title="리뷰 연동" id="rvwGroupNb" name="rvwGroupNb" value="${resultMap.goodsDtl.rvwGroupNb}">
</div> </div>
</td> </td>
<th>리뷰 작성 가능 여부</th> <th>리뷰 작성 가능 여부</th>
@@ -3358,7 +3350,7 @@
<span class="control-label">사용자페이지 판매중지 문구 변경 -> </span> <span class="control-label">사용자페이지 판매중지 문구 변경 -> </span>
</label> </label>
</div> </div>
<label for="selStpgeCustomWords"></label><input type="text" class="input-text input-trim" id="selStpgeCustomWords" name="selStpgeCustomWords" value="${resultMap.goodsDtl.selStpgeCustomWords}" <label for="selStpgeCustomWords"></label><input type="text" class="input-text" id="selStpgeCustomWords" name="selStpgeCustomWords" value="${resultMap.goodsDtl.selStpgeCustomWords}"
<c:if test="${resultMap.goodsDtl.selStpgeCustomWordsAt ne 'Y'}"> disabled </c:if> <c:if test="${resultMap.goodsDtl.selStpgeCustomWordsAt ne 'Y'}"> disabled </c:if>
/> />
<span class="parentheses">) </span> <span class="parentheses">) </span>
@@ -3395,7 +3387,7 @@
<th>예약 상품 안내문구</th> <th>예약 상품 안내문구</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text xl input-trim" type="text" <input class="input-text xl" type="text"
id="resveGoodsGuidanceWordsCn" id="resveGoodsGuidanceWordsCn"
name="resveGoodsGuidanceWordsCn" name="resveGoodsGuidanceWordsCn"
value="${resultMap.goodsDtl.resveGoodsGuidanceWordsCn}" value="${resultMap.goodsDtl.resveGoodsGuidanceWordsCn}"
@@ -3461,7 +3453,7 @@
<tr> <tr>
<th>노출 문구</th> <th>노출 문구</th>
<td> <td>
<input class="input-text xl input-trim" type="text" <input class="input-text xl" type="text"
title="노출 문구" id="expsrSetupFwords" title="노출 문구" id="expsrSetupFwords"
name="expsrSetupFwords" name="expsrSetupFwords"
<c:choose> <c:choose>
@@ -3552,7 +3544,7 @@
<span class="ml-4">개의 수량을</span> <span class="ml-4">개의 수량을</span>
<input type="text" id="rltmQyDdctStdrDt" value="${fn:split(resultMap.goodsDtl.rltmQyDdctStdrDt,'T')[0]}" class="datepicker" title="이벤트가판매 가수량차감기준일시 설정" autocomplete="off" <c:if test="${resultMap.goodsDtl.rltmQyBannerDvCd ne '03'}">disabled</c:if> > <input type="text" id="rltmQyDdctStdrDt" value="${fn:split(resultMap.goodsDtl.rltmQyDdctStdrDt,'T')[0]}" class="datepicker" title="이벤트가판매 가수량차감기준일시 설정" autocomplete="off" <c:if test="${resultMap.goodsDtl.rltmQyBannerDvCd ne '03'}">disabled</c:if> >
<span class="ml-4">부터</span> <span class="ml-4">부터</span>
<input type="text" class="input-text sm right number" title="이벤트가판매 가수량차감시간 설정" value="${resultMap.goodsDtl.rltmQyDdctTme}" id="rltmQyDdctTme" <c:if test="${resultMap.goodsDtl.rltmQyBannerDvCd ne '03'}">disabled</c:if> > <input type="text" class="input-text sm right" title="이벤트가판매 가수량차감시간 설정" value="${resultMap.goodsDtl.rltmQyDdctTme}" id="rltmQyDdctTme" <c:if test="${resultMap.goodsDtl.rltmQyBannerDvCd ne '03'}">disabled</c:if> >
<span class="ml-4">분마다</span> <span class="ml-4">분마다</span>
<input class="input-text sm right number" id="rltmDdctQy" value="${resultMap.goodsDtl.rltmDdctQy}" type="text" title="이벤트가판매 가수량차감수량 설정" <c:if test="${resultMap.goodsDtl.rltmQyBannerDvCd ne '03'}">disabled</c:if> > <input class="input-text sm right number" id="rltmDdctQy" value="${resultMap.goodsDtl.rltmDdctQy}" type="text" title="이벤트가판매 가수량차감수량 설정" <c:if test="${resultMap.goodsDtl.rltmQyBannerDvCd ne '03'}">disabled</c:if> >
<span class="ml-4">개씩 차감</span> <span class="ml-4">개씩 차감</span>
@@ -3775,7 +3767,7 @@
<div class="optionApply__inputContainer"> <div class="optionApply__inputContainer">
<c:choose> <c:choose>
<c:when test="${optnNm01_status.index eq '0'}"> <c:when test="${optnNm01_status.index eq '0'}">
<input class="input-text full input-trim" value="${optnNm011}" type="text" title="일반옵션명" name="optnNm1_normal" id="optnNm1_normal${optnNm01_status.index}"> <input class="input-text full" value="${optnNm011}" type="text" title="일반옵션명" name="optnNm1_normal" id="optnNm1_normal${optnNm01_status.index}">
<%-- <button type="button" class="btn outline xsm optionDel02">삭제</button>--%> <%-- <button type="button" class="btn outline xsm optionDel02">삭제</button>--%>
<button type="button" class="btn outline xsm optionVal98">옵션값 추가</button> <button type="button" class="btn outline xsm optionVal98">옵션값 추가</button>
<c:forEach var="goodsOptnInnb01" items="${fn:split(optnList01.goodsOptnInnb, '|')}" varStatus="goodsOptnInnb01_status"> <c:forEach var="goodsOptnInnb01" items="${fn:split(optnList01.goodsOptnInnb, '|')}" varStatus="goodsOptnInnb01_status">
@@ -3785,7 +3777,7 @@
</c:forEach> </c:forEach>
</c:when> </c:when>
<c:otherwise> <c:otherwise>
<input class="input-text full input-trim" value="${optnNm011}" type="hidden" title="일반옵션명" name="optnNm1_normal" id="optnNm1_normal${optnTy01idx.index}${optnNm01_status.index}"> <input class="input-text full" value="${optnNm011}" type="hidden" title="일반옵션명" name="optnNm1_normal" id="optnNm1_normal${optnTy01idx.index}${optnNm01_status.index}">
<c:forEach var="goodsOptnInnb01" items="${fn:split(optnList01.goodsOptnInnb, '|')}" varStatus="goodsOptnInnb01_status"> <c:forEach var="goodsOptnInnb01" items="${fn:split(optnList01.goodsOptnInnb, '|')}" varStatus="goodsOptnInnb01_status">
<c:if test="${goodsOptnInnb01_status.index ne '0' and optnNm01_status.index eq goodsOptnInnb01_status.index }"> <c:if test="${goodsOptnInnb01_status.index ne '0' and optnNm01_status.index eq goodsOptnInnb01_status.index }">
<input type="hidden" name="goodsOptnInnb_normal" value="${goodsOptnInnb01}"/> <input type="hidden" name="goodsOptnInnb_normal" value="${goodsOptnInnb01}"/>
@@ -3799,7 +3791,7 @@
<div class="optionApply__inputContainer"> <div class="optionApply__inputContainer">
<c:choose> <c:choose>
<c:when test="${optnNm01_status.index eq '0'}"> <c:when test="${optnNm01_status.index eq '0'}">
<input class="input-text full input-trim" value="${optnNm011}" type="text" title="일반옵션명" name="optnNm1_normal" id="optnNm1_normal${optnTy01idx.index}${optnNm01_status.index}"> <input class="input-text full" value="${optnNm011}" type="text" title="일반옵션명" name="optnNm1_normal" id="optnNm1_normal${optnTy01idx.index}${optnNm01_status.index}">
<button type="button" class="btn outline xsm optionDel02">삭제</button> <button type="button" class="btn outline xsm optionDel02">삭제</button>
<button type="button" class="btn outline xsm optionVal98">옵션값 추가</button> <button type="button" class="btn outline xsm optionVal98">옵션값 추가</button>
<c:forEach var="goodsOptnInnb01" items="${fn:split(optnList01.goodsOptnInnb, '|')}" varStatus="goodsOptnInnb01_status"> <c:forEach var="goodsOptnInnb01" items="${fn:split(optnList01.goodsOptnInnb, '|')}" varStatus="goodsOptnInnb01_status">
@@ -3809,7 +3801,7 @@
</c:forEach> </c:forEach>
</c:when> </c:when>
<c:otherwise> <c:otherwise>
<input class="input-text full input-trim" value="${optnNm011}" type="hidden" title="일반옵션명" name="optnNm1_normal" id="optnNm1_normal${optnTy01idx.index}${optnNm01_status.index}"> <input class="input-text full" value="${optnNm011}" type="hidden" title="일반옵션명" name="optnNm1_normal" id="optnNm1_normal${optnTy01idx.index}${optnNm01_status.index}">
<c:forEach var="goodsOptnInnb01" items="${fn:split(optnList01.goodsOptnInnb, '|')}" varStatus="goodsOptnInnb01_status"> <c:forEach var="goodsOptnInnb01" items="${fn:split(optnList01.goodsOptnInnb, '|')}" varStatus="goodsOptnInnb01_status">
<c:if test="${goodsOptnInnb01_status.index ne '0' and optnNm01_status.index eq goodsOptnInnb01_status.index }"> <c:if test="${goodsOptnInnb01_status.index ne '0' and optnNm01_status.index eq goodsOptnInnb01_status.index }">
<input type="hidden" name="goodsOptnInnb_normal" value="${goodsOptnInnb01}"/> <input type="hidden" name="goodsOptnInnb_normal" value="${goodsOptnInnb01}"/>
@@ -3852,7 +3844,7 @@
<button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button>
<button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button>
</div> </div>
<input class="input-text full input-trim" type="text" id="optnVal1_normal${optnTy01idx.index}${optnVal011_status.index}" name="optnVal1_normal" title="옵션값" value="${optnVal011}"> <input class="input-text full" type="text" id="optnVal1_normal${optnTy01idx.index}${optnVal011_status.index}" name="optnVal1_normal" title="옵션값" value="${optnVal011}">
</div> </div>
</c:forEach> </c:forEach>
</div> </div>
@@ -3860,14 +3852,14 @@
<td> <td>
<div class="optionApply__priceContainer"> <div class="optionApply__priceContainer">
<c:forEach var="optnCd011" items="${fn:split(optnList01.optnCd1, '|')}"> <c:forEach var="optnCd011" items="${fn:split(optnList01.optnCd1, '|')}">
<input class="input-text full input-trim" type="text" title="일반옵션 상품코드" name="optnCd1_normal" value="${optnCd011}" > <input class="input-text full" type="text" title="일반옵션 상품코드" name="optnCd1_normal" value="${optnCd011}" >
</c:forEach> </c:forEach>
</div> </div>
</td> </td>
<td> <td>
<div class="optionApply__priceContainer"> <div class="optionApply__priceContainer">
<c:forEach var="hscode011" items="${fn:split(optnList01.hscode, '|')}"> <c:forEach var="hscode011" items="${fn:split(optnList01.hscode, '|')}">
<input class="input-text full input-trim" type="text" title="HS Code" name="hscode_normal" value="${hscode011}" maxlength="10" > <input class="input-text full" type="text" title="HS Code" name="hscode_normal" value="${hscode011}" maxlength="10" >
</c:forEach> </c:forEach>
</div> </div>
</td> </td>
@@ -4005,7 +3997,7 @@
<td> <td>
<div class="optionApply__inputList"> <div class="optionApply__inputList">
<div class="optionApply__inputContainer"> <div class="optionApply__inputContainer">
<input class="input-text full input-trim" type="text" name="optnNm1_normal" title="옵션명" id="optnNm1_normal0" value=""> <input class="input-text full" type="text" name="optnNm1_normal" title="옵션명" id="optnNm1_normal0" value="">
<button type="button" class="btn outline xsm optionDel01">삭제</button> <button type="button" class="btn outline xsm optionDel01">삭제</button>
<button type="button" class="btn outline xsm optionVal98" >옵션값 추가</button> <button type="button" class="btn outline xsm optionVal98" >옵션값 추가</button>
</div> </div>
@@ -4036,19 +4028,19 @@
<button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button>
<button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button>
</div> </div>
<input class="input-text full input-trim" type="text" id="optnVal1_normal0" name="optnVal1_normal" title="옵션값" value=""> <input class="input-text full" type="text" id="optnVal1_normal0" name="optnVal1_normal" title="옵션값" value="">
<input type="hidden" name="goodsOptnInnb_normal" value=""/> <input type="hidden" name="goodsOptnInnb_normal" value=""/>
</div> </div>
</div> </div>
</td> </td>
<td> <td>
<div class="optionApply__priceContainer"> <div class="optionApply__priceContainer">
<input class="input-text full input-trim" type="text" title="상품코드" name="optnCd1_normal" value="" > <input class="input-text full" type="text" title="상품코드" name="optnCd1_normal" value="" >
</div> </div>
</td> </td>
<td> <td>
<div class="optionApply__priceContainer"> <div class="optionApply__priceContainer">
<input class="input-text full input-trim" type="text" title="HS Code" name="hscode_normal" value="" maxlength="10" > <input class="input-text full" type="text" title="HS Code" name="hscode_normal" value="" maxlength="10" >
</div> </div>
</td> </td>
<td> <td>
@@ -4195,16 +4187,16 @@
<td> <td>
</td> </td>
<td> <td>
<input class="input-text full input-trim" name ="optnNm1_invntry" type="text" title="재고옵션명1" value="${optnList02.optnNm1}"> <input class="input-text full" name ="optnNm1_invntry" type="text" title="재고옵션명1" value="${optnList02.optnNm1}">
</td> </td>
<td> <td>
<input class="input-text full input-trim" name ="optnNm2_invntry" type="text" title="재고옵선명2" value="${optnList02.optnNm2}"> <input class="input-text full" name ="optnNm2_invntry" type="text" title="재고옵선명2" value="${optnList02.optnNm2}">
</td> </td>
<td> <td>
<input class="input-text full input-trim" name="optnNm3_invntry" type="text" title="재고옵션명3" value="${optnList02.optnNm3}"> <input class="input-text full" name="optnNm3_invntry" type="text" title="재고옵션명3" value="${optnList02.optnNm3}">
</td> </td>
<td> <td>
<input class="input-text full input-trim" name="optnNm4_invntry" type="text" title="재고옵션명4" value="${optnList02.optnNm4}"> <input class="input-text full" name="optnNm4_invntry" type="text" title="재고옵션명4" value="${optnList02.optnNm4}">
</td> </td>
<td> <td>
</td> </td>
@@ -4242,17 +4234,17 @@
<td> <td>
</td> </td>
<td> <td>
<input class="input-text full input-trim" name ="optnNm1_invntry" type="text" title="재고옵션명1" value=""> <input class="input-text full" name ="optnNm1_invntry" type="text" title="재고옵션명1" value="">
<input type="hidden" name="goodsOptnInnb_invntry" value="" /> <input type="hidden" name="goodsOptnInnb_invntry" value="" />
</td> </td>
<td> <td>
<input class="input-text full input-trim" name ="optnNm2_invntry" type="text" title="재고옵선명2" value=""> <input class="input-text full" name ="optnNm2_invntry" type="text" title="재고옵선명2" value="">
</td> </td>
<td> <td>
<input class="input-text full input-trim" name="optnNm3_invntry" type="text" title="재고옵션명3" value=""> <input class="input-text full" name="optnNm3_invntry" type="text" title="재고옵션명3" value="">
</td> </td>
<td> <td>
<input class="input-text full input-trim" name="optnNm4_invntry" type="text" title="재고옵션명4" value=""> <input class="input-text full" name="optnNm4_invntry" type="text" title="재고옵션명4" value="">
</td> </td>
<td> <td>
@@ -4302,13 +4294,13 @@
<label for="stdrDvAt02-${opt02Status.index}"></label> <label for="stdrDvAt02-${opt02Status.index}"></label>
</div> </div>
</td> </td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 값1" name="optnVal1_invntry" value="${goodsOpt02Val.optnVal1}" /> <td><input class="input-text full" type="text" title="재고옵션 값1" name="optnVal1_invntry" value="${goodsOpt02Val.optnVal1}" />
<input type="hidden" name="goodsOptnInnb_invntry" value="${goodsOpt02Val.goodsOptnInnb}" /> <input type="hidden" name="goodsOptnInnb_invntry" value="${goodsOpt02Val.goodsOptnInnb}" />
</td> </td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 값2" name="optnVal2_invntry" value="${goodsOpt02Val.optnVal2}"/></td> <td><input class="input-text full" type="text" title="재고옵션 값2" name="optnVal2_invntry" value="${goodsOpt02Val.optnVal2}"/></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 값3" name="optnVal3_invntry" value="${goodsOpt02Val.optnVal3}" /></td> <td><input class="input-text full" type="text" title="재고옵션 값3" name="optnVal3_invntry" value="${goodsOpt02Val.optnVal3}" /></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 값4" name="optnVal4_invntry" value="${goodsOpt02Val.optnVal4} "/></td> <td><input class="input-text full" type="text" title="재고옵션 값4" name="optnVal4_invntry" value="${goodsOpt02Val.optnVal4} "/></td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 코드" name="optnCd1_invntry" value="${goodsOpt02Val.optnCd1}" /></td> <td><input class="input-text full" type="text" title="재고옵션 코드" name="optnCd1_invntry" value="${goodsOpt02Val.optnCd1}" /></td>
<td><input class="input-text full number right" type="text" value="<fmt:formatNumber value="${goodsOpt02Val.invntryQy}" pattern="#,###"/>" title="재고옵션 재고" name="invntryQy_invntry" <c:if test="${resultMap.goodsDtl.invntryPolicyCd eq '02'}"> disabled </c:if> /></td> <td><input class="input-text full number right" type="text" value="<fmt:formatNumber value="${goodsOpt02Val.invntryQy}" pattern="#,###"/>" title="재고옵션 재고" name="invntryQy_invntry" <c:if test="${resultMap.goodsDtl.invntryPolicyCd eq '02'}"> disabled </c:if> /></td>
<td><input class="input-text full right" type="text" value="<fmt:formatNumber value="${goodsOpt02Val.usefulInvntry}" pattern="#,###"/>" title="재고옵션 가용재고" disabled /></td> <td><input class="input-text full right" type="text" value="<fmt:formatNumber value="${goodsOpt02Val.usefulInvntry}" pattern="#,###"/>" title="재고옵션 가용재고" disabled /></td>
<td><input class="input-text full number right" type="text" value="<fmt:formatNumber value="${goodsOpt02Val.cnsmrpric}" pattern="#,###"/>" title="재고옵션 소비자가" name="cnsmrpric_invntry"/></td> <td><input class="input-text full number right" type="text" value="<fmt:formatNumber value="${goodsOpt02Val.cnsmrpric}" pattern="#,###"/>" title="재고옵션 소비자가" name="cnsmrpric_invntry"/></td>
@@ -4331,7 +4323,7 @@
</div> </div>
</div> </div>
</td> </td>
<td><input class="input-text full input-trim" type="text" title="재고옵션 정보" name="optnInfo_invntry" value="${goodsOpt02Val.optnInfo}"/></td> <td><input class="input-text full" type="text" title="재고옵션 정보" name="optnInfo_invntry" value="${goodsOpt02Val.optnInfo}"/></td>
<td> <td>
<div class="compnbDscntAt_invntryList" style="height: 100%; display: flex; flex-direction: column; justify-content: space-around;"> <div class="compnbDscntAt_invntryList" style="height: 100%; display: flex; flex-direction: column; justify-content: space-around;">
<div class="compnbDscntAt_invntry"> <div class="compnbDscntAt_invntry">
@@ -5013,7 +5005,7 @@
<th>배송 안내 문구</th> <th>배송 안내 문구</th>
<td> <td>
<div class="td-inner"> <div class="td-inner">
<input class="input-text full input-trim" type="text" id="dlvyGuidanceWordsCn" name="dlvyGuidanceWordsCn" value="${ resultMap.goodsDtl.dlvyGuidanceWordsCn}" title="배송안내문구"> <input class="input-text full" type="text" id="dlvyGuidanceWordsCn" name="dlvyGuidanceWordsCn" value="${ resultMap.goodsDtl.dlvyGuidanceWordsCn}" title="배송안내문구">
</div> </div>
</td> </td>
</tr> </tr>
@@ -5531,7 +5523,7 @@
//옵션명 //옵션명
$closestTr.find('td:eq(' + tdCount++ + ') .optionApply__inputList').append(` $closestTr.find('td:eq(' + tdCount++ + ') .optionApply__inputList').append(`
<div class="optionApply__inputContainer" style="margin: 0"> <div class="optionApply__inputContainer" style="margin: 0">
<input class="input-text full input-trim `+optnNm.attr('id')+`" type="hidden" value="`+optnNmVal+`" title="일반옵션명" name="optnNm1_normal"> <input class="input-text full `+optnNm.attr('id')+`" type="hidden" value="`+optnNmVal+`" title="일반옵션명" name="optnNm1_normal">
</div> </div>
`); `);
//노출여부 //노출여부
@@ -5556,14 +5548,14 @@
<button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 up"><span class="visually-hidden">위로</span></button>
<button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button> <button type="button" class="optionApply__moveBtn optionMove01 down"><span class="visually-hidden">아래로</span></button>
</div> </div>
<input class="input-text full input-trim" value="" type="text" title="일반옵션값" name="optnVal1_normal"> <input class="input-text full" value="" type="text" title="일반옵션값" name="optnVal1_normal">
</div> </div>
`); `);
$closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(` $closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(`
<input class="input-text full input-trim" type="text" title="일반옵션코드" name="optnCd1_normal"> <input class="input-text full" type="text" title="일반옵션코드" name="optnCd1_normal">
`); `);
$closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(` $closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(`
<input class="input-text full input-trim" value="220600" type="text" title="HS Code" name="hscode_normal" maxlength="10"> <input class="input-text full" value="220600" type="text" title="HS Code" name="hscode_normal" maxlength="10">
`); `);
$closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(` $closestTr.find('td:eq(' + tdCount++ + ') .optionApply__priceContainer').append(`
<input class="input-text full" value="0.0" type="text" title="실무게(KG)" name="realWt_normal"> <input class="input-text full" value="0.0" type="text" title="실무게(KG)" name="realWt_normal">

View File

@@ -82,7 +82,7 @@
} }
if(!pageUnit) { if(!pageUnit) {
dataStr = `$('#listForm').serialize();` dataStr = $('#listForm').serialize();
} else { } else {
if($('#pageUnit').length){ if($('#pageUnit').length){
$('#pageUnit').val(pageUnit); $('#pageUnit').val(pageUnit);

View File

@@ -33,7 +33,6 @@
<c:set var="order" value="${data.order}"/> <c:set var="order" value="${data.order}"/>
<script src="<c:url value='/js/dlvylc/dlvylc.js'/>"></script> <script src="<c:url value='/js/dlvylc/dlvylc.js'/>"></script>
<script src="<c:url value='/js/sopmal/refund-popup.js'/>"></script>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
@@ -665,18 +664,29 @@
return; return;
} }
fn_load_refund_popup('<c:url value="/sopmal/mpage/ordr/selectSetleCanclPopupForm"/>', { $.ajax({
'sopmalCd':sopmalCd, type:'post',
'ordrInnb':ordrInnb, url:'<c:url value="/sopmal/mpage/ordr/selectSetleCanclPopupForm"/>',
'ordrDlvyInnb':ordrDlvyInnb data:{
}, function(popup) { 'sopmalCd':sopmalCd,
$(popup).find('.orderRefundPop .select-box select').niceSelect(); 'ordrInnb':ordrInnb,
'ordrDlvyInnb':ordrDlvyInnb
},
success:function(html) {
$('#refund-pop').remove();
$(popup).find('#refundAcntnb').on("input", function () { $('#refundPopupDiv').html(html);
this.value = this.value.replace(/[^0-9]/g, "");
});
$(popup).modal(); const popup = $('#refund-pop');
$(popup).find('.orderRefundPop .select-box select').niceSelect();
$(popup).find('#refundAcntnb').on("input", function () {
this.value = this.value.replace(/[^0-9]/g, "");
});
$(popup).modal();
}
}); });
} }
@@ -1625,10 +1635,7 @@
</c:if> </c:if>
<tr> <tr>
<th>결제금액</th> <th>결제금액</th>
<td> <td><span class="comma"><fmt:formatNumber value="${setle.setleAmt}" pattern="#,###"/></span>${curUnit} / <span class="comma">${setle.wonSetleAmt}</span>${krUnit}</td>
<span class="comma"><fmt:formatNumber value="${setle.setleAmt}" pattern="#,###"/></span>${curUnit}
<c:if test="${data.setleList[0].pgCmpnyNm ne 'stripe'}">/ <span class="comma">${setle.wonSetleAmt}</span>${krUnit}</c:if>
</td>
</tr> </tr>
<c:if test = "${order.ordrSttusCd ne '85' && order.ordrSttusCd ne '95'}"><%--주문취소시 미노출--%> <c:if test = "${order.ordrSttusCd ne '85' && order.ordrSttusCd ne '95'}"><%--주문취소시 미노출--%>
<tr> <tr>
@@ -1695,10 +1702,7 @@
</ul> </ul>
<div class="cartOrderBox__total"> <div class="cartOrderBox__total">
<span class="cartOrderBox__totalTh">결제금액</span> <span class="cartOrderBox__totalTh">결제금액</span>
<span class="cartOrderBox__totalTd"> <span class="cartOrderBox__totalTd"><span class="comma"><fmt:formatNumber value="${total.setleAmt}" pattern="#,###"/></span><span class="priceUnit">${curUnit}</span> / <span class="comma">${total.wonRlSetleAmt}</span><span class="priceUnit">${krUnit}</span></span>
<span class="comma"><fmt:formatNumber value="${total.setleAmt}" pattern="#,###"/></span><span class="priceUnit">${curUnit}</span>
<c:if test="${data.setleList[0].pgCmpnyNm ne 'stripe'}">/ <span class="comma">${total.wonRlSetleAmt}</span><span class="priceUnit">${krUnit}</span></c:if>
</span>
</div> </div>
</div> </div>
</div> </div>
@@ -1847,4 +1851,4 @@
<div id="modalDiv"></div> <div id="modalDiv"></div>
<div id="refundPopupDiv"></div> <div id="refundPopupDiv"></div>
</body> </body>
</html> </html>

View File

@@ -870,12 +870,10 @@
<span class="comma"><c:out value="${ reTotAmt.realRefundAmt }"/></span> <span class="comma"><c:out value="${ reTotAmt.realRefundAmt }"/></span>
<span class="priceUnit">${curUnit}</span> <span class="priceUnit">${curUnit}</span>
</div> </div>
<c:if test="${resultMap.result.refnd.pgCmpnyNm ne 'stripe'}"> <span class="priceSum__itemPrice">
<span class="priceSum__itemPrice"> [<span class="comma"><c:out value="${ reTotAmt.realWonRefundAmt }"/></span>
[<span class="comma"><c:out value="${ reTotAmt.realWonRefundAmt }"/></span> <span class="priceUnit">${krUnit}</span>]
<span class="priceUnit">${krUnit}</span>] </span>
</span>
</c:if>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -32,7 +32,6 @@
<jsp:include page="/WEB-INF/views/comm/Include.jsp"/> <jsp:include page="/WEB-INF/views/comm/Include.jsp"/>
<script src="<c:url value='/js/dlvylc/dlvylc.js'/>"></script> <script src="<c:url value='/js/dlvylc/dlvylc.js'/>"></script>
<script src="<c:url value='/js/sopmal/refund-popup.js'/>"></script>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
@@ -660,18 +659,29 @@
return; return;
} }
fn_load_refund_popup('<c:url value="/sopmal/mpage/ordr/selectSetleCanclPopupForm"/>', { $.ajax({
'sopmalCd':sopmalCd, type:'post',
'ordrInnb':ordrInnb, url:'<c:url value="/sopmal/mpage/ordr/selectSetleCanclPopupForm"/>',
'ordrDlvyInnb':ordrDlvyInnb data:{
}, function(popup) { 'sopmalCd':sopmalCd,
$(popup).find('.orderRefundPop .select-box select').niceSelect(); 'ordrInnb':ordrInnb,
'ordrDlvyInnb':ordrDlvyInnb
},
success:function(html) {
$('#refund-pop').remove();
$(popup).find('#refundAcntnb').on("input", function () { $('#refundPopupDiv').html(html);
this.value = this.value.replace(/[^0-9]/g, "");
});
$(popup).modal(); const popup = $('#refund-pop');
$(popup).find('.orderRefundPop .select-box select').niceSelect();
$(popup).find('#refundAcntnb').on("input", function () {
this.value = this.value.replace(/[^0-9]/g, "");
});
$(popup).modal();
}
}); });
} }
@@ -1481,12 +1491,10 @@
<span class="comma"><c:out value="${ reTotAmt.rlRefundAmt }"/></span> <span class="comma"><c:out value="${ reTotAmt.rlRefundAmt }"/></span>
<span class="priceUnit">${curUnit}</span> <span class="priceUnit">${curUnit}</span>
</div> </div>
<c:if test="${data.setleList[0].pgCmpnyNm ne 'stripe'}"> <span class="priceSum__itemPrice">
<span class="priceSum__itemPrice"> [<span class="comma"><c:out value="${ reTotAmt.realWonRefundAmt }"/></span>
[<span class="comma"><c:out value="${ reTotAmt.realWonRefundAmt }"/></span> <span class="priceUnit">${krUnit}</span>]
<span class="priceUnit">${krUnit}</span>] </span>
</span>
</c:if>
</div> </div>
</div> </div>
</div> </div>
@@ -1778,10 +1786,7 @@
</c:if> </c:if>
<tr> <tr>
<th>결제금액</th> <th>결제금액</th>
<td> <td><span class="comma"><fmt:formatNumber value="${setle.setleAmt}" pattern="#,###"/></span>${curUnit} / <span class="comma">${setle.wonSetleAmt}</span>${krUnit}</td>
<span class="comma"><fmt:formatNumber value="${setle.setleAmt}" pattern="#,###"/></span>${curUnit}
<c:if test="${data.setleList[0].pgCmpnyNm ne 'stripe'}">/ <span class="comma">${setle.wonSetleAmt}</span>${krUnit}</c:if>
</td>
</tr> </tr>
<c:if test = "${order.ordrSttusCd ne '85' && order.ordrSttusCd ne '95'}"><%--주문취소시 미노출--%> <c:if test = "${order.ordrSttusCd ne '85' && order.ordrSttusCd ne '95'}"><%--주문취소시 미노출--%>
<tr> <tr>
@@ -1959,4 +1964,4 @@
<div id="modalDiv"></div> <div id="modalDiv"></div>
<div id="refundPopupDiv"></div> <div id="refundPopupDiv"></div>
</body> </body>
</html> </html>

View File

@@ -521,14 +521,13 @@
}); });
/* 결제정보 결제수단 버튼 선택 이벤트 */ /* 결제정보 결제수단 버튼 선택 이벤트 */
$('input[name="pg"]').on('click', function(event, skipDefaultMethod) { $('input[name="pg"]').on('click', function() {
const form = $(this).closest('#setleForm') const form = $(this).closest('#setleForm')
const id = $(this).attr('id'); const id = $(this).attr('id');
const pgCmpnyNm = $(this).val(); const pgCmpnyNm = $(this).val();
$(form).find('.pgContent').hide(); $(form).find('.pgContent').hide();
$(form).find('#' + id + 'Content').show(); $(form).find('#' + id + 'Content').show();
$('.cartOrderBox__totalKr').show();
//$(form).find('#setleSetupTyCd').val() === '01' ? $(form).find('#pg04Content').show() : $(form).find('#pg03Content').show(); //$(form).find('#setleSetupTyCd').val() === '01' ? $(form).find('#pg04Content').show() : $(form).find('#pg03Content').show();
if($(form).find('#setleSetupTyCd').val() === '01'){$(form).find('#pg04Content').show();} if($(form).find('#setleSetupTyCd').val() === '01'){$(form).find('#pg04Content').show();}
@@ -574,22 +573,12 @@
}); });
$(form).find('#setleTyCd').val('03'); $(form).find('#setleTyCd').val('03');
} else if('st01' === id){ //Stripe
$('.cartOrderBox__totalKr').hide();
} else { } else {
$(form).find('#setleTyCd').val(''); $(form).find('#setleTyCd').val('');
$('.order-method-normal__btn').removeClass('active'); $('.order-method-normal__btn').removeClass('active');
$('.order-method-normal__content').hide(); $('.order-method-normal__content').hide();
} }
// 통화를 선택하면 사용 가능한 첫 결제수단을 기존 클릭 처리로 선택한다.
// 결제수단 버튼에서 라디오를 갱신할 때는 재귀 선택을 생략한다.
if (!skipDefaultMethod && ['st01', 'pg03', 'pg04', 'pg06'].includes(id)) {
$(form).find('#' + id + 'Content')
.find('.order-method-normal__btn:visible:not(:disabled)')
.first().trigger('click');
}
}); });
/* 결제정보 > 일반결제 > 결제수단 버튼 선택 이벤트 */ /* 결제정보 > 일반결제 > 결제수단 버튼 선택 이벤트 */
@@ -598,8 +587,10 @@
const content = $('.order-method-normal__content'); const content = $('.order-method-normal__content');
const useCashMlgAmt = $('#useCashMlgAmt').val(); const useCashMlgAmt = $('#useCashMlgAmt').val();
const pgId = $(this).closest('.pgContent').attr('id').replace(/Content$/, ''); //$('#setleSetupTyCd').val() === '01' ? $('#pg04').click() : $('#pg03').click();
$('#' + pgId).trigger('click', [true]); if($('#setleSetupTyCd').val() === '01'){$('#pg04').click();}
else if($('#setleSetupTyCd').val() === '02'){$('#pg03').click();}
else if($('#setleSetupTyCd').val() === '03'){$('#pg06').click();}
$('.order-method-normal__btn').removeClass('active'); $('.order-method-normal__btn').removeClass('active');
$(this).addClass('active'); $(this).addClass('active');
@@ -651,12 +642,12 @@
const kcpMid = '<c:out value="${data.payInfo.kcpMid}"/>'; const kcpMid = '<c:out value="${data.payInfo.kcpMid}"/>';
const bpayMid = '<c:out value="${data.payInfo.bpayMid}"/>'; const bpayMid = '<c:out value="${data.payInfo.bpayMid}"/>';
// 개발서버 네이버페이 CPID 구분 적용 취소 // 개발서버 네이버페이 CPID 구분 적용 취소
$(form).find('#siteCdMid').val(kcpMid); // $(form).find('#siteCdMid').val(kcpMid);
// if('naverpay' === id) { if('naverpay' === id) {
// $(form).find('#siteCdMid').val(bpayMid); $(form).find('#siteCdMid').val(bpayMid);
// } else { } else {
// $(form).find('#siteCdMid').val(kcpMid); $(form).find('#siteCdMid').val(kcpMid);
// } }
}); });
/* 결제예정금액 > 약관 전체동의 선택 이벤트 */ /* 결제예정금액 > 약관 전체동의 선택 이벤트 */
@@ -3039,7 +3030,7 @@
return false; return false;
} }
if ('kcp' === pgCmpnyNm || 'toss' === pgCmpnyNm || 'kiwoom' === pgCmpnyNm || 'stripe' === pgCmpnyNm) { if ('kcp' === pgCmpnyNm || 'toss' === pgCmpnyNm || 'kiwoom' === pgCmpnyNm) {
const div = $('#setleForm').find('.order-method-normal'); const div = $('#setleForm').find('.order-method-normal');
if (!$(div).find('.order-method-normal__btn-container button').hasClass('active')) { if (!$(div).find('.order-method-normal__btn-container button').hasClass('active')) {
@@ -4248,27 +4239,11 @@
</c:if> </c:if>
<%-- 퀵계좌이체 끝 --%> <%-- 퀵계좌이체 끝 --%>
<%-- Stripe 시작 --%>
<c:if test="${'Y' eq payInfo.stripeUseAt}">
<div class="custom-radio is-medium">
<input type="radio" name="pg" id="st01" value="stripe">
<label for="st01">엔화(¥) 결제</label>
</div>
<div id="st01Content" class="pgContent order-method-normal" <%-- style="display: none"--%>>
<div class="order-method-normal__btn-container">
<button type="button" name="01" id="stripe" class="order-method-normal__btn gift_pay">
<div class="order-method-normal__icon order-method-normal__icon--card"></div>신용카드
</button>
</div>
</div>
</c:if>
<%-- Stripe 끝 --%>
<%-- toss 결제 시작 --%> <%-- toss 결제 시작 --%>
<c:if test="${'02' eq payInfo.setleSetupTyCd}"> <c:if test="${'02' eq payInfo.setleSetupTyCd}">
<div class="custom-radio is-medium"> <div class="custom-radio is-medium">
<input type="radio" name="pg" id="pg03" value="toss"> <input type="radio" name="pg" id="pg03" value="toss">
<label for="pg03">원화(₩) 결제</label> <label for="pg03">일반결제</label>
</div> </div>
<div id="pg03Content" class="pgContent order-method-normal" <%-- style="display: none"--%>> <div id="pg03Content" class="pgContent order-method-normal" <%-- style="display: none"--%>>
<div class="order-method-normal__btn-container"> <div class="order-method-normal__btn-container">
@@ -4400,7 +4375,7 @@
<c:if test="${'01' eq payInfo.setleSetupTyCd}"> <c:if test="${'01' eq payInfo.setleSetupTyCd}">
<div class="custom-radio is-medium"> <div class="custom-radio is-medium">
<input type="radio" name="pg" id="pg04" value="kcp"> <input type="radio" name="pg" id="pg04" value="kcp">
<label for="pg04">원화(₩) 결제</label> <label for="pg04">일반결제</label>
</div> </div>
<div id="pg04Content" class="pgContent order-method-normal" <%-- style="display: none"--%>> <div id="pg04Content" class="pgContent order-method-normal" <%-- style="display: none"--%>>
<div class="order-method-normal__btn-container"> <div class="order-method-normal__btn-container">
@@ -4532,7 +4507,7 @@
<c:if test="${'03' eq payInfo.setleSetupTyCd}"> <c:if test="${'03' eq payInfo.setleSetupTyCd}">
<div class="custom-radio is-medium"> <div class="custom-radio is-medium">
<input type="radio" name="pg" id="pg06" value="kiwoom"> <input type="radio" name="pg" id="pg06" value="kiwoom">
<label for="pg06">원화(₩) 결제</label> <label for="pg06">일반결제</label>
</div> </div>
<div id="pg06Content" class="pgContent order-method-normal" <%-- style="display: none"--%>> <div id="pg06Content" class="pgContent order-method-normal" <%-- style="display: none"--%>>
<div class="order-method-normal__btn-container"> <div class="order-method-normal__btn-container">
@@ -4681,11 +4656,11 @@
<span class="cartOrderBox__td"><span class="cartOrderBox__discountMinus">(-)</span><span id="dscntAmtSapn" class="comma">0</span><span class="priceUnit">${curUnit}</span></span> <span class="cartOrderBox__td"><span class="cartOrderBox__discountMinus">(-)</span><span id="dscntAmtSapn" class="comma">0</span><span class="priceUnit">${curUnit}</span></span>
</li> </li>
</ul> </ul>
<div class="cartOrderBox__total"> <div class="cartOrderBox__total" style="margin-bottom: 5px;">
<span class="cartOrderBox__totalTh">총 결제금액</span> <span class="cartOrderBox__totalTh">총 결제금액</span>
<span class="cartOrderBox__td"><span id="setleAmtSapn" class="comma">0</span><span class="priceUnit">${curUnit}</span></span> <span class="cartOrderBox__td"><span id="setleAmtSapn" class="comma">0</span><span class="priceUnit">${curUnit}</span></span>
</div> </div>
<div class="cartOrderBox__total cartOrderBox__totalKr" style="margin-top: 10px;"> <div class="cartOrderBox__total" style="margin-top: 5px;">
<span class="cartOrderBox__totalTh"></span> <span class="cartOrderBox__totalTh"></span>
<span class="cartOrderBox__totalTd"><span id="setleAmtKrSapn" class="comma">0</span><span class="priceUnit">${krUnit}</span></span> <span class="cartOrderBox__totalTd"><span id="setleAmtKrSapn" class="comma">0</span><span class="priceUnit">${krUnit}</span></span>
</div> </div>

View File

@@ -539,10 +539,7 @@
</c:if> </c:if>
<tr> <tr>
<th>결제금액</th> <th>결제금액</th>
<td> <td><span class="comma"><fmt:formatNumber value="${setle.setleAmt}" pattern="#,###"/></span>${curUnit} / <span class="comma"><fmt:formatNumber value="${setle.wonSetleAmt}" pattern="#,###"/></span>${krUnit}</td>
<span class="comma"><fmt:formatNumber value="${setle.setleAmt}" pattern="#,###"/></span>${curUnit}
<c:if test="${data.setleList[0].pgCmpnyNm ne 'stripe'}">/ <span class="comma"><fmt:formatNumber value="${setle.wonSetleAmt}" pattern="#,###"/></span>${krUnit}</c:if>
</td>
</tr> </tr>
<tr> <tr>
<th>결제일시</th> <th>결제일시</th>
@@ -626,10 +623,7 @@
</ul> </ul>
<div class="cartOrderBox__total"> <div class="cartOrderBox__total">
<span class="cartOrderBox__totalTh">결제금액</span> <span class="cartOrderBox__totalTh">결제금액</span>
<span class="cartOrderBox__totalTd"> <span class="cartOrderBox__totalTd"><span class="comma"><fmt:formatNumber value="${total.setleAmt}" pattern="#,###"/></span><span class="priceUnit">${curUnit}</span> / <span class="comma"><fmt:formatNumber value="${total.wonRlSetleAmt}" pattern="#,###"/></span><span class="priceUnit">${krUnit}</span></span>
<span class="comma"><fmt:formatNumber value="${total.setleAmt}" pattern="#,###"/></span><span class="priceUnit">${curUnit}</span>
<c:if test="${data.setleList[0].pgCmpnyNm ne 'stripe'}">/ <span class="comma"><fmt:formatNumber value="${total.wonRlSetleAmt}" pattern="#,###"/></span><span class="priceUnit">${krUnit}</span></c:if>
</span>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,66 +0,0 @@
<%@ 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 : OrsrReqstStripeR.jsp
Description : Stripe 주문 요청
Modification Information
수정일 수정자 수정내용
------- -------- ---------------------------
2026-09-17 이대환 최초 생성
--%>
<!DOCTYPE html>
<html lang="ko">
<head>
<!-- <meta charset="UTF-8"> -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Expires" content="-1" />
<meta http-equiv="Pragma" content="no-cache" />
<script src="<c:url value='/pc/vendor/jquery-3.7.1.min.js'/>"></script>
<script type="text/javascript" language="javascript">
$(document).ready(function() {
$.ajax({
url : "<c:url value="/sopmal/stripe/checkout"/>",
type : "POST",
data : $('#order_info').serialize(),
success : function(res) {
console.log(res);
const data = JSON.parse(res.resBody.result);
window.location.replace(data.redirectUrl);
}
});
});
</script>
</head>
<body>
<%-- Controller에 넘어가는 값 --%>
<form name="order_info" id="order_info">
<input type="hidden" name="sopmalCd" class="sopmalCd" value="${data.setle.sopmalCd}" />
<input type="hidden" name="ordrInnb" class="ordrInnb" value="${data.setle.ordrInnb}" />
<input type="hidden" name="pgCmpnyNm" class="pgCmpnyNm" value="${data.setle.pgCmpnyNm}" />
<input type="hidden" name="setleTyCd" class="setleTyCd" value="${data.setle.setleTyCd}" />
<input type="hidden" name="goodsNm" class="goodsNm" value="${data.setle.goodsNm}"/>
<input type="hidden" name="setleAmt" class="setleAmt" value="${data.setle.wonSetleAmt}"/>
<input type="hidden" name="jpSetleAmt" class="jpSetleAmt" value="${data.setle.setleAmt}"/>
<input type="hidden" name="ordrrNm" class="ordrrNm" value="${data.ordr.ordrrNm}"/>
<input type="hidden" name="ordrrEmail" class="ordrrEmail" value="${data.ordr.ordrrEmail}"/>
<input type="hidden" name="ordrrMbtlnb" class="ordrrMbtlnb" value="${data.ordr.ordrrMbtlnb}"/>
<input type="hidden" name="mbrId" class="mbrId" value="${data.ordr.mbrId}"/>
<input type="hidden" name="mbrInnb" class="mbrInnb" value="${data.ordr.mbrInnb}" />
<input type="hidden" name="sesionId" class="sesionId" value="${data.ordr.sesionId}" />
<input type="hidden" name="subsvcInnb" id="subsvcInnb" value="${subsvcInnb}"/>
</form>
</body>
</html>

View File

@@ -1,64 +0,0 @@
<%@ 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 : PayStripeCnclC.jsp
Description : Stripe 결제 실패창
Modification Information
수정일 수정자 수정내용
------- -------- ---------------------------
2026-09-17 이대환 최초 생성
--%>
<!DOCTYPE html>
<html lang="ko">
<head>
<title>결제 실패</title>
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<script src="<c:url value='/pc/vendor/jquery-3.7.1.min.js'/>"></script>
<script>
$(document).ready(function() {
var returnUrl = '${returnUrl}';
var status = '${status}';
var payment_status = '${payment_status}';
var customer_details = '${customer_details}';
let form = $('<form></form>');
$(form).attr('method', 'post');
$(form).attr('action', returnUrl);
history.replaceState(null, '', returnUrl);
$(form).append($('<input/>', {type:'hidden', name:'sopmalCd', value:'${sopmalCd}'}));
$(form).append($('<input/>', {type:'hidden', name:'ordrInnb', value:'${ordrInnb}'}));
$(form).append($('<input/>', {type:'hidden', name:'pgCmpnyNm', value:'${pgCmpnyNm}'}));
$(form).append($('<input/>', {type:'hidden', name:'setleTyCd', value:'${setleTyCd}'}));
$(form).append($('<input/>', {type:'hidden', name:'goodsNm', value:'${goodsNm}'}));
$(form).append($('<input/>', {type:'hidden', name:'setleAmt', value:'${setleAmt}'}));
$(form).append($('<input/>', {type:'hidden', name:'ordrrNm', value:'${ordrrNm}'}));
$(form).append($('<input/>', {type:'hidden', name:'ordrrEmail', value:'${ordrrEmail}'}));
$(form).append($('<input/>', {type:'hidden', name:'ordrrMbtlnb', value:'${ordrrMbtlnb}'}));
$(form).append($('<input/>', {type:'hidden', name:'mbrId', value:'${mbrId}'}));
$(form).append($('<input/>', {type:'hidden', name:'mbrInnb', value:'${mbrInnb}'}));
$(form).append($('<input/>', {type:'hidden', name:'sesionId', value:'${sesionId}'}));
$(form).append($('<input/>', {type:'hidden', name:'message', value:'${message}'}));
$(form).append($('<input/>', {type:'hidden', name:'subsvcInnb', value:'${subsvcInnb}'}));
$(form).appendTo('body');
$(form).submit().remove();
});
</script>
</head>
<body>
<section>
<h1>결제 취소</h1>
</section>
</body>
</html>

View File

@@ -1,108 +0,0 @@
<%@ 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 : PayStripeSucsC.jsp
Description : Stripe 결제 성공창
Modification Information
수정일 수정자 수정내용
------- -------- ---------------------------
2026-09-17 이대환 최초 생성
--%>
<!DOCTYPE html>
<html lang="ko">
<head>
<title>결제 결과 확인 중</title>
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<style>
body {
margin: 0;
min-height: 100vh;
display: grid;
place-items: center;
background: #f8fafc;
color: #202938;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
.payment-progress {
padding: 32px 20px;
text-align: center;
}
.payment-progress__spinner {
width: 44px;
height: 44px;
margin: 0 auto 24px;
border: 4px solid #e2e8f0;
border-top-color: #0075d4;
border-radius: 50%;
animation: payment-spin 0.9s linear infinite;
}
.payment-progress h1 {
margin: 0 0 10px;
font-size: 20px;
line-height: 1.5;
word-break: keep-all;
}
.payment-progress p {
margin: 0;
color: #64748b;
font-size: 15px;
line-height: 1.6;
}
@keyframes payment-spin {
to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
.payment-progress__spinner { animation: none; }
}
</style>
<script src="<c:url value='/pc/vendor/jquery-3.7.1.min.js'/>"></script>
<script>
$(document).ready(function() {
var returnUrl = '${returnUrl}';
var status = '${status}';
var payment_status = '${payment_status}';
var customer_details = '${customer_details}';
let form = $('<form></form>');
$(form).attr('method', 'post');
$(form).attr('action', returnUrl);
history.replaceState(null, '', returnUrl);
$(form).append($('<input/>', {type:'hidden', name:'sopmalCd', value:'${sopmalCd}'}));
$(form).append($('<input/>', {type:'hidden', name:'ordrInnb', value:'${ordrInnb}'}));
$(form).append($('<input/>', {type:'hidden', name:'pgCmpnyNm', value:'${pgCmpnyNm}'}));
$(form).append($('<input/>', {type:'hidden', name:'setleTyCd', value:'${setleTyCd}'}));
$(form).append($('<input/>', {type:'hidden', name:'goodsNm', value:'${goodsNm}'}));
$(form).append($('<input/>', {type:'hidden', name:'setleAmt', value:'${setleAmt}'}));
$(form).append($('<input/>', {type:'hidden', name:'ordrrNm', value:'${ordrrNm}'}));
$(form).append($('<input/>', {type:'hidden', name:'ordrrEmail', value:'${ordrrEmail}'}));
$(form).append($('<input/>', {type:'hidden', name:'ordrrMbtlnb', value:'${ordrrMbtlnb}'}));
$(form).append($('<input/>', {type:'hidden', name:'mbrId', value:'${mbrId}'}));
$(form).append($('<input/>', {type:'hidden', name:'mbrInnb', value:'${mbrInnb}'}));
$(form).append($('<input/>', {type:'hidden', name:'sesionId', value:'${sesionId}'}));
$(form).append($('<input/>', {type:'hidden', name:'message', value:'${message}'}));
$(form).append($('<input/>', {type:'hidden', name:'subsvcInnb', value:'${subsvcInnb}'}));
$(form).appendTo('body');
$(form).submit().remove();
});
</script>
</head>
<body>
<section class="payment-progress" role="status" aria-live="polite">
<div class="payment-progress__spinner" aria-hidden="true"></div>
<h1>결제 결과를 확인하고 있습니다.</h1>
<p>잠시만 기다려 주세요.</p>
</section>
</body>
</html>

View File

@@ -1,51 +0,0 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<c:choose>
<c:when test="${mobile}">
<jsp:include page="/WEB-INF/views/comm/mobile/Include.jsp"/>
</c:when>
<c:otherwise>
<jsp:include page="/WEB-INF/views/comm/Include.jsp"/>
</c:otherwise>
</c:choose>
<title>결제 중단 안내</title>
</head>
<body>
<div class="screen-wrap">
<c:choose>
<c:when test="${mobile}">
<header class="header header--sub">
<jsp:include page="/WEB-INF/views/comm/mobile/Header.jsp"/>
</header>
<jsp:include page="/WEB-INF/views/comm/mobile/TabBar.jsp"/>
</c:when>
<c:otherwise>
<jsp:include page="/WEB-INF/views/comm/Header.jsp"/>
</c:otherwise>
</c:choose>
<main class="main content-wrap">
<div class="sub-wrapper sub-page">
<div class="sub-content sub-box">
<div class="orderFailed">
<div class="orderFailed__inner">
<h3 class="orderFailed__title">결제를 중단하셨습니다.</h3>
<p class="orderFailed__text">이 결제창에서 결제를 완료하지 않았습니다.<br>주문/배송조회에서 주문 상태를 확인한 뒤 다시 결제해 주세요.</p>
</div>
<div class="sub-bottom-btn-container fullBtnSection">
<a class="btn xl outline" href="<c:url value='/sopmal/mpage/ordr/selectMbrOrdrListInqire'/>">주문/배송조회</a>
<a class="btn xl outline" href="<c:url value='/sopmal/main'/>">쇼핑 계속하기</a>
</div>
</div>
</div>
</div>
</main>
<c:if test="${!mobile}">
<jsp:include page="/WEB-INF/views/comm/Footer.jsp"/>
</c:if>
</div>
</body>
</html>

View File

@@ -1,35 +0,0 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:url var="cancelUrl" value="/sopmal/stripe/stripeCancel">
<c:param name="sessionId" value="${sessionId}"/>
<c:param name="sopmalCd" value="${sopmalCd}"/>
</c:url>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>결제창으로 이동</title>
<script>
window.addEventListener('pageshow', function (event) {
const checkout = document.getElementById('stripeCheckout');
const cancel = document.getElementById('stripeCancel');
const navigation = performance.getEntriesByType('navigation')[0];
// 일반 복귀와 BFCache 복귀 모두 새 결제 세션을 만들지 않고 처리한다.
if (event.persisted || (navigation && navigation.type === 'back_forward')
|| (history.state && history.state.stripeRedirected)
|| !checkout.getAttribute('href')) {
window.location.replace(cancel.href);
return;
}
history.replaceState({stripeRedirected: true}, '', window.location.href);
window.location.assign(checkout.href);
});
</script>
</head>
<body>
<p>결제창으로 이동하고 있습니다.</p>
<a id="stripeCheckout" href="<c:out value='${checkoutUrl}'/>">결제창 열기</a>
<a id="stripeCancel" href="<c:out value='${cancelUrl}'/>">결제 중단</a>
</body>
</html>

View File

@@ -524,14 +524,13 @@
});*/ });*/
/* 결제정보 결제수단 버튼 선택 이벤트 */ /* 결제정보 결제수단 버튼 선택 이벤트 */
$('input[name="pg"]').on('click', function(event, skipDefaultMethod) { $('input[name="pg"]').on('click', function() {
const form = $(this).closest('#setleForm') const form = $(this).closest('#setleForm')
const id = $(this).attr('id'); const id = $(this).attr('id');
const pgCmpnyNm = $(this).val(); const pgCmpnyNm = $(this).val();
$(form).find('.pgContent').hide(); $(form).find('.pgContent').hide();
$(form).find('#' + id + 'Content').show(); $(form).find('#' + id + 'Content').show();
$('.cartOrderBox__totalKr').show();
//$(form).find('#setleSetupTyCd').val() === '01' ? $(form).find('#pg04Content').show() : $(form).find('#pg03Content').show(); //$(form).find('#setleSetupTyCd').val() === '01' ? $(form).find('#pg04Content').show() : $(form).find('#pg03Content').show();
if($(form).find('#setleSetupTyCd').val() === '01'){$(form).find('#pg04Content').show();} if($(form).find('#setleSetupTyCd').val() === '01'){$(form).find('#pg04Content').show();}
@@ -577,22 +576,12 @@
}); });
$(form).find('#setleTyCd').val('03'); $(form).find('#setleTyCd').val('03');
} else if('st01' === id){ //Stripe
$('.cartOrderBox__totalKr').hide();
} else { } else {
$(form).find('#setleTyCd').val(''); $(form).find('#setleTyCd').val('');
$('.order-method-normal__btn').removeClass('active'); $('.order-method-normal__btn').removeClass('active');
$('.order-method-normal__content').hide(); $('.order-method-normal__content').hide();
} }
// 통화를 선택하면 사용 가능한 첫 결제수단을 기존 클릭 처리로 선택한다.
// 결제수단 버튼에서 라디오를 갱신할 때는 재귀 선택을 생략한다.
if (!skipDefaultMethod && ['st01', 'pg03', 'pg04', 'pg06'].includes(id)) {
$(form).find('#' + id + 'Content')
.find('.order-method-normal__btn:visible:not(:disabled)')
.first().trigger('click');
}
}); });
/* 결제정보 > 일반결제 > 결제수단 버튼 선택 이벤트 */ /* 결제정보 > 일반결제 > 결제수단 버튼 선택 이벤트 */
@@ -601,8 +590,10 @@
const content = $('.order-method-normal__content'); const content = $('.order-method-normal__content');
const useCashMlgAmt = $('#useCashMlgAmt').val(); const useCashMlgAmt = $('#useCashMlgAmt').val();
const pgId = $(this).closest('.pgContent').attr('id').replace(/Content$/, ''); //$('#setleSetupTyCd').val() === '01' ? $('#pg04').click() : $('#pg03').click();
$('#' + pgId).trigger('click', [true]); if($('#setleSetupTyCd').val() === '01'){$('#pg04').click();}
else if($('#setleSetupTyCd').val() === '02'){$('#pg03').click();}
else if($('#setleSetupTyCd').val() === '03'){$('#pg06').click();}
$('.order-method-normal__btn').removeClass('active'); $('.order-method-normal__btn').removeClass('active');
$(this).addClass('active'); $(this).addClass('active');
@@ -3007,7 +2998,7 @@
return false; return false;
} }
if ('kcp' === pgCmpnyNm || 'toss' === pgCmpnyNm || 'kiwoom' === pgCmpnyNm || 'stripe' === pgCmpnyNm) { if ('kcp' === pgCmpnyNm || 'toss' === pgCmpnyNm || 'kiwoom' === pgCmpnyNm) {
const div = $('#setleForm').find('.order-method-normal'); const div = $('#setleForm').find('.order-method-normal');
if (!$(div).find('.order-method-normal__btn-container button').hasClass('active')) { if (!$(div).find('.order-method-normal__btn-container button').hasClass('active')) {
@@ -4214,27 +4205,11 @@
</c:if> </c:if>
<%-- 퀵계좌이체 끝 --%> <%-- 퀵계좌이체 끝 --%>
<%-- Stripe 시작 --%>
<c:if test="${'Y' eq payInfo.stripeUseAt}">
<div class="custom-radio is-medium">
<input type="radio" name="pg" id="st01" value="stripe">
<label for="st01">엔화(¥) 결제</label>
</div>
<div id="st01Content" class="pgContent order-method-normal" <%-- style="display: none"--%>>
<div class="order-method-normal__btn-container">
<button type="button" name="01" id="stripe" class="order-method-normal__btn gift_pay">
<div class="order-method-normal__icon order-method-normal__icon--card"></div>신용카드
</button>
</div>
</div>
</c:if>
<%-- Stripe 끝 --%>
<%-- toss 결제 시작 --%> <%-- toss 결제 시작 --%>
<c:if test="${'02' eq payInfo.setleSetupTyCd}"> <c:if test="${'02' eq payInfo.setleSetupTyCd}">
<div class="custom-radio is-medium"> <div class="custom-radio is-medium">
<input type="radio" name="pg" id="pg03" value="toss"> <input type="radio" name="pg" id="pg03" value="toss">
<label for="pg03">원화(₩) 결제</label> <label for="pg03">일반결제</label>
</div> </div>
<div id="pg03Content" class="pgContent order-method-normal" <%-- style="display: none"--%>> <div id="pg03Content" class="pgContent order-method-normal" <%-- style="display: none"--%>>
<div class="order-method-normal__btn-container"> <div class="order-method-normal__btn-container">
@@ -4366,7 +4341,7 @@
<c:if test="${'01' eq payInfo.setleSetupTyCd}"> <c:if test="${'01' eq payInfo.setleSetupTyCd}">
<div class="custom-radio is-medium"> <div class="custom-radio is-medium">
<input type="radio" name="pg" id="pg04" value="kcp"> <input type="radio" name="pg" id="pg04" value="kcp">
<label for="pg04">원화(₩) 결제</label> <label for="pg04">일반결제</label>
</div> </div>
<div id="pg04Content" class="pgContent order-method-normal" <%-- style="display: none"--%>> <div id="pg04Content" class="pgContent order-method-normal" <%-- style="display: none"--%>>
<div class="order-method-normal__btn-container"> <div class="order-method-normal__btn-container">
@@ -4498,7 +4473,7 @@
<c:if test="${'03' eq payInfo.setleSetupTyCd}"> <c:if test="${'03' eq payInfo.setleSetupTyCd}">
<div class="custom-radio is-medium"> <div class="custom-radio is-medium">
<input type="radio" name="pg" id="pg06" value="kiwoom"> <input type="radio" name="pg" id="pg06" value="kiwoom">
<label for="pg06">원화(₩) 결제</label> <label for="pg06">일반결제</label>
</div> </div>
<div id="pg06Content" class="pgContent order-method-normal" <%-- style="display: none"--%>> <div id="pg06Content" class="pgContent order-method-normal" <%-- style="display: none"--%>>
<div class="order-method-normal__btn-container"> <div class="order-method-normal__btn-container">
@@ -4647,11 +4622,11 @@
<span class="cartOrderBox__td"><span class="cartOrderBox__discountMinus">(-)</span><span id="dscntAmtSapn" class="comma">0</span><span class="priceUnit">${curUnit}</span></span> <span class="cartOrderBox__td"><span class="cartOrderBox__discountMinus">(-)</span><span id="dscntAmtSapn" class="comma">0</span><span class="priceUnit">${curUnit}</span></span>
</li> </li>
</ul> </ul>
<div class="cartOrderBox__total"> <div class="cartOrderBox__total" style="margin-bottom: 5px;">
<span class="cartOrderBox__totalTh">총 결제금액</span> <span class="cartOrderBox__totalTh">총 결제금액</span>
<span class="cartOrderBox__td"><span id="setleAmtSapn" class="comma">0</span><span class="priceUnit">${curUnit}</span></span> <span class="cartOrderBox__td"><span id="setleAmtSapn" class="comma">0</span><span class="priceUnit">${curUnit}</span></span>
</div> </div>
<div class="cartOrderBox__total cartOrderBox__totalKr" style="margin-top: 10px;"> <div class="cartOrderBox__total" style="margin-top: 5px;">
<span class="cartOrderBox__totalTh"></span> <span class="cartOrderBox__totalTh"></span>
<span class="cartOrderBox__totalTd"><span id="setleAmtKrSapn" class="comma">0</span><span class="priceUnit">${krUnit}</span></span> <span class="cartOrderBox__totalTd"><span id="setleAmtKrSapn" class="comma">0</span><span class="priceUnit">${krUnit}</span></span>
</div> </div>

View File

@@ -528,8 +528,7 @@
$(form).append($('<input/>', {type: 'hidden', name: 'sopmalCd', id: 'sopmalCd', value: sopmalCd})); $(form).append($('<input/>', {type: 'hidden', name: 'sopmalCd', id: 'sopmalCd', value: sopmalCd}));
$(form).append($('<input/>', {type: 'hidden', name: 'ordrInnb', id: 'ordrInnb', value: ordrInnb})); $(form).append($('<input/>', {type: 'hidden', name: 'ordrInnb', id: 'ordrInnb', value: ordrInnb}));
// 인증 갱신 후에도 조회 조건을 유지한다. 실제 취소 등록은 기존 POST를 사용한다. $(form).attr('method', 'post');
$(form).attr('method', 'get');
$(form).attr('action', '<c:url value="/sopmal/mpage/ordr/selectSetleCanclPopupForm"/>'); $(form).attr('action', '<c:url value="/sopmal/mpage/ordr/selectSetleCanclPopupForm"/>');
$(form).submit(); $(form).submit();
@@ -1160,10 +1159,7 @@
</c:if> </c:if>
<tr> <tr>
<th>결제금액</th> <th>결제금액</th>
<td> <td><span class="comma"><fmt:formatNumber value="${setle.setleAmt}" pattern="#,###"/></span>${curUnit} / <span class="comma">${setle.wonSetleAmt}</span>${krUnit}</td>
<span class="comma"><fmt:formatNumber value="${setle.setleAmt}" pattern="#,###"/></span>${curUnit}
<c:if test="${data.setleList[0].pgCmpnyNm ne 'stripe'}">/ <span class="comma">${setle.wonSetleAmt}</span>${krUnit}</c:if>
</td>
</tr> </tr>
<c:if test = "${order.ordrSttusCd ne '85' && order.ordrSttusCd ne '95'}"><%--주문취소시 미노출--%> <c:if test = "${order.ordrSttusCd ne '85' && order.ordrSttusCd ne '95'}"><%--주문취소시 미노출--%>
<tr <c:if test = "${empty setle.issuSttusCd}">style="border-bottom: 0.5px solid #e9ecef;"</c:if>> <tr <c:if test = "${empty setle.issuSttusCd}">style="border-bottom: 0.5px solid #e9ecef;"</c:if>>
@@ -1246,8 +1242,7 @@
<tr> <tr>
<th>총 결제금액</th> <th>총 결제금액</th>
<td> <td>
<span class="comma"><fmt:formatNumber value="${total.setleAmt}" pattern="#,###"/></span>${curUnit} <span class="comma"><fmt:formatNumber value="${total.setleAmt}" pattern="#,###"/></span>${curUnit} / <span class="comma">${total.wonRlSetleAmt}</span>${krUnit}
<c:if test="${data.setleList[0].pgCmpnyNm ne 'stripe'}">/ <span class="comma">${total.wonRlSetleAmt}</span>${krUnit}</c:if>
</td> </td>
</tr> </tr>
</tfoot> </tfoot>
@@ -1414,4 +1409,4 @@
</div> </div>
<%-- 마이크로 모달 DIV 종료--%> <%-- 마이크로 모달 DIV 종료--%>
</body> </body>
</html> </html>

View File

@@ -692,10 +692,7 @@
<tr> <tr>
<th>실 환불금액</th> <th>실 환불금액</th>
<td> <td>
<span class="comma"><c:out value="${ reTotAmt.realRefundAmt }"/></span>${curUnit} <span class="comma"><c:out value="${ reTotAmt.realRefundAmt }"/></span>${curUnit} [<span class="comma"><c:out value="${ reTotAmt.realWonRefundAmt }"/></span>${krUnit}]
<c:if test="${resultMap.result.refnd.pgCmpnyNm ne 'stripe'}">
[<span class="comma"><c:out value="${ reTotAmt.realWonRefundAmt }"/></span>${krUnit}]
</c:if>
</td> </td>
</tr> </tr>
</tfoot> </tfoot>

View File

@@ -510,8 +510,7 @@
$(form).append($('<input/>', {type: 'hidden', name: 'sopmalCd', id: 'sopmalCd', value: sopmalCd})); $(form).append($('<input/>', {type: 'hidden', name: 'sopmalCd', id: 'sopmalCd', value: sopmalCd}));
$(form).append($('<input/>', {type: 'hidden', name: 'ordrInnb', id: 'ordrInnb', value: ordrInnb})); $(form).append($('<input/>', {type: 'hidden', name: 'ordrInnb', id: 'ordrInnb', value: ordrInnb}));
// 인증 갱신 후에도 조회 조건을 유지한다. 실제 취소 등록은 기존 POST를 사용한다. $(form).attr('method', 'post');
$(form).attr('method', 'get');
$(form).attr('action', '<c:url value="/sopmal/mpage/ordr/selectSetleCanclPopupForm"/>'); $(form).attr('action', '<c:url value="/sopmal/mpage/ordr/selectSetleCanclPopupForm"/>');
$(form).submit(); $(form).submit();
@@ -971,8 +970,7 @@
<tr> <tr>
<th>실 환불금액</th> <th>실 환불금액</th>
<td> <td>
<span class="comma"><c:out value="${ reTotAmt.realRefundAmt }"/></span>${curUnit} <span class="comma"><c:out value="${ reTotAmt.realRefundAmt }"/></span>${curUnit} [<span class="comma"><c:out value="${ reTotAmt.realWonRefundAmt }"/></span>${krUnit}]
<c:if test="${data.setleList[0].pgCmpnyNm ne 'stripe'}">[<span class="comma"><c:out value="${ reTotAmt.realWonRefundAmt }"/></span>${krUnit}]</c:if>
</td> </td>
</tr> </tr>
</tfoot> </tfoot>
@@ -1262,10 +1260,7 @@
</c:if> </c:if>
<tr> <tr>
<th>결제금액</th> <th>결제금액</th>
<td> <td><span class="comma"><fmt:formatNumber value="${setle.setleAmt}" pattern="#,###"/></span>${curUnit} / <span class="comma">${setle.wonSetleAmt}</span>${krUnit}</td>
<span class="comma"><fmt:formatNumber value="${setle.setleAmt}" pattern="#,###"/></span>${curUnit}
<c:if test="${data.setleList[0].pgCmpnyNm ne 'stripe'}">/ <span class="comma">${setle.wonSetleAmt}</span>${krUnit}</c:if>
</td>
</tr> </tr>
<c:if test = "${order.ordrSttusCd ne '85' && order.ordrSttusCd ne '95'}"><%--주문취소시 미노출--%> <c:if test = "${order.ordrSttusCd ne '85' && order.ordrSttusCd ne '95'}"><%--주문취소시 미노출--%>
<tr <c:if test = "${empty setle.issuSttusCd}">style="border-bottom: 0.5px solid #e9ecef;"</c:if>> <tr <c:if test = "${empty setle.issuSttusCd}">style="border-bottom: 0.5px solid #e9ecef;"</c:if>>
@@ -1452,4 +1447,4 @@
</div> </div>
<%-- 마이크로 모달 DIV 종료--%> <%-- 마이크로 모달 DIV 종료--%>
</body> </body>
</html> </html>

View File

@@ -565,16 +565,13 @@
}); });
/* 결제정보 결제수단 버튼 선택 이벤트 */ /* 결제정보 결제수단 버튼 선택 이벤트 */
$('input[name="pg"]').on('click', function(event, skipDefaultMethod) { $('input[name="pg"]').on('click', function() {
const form = $(this).closest('#setleForm') const form = $(this).closest('#setleForm')
const id = $(this).attr('id'); const id = $(this).attr('id');
const pgCmpnyNm = $(this).val(); const pgCmpnyNm = $(this).val();
$(form).find('.pgContent').hide(); $(form).find('.pgContent').hide();
$(form).find('#' + id + 'Content').show(); $(form).find('#' + id + 'Content').show();
$('.setleAmtDivde').show();
$('.setleAmtKrSapn').show();
$('.priceUnitKr').show();
//$(form).find('#setleSetupTyCd').val() === '01' ? $(form).find('#pg04Content').show() : $(form).find('#pg03Content').show(); //$(form).find('#setleSetupTyCd').val() === '01' ? $(form).find('#pg04Content').show() : $(form).find('#pg03Content').show();
if($(form).find('#setleSetupTyCd').val() === '01'){$(form).find('#pg04Content').show();} if($(form).find('#setleSetupTyCd').val() === '01'){$(form).find('#pg04Content').show();}
@@ -622,24 +619,12 @@
}); });
$(form).find('#setleTyCd').val('03'); $(form).find('#setleTyCd').val('03');
} else if('st01' === id){ //Stripe
$('.setleAmtDivde').hide();
$('.setleAmtKrSapn').hide();
$('.priceUnitKr').hide();
} else { } else {
$(form).find('#setleTyCd').val(''); $(form).find('#setleTyCd').val('');
$('.order-method-normal__btn').removeClass('active'); $('.order-method-normal__btn').removeClass('active');
$('.order-method-normal__content').hide(); $('.order-method-normal__content').hide();
} }
// 통화를 선택하면 사용 가능한 첫 결제수단을 기존 클릭 처리로 선택한다.
// 결제수단 버튼에서 라디오를 갱신할 때는 재귀 선택을 생략한다.
if (!skipDefaultMethod && ['st01', 'pg03', 'pg04', 'pg06'].includes(id)) {
$(form).find('#' + id + 'Content')
.find('.order-method-normal__btn:visible:not(:disabled)')
.first().trigger('click');
}
}); });
/* 결제정보 > 일반결제 > 결제수단 버튼 선택 이벤트 */ /* 결제정보 > 일반결제 > 결제수단 버튼 선택 이벤트 */
@@ -648,8 +633,10 @@
const content = $('.order-method-normal__content'); const content = $('.order-method-normal__content');
const useCashMlgAmt = $('#useCashMlgAmt').val(); const useCashMlgAmt = $('#useCashMlgAmt').val();
const pgId = $(this).closest('.pgContent').attr('id').replace(/Content$/, ''); //$('#setleSetupTyCd').val() === '01' ? $('#pg04').click() : $('#pg03').click();
$('#' + pgId).trigger('click', [true]); if($('#setleSetupTyCd').val() === '01'){$('#pg04').click();}
else if($('#setleSetupTyCd').val() === '02'){$('#pg03').click();}
else if($('#setleSetupTyCd').val() === '03'){$('#pg06').click();}
$('.order-method-normal__btn').removeClass('active'); $('.order-method-normal__btn').removeClass('active');
$(this).addClass('active'); $(this).addClass('active');
@@ -3142,7 +3129,7 @@
return false; return false;
} }
if ('kcp' === pgCmpnyNm || 'toss' === pgCmpnyNm || 'kiwoom' === pgCmpnyNm || 'stripe' === pgCmpnyNm) { if ('kcp' === pgCmpnyNm || 'toss' === pgCmpnyNm || 'kiwoom' === pgCmpnyNm) {
const div = $('#setleForm').find('.order-method-normal'); const div = $('#setleForm').find('.order-method-normal');
if (!$(div).find('.order-method-normal__btn-container button').hasClass('active')) { if (!$(div).find('.order-method-normal__btn-container button').hasClass('active')) {
@@ -4331,27 +4318,11 @@
</c:if> </c:if>
<%-- 퀵계좌이체 끝 --%> <%-- 퀵계좌이체 끝 --%>
<%-- Stripe 시작 --%>
<c:if test="${'Y' eq payInfo.stripeUseAt}">
<div class="custom-radio is-medium">
<input type="radio" name="pg" id="st01" value="stripe">
<label for="st01">엔화(¥) 결제</label>
</div>
<div id="st01Content" class="pgContent order-method-normal" <%-- style="display: none"--%>>
<div class="order-method-normal__btn-container">
<button type="button" name="01" id="stripe" class="order-method-normal__btn gift_pay">
<div class="order-method-normal__icon order-method-normal__icon--card"></div>신용카드
</button>
</div>
</div>
</c:if>
<%-- Stripe 끝 --%>
<%-- toss 결제 시작 --%> <%-- toss 결제 시작 --%>
<c:if test="${'02' eq payInfo.setleSetupTyCd}"> <c:if test="${'02' eq payInfo.setleSetupTyCd}">
<div class="custom-radio is-medium"> <div class="custom-radio is-medium">
<input type="radio" name="pg" id="pg03" value="toss"> <input type="radio" name="pg" id="pg03" value="toss">
<label for="pg03">원화(₩) 결제</label> <label for="pg03">일반결제</label>
</div> </div>
<div id="pg03Content" class="pgContent order-method-normal"> <div id="pg03Content" class="pgContent order-method-normal">
<div class="order-method-normal__btn-container"> <div class="order-method-normal__btn-container">
@@ -4483,7 +4454,7 @@
<c:if test="${'01' eq payInfo.setleSetupTyCd}"> <c:if test="${'01' eq payInfo.setleSetupTyCd}">
<div class="custom-radio is-medium"> <div class="custom-radio is-medium">
<input type="radio" name="pg" id="pg04" value="kcp"> <input type="radio" name="pg" id="pg04" value="kcp">
<label for="pg04">원화(₩) 결제</label> <label for="pg04">일반결제</label>
</div> </div>
<div id="pg04Content" class="pgContent order-method-normal" > <div id="pg04Content" class="pgContent order-method-normal" >
<div class="order-method-normal__btn-container"> <div class="order-method-normal__btn-container">
@@ -4615,7 +4586,7 @@
<c:if test="${'03' eq payInfo.setleSetupTyCd}"> <c:if test="${'03' eq payInfo.setleSetupTyCd}">
<div class="custom-radio is-medium"> <div class="custom-radio is-medium">
<input type="radio" name="pg" id="pg06" value="kiwoom"> <input type="radio" name="pg" id="pg06" value="kiwoom">
<label for="pg06">원화(₩) 결제</label> <label for="pg06">일반결제</label>
</div> </div>
<div id="pg06Content" class="pgContent order-method-normal" > <div id="pg06Content" class="pgContent order-method-normal" >
<div class="order-method-normal__btn-container"> <div class="order-method-normal__btn-container">
@@ -4790,7 +4761,7 @@
<div class="bottomFixedControls__inner"> <div class="bottomFixedControls__inner">
<dl class="bottomFixedControls__totalPrice"> <dl class="bottomFixedControls__totalPrice">
<dt>총 금액</dt> <dt>총 금액</dt>
<dd><span class="setleAmtSapn comma"></span><span class="priceUnit">${curUnit}</span><span class="setleAmtDivde"> / </span><span class="setleAmtKrSapn comma"></span><span class="priceUnit priceUnitKr">${krUnit}</span></dd> <dd><span class="setleAmtSapn comma"></span><span class="priceUnit">${curUnit}</span> / <span class="setleAmtKrSapn comma"></span><span class="priceUnit">${krUnit}</span></dd>
</dl> </dl>
</div> </div>
<div class="bottomFixedControls__inner"> <div class="bottomFixedControls__inner">
@@ -5000,4 +4971,4 @@
<div id="dlvyDiv"></div> <div id="dlvyDiv"></div>
<div id="modalDiv"></div> <div id="modalDiv"></div>
</body> </body>
</html> </html>

View File

@@ -411,8 +411,7 @@
<tr> <tr>
<th>총 결제금액</th> <th>총 결제금액</th>
<td> <td>
<span class="comma"><fmt:formatNumber value="${total.setleAmt}" pattern="#,###"/></span>${curUnit} <span class="comma"><fmt:formatNumber value="${total.setleAmt}" pattern="#,###"/></span>${curUnit} / <span class="comma"><fmt:formatNumber value="${total.wonRlSetleAmt}" pattern="#,###"/></span>${krUnit}
<c:if test="${data.setleList[0].pgCmpnyNm ne 'stripe'}">/ <span class="comma"><fmt:formatNumber value="${total.wonRlSetleAmt}" pattern="#,###"/></span>${krUnit}</c:if>
</td> </td>
</tr> </tr>
</tfoot> </tfoot>

View File

@@ -568,16 +568,13 @@
});*/ });*/
/* 결제정보 결제수단 버튼 선택 이벤트 */ /* 결제정보 결제수단 버튼 선택 이벤트 */
$('input[name="pg"]').on('click', function(event, skipDefaultMethod) { $('input[name="pg"]').on('click', function() {
const form = $(this).closest('#setleForm') const form = $(this).closest('#setleForm')
const id = $(this).attr('id'); const id = $(this).attr('id');
const pgCmpnyNm = $(this).val(); const pgCmpnyNm = $(this).val();
$(form).find('.pgContent').hide(); $(form).find('.pgContent').hide();
$(form).find('#' + id + 'Content').show(); $(form).find('#' + id + 'Content').show();
$('.setleAmtDivde').show();
$('.setleAmtKrSapn').show();
$('.priceUnitKr').show();
//$(form).find('#setleSetupTyCd').val() === '01' ? $(form).find('#pg04Content').show() : $(form).find('#pg03Content').show(); //$(form).find('#setleSetupTyCd').val() === '01' ? $(form).find('#pg04Content').show() : $(form).find('#pg03Content').show();
if($(form).find('#setleSetupTyCd').val() === '01'){$(form).find('#pg04Content').show();} if($(form).find('#setleSetupTyCd').val() === '01'){$(form).find('#pg04Content').show();}
@@ -625,24 +622,12 @@
}); });
$(form).find('#setleTyCd').val('03'); $(form).find('#setleTyCd').val('03');
} else if('st01' === id){ //Stripe
$('.setleAmtDivde').hide();
$('.setleAmtKrSapn').hide();
$('.priceUnitKr').hide();
} else { } else {
$(form).find('#setleTyCd').val(''); $(form).find('#setleTyCd').val('');
$('.order-method-normal__btn').removeClass('active'); $('.order-method-normal__btn').removeClass('active');
$('.order-method-normal__content').hide(); $('.order-method-normal__content').hide();
} }
// 통화를 선택하면 사용 가능한 첫 결제수단을 기존 클릭 처리로 선택한다.
// 결제수단 버튼에서 라디오를 갱신할 때는 재귀 선택을 생략한다.
if (!skipDefaultMethod && ['st01', 'pg03', 'pg04', 'pg06'].includes(id)) {
$(form).find('#' + id + 'Content')
.find('.order-method-normal__btn:visible:not(:disabled)')
.first().trigger('click');
}
}); });
/* 결제정보 > 일반결제 > 결제수단 버튼 선택 이벤트 */ /* 결제정보 > 일반결제 > 결제수단 버튼 선택 이벤트 */
@@ -651,8 +636,10 @@
const content = $('.order-method-normal__content'); const content = $('.order-method-normal__content');
const useCashMlgAmt = $('#useCashMlgAmt').val(); const useCashMlgAmt = $('#useCashMlgAmt').val();
const pgId = $(this).closest('.pgContent').attr('id').replace(/Content$/, ''); //$('#setleSetupTyCd').val() === '01' ? $('#pg04').click() : $('#pg03').click();
$('#' + pgId).trigger('click', [true]); if($('#setleSetupTyCd').val() === '01'){$('#pg04').click();}
else if($('#setleSetupTyCd').val() === '02'){$('#pg03').click();}
else if($('#setleSetupTyCd').val() === '03'){$('#pg06').click();}
$('.order-method-normal__btn').removeClass('active'); $('.order-method-normal__btn').removeClass('active');
$(this).addClass('active'); $(this).addClass('active');
@@ -3130,7 +3117,7 @@
return false; return false;
} }
if ('kcp' === pgCmpnyNm || 'toss' === pgCmpnyNm || 'kiwoom' === pgCmpnyNm || 'stripe' === pgCmpnyNm) { if ('kcp' === pgCmpnyNm || 'toss' === pgCmpnyNm || 'kiwoom' === pgCmpnyNm) {
const div = $('#setleForm').find('.order-method-normal'); const div = $('#setleForm').find('.order-method-normal');
if (!$(div).find('.order-method-normal__btn-container button').hasClass('active')) { if (!$(div).find('.order-method-normal__btn-container button').hasClass('active')) {
@@ -4320,27 +4307,11 @@
</c:if> </c:if>
<%-- 퀵계좌이체 끝 --%> <%-- 퀵계좌이체 끝 --%>
<%-- Stripe 시작 --%>
<c:if test="${'Y' eq payInfo.stripeUseAt}">
<div class="custom-radio is-medium">
<input type="radio" name="pg" id="st01" value="stripe">
<label for="st01">엔화(¥) 결제</label>
</div>
<div id="st01Content" class="pgContent order-method-normal" <%-- style="display: none"--%>>
<div class="order-method-normal__btn-container">
<button type="button" name="01" id="stripe" class="order-method-normal__btn gift_pay">
<div class="order-method-normal__icon order-method-normal__icon--card"></div>신용카드
</button>
</div>
</div>
</c:if>
<%-- Stripe 끝 --%>
<%-- toss 결제 시작 --%> <%-- toss 결제 시작 --%>
<c:if test="${'02' eq payInfo.setleSetupTyCd}"> <c:if test="${'02' eq payInfo.setleSetupTyCd}">
<div class="custom-radio is-medium"> <div class="custom-radio is-medium">
<input type="radio" name="pg" id="pg03" value="toss"> <input type="radio" name="pg" id="pg03" value="toss">
<label for="pg03">원화(₩) 결제</label> <label for="pg03">일반결제</label>
</div> </div>
<div id="pg03Content" class="pgContent order-method-normal"> <div id="pg03Content" class="pgContent order-method-normal">
<div class="order-method-normal__btn-container"> <div class="order-method-normal__btn-container">
@@ -4472,7 +4443,7 @@
<c:if test="${'01' eq payInfo.setleSetupTyCd}"> <c:if test="${'01' eq payInfo.setleSetupTyCd}">
<div class="custom-radio is-medium"> <div class="custom-radio is-medium">
<input type="radio" name="pg" id="pg04" value="kcp"> <input type="radio" name="pg" id="pg04" value="kcp">
<label for="pg04">원화(₩) 결제</label> <label for="pg04">일반결제</label>
</div> </div>
<div id="pg04Content" class="pgContent order-method-normal" > <div id="pg04Content" class="pgContent order-method-normal" >
<div class="order-method-normal__btn-container"> <div class="order-method-normal__btn-container">
@@ -4604,7 +4575,7 @@
<c:if test="${'03' eq payInfo.setleSetupTyCd}"> <c:if test="${'03' eq payInfo.setleSetupTyCd}">
<div class="custom-radio is-medium"> <div class="custom-radio is-medium">
<input type="radio" name="pg" id="pg06" value="kiwoom"> <input type="radio" name="pg" id="pg06" value="kiwoom">
<label for="pg06">원화(₩) 결제</label> <label for="pg06">일반결제</label>
</div> </div>
<div id="pg06Content" class="pgContent order-method-normal" > <div id="pg06Content" class="pgContent order-method-normal" >
<div class="order-method-normal__btn-container"> <div class="order-method-normal__btn-container">
@@ -4779,7 +4750,7 @@
<div class="bottomFixedControls__inner"> <div class="bottomFixedControls__inner">
<dl class="bottomFixedControls__totalPrice"> <dl class="bottomFixedControls__totalPrice">
<dt>총 금액</dt> <dt>총 금액</dt>
<dd><span class="setleAmtSapn comma"></span><span class="priceUnit">${curUnit}</span><span class="setleAmtDivde"> / </span><span class="setleAmtKrSapn comma"></span><span class="priceUnit priceUnitKr">${krUnit}</span></dd> <dd><span class="setleAmtSapn comma"></span><span class="priceUnit">${curUnit}</span> / <span class="setleAmtKrSapn comma"></span><span class="priceUnit">${krUnit}</span></dd>
</dl> </dl>
</div> </div>
<div class="bottomFixedControls__inner"> <div class="bottomFixedControls__inner">
@@ -4989,4 +4960,4 @@
<div id="dlvyDiv"></div> <div id="dlvyDiv"></div>
<div id="modalDiv"></div> <div id="modalDiv"></div>
</body> </body>
</html> </html>

View File

@@ -1,123 +0,0 @@
package com.wb.domainserver.domain.admin.instcSle.mtng.service;
import com.wb.domainserver.domain.admin.instcSle.mtng.mapper.BOMaMtngMapper;
import com.wb.domainserver.domain.admin.instcSle.mtng.vo.BOPreOrderValidVO;
import com.wb.domainserver.domain.gcone.mbr.mlg.service.BOMlgService;
import com.wb.domainserver.domain.gcone.mbr.mlg.vo.BOMlgSrchVO;
import com.wb.domainserver.util.dataaccess.DataMap;
import org.junit.jupiter.api.Test;
import org.springframework.test.util.ReflectionTestUtils;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
class InventoryShortageMessageTest {
private BOPreOrderValidVO goods(String id, String option, int quantity, int total) {
return BOPreOrderValidVO.builder().sopmalCd("SK").goodsInnb(id).goodsNm("요청 상품명")
.goodsOptnInnb(option).optionNm("옵션 " + option).qy(String.valueOf(quantity))
.goodsTotalQy(total).subsvcInnb("").mbrInnb("1").mbrDvCd("SK")
.useMlgAmt("0").useCashMlgAmt("0").build();
}
private DataMap row(String name, int optionStock, int totalStock, int optionError, int totalError) {
DataMap row = new DataMap();
row.put("stockGoodsNm", name);
row.put("optionAvailableQy", optionStock);
row.put("goodsAvailableQy", totalStock);
row.put("invntry", optionError);
row.put("invntryPolicy", totalError);
return row;
}
@Test
void allShortageProductsAppearButAvailableProductsDoNot() {
InventoryShortageMessage message = new InventoryShortageMessage();
message.add(goods("138", "1", 2, 2), List.of(row("상품 A", 1, 5, 1, 0)));
message.add(goods("128", "1", 1, 1), List.of(row("상품 B", 0, 0, 1, 1)));
message.add(goods("170", "1", 1, 1), List.of(row("상품 C", 4, 4, 0, 0)));
String text = message.render();
assertTrue(text.contains("상품 A\n 주문 수량: 2병 / 현재 구매 가능: 1병"));
assertTrue(text.contains("상품 B\n 주문 수량: 1병 / 현재 구매 가능: 0병"));
assertFalse(text.contains("상품 C"));
assertFalse(text.contains("GC25"));
}
@Test
void duplicateValidationRowsDoNotDuplicateTheProductOrOrderQuantity() {
InventoryShortageMessage message = new InventoryShortageMessage();
DataMap row = row("상품 A", 0, 0, 1, 1);
message.add(goods("138", "1", 2, 2), List.of(row, row));
assertEquals(1, message.render().split("· 상품 A", -1).length - 1);
assertTrue(message.render().contains("주문 수량: 2병"));
}
@Test
void multipleOptionsShowSharedLimitWithoutAddingTheirCapacities() {
InventoryShortageMessage message = new InventoryShortageMessage();
message.add(goods("138", "1", 2, 4), List.of(row("상품 A", 3, 3, 0, 1)));
message.add(goods("138", "2", 2, 4), List.of(row("상품 A", 5, 3, 0, 1)));
assertTrue(message.render().contains("총 주문 수량: 4병 / 상품 전체 재고 한도: 3병"));
assertTrue(message.render().contains("옵션 1: 주문 2병 / 옵션별 구매 가능 3병"));
assertTrue(message.render().contains("옵션 2: 주문 2병 / 옵션별 구매 가능 3병"));
assertTrue(message.render().contains("상품 전체 재고 한도 안에서 함께 적용"));
}
@Test
void totalLimitAndNegativeStockAreHandled() {
InventoryShortageMessage message = new InventoryShortageMessage();
message.add(goods("138", "1", 2, 2), List.of(row("상품 A", 8, -2, 0, 1)));
assertTrue(message.render().contains("현재 구매 가능: 0병"));
}
@Test
void stockCountOfOneAndNumericProductNameAreNotValidationFailures() {
BOMaMtngService service = serviceWithStockRows(row("1", 1, 1, 0, 0));
Map<String, Object> result = service.selectBOPreOrderValidation(List.of(goods("138", "1", 1, 1)));
assertEquals("N", result.get("result"));
assertFalse(result.containsKey("message"));
}
@Test
void stockFailuresUseReadableMessageThroughTheService() {
BOMaMtngService service = serviceWithStockRows(row("상품 A", 0, 0, 1, 1));
Map<String, Object> result = service.selectBOPreOrderValidation(List.of(goods("138", "1", 2, 2)));
assertEquals("Y", result.get("result"));
assertTrue(result.get("message").toString().contains("상품 A\n 주문 수량: 2병 / 현재 구매 가능: 0병"));
}
@Test
void inventoryNoticeStillListsProductsWhenAnotherQuantityRestrictionFails() {
DataMap row = row("상품 A", 0, 0, 1, 1);
row.put("purchsQyLmtt", 1);
Map<String, Object> result = serviceWithStockRows(row)
.selectBOPreOrderValidation(List.of(goods("138", "1", 2, 2)));
assertTrue(result.get("message").toString().contains("현재 구매 가능: 0병"));
}
@Test
void unrelatedValidationMessageIsPreserved() {
DataMap row = row("상품 A", 5, 5, 0, 0);
row.put("selpric", 1);
Map<String, Object> result = serviceWithStockRows(row)
.selectBOPreOrderValidation(List.of(goods("138", "1", 1, 1)));
assertEquals("Y", result.get("result"));
assertTrue(result.get("message").toString().contains("GC25S0324006"));
}
private BOMaMtngService serviceWithStockRows(DataMap row) {
BOMaMtngService service = new BOMaMtngService();
BOMaMtngMapper mapper = mock(BOMaMtngMapper.class);
when(mapper.selectBOPreOrderValidation(any())).thenReturn(List.of(row));
BOMlgService mileage = mock(BOMlgService.class);
when(mileage.selectBOMlgBlceSum(any(BOMlgSrchVO.class))).thenReturn(BigDecimal.ZERO);
when(mileage.selectBOCashBlce(any())).thenReturn(BigDecimal.ZERO);
ReflectionTestUtils.setField(service, "mapper", mapper);
ReflectionTestUtils.setField(service, "boMlgService", mileage);
return service;
}
}

View File

@@ -1,36 +0,0 @@
package com.wb.domainserver.domain.gcone.goods.purchs.service;
import org.junit.jupiter.api.Test;
import java.util.LinkedHashMap;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
class StripeGoodsNameTest {
private LinkedHashMap<String, Object> goods(int quantity) {
LinkedHashMap<String, Object> goods = new LinkedHashMap<>();
goods.put("qy", quantity);
return goods;
}
@Test
void oneBottleKeepsItsName() {
assertEquals("사케 A", BOOrderService.buildStripeGoodsName("사케 A", List.of(goods(1))));
}
@Test
void twoBottlesOfTheSameProductIncludeTheAdditionalBottle() {
assertEquals("사케 A 외 1병", BOOrderService.buildStripeGoodsName("사케 A", List.of(goods(2))));
}
@Test
void multipleProductsUseTheSumOfQuantitiesRatherThanProductCount() {
assertEquals("사케 A 외 4병", BOOrderService.buildStripeGoodsName("사케 A", List.of(goods(2), goods(3))));
}
@Test
void separateOptionsOfOneProductAlsoCountAsBottles() {
assertEquals("사케 A 외 2병", BOOrderService.buildStripeGoodsName("사케 A", List.of(goods(1), goods(2))));
}
}

View File

@@ -1,92 +0,0 @@
package com.wb.domainserver.domain.gcone.goods.purchs.service;
import com.wb.domainserver.domain.gcone.goods.purchs.mapper.BOPurchsMapper;
import com.wb.domainserver.domain.gcone.goods.purchs.vo.BOOrderItemVO;
import com.wb.domainserver.domain.gcone.goods.purchs.vo.BOOrderSetleVO;
import com.wb.domainserver.domain.gcone.goods.purchs.vo.BOOrderVO;
import com.wb.domainserver.domain.gcone.goods.subsvc.service.BOSubsvcService;
import com.wb.domainserver.exception.WnbtRestException;
import com.wb.domainserver.util.dataaccess.DataMap;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.test.util.ReflectionTestUtils;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.LinkedHashMap;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
class SubscriptionPaymentNameTest {
private BOOrderService service;
private BOSubsvcService subscriptions;
private BOPurchsMapper mapper;
private BOOrderVO order;
private List<BOOrderItemVO> items;
@BeforeEach
void setUp() {
service = new BOOrderService();
subscriptions = mock(BOSubsvcService.class);
mapper = mock(BOPurchsMapper.class);
BOOrderNoService numbers = mock(BOOrderNoService.class);
when(numbers.generateOrderSetleNo()).thenReturn(BigInteger.ONE);
ReflectionTestUtils.setField(service, "subsvcService", subscriptions);
ReflectionTestUtils.setField(service, "mapper", mapper);
ReflectionTestUtils.setField(service, "orderNoService", numbers);
order = new BOOrderVO();
order.setSopmalCd("SK");
order.setOrdrInnb(BigInteger.TEN);
order.setSubsvcInnb(28);
BOOrderItemVO item = new BOOrderItemVO();
item.setGoodsNm("구독서비스상품");
items = List.of(item, item, item, item, item, item);
DataMap detail = new DataMap();
detail.put("subsvcNm", "구독서비스 출시 기념 이벤트");
when(subscriptions.selectBOSubsvcDetail(any())).thenReturn(detail);
}
private BOOrderSetleVO settle(String provider) {
LinkedHashMap<String, Object> payment = new LinkedHashMap<>();
payment.put("rlSetleAmt", "15000");
payment.put("wonRlSetleAmt", "142500");
payment.put("pgCmpnyNm", provider);
payment.put("setleTyCd", "01");
payment.put("ordrDvCd", "01");
return service.insertSetle(order, payment, items, new LinkedHashMap<>(), new LinkedHashMap<>());
}
@Test
void stripeUsesSubscriptionNameAndPreservesAmounts() {
BOOrderSetleVO payment = settle("stripe");
assertEquals("구독서비스 출시 기념 이벤트", payment.getGoodsNm());
assertEquals(new BigDecimal("15000"), payment.getSetleAmt());
assertEquals(new BigDecimal("142500"), payment.getWonSetleAmt());
verify(subscriptions).selectBOSubsvcDetail(argThat(vo -> "SK".equals(vo.getSopmalCd())
&& "28".equals(vo.getSubsvcInnb())));
verify(mapper).insertOrderSetle(argThat(vo -> "구독서비스 출시 기념 이벤트".equals(vo.getGoodsNm())));
verify(mapper).insertSales(argThat(vo -> "구독서비스 출시 기념 이벤트".equals(vo.getGoodsNm())));
}
@Test
void kiwoomUsesTheSameSubscriptionName() {
assertEquals("구독서비스 출시 기념 이벤트", settle("kiwoom").getGoodsNm());
}
@Test
void normalOrderKeepsExistingKiwoomName() {
order.setSubsvcInnb(null);
assertEquals("구독서비스상품 외5", settle("kiwoom").getGoodsNm());
verifyNoInteractions(subscriptions);
}
@Test
void missingSubscriptionNameStopsBeforeSavingPayment() {
when(subscriptions.selectBOSubsvcDetail(any())).thenReturn(null);
assertThrows(WnbtRestException.class, () -> settle("stripe"));
verifyNoInteractions(mapper);
}
}

View File

@@ -1,119 +0,0 @@
package com.wb.domainserver.domain.sopmal.login.controller;
import com.wb.domainserver.domain.admin.store.sopmal.service.BOMaSopmalService;
import com.wb.domainserver.domain.gcone.login.service.LoginService;
import com.wb.domainserver.realm.RealmContextHolder;
import com.wb.domainserver.security.filter.JwtAuthenticationFilter;
import com.wb.domainserver.security.user.SecurityUserDetailService;
import io.jsonwebtoken.JwtException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.http.Cookie;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.core.context.SecurityContextHolder;
import java.nio.charset.StandardCharsets;
import org.springframework.security.core.userdetails.User;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
class RefundPopupAuthenticationTest {
private final String popupUrl = "http://localhost/sopmal/mpage/ordr/selectSetleCanclPopupForm"
+ "?sopmalCd=SK&ordrInnb=test-order&ordrDlvyInnb=test-delivery";
@BeforeEach
void setUp() {
RealmContextHolder.setRealm("sopmal");
}
@AfterEach
void tearDown() {
RealmContextHolder.clear();
SecurityContextHolder.clearContext();
}
@Test
void missingRefreshTokenRedirectsToLoginOnlyOnce() throws Exception {
LoginService service = mock(LoginService.class);
LoginController controller = new LoginController(service, mock(BOMaSopmalService.class));
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/sopmal/tokens/refresh");
request.setParameter("redirect_uri", popupUrl);
MockHttpServletResponse response = new MockHttpServletResponse();
// MockHttpServletResponse rejects a second redirect after commit, as Tomcat does.
assertDoesNotThrow(() -> controller.refreshToken(request, response));
assertEquals("/sopmal/login/page/sopmal?redirect_uri=" +
java.net.URLEncoder.encode(popupUrl, StandardCharsets.UTF_8), response.getRedirectedUrl());
verifyNoInteractions(service);
}
@Test
void validRefreshTokenRenewsAndReturnsToPopupWithOrderParameters() throws Exception {
LoginService service = mock(LoginService.class);
LoginController controller = new LoginController(service, mock(BOMaSopmalService.class));
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/sopmal/tokens/refresh");
request.setCookies(new Cookie("RFT", "mock-refresh-token"));
request.setParameter("redirect_uri", popupUrl);
MockHttpServletResponse response = new MockHttpServletResponse();
controller.refreshToken(request, response);
verify(service).createRenewLoginToken(request, response);
assertEquals(popupUrl, response.getRedirectedUrl());
}
@Test
void expiredAccessCookieKeepsGetQueryWhenSendingToRefresh() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("GET",
"/sopmal/mpage/ordr/selectSetleCanclPopupForm");
request.setQueryString("sopmalCd=SK&ordrInnb=test-order&ordrDlvyInnb=test-delivery");
request.setCookies(new Cookie("token_expire", "1"));
FilterChain chain = mock(FilterChain.class);
MockHttpServletResponse response = new MockHttpServletResponse();
new JwtAuthenticationFilter(mock(SecurityUserDetailService.class)).doFilter(request, response, chain);
assertEquals("/sopmal/tokens/refresh?redirect_uri=" +
java.net.URLEncoder.encode(popupUrl, StandardCharsets.UTF_8) + "&expire=p",
response.getRedirectedUrl());
verifyNoInteractions(chain);
}
@Test
void validAccessTokenReachesPopupWithoutRedirect() throws Exception {
SecurityUserDetailService service = mock(SecurityUserDetailService.class);
when(service.loadUserByUsername("valid-test-token"))
.thenReturn(User.withUsername("test").password("unused").authorities("ROLE_USER").build());
MockHttpServletRequest request = new MockHttpServletRequest("GET",
"/sopmal/mpage/ordr/selectSetleCanclPopupForm");
request.setCookies(new Cookie("ACT", "valid-test-token"));
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = mock(FilterChain.class);
new JwtAuthenticationFilter(service).doFilter(request, response, chain);
verify(chain).doFilter(request, response);
assertNull(response.getRedirectedUrl());
assertTrue(SecurityContextHolder.getContext().getAuthentication().isAuthenticated());
}
@Test
void invalidAccessJwtRedirectsToLogoutWithoutLoadingPopup() throws Exception {
SecurityUserDetailService service = mock(SecurityUserDetailService.class);
when(service.loadUserByUsername("invalid-test-token")).thenThrow(new JwtException("expired test token"));
MockHttpServletRequest request = new MockHttpServletRequest("GET",
"/sopmal/mpage/ordr/selectSetleCanclPopupForm");
request.setCookies(new Cookie("ACT", "invalid-test-token"));
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = mock(FilterChain.class);
new JwtAuthenticationFilter(service).doFilter(request, response, chain);
assertEquals("/sopmal/logout", response.getRedirectedUrl());
verifyNoInteractions(chain);
}
}

View File

@@ -1,108 +0,0 @@
package com.wb.domainserver.domain.sopmal.stripe.controller;
import com.stripe.StripeClient;
import com.stripe.model.checkout.Session;
import com.wb.domainserver.domain.gcone.ordr.pay.service.BOPayService;
import com.wb.domainserver.security.authentication.AnonymousUser;
import com.wb.domainserver.security.authentication.MemberJwtContextHolder;
import com.wb.domainserver.util.util.Util;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.ui.ModelMap;
import org.springframework.web.server.ResponseStatusException;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
class StripeNavigationTest {
private StripeController controller;
private Session session;
@BeforeEach
void setUp() throws Exception {
controller = new StripeController();
BOPayService payService = mock(BOPayService.class);
StripeClient client = mock(StripeClient.class, RETURNS_DEEP_STUBS);
session = mock(Session.class);
when(payService.createStripeClient("TEST")).thenReturn(client);
when(client.v1().checkout().sessions().retrieve("cs_test_navigation")).thenReturn(session);
when(session.getMetadata()).thenReturn(Map.of("mbrInnb", "42", "sopmalCd", "TEST"));
ReflectionTestUtils.setField(controller, "payService", payService);
}
@Test
void localReturnBaseOverridesShopDomainForBothCallbacks() {
ReflectionTestUtils.setField(controller, "stripeReturnBaseUrl", "http://loc.soju1sake1.com:18500/");
assertEquals("http://loc.soju1sake1.com:18500",
controller.resolveStripeReturnBaseUrl("https://dev.example.com"));
}
@Test
void otherProfilesKeepTheShopDomain() {
assertEquals("https://shop.example.com",
controller.resolveStripeReturnBaseUrl("https://shop.example.com/"));
}
@Test
void redirectOnlyAcceptsTheOwningMember() throws Exception {
AnonymousUser user = new AnonymousUser();
user.setUserInnb(42);
try (MockedStatic<MemberJwtContextHolder> context = mockStatic(MemberJwtContextHolder.class)) {
context.when(MemberJwtContextHolder::getMemberInfo).thenReturn(user);
when(session.getStatus()).thenReturn("open");
when(session.getUrl()).thenReturn("https://checkout.stripe.com/test");
ModelMap model = new ModelMap();
assertEquals("sopmal/ordr/StripeRedirectR",
controller.checkoutRedirect(model, "cs_test_navigation", "TEST"));
assertEquals("https://checkout.stripe.com/test", model.get("checkoutUrl"));
user.setUserInnb(99);
assertThrows(ResponseStatusException.class,
() -> controller.checkoutRedirect(new ModelMap(), "cs_test_navigation", "TEST"));
}
}
@Test
void expiredSessionDoesNotReopenCheckout() throws Exception {
AnonymousUser user = new AnonymousUser();
user.setUserInnb(42);
try (MockedStatic<MemberJwtContextHolder> context = mockStatic(MemberJwtContextHolder.class)) {
context.when(MemberJwtContextHolder::getMemberInfo).thenReturn(user);
when(session.getStatus()).thenReturn("expired");
ModelMap model = new ModelMap();
controller.checkoutRedirect(model, "cs_test_navigation", "TEST");
assertEquals("", model.get("checkoutUrl"));
}
}
@Test
void unpaidReturnRendersOneNoticeForDesktopAndMobile() throws Exception {
when(session.getStatus()).thenReturn("open");
when(session.getPaymentStatus()).thenReturn("unpaid");
MockHttpServletRequest request = new MockHttpServletRequest();
try (MockedStatic<Util> util = mockStatic(Util.class)) {
for (String device : new String[]{"sopmal", "sopmal_m"}) {
util.when(() -> Util.getDeviceType(request)).thenReturn(device);
ModelMap model = new ModelMap();
assertEquals("sopmal/ordr/StripeCancelR",
controller.stripeCancel(request, model, "cs_test_navigation", "TEST"));
assertEquals("sopmal_m".equals(device), model.get("mobile"));
assertFalse(model.containsKey("returnUrl"));
}
}
}
@Test
void paidReturnDoesNotShowCancellation() throws Exception {
when(session.getStatus()).thenReturn("complete");
when(session.getPaymentStatus()).thenReturn("paid");
ModelMap model = new ModelMap();
assertEquals("sopmal/ordr/PayStripeSucsC", controller.stripeCancel(
new MockHttpServletRequest(), model, "cs_test_navigation", "TEST"));
assertEquals("/sopmal/ordr/selectOrdrCompt", model.get("returnUrl"));
}
}

View File

@@ -1,78 +0,0 @@
const fs = require('node:fs');
const path = require('node:path');
const vm = require('node:vm');
const assert = require('node:assert/strict');
const source = fs.readFileSync(path.join(__dirname,
'../../main/resources/static/js/sopmal/refund-popup.js'), 'utf8');
const detail = 'http://local/sopmal/mpage/ordr/selectMbrSubsvcOrdrDtlInqire?ordrInnb=test-order&pageIndex=1';
const endpoint = '/sopmal/mpage/ordr/selectSetleCanclPopupForm';
const data = {sopmalCd: 'SK', ordrInnb: 'test-order', ordrDlvyInnb: 'delivery-1'};
async function run({status = 200, finalPath = endpoint, redirected = false, html = 'popup', networkError = false}) {
const calls = {alerts: [], navigations: [], inserts: [], ready: 0, parse: 0, scriptRemoved: 0};
const popup = {querySelectorAll: () => [{remove: () => calls.scriptRemoved++}]};
const context = {
URL, Object,
window: {location: {href: detail, assign: url => calls.navigations.push(url)},
alert: message => calls.alerts.push(message)},
fetch: async (url, options) => {
calls.request = {url: new URL(url), options};
if (networkError) throw new Error('offline');
return {status, ok: status >= 200 && status < 300, redirected,
url: new URL(finalPath, detail).href, text: async () => html};
},
DOMParser: class {
parseFromString(text) {
calls.parse++;
return {querySelector: selector => {
assert.equal(selector, '#refund-pop');
return text === 'popup' ? popup : null;
}};
}
},
$: selector => ({remove() {}, empty() {return this;},
append: node => calls.inserts.push(node)})
};
vm.runInNewContext(source, context);
await context.fn_load_refund_popup(endpoint, data, () => calls.ready++);
return calls;
}
(async () => {
for (const redirected of [false, true]) {
const result = await run({redirected});
assert.equal(result.ready, 1, 'normal / refreshed session opens the popup');
assert.equal(result.alerts.length, 0);
assert.equal(result.scriptRemoved, 1);
assert.equal(result.request.options.method, 'GET');
assert.equal(result.request.options.cache, 'no-store');
assert.equal(result.request.url.searchParams.get('ordrInnb'), data.ordrInnb);
assert.equal(result.request.url.searchParams.get('ordrDlvyInnb'), data.ordrDlvyInnb);
}
for (const auth of [
{status: 401},
{finalPath: '/sopmal/login/page/sopmal', redirected: true, html: '<script>login script</script>'},
{finalPath: '/sopmal/main', redirected: true}
]) {
const result = await run(auth);
assert.equal(result.ready, 0);
assert.equal(result.inserts.length, 0, 'never insert a login/main page into the popup');
assert.equal(result.parse, 0, 'do not parse or execute login HTML');
assert.match(result.alerts[0], /로그인 시간이 만료/);
const login = new URL(result.navigations[0]);
assert.equal(login.pathname, '/sopmal/login');
assert.equal(login.searchParams.get('redirect_uri'), detail);
}
for (const failure of [
{status: 500}, {status: 403}, {html: ''}, {html: 'unexpected HTML'},
{networkError: true}, {finalPath: '/', redirected: true}
]) {
const result = await run(failure);
assert.equal(result.ready, 0);
assert.equal(result.inserts.length, 0);
assert.equal(result.navigations.length, 0, 'ordinary errors must not force a login');
assert.match(result.alerts[0], /불러오지 못했습니다/);
}
console.log('PASS: 11 refund popup authentication, refresh, and error response scenarios');
})().catch(error => {console.error(error); process.exitCode = 1;});

View File

@@ -1,40 +0,0 @@
const fs = require('node:fs');
const path = require('node:path');
const vm = require('node:vm');
const assert = require('node:assert/strict');
const view = fs.readFileSync(path.join(__dirname,
'../../main/webapp/WEB-INF/views/sopmal/ordr/StripeRedirectR.jsp'), 'utf8');
const script = view.match(/<script>([\s\S]*?)<\/script>/)[1];
function check({persisted = false, type = 'navigate', state = null, checkoutUrl = 'https://checkout.stripe.com/test'}, expected) {
let handler;
const calls = [];
const context = {
window: {
addEventListener: (event, callback) => { assert.equal(event, 'pageshow'); handler = callback; },
location: {
href: 'http://local/sopmal/stripe/checkoutRedirect',
replace: url => calls.push(['replace', url]),
assign: url => calls.push(['assign', url])
}
},
document: {getElementById: id => id === 'stripeCheckout'
? {href: checkoutUrl, getAttribute: () => checkoutUrl}
: {href: 'http://local/sopmal/stripe/stripeCancel'}},
performance: {getEntriesByType: () => [{type}]},
history: {state, replaceState: function (next) { this.state = next; }}
};
vm.runInNewContext(script, context);
handler({persisted});
assert.deepEqual(calls, [expected]);
return {handler, calls};
}
const initial = check({}, ['assign', 'https://checkout.stripe.com/test']);
initial.handler({persisted: true});
assert.deepEqual(initial.calls[1], ['replace', 'http://local/sopmal/stripe/stripeCancel']);
check({type: 'back_forward'}, ['replace', 'http://local/sopmal/stripe/stripeCancel']);
check({state: {stripeRedirected: true}}, ['replace', 'http://local/sopmal/stripe/stripeCancel']);
check({checkoutUrl: ''}, ['replace', 'http://local/sopmal/stripe/stripeCancel']);
console.log('PASS: initial entry, BFCache return, history return, repeat entry, expired session');