Spring으로 외부 API 호출하기 - (5) 카카오톡 퀵 API 분석하기 (주문/배송 상태 변경하기)

sliver gun·2024년 12월 20일

egovFramework

목록 보기
12/14

🔰목차

  1. 서론
  2. 주문/배송 변경 요청
    1. 호출 방식
    2. 요청 헤더
    3. 요청 파라미터
    4. 요청 예시코드
    5. 요청 Body
    6. 요청 응답
  3. 적용 방법
  4. 결론
  5. 레퍼런스

서론

이번엔 주문/배송 상태 변경 기능을 추가해보도록 하겠다.


주문/배송 변경 요청

호출 방식

[API_ENDPOINT]/api/v1/developers/orders/${partnerOrderId}/status 으로 PATCH 를 요청한다.

요청 헤더

ParameterDescription
Authorization시작하기에서 생성한 Authorization 파라미터 값
vendorkakaoT 퀵∙도보 배송 API Sandbox에서 발급받은 Vendor 아이디
Content-Typeapplication/json

여태까지와 똑같은 헤더값이다

요청 파라미터

NameTypeDescriptionRequired
partnerOrderIdString연동사 주문 아이디필수

이번에도 조회와 똑같이 partnerOrderId 를 path 파라미터로 사용한다.

요청 예시코드

curl -X 'PATCH' \
'https://open-api-logistics.kakaomobility.com/goa-sandbox-service/api/v1/developers/orders/${partnerOrderId}/status' \
-H 'accept: application/json' \
-H 'vendor: ${vendor_id}' \
-H 'Authorization: XXX' \
-H 'Content-Type: application/json' \
-d '{
  "orderStatus": "CANCEL",
  "cancelBy": "ADMIN"
}'

이번엔 orderStatuscancelBy 가 Body를 구성한다.

요청 Body

NameTypeDescriptionRequired
orderStatusEnum(String)변경하려는 주문의 상태다음 중 하나: ABORT: 배송 강제 종료MATCH_PICKER: 배송원 배정 완료CANCEL: 배송 취소PICKUP_COMPLETED: 배송원 픽업 완료DROPOFF_COMPLETED: 배송 완료필수
cancelByEnum(String)주문 취소 주체다음 중 하나: PICKER: 배송원에 의한 주문 취소ADMIN: 관리자에 의한 주문 취소선택

요청 응답

따로 JSON으로 응답하지 않고 요청에 대한 성공 여부를 HTTP 상태 코드로 전달받는다.


적용 방법

결론부터 말하자면 지금까지 했던 것처럼 MVC 기반에서 작동시키기엔 지금의 환경에서는 무리가 있다.

필자는 이 작업을 eGovFramework 3.10에서 진행하고 있으며 해당 환경은 버전이 낮아 HiddenHttpMethodFilter 와 같은 POST를 PATCH로 바꿔주는 방식을 사용하기 까다롭다.

정상적인 Response를 받는 것은 실패했지만 어떤 식으로 접근했는지 적어보려고 한다.

@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
    return new HiddenHttpMethodFilter();
}

먼저 HiddenHttpMethodFilter 를 빈으로 가져와야한다.

HiddenHttpMethodFilter은 POST를 PATCH로 변환할 수 있는 필터다.

만약 Spring boot 환경이 아닌 Spring MVC 환경이라면 web.xml 파일에 설정해야 한다.

<filter>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

jsp에서는 를 통해 Controller에 PATCH 요청을 보낸다.

<body>
  <div class="container">
    <h3 class="title">주문 변경할 ID</h3>
    <p id="vendor" hidden>${vender}</p>
    <p id="authorization" hidden>${authorization}</p>
    <form id="orderPatch" method="post">
      <label for="partnerOrderId">파트너 ID</label>
      **<input type="hidden" name="_method" value="PATCH">**
			...
    <button type="button" class="btn-submit" onclick="submitForm()">조회</button>
    </form>
	
		
		<script>
		function submitForm() {
			const form = document.getElementById("orderPatch");
			const ID = document.getElementById("partnerOrderId").value;

			if (ID) {
				form.action = '/kakaoTest/patch/' + ID + '.do';
				form.submit();
			} else {
				alert("Invaild ID");
			}
		}
		</script>
	</div>
</body>

form에서 hidden으로 보낸 PATCH 요청을 Controller에선 params = “_method=PATCH”를 추가해서 처리하도록 한다.

@RequestMapping(value = "/patch/{partnerOrderId}.do", method = RequestMethod.POST, params = "_method=PATCH")
public String patchOrder(@PathVariable String partnerOrderId, @ModelAttribute OrderVO orderVO, Model model) {
	try {
	  	final String API_ENDPOINT = apiConfig.getHostURL() + "/api/v1/developers/orders/" + partnerOrderId + "/status";
	    final String VENDOR_ID = apiConfig.getVendorID();
	    
	    final String authorization = getAuthorization();
	      
	    JSONObject json = new JSONObject();
	
	    // JSON 객체에 데이터 삽입
	    json.put("orderStatus", orderVO.getOrderStatus());
	    json.put("cancelBy", orderVO.getCancelBy());
	    
	    // HTTP Header 설정
	    HttpHeaders headers = new HttpHeaders();
	    headers.set("Content-Type", "application/json");
	    headers.set("Authorization", authorization);
	    headers.set("vendor", VENDOR_ID);
	
	    // HTTP 요청 생성
	    HttpEntity<String> requestEntity = new HttpEntity<>(json.toString(), headers);
	    
	    // API 호출
	    ResponseEntity<String> response = null;
	    try {
	        response = restTemplate.postForEntity(API_ENDPOINT, requestEntity, String.class);
	
	        System.out.println("Response Status Code: " + response.getStatusCode());
	        System.out.println("Response Body: " + response.getBody());
	    } catch (Exception e) {
	        System.out.println("기타 예외 발생");
	        e.printStackTrace();
	    }
	
	    // 응답 처리
	    model.addAttribute("responseCode", response.getStatusCodeValue());
	    model.addAttribute("responseBody", response.getBody());
	    
	    return "result";

  } catch (Exception e) {
	    e.printStackTrace();
	    System.out.println("Error: " + e.getMessage());
	    
	    return "result";
  }
}

다음과 같은 과정을 거친다면 어느정도 spring 환경이 최신 버전일 때 정상적으로 작동할 것으로 예상된다.


결론

PATCH는 애초에 웹 어플리케이션에서 작동하기 보다 REST API에서 작동하는 요청이다 보니 웹에서는 여러가지로 호환이 안되는 문제를 깨달았다.

이 프로젝트는 잠정적으로 끝났지만 나머지 구현했던 부분들에 대해서도 작성할 예정이다.


레퍼런스

https://logistics-developers.kakaomobility.com/document/patch-orders-status

0개의 댓글