Toss Payments 정리 4
Toss Payments 정리 4 - 결제 취소
5분 소요
결제 취소
금액 전액, 부분 환불하는 방법, 가상계좌 결제 취소하는 방법, 결제위젯에서 가상계좌 정보 확인하는 방법
결제 취소 기한
각 결제수단마다 취소 기한, 취소 소요 시간이 다르다.
| 결제 수단 | 취소 기한 | 취소 소요 기간 |
|---|---|---|
| 카드 | 취소 기한은 없지만, 카드사 별로 결제 데이터 보관 기간이 달라서 1년을 초과하면 취소가 안될 수 있어요. | 결제가 매입되기 전에는 취소 직후 환불됩니다. 매입 이후 또는 부분 취소는 요청 후 영업일 기준 3~4일이 소요됩니다. |
| 계좌이체 | 180일 이내의 거래만 취소 가능합니다. | 실시간으로 환불됩니다. |
| 가상계좌 | 상점마다 설정이 다를 수 있으나 보통 365일 동안 취소가 가능합니다. | 영입일 기준 총 2일이 소요됩니다. 의심거래로 탐지된 결제는 최대 영업일 기준 9일이 소요될 수 있습니다. |
| 휴대폰 | 통신사 정책으로 결제가 발생한 당월에만 취소가 가능합니다. | 당일 취소됩니다. |
| 해외 간편결제(PayPal) | 180일 이내의 거래만 취소 가능합니다. | 영업일 기준 최대 5일이 소요됩니다. 일부 환불은 카드 회사에 따라 최대 30일이 소요될 수 있습니다. |
전액 취소하기
결제 취소 API 엔드포인트에 결제 승인 API 요청 결과로 받은 paymentKey를 Path 파라미터로 추가하고 API 요청 본문에 취소 이유를 cancelReason 파라미터로 추가한다. 멱등키 헤더를 추가하면 중복 취소 없이 안전하게 처리된다.
예시
curl --request POST \
--url https://api.tosspayments.com/v1/payments/{paymentKey}/cancel \
--header 'Authorization: Basic dGVzdF9za19EbnlScFFXR3JORGFuZTY3NXlXTDNLd3YxTTlFOg==' \
--header 'Content-Type: application/json' \
--data '{"cancelReason":"구매자가 취소를 원함"}'
API 응답
{
"mId": "tosspayments",
"version": "2024-06-01",
"lastTransactionKey": "yWpEucOHC3DxVp9otKtRe",
"paymentKey": "8VE82d0fRXKDrGRelDmrZ",
"orderId": "HqXXAmCbzKnj8udfE8Oak",
"orderName": "토스 티셔츠 외 2건",
"currency": "KRW",
"method": "카드",
"status": "CANCELED",
//...
"cancels": [
{
"cancelReason": "구매자가 취소를 원함",
"canceledAt": "2022-01-01T11:32:04+09:00",
"cancelAmount": 10000,
"taxFreeAmount": 0,
"taxExemptionAmount": 0,
"refundableAmount": 0,
"transferDiscountAmount": 0,
"easyPayDiscountAmount": 0,
"transactionKey": "8B4F646A829571D870A3011A4E13D640",
"receiptKey": "V4AJ6AhSWsGN0RocizZQlagPLN8s2IahJLXpfSHzQBTKoDG7",
"cancelStatus": "DONE",
"cancelRequestId": null
}
],
"secret": null,
"type": "NORMAL",
"easyPay": "토스페이",
"country": "KR",
"failure": null,
"totalAmount": 10000,
"balanceAmount": 0,
"suppliedAmount": 0,
"vat": 0,
"metadata": null,
"taxFreeAmount": 0,
"taxExemptionAmount": 0
}
위 응답의 cancels 배열에 취소한 건에 대한 정보가 담겨있다. 각 취소 거래마다 거래를 구분하는 transactionKey를 가지고 있다.
부분 취소하기
결제 금액 중 일부만 취소하려면 결제 취소 API의 엔드포인트에 paymentKey와 함께 cancelAmount파라미터에 취소할 금액을 추가한다. cancelAmount에 값이 없으면 전액 취소로 처리된다.
예시
curl --request POST \
--url https://api.tosspayments.com/v1/payments/qXDf1Res_RqWuEzSZPEb2/cancel \
--header 'Authorization: Basic dGVzdF9za19EbnlScFFXR3JORGFuZTY3NXlXTDNLd3YxTTlFOg==' \
--header 'Content-Type: application/json' \
--data '{"cancelReason":"구매자가 취소를 원함","cancelAmount":1000}'
부분 취소를 여러 번 하면 아래와 같이 cancels 필드에 취소 객체가 여러 개 돌아온다.
{
// ...
"cancels": [
{
"cancelAmount": 1000,
"cancelReason": "구매자가 취소를 원함",
"taxFreeAmount": 0,
"taxExemptionAmount": 0,
"refundableAmount": 9000,
"transferDiscountAmount": 0,
"easyPayDiscountAmount": 0,
"canceledAt": "2022-01-01T23:23:52+09:00",
"transactionKey": "8B4F646A829571D870A3011A4E13D640",
"receiptKey": "CuskOnzZEf0Xbwo8eMZ56slTAXbJ8jUjTX3n6SNuvY5d7Fpf",
"cancelStatus": "DONE",
"cancelRequestId": null
},
{
"cancelAmount": 1000,
"cancelReason": "구매자가 다른 품목도 취소를 원함",
"taxFreeAmount": 0,
"taxExemptionAmount": 0,
"refundableAmount": 8000,
"transferDiscountAmount": 0,
"easyPayDiscountAmount": 0,
"canceledAt": "2022-01-02T20:00:00+09:00",
"transactionKey": "6673C15BF350C3F9BF45CEFC48C7A24E",
"receiptKey": "PLDm1CZSQxTBvYrHytz3yt3MU09Nx57IoCxIEJ8HPzOyIRos",
"cancelStatus": "DONE",
"cancelRequestId": null
}
]
// ...
}