결제취소 API

결제취소 API를 사용해서 승인된 결제를 취소하고 결제수단으로 환불받는 기능을 구현해보세요.

API 사용하기에서 API 사용에 필요한 인증 정보를 구성해두세요.

승인된 결제 취소하기

결제가 승인될 때 발급된 paymentKey와 결제취소 이유만 있으면 결제취소가 가능합니다. paymentKey는 Path 파라미터로, 취소 이유는 요청 본문에 추가하세요.

요청
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.tosspayments.com/v1/payments/{paymentKey}/cancel"))
    .header("Authorization", "Basic dGVzdF9za196WExrS0V5cE5BcldtbzUwblgzbG1lYXhZRzVSOg==")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("{\"cancelReason\":\"고객이 취소를 원함\"}"))
    .build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

같은 paymentKey를 이용한 취소 요청이 1초에 2번 이상 연속으로 들어오면 첫 번째 요청만 처리됩니다.

부분 취소하기

부분 취소를 하려면 cancelAmount에 취소할 만큼의 금액을 추가해서 결제취소 API를 요청합니다. 값을 따로 넣지 않으면 결제한 전액이 취소됩니다.

해당 결제 건의 정보를 담은 Payment 객체의 cancels 필드에 취소한 기록이 쌓입니다.

응답
// Payment 객체
{
// ...
"cancels": [
{
"cancelAmount": 1000,
"cancelReason": "고객이 취소를 원함",
"taxFreeAmount": 0,
"taxAmount": null,
"refundableAmount": 9000,
"canceledAt": "2021-06-22T23:23:52+09:00"
},
{
"cancelAmount": 1000,
"cancelReason": "고객이 다른 품목도 취소를 원함",
"taxFreeAmount": 0,
"taxAmount": null,
"refundableAmount": 8000,
"canceledAt": "2021-06-23T20:00:00+09:00"
}
]
// ...
}

가상계좌 결제 취소하기

가상계좌로 입금한 결제를 취소할 때는 환불 받을 계좌 정보가 담긴 refundReceiveAccount를 포함해서 결제취소를 요청해야 합니다. 해당 파라미터에 담긴 계좌 정보로 결제한 금액이 환불됩니다.

요청
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.tosspayments.com/v1/payments/{paymentKey}/cancel"))
    .header("Authorization", "Basic dGVzdF9za196WExrS0V5cE5BcldtbzUwblgzbG1lYXhZRzVSOg==")
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("{\"cancelReason\":\"고객이 취소를 원함\",\"cancelAmount\":1000,\"refundReceiveAccount\":{\"bank\":\"우리\",\"accountNumber\":\"1000123456789\",\"holderName\":\"김토페\"}}"))
    .build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

취소 요청을 안전하게 처리하기

refundableAmount 파라미터를 요청에 포함하면 취소 요청을 안전하게 처리할 수 있습니다.

토스페이먼츠 서버에서는 요청에 포함된 refundableAmount와 실제 환불 가능한 잔액 정보가 서로 다른 경우 응답으로 에러를 보냅니다.

예를 들어,

  1. 고객이 15,000원을 결제한 뒤 5,000원을 취소하고 싶습니다. 이 때 취소할 수 있는 금액은 전액이므로 결제취소를 요청할 때 refundableAmount값으로 15000 을 넣습니다.

  2. 5,000원이 성공적으로 부분 취소되어 응답으로 돌아오는 refundableAmount는 10,000원 입니다.

  3. 이후 고객이 한 번 더 5,000원을 취소하려고 합니다. 앞서 돌아온 취소 가능한 잔액은 10,000원이므로 두번째 취소를 할 때는 refundableAmount 값으로 10000을 넣어줍니다.

이런 식으로 현재 환불할 수 있는 잔액을 refundableAmount 값으로 담아 보내면, 이 값을 확인해서 결제취소가 중복으로 요청되거나 결제된 금액보다 더 많이 취소하는 등의 상황을 방지합니다.


결제취소 API를 자세히 알아보세요

결제취소 API를 직접 실행해보세요

내용이 도움 되셨나요?
  • 더 궁금한 내용이 있나요?
  • 코드 샘플을 참고하세요
  • 기술지원이 필요한가요?
    디스코드 채팅|이메일 보내기