From 3e78be7d5c3f1efd39806a14537ee099ac1b9e5d Mon Sep 17 00:00:00 2001 From: JONGHAN Date: Tue, 6 Jan 2026 16:54:55 +0900 Subject: [PATCH 1/2] =?UTF-8?q?refactor:=20=EA=B2=B0=EC=A0=9C=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/static/payment-test.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/static/payment-test.html b/src/main/resources/static/payment-test.html index 14bffc3..b0321d9 100644 --- a/src/main/resources/static/payment-test.html +++ b/src/main/resources/static/payment-test.html @@ -244,8 +244,8 @@

주문 처리 완료

const orderStatus = data.orderStatus; - // ORDERED 상태: 결제 위젯 표시 - if (orderStatus === 'ORDERED') { + // PENDING_PAYMENT 상태: 결제 위젯 표시 + if (orderStatus === 'PENDING_PAYMENT') { paymentWidgetArea.style.display = 'block'; await initPaymentWidget(data); } @@ -255,7 +255,7 @@

주문 처리 완료

await loadPaymentInfo(data.orderId); } // CANCELLED, REFUNDED 등: 안내 메시지만 표시 - else if (['CANCELLED', 'REFUNDED', 'RETURN_REQUESTED', 'RETURNED', 'REFUND_REQUESTED'].includes(orderStatus)) { + else if (['PENDING_PAYMENT ', 'CANCELLED', 'REFUNDED', 'RETURN_REQUESTED', 'RETURNED', 'REFUND_REQUESTED'].includes(orderStatus)) { cannotActionArea.style.display = 'block'; const messageElement = document.getElementById('cannot-action-message'); From 33a9453ac91706c7f900015e81bb6aa026ea93df Mon Sep 17 00:00:00 2001 From: JONGHAN Date: Tue, 6 Jan 2026 17:05:15 +0900 Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20=EA=B2=B0=EC=A0=9C=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/payment/PaymentController.java | 42 +++++++++++++++++-- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/kt/controller/payment/PaymentController.java b/src/main/java/com/kt/controller/payment/PaymentController.java index d0cc627..4471333 100644 --- a/src/main/java/com/kt/controller/payment/PaymentController.java +++ b/src/main/java/com/kt/controller/payment/PaymentController.java @@ -93,6 +93,7 @@ public ResponseEntity confirmPayment(@RequestBody PaymentTossConfirmRequest r ) { String orderId = request.orderId().split("-")[0]; Long orderIdLong = Long.parseLong(orderId); + String paymentKey = request.paymentKey(); try { String url = tossPaymentsProperties.getApiUrl() + "/confirm"; @@ -124,12 +125,29 @@ public ResponseEntity confirmPayment(@RequestBody PaymentTossConfirmRequest r if (response.getStatusCode() == HttpStatus.OK) { Map tossPayment = response.getBody(); - Long paymentId = paymentFacade.completePayment(tossPayment, currentUser.getId(), orderIdLong); + try { + Long paymentId = paymentFacade.completePayment(tossPayment, currentUser.getId(), orderIdLong); - Map responseBody = new HashMap<>(tossPayment); - responseBody.put("paymentId", paymentId); + Map responseBody = new HashMap<>(tossPayment); + responseBody.put("paymentId", paymentId); + + return ResponseEntity.ok(responseBody); + + } catch (Exception e) { + System.out.println("결제 실패sdlkjfnmalskdmfklamsdklfmaklsdmfklamsdflkmasdklf"); + + cancelTossPayment(paymentKey, "시스템 오류로 인한 자동 취소"); + + orderService.rollback(orderIdLong); + + return ResponseEntity + .status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of( + "code", ErrorCode.PAYMENT_CANCEL_FAILED, + "message", "결제는 승인되었으나 처리 중 오류가 발생하여 자동 취소" + )); + } - return ResponseEntity.ok(responseBody); } return ResponseEntity.ok(response.getBody()); @@ -224,6 +242,22 @@ public ApiResult> getClientKey() { return ApiResult.ok(Map.of("clientKey", tossPaymentsProperties.getClientKey())); } + /* 이 코드 service로 빼야하는지 등 검토좀 한번 ㅂ부탁드릴게요!*/ + private void cancelTossPayment(String paymentKey, String cancelReason) { + String url = tossPaymentsProperties.getApiUrl() + "/" + paymentKey + "/cancel"; + String auth = tossPaymentsProperties.getSecretKey() + ":"; + String encodedAuth = java.util.Base64.getEncoder() + .encodeToString(auth.getBytes(StandardCharsets.UTF_8)); + + HttpHeaders headers = new HttpHeaders(); + headers.add("Authorization", "Basic " + encodedAuth); + headers.setContentType(MediaType.APPLICATION_JSON); + + Map body = Map.of("cancelReason", cancelReason); + + HttpEntity> entity = new HttpEntity<>(body, headers); + restTemplate.postForEntity(url, entity, Map.class); + } }