에스크로는 구매자가 결제한 대금을 토스페이먼츠가 보관하고 있다가, 배송과 구매확정이 끝나면 상점에 지급하는 구매자 보호 서비스예요. 에스크로에 대한 추가 설명은 링크를 참고하세요. 해당 페이지는 에스크로 결제를 API로 조회하고, 배송 정보를 등록·수정하고, 구매자의 취소 요청을 수락하고, 구매확정 요청 메일을 다시 보내는 방법을 설명해요.
에스크로 상세 API 레퍼런스는 부가 API 에스크로에서, 웹훅 이벤트는 웹훅 이벤트 에스크로에서 확인하세요.
| 노드 | 상태 |
|---|---|
| 5a. 구매확정 | status=CONFIRMED · confirmType=CUSTOMER |
| 5b. 자동확정 | status=CONFIRMED · confirmType=AUTO |
| 5c. 취소 요청 | status=CANCEL_REQUESTED |
| 6a. 취소 확정 | status=CANCELED · cancelType=CUSTOMER |
- 에스크로 결제가 승인되면 결제 응답의
escrowKey를 상점 DB에 보관하세요. 이후 모든 에스크로 요청을 이 값으로 보내요 — 이 값이 에스크로 거래의id예요. 상품 정보는 결제할 때 보낸escrowProducts로 이미 들어와 있어서 에스크로 API로 상품을 따로 등록하지 않아요. 결제 1건에 배송할 상품이 1개라면escrowProducts를 보내지 않아도 Payment 객체의orderId와orderName을 기반으로 상품 정보가 자동 생성돼요. 배송할 상품이 여러 개로 나뉘는 경우에만escrowProducts로 명시해주세요. - 상품을 발송하면 배송 등록 API를 호출하세요. 상품마다 한 건씩이에요. 모든 상품이 배송완료되면 자동확정 기한이 시작돼요.
- 구매확정은 구매자가 해요. 확정 API는 없어요. 구매자가 확정하거나 기한이 지나 자동확정되면
escrow.changed웹훅과 조회 API의status=CONFIRMED로 알 수 있어요. - 구매자가 취소를 신청하면(
status=CANCEL_REQUESTED) 취소 요청 수락 API로 수락하거나, 구매확정 요청 메일 재발송 API로 구매자에게 확정을 다시 요청하세요.
거래 상태가 바뀌면 escrow.changed, 배송이 등록·변경되면 delivery.changed 웹훅이 발송돼요.
에스크로 결제는 결제(Payment) 객체에 escrowKey 필드가 실려요. 결제 승인 응답과 결제 조회 응답 모두에서 받을 수 있어요. 이 값이 에스크로 거래의 id예요 — 그대로 GET /v2/escrows/{id}에 넣으면 돼요.
- 에스크로 결제가 아니면
escrowKey가null이에요. 에스크로 사용 여부 판별은useEscrow로 하세요 —escrowKey의 null 여부로 판별하면 안 돼요. useEscrow: true인데escrowKey가null일 수 있어요. 가상계좌 입금 전에는 에스크로 거래가 아직 개설되지 않아 키가 없어요. 입금 후 결제를 다시 조회하면 채워져요.
거래는 4개 상태로 흘러가요. status로 상점의 할 일이 정해져요.
| 상태 | 의미 | 상점의 할 일 |
|---|---|---|
IN_PROGRESS | 결제 완료·확정 전 | 배송 등록 여부 확인 |
CANCEL_REQUESTED | 구매자가 취소 신청, 수락 판단 대기 | 취소 수락 또는 확정요청 재발송 |
CONFIRMED | 구매확정 완료 | 없음 |
CANCELED | 취소 확정 (종결) | 없음 |
- 종결 상태는
CANCELED하나예요. 드물게 확정 직후 결제가 취소되면CONFIRMED뒤에CANCELED가 올 수 있어요. - 어떻게 끝났는지는
confirmType·cancelType으로 봐요. 특히CANCELED는 상점이 취소를 수락한 거래(cancelType=CUSTOMER)와 대상 결제가 취소되어 끌려 종결된 거래(cancelType=TARGET_CANCELED)가 섞여 있어서 집계할 때 둘을 한데 묶지 마세요.
- 상품:배송 = 1:1이에요. 상품이 여러 개면 상품 수만큼 배송 등록 API를 여러 번 호출하세요. 상품을 여러 개 등록하려면 결제 요청의
escrowProducts로 전달하세요. 결제 1건에 배송 상품이 1개인 일반적인 경우에는escrowProducts를 보내지 않아도 Payment 객체의orderId와orderName을 기반으로 에스크로 상품 정보가 자동으로 생성돼요. - 에스크로 거래 조회 응답의
products[].id를 배송 등록 요청의targetId에 그대로 넣어요(targetType: ESCROW_PRODUCT). - 에스크로 거래 조회 응답의
deliveryIds는 등록된 배송 리소스의 ID 목록이에요.products보다 개수가 적으면 아직 등록할 배송이 남은 거예요. - 배송 상태는 두 가지예요.
IN_TRANSIT— 택배로 등록되고 배송추적이 시작된 상태COMPLETED— 배송완료 (택배는 추적이 완료 판정 / 직접 전달은 등록 즉시)
- 배송 방법은 두 가지예요.
SHIPMENT— 택배. 등록 시 배송추적이 시작돼요. 택배사 코드 목록에서 지원 택배사를 확인하세요.DIRECT— 직접 전달. 등록 즉시COMPLETED처리돼요.
구매자가 확정하지 않아도 기한이 지나면 자동으로 구매확정돼요(status=CONFIRMED·confirmType=AUTO).
- 기한은 거래의 모든 상품이 배송완료된 시점부터 기산돼요. 하나라도 등록되지 않았거나 배송중이면 기한이 시작되지 않아요.
- 기한은 영업일 기준(공휴일 제외)으로 계산되고, 며칠인지는 상점 계약에 따라 달라요.
- 기한이 지난 거래는 배치가 확정해요. 기한 도래 즉시가 아니라 하루 단위로 처리돼요.
- 취소 요청 중인 거래는 자동확정되지 않아요. 기한이 지나도 멈춰 있어요 — 취소 요청을 수락하거나, 구매확정 요청 메일을 재발송해 구매자가 확정하게 하세요.
- 기한 시각 자체는 API로 노출되지 않아요.
- 에스크로 거래는 진행 중 부분취소가 불가해서 전액 취소예요. 금액을 지정하지 않아요. 결제 취소 API로도 부분취소가 거절돼요. 부분취소는 구매확정 이후에만 가능해요.
- 환불 계좌는 구매자가 취소 요청 과정에서 직접 등록한 계좌를 써요. 상점이 전달하지 않고 응답에도 노출되지 않아요.
- 상점이 취소 요청을 반려하는 경로는 없어요. 선택지는 수락 또는 미조치예요. 대신 구매확정 요청 메일 재발송 API로 구매자에게 확정을 다시 요청할 수 있어요.
- 상점이 먼저 취소하려면 결제 취소 API를 쓰세요. 그 경로로 끝난 거래는
cancelType=TARGET_CANCELED로 남아요.
test_sk_키 결제는 택배사 실연동 없이 처리돼요. 배송추적은 테스트용 동작이에요.- 응답과 웹훅은 실제와 동일한 형태로 내려와요.
구매자 메일은 실제로 발송돼요 — 테스트 환경이어도 구매확정 요청 메일 등은 입력한 구매자 이메일 주소로 실제 발송돼요. 테스트할 때는 구매자 이메일에 받아볼 수 있는 주소를 넣으세요.
- 에스크로 결제 판별은
useEscrow로 하세요.escrowKey가null이어도 에스크로 결제일 수 있어요(가상계좌 입금 전). - 입금 전 에스크로 조회는 404예요. 가상계좌 결제는 입금이 완료되어야 에스크로 거래가 개설돼요.
- 배송 수정 API는 송장 정정·직접 전달 전환만 가능해요.
DIRECT로 등록한 배송은 즉시 완료 상태라 수정이 항상 막혀요. 잘못 등록해 완료된 건은 고객센터로 문의하세요. - 송장 정정은 웹훅이 발송되지 않아요. 배송 상태가
IN_TRANSIT에서 변하지 않기 때문이에요. 송장 정보가 중요한 시점에는 배송 조회 API로 확인하세요. - 구매확정 요청 메일은 24시간 쿨다운이 있어요. 발송 대기 중이거나 마지막 발송 후 24시간이 지나지 않았으면
403 FORBIDDEN_RECENT_CONFIRM_REQUEST로 막혀요.