토스 결제 API 연동 중
성공 시 응답
{
"mId": "tosspayments",
"version": "2022-06-08",
"paymentKey": "T1UwdsBoNhvzO-fUy8BkC",
"status": "DONE",
"transactionKey": "-93-dcZeXmDd_pUfnKIwA",
"lastTransactionKey": "MSmTdHS56DmjArbD2PeDM",
"orderId": "xwFi1a_v3pidotzeXqkiE",
"orderName": "토스 티셔츠 외 2건",
"requestedAt": "2022-06-08T15:40:09+09:00",
"approvedAt": "2022-06-08T15:40:49+09:00",
"useEscrow": false,
"cultureExpense": false,
"card": {
"company": "농협",
"number": "123456******7890",
"installmentPlanMonths": 0,
"isInterestFree": false,
"interestPayer": null,
"approveNo": "00000000",
"useCardPoint": false,
"cardType": "신용",
"ownerType": "개인",
"acquireStatus": "READY",
"receiptUrl": "https://dashboard.tosspayments.com/sales-slip?transactionId=KAgfjGxIqVVXDxOiSW1wUnRWBS1dszn3DKcuhpm7mQlKP0iOdgPCKmwEdYglIHX&ref=PX",
"amount": 15000
},
"virtualAccount": null,
"transfer": null,
"mobilePhone": null,
"giftCertificate": null,
"cashReceipt": null,
"discount": null,
"cancels": null,
"secret": null,
"type": "NORMAL",
"easyPay": null,
"country": "KR",
"failure": null,
"isPartialCancelable": true,
"receipt": {
"url": "https://dashboard.tosspayments.com/sales-slip?transactionId=KAgfjGxIqVVXDxOiSW1wUnRWBS1dszn3DKcuhpm7mQlKP0iOdgPCKmwEdYglIHX&ref=PX"
},
"currency": "KRW",
"totalAmount": 15000,
"balanceAmount": 15000,
"suppliedAmount": 13636,
"vat": 1364,
"taxFreeAmount": 0,
"method": "카드"
}
실패 시 응답
{
"code": "NOT_FOUND_PAYMENT",
"message": "존재하지 않는 결제 입니다."
}
이렇게 성공/실패 시 받는 객체가 달라서 bodyToMono를 성공 객체로만 받아서는 실패 시 응답 메세지를 클라이언트쪽에 리턴에 줄 수 없었다.
구글링 해보니 clientResponse로 응답 코드에 따라 객체를 다르게 받는 법을 찾았다.
@Service
@Slf4j
@RequiredArgsConstructor
public class TossPaymentApproveService {
private static final String END_POINT = "/v1/payments/{paymentKey}";
private final TossApiConfig tossApiConfig;
public Object approve(String paymentKey, TossPaymentDTO.ApproveRequest request) {
return WebClient.create(tossApiConfig.getUrl()).post()
.uri(uriBuilder -> uriBuilder
.path(END_POINT)
.build(paymentKey))
.header(AUTHORIZATION, tossApiConfig.getBasicSecretKey())
.header(CONTENT_TYPE, "application/json")
.bodyValue(request)
.exchangeToMono(clientResponse -> getResponseObject(clientResponse))
.block();
}
private Mono<Object> getResponseObject(ClientResponse clientResponse) {
if (clientResponse.statusCode().isError()) {
return clientResponse.bodyToMono(ApproveErrorResponse.class);
}
return clientResponse.bodyToMono(ApproveResponse.class);
}
}
200 응답 시 ApproveResponse 객체로 받고, 200 이 외는 ApproveErrorResponse 객체로 받도록 했다.
+ 이후 받은 객체를 판별하여 error response는 예외 처리한다.
private ApproveResponse validateResponse(Object response) {
if (response instanceof ApproveResponse) {
return (ApproveResponse) response;
}
if (response instanceof ApproveErrorResponse) {
throw new CommonException(ResponseCode.API_REQUEST_FAIL,
((ApproveErrorResponse) response).getMessage());
}
throw new CommonException(ResponseCode.INVALID_RESPONSE);
}
참조
Get API response error message using Web Client Mono in Spring Boot
I am using webflux Mono (in Spring boot 5) to consume an external API. I am able to get data well when the API response status code is 200, but when the API returns an error I am not able to retrie...
stackoverflow.com
'Back-End > SpringBoot' 카테고리의 다른 글
[SpringBoot/QueryDsl] java.lang.IllegalArgumentException: Multiple entries with same key (0) | 2022.09.04 |
---|---|
[SpringBoot] e.getStackTrace() 출력 결과 차이 (0) | 2022.08.11 |
[SpringBoot/MapStruct] MapStruct source 없이 default value 넣기 (0) | 2022.07.04 |
[SpringBoot] 슬랙 메시지 전송 (0) | 2022.05.21 |
[SpringBoot/JPA] @Embeddable, @EmbeddedId로 복합키 설정 (0) | 2022.05.21 |