ACI Express - ACI Key 발급 API

배송조회(운송장번호 조회) - aciExpress 팝업 적용
>> 쇼핑몰 주문/배송 > 주문 상세,
>> 주문 관리 > 전체주문조회 > 주문상세,
>> 주문 관리 > 출고 조회 > 출고 목록 조회,
>> 주문 관리 > 출고 조회 > 출고 상세 조회,
>> 주문 관리 > 출고 조회 > 출고 상태 변경,
>> 반품환불관리 > 반품환불 처리 > 반품/환불 상세 > 원주문 정보 펼쳐보기

(cherry picked from commit 1e1ee301d6)
This commit is contained in:
이대환
2026-05-28 17:53:15 +09:00
parent 45c85b6079
commit acb8d314d9
15 changed files with 274 additions and 140 deletions

View File

@@ -46,6 +46,9 @@ public class BOCommonService {
@Value("${secret.key}")
private String secretKey;
@Value("${aciexpress.apikey}")
private String aciApiKey;
/**
* <p>비밀번호를 암호화 한다</p>
@@ -287,4 +290,10 @@ public class BOCommonService {
return secretKey;
}
/**
* aci Api키 조회
* @return String
*/
public String selectAciApiKey() {return aciApiKey;}
}

View File

@@ -161,6 +161,14 @@ public interface BODlivyMapper {
public List<BODlivyVO> selectBOOrdrDlvyDtlsInqireGroupOrdr(BODlivyVO boDlivyVO);
/**
* 주문 배송 추적 조회 : 송장번호 조회
* @param boDlivyVO
* @return
*/
public String selectBOOrdrInvcnb(BODlivyVO boDlivyVO);
/**
* 출고 상태 '상품 준비' or '배송중' 되돌리기 / 출고 상태 변경 단건
* @param dlivyVO

View File

@@ -1,59 +1,40 @@
package com.wb.domainserver.domain.gcone.ordr.dlivy.service;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.wb.domainserver.domain.admin.store.sopmal.vo.BOShopSetupVO;
import com.fasterxml.jackson.databind.ObjectMapper;
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.vo.BOOrderLogVO;
import com.wb.domainserver.domain.gcone.mbr.mlg.service.BOMlgService;
import com.wb.domainserver.domain.gcone.mbr.mlg.vo.BOMlgVO;
import com.wb.domainserver.domain.gcone.ntcn.mssage.service.BOMssageService;
import com.wb.domainserver.domain.gcone.ordr.atmcrcpmny.vo.BOAtmcRcpmnyCnfirmVO;
import com.wb.domainserver.domain.gcone.ordr.dlivy.mapper.BODlivyMapper;
import com.wb.domainserver.domain.gcone.ordr.dlivy.vo.*;
import com.wb.domainserver.domain.gcone.ordr.ordr.mapper.BOOrdrMapper;
import com.wb.domainserver.domain.gcone.ordr.ordr.service.BOOrdrService;
import com.wb.domainserver.domain.gcone.ordr.ordr.vo.BOOrdrLogVO;
import com.wb.domainserver.domain.gcone.ordr.ordr.vo.BOOrdrShippingVO;
import com.wb.domainserver.domain.gcone.ordr.ordr.vo.BOOrdrVO;
import com.wb.domainserver.domain.gcone.ordr.pay.service.BOPayService;
import com.wb.domainserver.domain.gcone.ordr.pay.vo.BOPayVO;
import com.wb.domainserver.domain.gcone.ordr.rtngudrefnd.service.BORtngudrefndService;
import com.wb.domainserver.exception.WnbtRestException;
import com.wb.domainserver.exception.code.ErrorCode;
import com.wb.domainserver.util.dataaccess.DataMap;
import com.wb.domainserver.util.string.StringUtil;
import io.micrometer.common.util.StringUtils;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wb.domainserver.domain.gcone.ordr.dlivy.mapper.BODlivyMapper;
import com.wb.domainserver.util.dataaccess.DataMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.springframework.web.client.RestTemplate;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;
@Service
@Slf4j
@@ -83,6 +64,9 @@ public class BODlivyService {
@Autowired
BORtngudrefndService boRtngudrefndService;
@Autowired
private BOCommonService boCommonService;
/* ####################################
출고 리스트 서비스 시작
@@ -494,6 +478,167 @@ public class BODlivyService {
return contents;
}
/**
* ACI Key 발급 API
* @param
* @return List<DataMap>
*/
public DataMap selectBOAciKey() throws WnbtRestException {
String apiKey = boCommonService.selectAciApiKey();
DataMap message = new DataMap();
try {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("USERID", "UNIHAN");
headers.set("APIKEY", apiKey);
Map<String, Object> body = new HashMap<>();
HttpEntity<String> apiRequest =
new HttpEntity<>("{}", headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange(
"https://acieshop.com/api/kr/pod/v1.5/",
HttpMethod.POST,
apiRequest,
String.class
);
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(response.getBody());
message.put("status", jsonNode.get("Status").asText());
message.put("aciKey", jsonNode.get("ACIKey").asText());
message.put("errMsg", jsonNode.get("ErrMsg").asText());
}catch (WnbtRestException wre){
log.error(wre.getMessage());
throw wre;
}catch (RuntimeException re){
log.error(re.getMessage());
throw new WnbtRestException(ErrorCode.INTERNAL_SERVER_ERROR);
}catch (Exception e) {
log.error(e.getMessage(), e);
throw new WnbtRestException(ErrorCode.INTERNAL_SERVER_ERROR);
}
return message;
}
/**
* 화물 추적 - 운송장 조회 API
* @param boDlivyVO
* @return List<DataMap>
*/
public DataMap updateBOAciDelivery(BODlivyVO boDlivyVO) throws WnbtRestException {
DataMap aciMap = selectBOAciKey();
String aciKey = String.valueOf(aciMap.get("aciKey"));
DataMap message = new DataMap();
try {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("USERID", "UNIHAN");
headers.set("ACIKey", aciKey);
Map<String, Object> body = new HashMap<>();
body.put("BLNO", mapper.selectBOOrdrInvcnb(boDlivyVO));
HttpEntity<Map<String, Object>> apiRequest =
new HttpEntity<>(body, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange(
"ex",
HttpMethod.POST,
apiRequest,
String.class
);
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(response.getBody());
message.put("status", jsonNode.get("Status").asText());
JsonNode podInfoNode = jsonNode.get("PODInfo");
if(!podInfoNode.isNull()) {
List<DataMap> podInfoList = new ArrayList<>();
for(JsonNode podInfoItem : podInfoNode) {
DataMap PODInfo = new DataMap();
PODInfo.put("blno", podInfoItem.get("BLNO").asText());
PODInfo.put("dateLocalwhin", podInfoItem.get("DATE_LOCALWHIN").asText());
PODInfo.put("dateLocaldeparture", podInfoItem.get("DATE_LOCALDEPARTURE").asText());
PODInfo.put("dateIcnarrival", podInfoItem.get("DATE_ICNARRIVAL").asText());
PODInfo.put("dateCustomes", podInfoItem.get("DATE_CUSTOMES").asText());
PODInfo.put("dateDelivery", podInfoItem.get("DATE_DELIVERY").asText());
PODInfo.put("recipient", podInfoItem.get("RECIPIENT").asText());
PODInfo.put("wta", podInfoItem.get("WTA").asText());
PODInfo.put("wtdan", podInfoItem.get("WTDAN").asText());
List<DataMap> volumeList = new ArrayList<>();
for(JsonNode volumeItem : podInfoItem.get("VOLUME")) {
DataMap volume = new DataMap();
volume.put("width", volumeItem.get("WIDTH").asText());
volume.put("length", volumeItem.get("LENGTH").asText());
volume.put("height", volumeItem.get("HEIGHT").asText());
volumeList.add(volume);
}
PODInfo.put("volume", volumeList);
List<List> customsList = new ArrayList<>();
for(JsonNode customsItem : podInfoItem.get("CUSTOMS")) {
List<DataMap> customDetail = new ArrayList<>();
for(JsonNode customItem : customsItem) {
DataMap Custom = new DataMap();
Custom.put("dateEvent", customItem.get("DATE_EVENT").asText());
Custom.put("traceStatus", customItem.get("TRACE_STATUS").asText());
customDetail.add(Custom);
}
customsList.add(customDetail);
}
PODInfo.put("customs", customsList);
List<DataMap> localPodList = new ArrayList<>();
for(JsonNode localPodItem : podInfoItem.get("LOCAL_POD")) {
DataMap localPod = new DataMap();
localPod.put("traceStatus", localPodItem.get("TRACE_STATUS").asText());
localPod.put("dateEvent", localPodItem.get("DATE_EVENT").asText());
localPod.put("position", localPodItem.get("POSITION").asText());
localPodList.add(localPod);
}
PODInfo.put("localPod", localPodList);
podInfoList.add(PODInfo);
}
message.put("podInfo", podInfoList);
} else {
message.put("errMsg", jsonNode.get("ErrMsg").asText());
}
}catch (WnbtRestException wre){
log.error(wre.getMessage());
throw wre;
}catch (RuntimeException re){
log.error(re.getMessage());
throw new WnbtRestException(ErrorCode.INTERNAL_SERVER_ERROR);
}catch (Exception e) {
log.error(e.getMessage(), e);
throw new WnbtRestException(ErrorCode.INTERNAL_SERVER_ERROR);
}
return message;
}
/**
* 송장번호 조회
* @param boDlivyVO
* @return List<DataMap>
*/
public String selectBOOrdrInvcnb(BODlivyVO boDlivyVO) throws WnbtRestException {
return mapper.selectBOOrdrInvcnb(boDlivyVO);
}
/**

View File

@@ -36,6 +36,7 @@ import com.wb.domainserver.domain.sopmal.mpage.ordr.vo.MyOrdrDlvyVO;
import com.wb.domainserver.domain.sopmal.mpage.ordr.vo.MyOrdrShippingVO;
import com.wb.domainserver.domain.sopmal.mpage.ordr.vo.MyRefundVO;
import com.wb.domainserver.exception.WnbtRestException;
import com.wb.domainserver.response.ApiResponse;
import com.wb.domainserver.response.WnbtResponse;
import com.wb.domainserver.response.WnbtResponseBody;
import com.wb.domainserver.response.WnbtWebClientResponseHandler;
@@ -54,6 +55,7 @@ import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Base64Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
@@ -65,6 +67,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -725,26 +728,26 @@ public class MyOrdrController {
* @return
*/
@Policy(AuthPolicy.PUBLIC)
@RequestMapping(value="/selectDlvyInqire")
public String selectDlvyInqire(BODlivyVO boDlivyVO, ModelMap model, HttpServletRequest request){
// @RequestMapping(value="/selectDlvyInqire")
// public String selectDlvyInqire(BODlivyVO boDlivyVO, ModelMap model, HttpServletRequest request){
@RequestMapping(value="/selectDlvyInqire", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<WnbtResponse> selectDlvyInqire(BODlivyVO boDlivyVO){
// 작성자 정보 할당
AnonymousUser user = MemberJwtContextHolder.getMemberInfo();
if("01".equals(user.getSysDvCd())){
boDlivyVO.setSopmalCd(user.getSopmalCd()); // 쇼핑몰 코드
}
Map<String, Object> content = new HashMap<>();
content = dlivyService.selectBOOrdrDlvyDtlsInqire(boDlivyVO);
// model.addAttribute("resultMap", dlivyService.updateBOAciDelivery(boDlivyVO));
// return Util.getDeviceType(request) + "/mpage/ordr/DlvyInqireR";
model.addAttribute("resultMap", content);
// responseHandler.handleResponse(
// sendToResrc.ofPost(RESRC.GCONEBO, "/gcone/ordr/dlivy/selectBOOrdrDlvyDtlsInqire", dlivyVO),
// model,
// "resultMap"
// );
// return "sopmal/mpage/ordr/DlvyInqireR";
return Util.getDeviceType(request) + "/mpage/ordr/DlvyInqireR";
DataMap content = new DataMap();
content.put("invcnb", dlivyService.selectBOOrdrInvcnb(boDlivyVO));
return ResponseEntity.ok(
WnbtResponse.builder()
.resBody(new WnbtResponseBody(content))
.build()
);
}