본문으로 건너뛰기
2026. 7. 28
© WONKOOK LEE

취소는 왜 두 종류인가요?

온라인에서 결제를 취소하면 어떤 때는 카드 앱의 이용내역에서 그 건이 흔적 없이 사라집니다. 어떤 때는 결제와 취소가 두 줄로 나란히 남고, 돈은 며칠 뒤에야 돌아옵니다.

누른 버튼은 똑같이 하나였습니다. 금액도 카드도 같습니다. 그런데 결과가 다릅니다.

그렇다면 취소를 누른 순간에 되돌려진 것은 대체 무엇이었을까요?

이 글은 취소 한 건의 성질이 무엇 때문에 갈리는지 다룹니다. 승인·매입·정산·입금이라는 네 단계 자체는 카드를 긋는 순간 무슨 일이 벌어질까요?에서 그렸으니, 여기서는 취소 요청이 그 파이프라인의 어느 지점에 떨어졌는지가 취소의 종류를 정한다는 점을 파고듭니다. 취소된 거래의 수수료와 정산 조정은 결제 수수료는 누가 얼마를 가져가나요?, 뒤집힌 매출이 부가세 신고와 장부에서 어떻게 조정되는지는 카드 매출은 어떻게 장부와 세금이 될까요?의 몫입니다.



1. 경계선은 매입에 있다

승인이 한도를 잡아 둔 약속이고 매입이 대금 채권을 확정하는 단계라는 것은 카드를 긋는 순간 무슨 일이 벌어질까요?에서 정리했습니다.

취소가 이 둘 중 어디에서 들어오는지가 취소의 성질을 정합니다. 매입 전이라면 되돌릴 것이 약속밖에 없습니다. 잡아 둔 한도를 풀면 끝이고, 카드사가 가맹점에 지급할 금액은 애초에 생기지 않았습니다. 이것이 승인취소입니다.

매입이 끝난 뒤는 사정이 다릅니다. 카드사 원장에는 이미 "이 가맹점에 얼마를 지급한다"는 채권이 서 있고, 회원 쪽에는 청구할 금액이 잡혀 있습니다. 이미 서 버린 기록을 되돌리려면 반대 방향의 기록을 하나 더 만들어야 합니다. 이것이 매출취소이고, 일상에서 환불이라 부르는 것도 대개 이쪽입니다.

카드사와 가맹점 사이의 통신을 중계하는 VAN사(부가가치통신망, Value Added Network) 가운데 하나인 유비씨엔의 공개 개발자 문서는 이 경계를 마감이라는 말로 설명합니다(2026년 8월 확인 기준). 승인 직후 마감 전에 취소하는 것이 승인취소이고, 마감이 완료되어 매입이 진행된 이후의 취소는 정산 대상에서 차감하는 방식으로 처리된다는 것입니다. 같은 대상을 문서에 따라 매입취소라고도 부르는데, 이 시리즈는 매출취소로 통일해 쓰겠습니다.

그러면 마감은 언제일까요. 이 지점부터는 법령이 정하지 않고 계약과 관행이 정합니다. 국내 PG사의 공개 안내는 매일 23시 59분 59초에 그날의 카드 승인을 마감하고 자정부터 매입 작업을 시작한다고 적고 있습니다(토스페이먼츠 공개 문서, 2026년 8월 확인 기준). 이 값은 카드사·매입사·PG사와의 계약에 따라 달라집니다. 소비자 쪽에서 "당일 취소가 빠르다"는 말이 도는 이유가 이 하루라는 단위에 있습니다.

1편에서 본 매입 상태 필드에 CANCEL_REQUESTEDCANCELED가 따로 들어 있는 것도 같은 사정입니다. 매입을 되돌리는 일이 별개의 상태로 관리되어야 할 만큼, 매입 전과 후는 다른 세계입니다.

Recap

  • 승인은 한도를 잡아 둔 약속이고 매입은 대금 채권이 확정되는 단계이므로, 취소의 성질은 요청이 이 둘 사이 어디에 떨어졌는지로 갈립니다.
  • 매입 전 취소가 승인취소, 매입 후 취소가 매출취소(환불)입니다. 문서에 따라 매입취소라고도 부릅니다.
  • 그 경계인 매입 마감 시각은 카드사·매입사·PG사와의 계약에서 정해지는 관행값입니다.


2. 취소는 원 거래를 지우지 않는다

취소했으니 그 거래는 없어졌다는 감각은 자연스럽지만, 결제 시스템은 그렇게 동작하지 않습니다. 취소는 원 거래 레코드를 고쳐 쓰지 않습니다. 원 거래를 가리키는 새 거래를 하나 만듭니다.

공개된 연동 문서의 응답 필드가 이 사실을 그대로 드러냅니다. 나이스페이먼츠의 취소 API는 성공하면 취소 응답 TID인 cancelledTid를 돌려주는데, 매뉴얼은 부분취소에서 이 값이 원 거래의 tid와 다른 값으로 응답된다고 적어 둡니다. 토스페이먼츠는 부분취소를 여러 번 하면 결제 객체의 cancels 필드에 취소 객체가 여러 개 쌓이고, 각 취소가 자기 transactionKey를 가집니다. 취소 한 건이 거래 한 건만큼의 무게를 갖는다는 뜻입니다.

법 쪽에도 이유가 있습니다. 전자금융거래법은 거래 내용을 추적·검색하고 오류를 확인·정정할 수 있는 기록을 만들어 보존하도록 요구합니다.

전자금융거래법 제22조(전자금융거래기록의 생성ㆍ보존 및 파기) ① 금융회사등은 전자금융거래의 내용을 추적·검색하거나 그 내용에 오류가 발생할 경우에 이를 확인하거나 정정할 수 있는 기록(이하 이 조에서 "전자금융거래기록"이라 한다)을 생성하여 5년의 범위 안에서 대통령령이 정하는 기간동안 보존하여야 한다.

원 거래를 지워 버리면 추적할 대상이 사라집니다. 취소가 별도의 기록으로 쌓이는 구조는 이 의무와 맞물려 있습니다.

회계도 오래전부터 같은 습관을 갖고 있습니다. 잘못 적은 전표를 지우지 않고 반대 방향의 분개를 하나 더 얹어 상계합니다(지출 하나는 어떻게 전표가 될까요?). 취소 전표가 하는 일이 정확히 그것입니다.

그래서 소비자가 보는 화면이 갈립니다. 매입 전에 승인취소로 끝난 건은 청구 대상이 되기 전에 정리되므로 청구서에 오르지 않습니다. 매입 후 매출취소는 매출 전표와 취소 전표가 둘 다 매입되므로, 결제 한 줄과 취소 한 줄이 나란히 남거나 다음 청구분에서 차감되는 형태로 나타납니다.

Recap

  • 취소는 원 거래를 수정하지 않고 원 거래를 가리키는 새 거래를 만드는 일입니다. PG 문서의 cancelledTid, transactionKey 같은 필드가 그 흔적입니다.
  • 전자금융거래법 제22조는 추적과 정정이 가능한 기록을 만들어 보존하도록 요구하므로, 원 거래를 지우는 설계로는 그 의무를 지킬 수 없습니다.
  • 승인취소는 청구서에 오르기 전에 끝나고, 매출취소는 결제와 취소가 둘 다 기록으로 남습니다.


3. 응답이 오지 않았다: 망취소

여기까지는 취소를 요청한 쪽이 무엇을 되돌릴지 알고 있었습니다. 결제 연동에는 그것조차 모르는 상태가 있습니다.

가맹점 서버가 승인을 요청했는데 응답이 돌아오지 않았습니다. 타임아웃이 났거나 그 사이 회선이 끊겼습니다. 이때 확실한 것은 요청을 보냈다는 사실뿐입니다. 요청이 카드사에 닿지 않았을 수도 있고, 닿아서 승인까지 났는데 응답만 오다가 끊겼을 수도 있습니다. 뒤쪽이라면 회원의 한도는 이미 잡혀 있고 가맹점만 그것을 모릅니다. KICC의 공개 개발자 문서도 타임아웃을 요청은 갔는데 응답이 오다가 끊긴 경우일 수 있다고 설명하면서, 통신장애 오류코드 TP01에 대해 망취소 처리가 이뤄진다고 안내합니다.

이 불확정 상태를 "승인되지 않음"으로 확정하는 절차가 망취소(網取消)입니다. 망(網)은 통신망을 가리킵니다. 통신 때문에 생긴 취소라는 이름입니다.

나이스페이먼츠의 공개 매뉴얼은 조건을 좁게 적어 둡니다. 네트워크 순단이나 HTTP 클라이언트의 read timeout으로 승인 결과가 불확실할 때 망취소 API를 호출하고, 승인 요청과 응답 수신 처리에 실패한 경우에만 망취소를 요청하도록 권장합니다. 유효기간도 짧아서, 같은 문서는 한 시간을 넘기면 실패한다고 적고 있습니다(2026년 8월 확인 기준).

조건이 이렇게 좁은 이유는 망취소가 하는 일이 승인취소와 다르기 때문입니다. 승인취소는 존재를 확인한 승인을 지웁니다. 망취소는 존재하는지 모르는 승인을 없는 상태로 확정합니다. 그러니 지목하는 방법도 달라집니다. 승인 응답을 받지 못했으니 승인번호도 거래고유번호도 손에 없고, 남은 단서는 요청할 때 가맹점이 붙인 주문번호뿐입니다. 나이스페이먼츠의 망취소 API가 필수 파라미터로 주문번호 하나만 요구하는 것이 그래서입니다.

불확정 상태를 오래 두면 그 승인이 그날 마감을 타고 매입으로 넘어갑니다. 그러면 되돌릴 대상이 승인에서 매출로 바뀌고, 1절의 경계를 넘어섰으므로 매출취소로 처리해야 합니다. 망취소를 쓸 수 있는 시간이 짧은 것은 이 경계 안에서만 유효한 절차라는 뜻입니다.

망취소 전에 조회가 있다

국내 PG사 문서는 망취소를 영어로 net cancel이라 옮기고, API 이름도 대개 netcancel 계열입니다. 한편 KICC 문서는 타임아웃이 났을 때 거래상태 조회 API로 실제 상태를 먼저 확인하라고 안내합니다. 두 가지가 경쟁하는 방법은 아닙니다. 조회가 되면 조회로 확정하는 것이 정확하고, 조회조차 닿지 않을 때 남는 수단이 망취소입니다. 순서를 가진 한 절차의 두 단계로 보면 됩니다.

Recap

  • 승인을 요청하고 응답을 받지 못한 상태는 실패가 아니라 불확정입니다. 카드사 쪽에는 승인이 서 있을 수 있습니다.
  • 망취소는 그 불확정을 승인되지 않은 상태로 확정하는 보상 절차이며, 승인 응답 수신에 실패한 경우로 용도가 한정됩니다.
  • 승인번호가 없으니 주문번호로 거래를 지목하고, 유효 시간이 짧습니다. 시한을 넘기면 매입을 타고 넘어가 매출취소가 됩니다.


4. 같은 요청이 두 번 도착하면

통신 실패에는 반대쪽 얼굴이 있습니다. 응답을 받지 못한 가맹점 서버가 재시도를 하는 경우입니다. 첫 요청이 실제로는 승인까지 났다면, 재시도는 같은 결제를 두 번 승인시킵니다. 3절의 망취소가 "했는지 모르는 일을 없던 것으로" 만드는 장치였다면, 여기서 필요한 것은 "이미 한 일을 두 번 하지 않게" 만드는 장치입니다.

그 성질의 이름이 멱등성(idempotency)입니다. 같은 요청을 몇 번 보내도 결과가 첫 번째와 같아야 한다는 뜻이고, 이를 가능하게 하는 것은 요청에 붙는 식별자입니다. 서버가 두 요청을 같은 요청으로 알아볼 근거가 없으면, 재시도와 별개의 두 건을 구분할 방법이 없습니다.

토스페이먼츠는 이것을 헤더로 노출합니다. 모든 POST API에 Idempotency-Key 헤더를 붙일 수 있고, UUID처럼 충분히 무작위한 고유값을 쓰며 길이는 최대 300자입니다. 멱등키에 API 키·요청 주소·HTTP 메서드 조합까지 같은 요청이 다시 오면 첫 요청과 같은 응답이 돌아옵니다. 키의 수명은 처음 쓴 날부터 15일입니다(2026년 8월 확인 기준).

식별자를 헤더로 두지 않고 주문번호로 대신하는 방식도 있습니다. 같은 주문번호로 승인이 다시 들어오면 거절하는 것입니다. 토스페이먼츠의 공개 에러 코드 목록에 DUPLICATED_ORDER_ID("이미 승인 및 취소가 진행된 중복된 주문번호입니다")가 있는 것이 그 장치입니다. 취소 쪽에도 같은 방어가 있어서, ALREADY_CANCELED_PAYMENT("이미 취소된 결제 입니다")는 전액취소를 두 번 보내도 두 번 환불되지 않는다는 뜻입니다.

그런데 부분취소에서는 이 방어가 그대로 통하지 않습니다. 11만 원 결제에 3만 원 부분취소를 두 번 보내면 6만 원이 취소되는데, 두 요청 모두 그 자체로는 정당하고 이미 취소된 결제라는 판정에도 걸리지 않습니다. 그래서 포트원의 연동 문서는 취소를 요청할 때 환불 가능 금액을 검증값으로 함께 보내도록 안내합니다. 1만 원짜리 결제에서 이미 1천 원이 환불됐다면 검증값은 9천 원이고, 이 값이 서버가 아는 잔액과 어긋나면 요청이 막힙니다. 잔액이 이미 바뀌었으면 두 번째 요청을 그 지점에서 떨어뜨리는 장치입니다.

Recap

  • 응답을 받지 못한 뒤의 재시도는 중복 승인을 만듭니다. 멱등성은 같은 요청을 여러 번 보내도 결과가 첫 번째와 같다는 성질입니다.
  • 이를 보장하는 것은 요청 식별자입니다. Idempotency-Key 헤더(토스페이먼츠 기준 15일 유효)나 주문번호 중복 거절이 그 역할을 맡습니다.
  • 부분취소는 요청 하나하나가 정당하므로 중복 판정이 통하지 않습니다. 환불 가능 금액을 함께 검증해 잔액이 어긋나면 막는 방식이 쓰입니다.


5. 일부만 되돌리려는데 막히는 이유

부분취소는 취소 가능 금액이라는 잔액을 남깁니다. 전액취소는 거래를 끝내지만 부분취소는 그 잔액을 계속 유지해야 하므로, 원 거래를 여러 갈래로 쪼갤 수 있는 거래에서만 성립합니다.

그래서 부분취소가 막히는 경우가 여럿 있습니다. 포트원이 공개한 목록을 정리하면 이렇습니다(2026년 8월 확인 기준).

막히는 거래막는 근거
복합결제(카드사 포인트 등이 섞인 거래)카드사 정책
해외 카드(VISA · MASTER · JCB)국내 매입사 정책
선불카드 · 기프트카드 · 구매전용카드카드사 정책
법인카드 중 회원이 취소를 막아 둔 경우카드 소유자 설정
에스크로 거래결제수단 제약

첫 줄이 왜 걸리는지는 짐작할 수 있습니다. 카드사 포인트나 쿠폰처럼 원화가 아닌 수단이 한 거래에 섞여 있으면, 3만 원을 되돌릴 때 그 몫을 어느 수단에서 얼마나 빼야 하는지가 거래 정보만으로 정해지지 않습니다. 포트원 문서가 카드사 포인트를 쓴 결제 건에서 일부 카드사만 예외로 남는다고 적어 둔 것도 그 판단이 카드사마다 다르다는 뜻입니다.

금액 구조가 얹힌 거래에는 조건이 하나 더 붙습니다. 토스페이먼츠의 공개 에러 코드 EXCEED_CANCEL_AMOUNT_DISCOUNT_AMOUNT의 메시지는 "즉시할인금액보다 적은 금액은 부분취소가 불가능합니다"입니다. 즉시할인이 붙은 거래에서 취소 금액이 할인금액보다 작으면 막힌다는 뜻입니다.

이 제약들은 모두 카드사와 매입사의 정책에서 나옵니다. 포트원이 막히는 사유 칸에 "카드사 정책"과 "매입사 정책"을 적어 둔 것도 그래서고, 같은 결제수단인데 카드사에 따라 결과가 달라지는 것도 그래서입니다. 연동하는 쪽에서는 부분취소를 항상 가능한 기능으로 가정할 수 없습니다. 막힌 거래에서 금액을 일부만 줄이려면 전액을 취소하고 남길 금액으로 다시 승인하는 길밖에 남지 않습니다.

취소가 끝내 되지 않을 때

전자금융거래법은 이용자에게 오류 정정을 요구할 권리를 주고, 요구를 받은 사업자에게 기한을 정해 답할 의무를 지웁니다.

전자금융거래법 제8조(오류의 정정 등) ① 이용자는 전자금융거래에 오류가 있음을 안 때에는 그 금융회사 또는 전자금융업자에게 이에 대한 정정을 요구할 수 있다.

② 금융회사 또는 전자금융업자는 제1항의 규정에 따른 오류의 정정요구를 받은 때에는 이를 즉시 조사하여 처리한 후 정정요구를 받은 날부터 2주 이내에 오류의 원인과 처리 결과를 대통령령으로 정하는 방법에 따라 이용자에게 알려야 한다.

할부 거래에는 경로가 하나 더 있습니다. 할부거래에 관한 법률 제8조는 소비자의 청약 철회를 두고, 같은 법 제16조(소비자의 항변권) 제2항은 간접할부계약에서 할부가격이 대통령령으로 정한 금액 이상일 때에만 신용제공자에게 할부금의 지급을 거절할 수 있게 합니다. 같은 법 시행령 제11조는 그 금액을 10만 원으로, 신용카드를 사용한 할부거래는 20만 원으로 정하고 있습니다. 가맹점의 취소 처리와는 별개로 소비자가 카드사를 상대로 쓸 수 있는 수단이며, 금액 요건에 미치지 못하는 할부에는 이 경로가 열리지 않습니다.

Recap

  • 부분취소는 취소 가능 금액이라는 잔액을 남기므로, 원 거래를 쪼갤 수 있는 거래에서만 성립합니다.
  • 복합결제·해외 카드·선불카드·에스크로가 막히는 대표적인 경우이고, 막는 근거는 카드사와 매입사의 정책입니다.
  • 즉시할인이 붙은 거래는 취소 금액이 할인금액보다 작으면 막힙니다. 부분취소가 막힌 거래에서 금액을 줄이려면 전액취소 후 재승인밖에 남지 않습니다.


6. 한 건을 끝까지 따라가 보기

11만 원짜리 온라인 결제 한 건을 놓고, 취소 요청이 언제 어떤 상태에서 들어오는지만 바꿔 보겠습니다. 8월 24일 오후 3시에 일시불로 승인이 났고, 이 PG사의 매입 마감은 자정입니다.

취소 요청취소 금액매입취소의 종류남는 기록
승인 응답 수신 실패 (15:00)-망취소승인 1건 + 망취소 1건
당일 17:00110,000승인취소승인 1건 + 승인취소 1건
8월 26일110,000매출취소매출 전표 + 취소 전표
8월 26일30,000부분취소매출 전표 + 취소 전표. 잔액 80,000
8월 26일 (카드사 포인트를 섞어 결제했다면)30,000부분취소 불가(카드사에 따라)전액취소 + 재승인 80,000

첫 줄은 취소를 결심한 사람이 아무도 없는 경우입니다. 응답이 오지 않았을 뿐이고, 승인이 났는지는 가맹점도 모릅니다. 얼마를 취소한다고 적을 수도 없으니, 손에 있는 주문번호 하나로 망취소를 호출해 한 시간 안에 정리합니다. 승인이 실제로 났었다면 그것이 지워지고, 나지 않았다면 지울 것이 없다는 답이 돌아옵니다. 어느 쪽이든 결과는 승인되지 않은 상태로 같아집니다. 회원 화면에는 승인 문자와 취소 문자가 잇달아 도착할 수 있습니다.

두 번째 줄은 마감 전이라 되돌릴 것이 약속뿐입니다. 한도가 풀리고, 이 건은 매입으로 넘어가지 않으니 청구서에 오르지 않습니다.

세 번째 줄은 자정을 넘겼습니다. 같은 11만 원, 같은 전액 취소인데 성질이 달라져 취소 전표가 새로 매입돼야 합니다. 명세서에는 11만 원 결제와 11만 원 취소가 둘 다 남고, 청구서 마감이 사이에 끼면 취소가 다음 달로 밀립니다. 정산에서는 이미 지급된 대금을 되돌리는 조정이 붙습니다.

네 번째 줄에서 처음으로 잔액이 생깁니다. 3만 원이 취소되고 취소 가능 금액 8만 원이 남습니다. 이 잔액을 두 번 건드리지 않으려고 요청에 검증값을 얹는 이야기가 4절의 내용이었습니다.

다섯 번째 줄은 같은 3만 원인데 결제 수단 구성이 달라져 길이 막힙니다. 카드사 포인트가 섞인 복합결제이고 그 카드사가 부분취소를 막아 두었다면, 11만 원을 전액 취소하고 8만 원으로 다시 승인해야 합니다. 소비자가 실제로 부담하는 금액은 8만 원으로 같지만 기록은 세 건이 되고, 재승인의 승인일은 8월 24일에서 8월 26일로 옮겨 갑니다. 이 이틀은 가맹점 쪽 매출 인식 시점을 옮깁니다. 그 이야기는 카드 매출은 어떻게 장부와 세금이 될까요?에서 이어집니다.

같은 금액, 같은 카드인데 취소가 다섯 갈래로 갈렸습니다. 갈림길에 놓인 것은 취소 사유도 취소 금액도 아니었습니다. 요청이 승인과 매입 사이 어디에 떨어졌는지, 그리고 그 순간 요청하는 쪽이 무엇을 알고 있었는지였습니다. 도입부의 질문에도 이제 답할 수 있습니다. 취소가 되돌린 것은 거래가 아니라 그 거래에 대한 약속이거나 그 거래로 생긴 채권이고, 거래 자체는 취소 기록과 함께 그 자리에 남아 있습니다.

Recap

  • 같은 금액의 전액 취소라도 마감 전이면 승인취소, 마감 후면 매출취소입니다. 성질을 정하는 것은 요청 시각과 매입의 관계입니다.
  • 승인 결과를 모르는 채 되돌리는 경우만 망취소이고, 지목 수단은 주문번호이며 시한이 짧습니다.
  • 부분취소가 막히면 전액취소 후 재승인으로 우회하는데, 승인일이 옮겨지므로 매출 인식 시점까지 함께 바뀝니다.


References

좋은 사람들과 재미있는 일을 하며 열정적이고 즐겁게 살고 싶은 개발자