32,000건의 프리세일 주문. 녹색으로 빛나는 OMS 대시보드: 재고 있음. 그리고 아무도 모델링하지 않은 4일 지연으로 롱비치항 밖에 정박해 있는 입고 컨테이너. 2021년 블랙프라이데이를 사흘 앞둔 시점, 내가 함께 일했던 뷰티 툴 브랜드가 마주한 상황이었다. 사태가 수습되고 나니 2,800건이 출고되지 못했다. 환불, 재배송, 마켓플레이스 페널티로 $60,000 이상이 날아갔다 — 블랙프라이데이 마진 전체가 일주일 만에 사라진 것이다.

그 통화에서 나는 질문 하나를 던졌다. "판매 가능 수량에 입고 예정 재고가 포함되어 있습니까?" 3초의 침묵. 그리고 대답: "아마 들어 있을 겁니다." 그게 문제의 전부였다.

판매 가능 수량과 실재고는 다른 것이다. 프리세일 러시 기간에 그 둘의 간격은 생사가 갈리는 선이다.

다섯 개의 버킷, 하나의 계산식

많은 OMS 화면은 '재고'라는 숫자 하나만 보여준다. 나는 그런 화면을 충분히 열어봤기에 앙다. 그 숫자는 보통 실재고에 입고 예정을 더하고 예약을 뺀 뒤섞인 값이다. 이 계산은 비수기에는 무해하다. 입고 예정이 예측 가능하고 며칠의 오차가 문제가 되지 않기 때문이다. 프리세일은 다르다. 입고가 제때 도착한다는 내기 위에, 내일의 재고를 오늘 팔고 있는 것이다.

2021년 당시 롱비치의 혼잡으로 컨테이너 일주일 지연은 일상이 되었다. 입고 예정을 판매 가능하다고 세는 것은 항구가 막히지 않을 것이라는 도박이었다.

나는 OMS에 최소 다섯 개의 버킷을 둔다.

실재고: 입고 완료, 진열 완료, 피킹 가능. 입고 예정: 출고 완료, 미입고 — 돈은 나갔고, 물건은 아직 손에 없다. 할당: 주문에 묶였고, 아직 피킹되지 않음. 동결: 의도적으로 잠근 재고 — 프리세일 전용, 품질 보류, 고객 지정 로트. 안전재고: 하한선. 손대지 마라.

정확한 계산식은 단 하나다: 판매 가능 수량 = 실재고 − 할당 − 동결 − 안전재고. 입고 예정은 이 계산식에 들어가지 않는다.

실재고 5,000, 입고 예정 8,000, 할당 1,200, 동결 2,000, 안전재고 500인 SKU를 보자. 판매 가능 수량 = 5,000 − 1,200 − 2,000 − 500 = 1,300. 화면에 13,000(실재고 + 입고 예정 − 할당)이 뜬다면, 오늘 주문에 대해 미래 재고 11,700개를 팔고 있는 셈이다. 컨테이너 하나만 늦어도 초과 판매가 폭발한다.

그럼 입고 예정은 어디에 쓰는가. 별도의 프리세일 풀에 쓴다. 프리세일 상품 페이지는 이 풀에서만 차감하고, 스팟 판매 가능 수량에는 절대 손대지 않는다. 풀 수준 = 확정 입고 예정 × 신뢰도 계수. 계수는 공급업체 실적에 따라 정한다. 납기 준수율 95% 이상인 공급업체는 0.9, 만성적으로 3~5일 늦는 곳은 0.6, 신규 공급업체는 0 — 실적을 증명하기 전까지는 프리세일 권한이 없다. 프리세일이 파는 것은 '확실성'이다. 계수는 당신의 정직함 점수다.

프리세일이 재고를 먹는 순서

프리세일은 미래의 실재고를 앞당겨 파는 것이다. 그래서 프리세일과 스팟 재고는 두 개의 풀에 살며, 물리적으로 분리되고, 절대 섞이지 않는다.

순서는 이렇다. 프리세일 주문은 먼저 프리세일 풀에서 차감한다. 입고 예정이 도착해 실재고로 바뀌면 프리세일 풀을 다시 채운다. 스팟 주문은 스팟 판매 가능 수량에서만 차감하고, 프리세일 풀에는 절대 손대지 않는다. 그리고 프리세일 주문이 스팟 재고를 직접 먹는 일도 없다.

왜 이렇게 엄격해야 하는가? 2022년 프라임데이 때 내 아웃도어 용품 고객사는 프리세일과 스팟을 하나의 풀로 돌렸다. 프리세일이 풀을 쓸어갔고, 스팟 주문이 들어왔을 때는 피킹할 수 있는 게 아무것도 없었으며, 고객 서비스가 일주일 내내 몷매를 맞았다. 두 개의 풀로 나누면, 프리세일이 매진되어도 스팟 본업에는 손대지 않는다 — 최악의 경우 프리세일 리스팅을 닫으면 핵심은 계속 돌아간다.

동결 타이밍도 중요하다. 프리세일 시작 전에 해당 재고를 동결한다. 동결 수량 = 계획 프리세일 물량 + 쿠션. 쿠션은 계획 물량의 10–15%를 쓰고, 취소와 파손을 커버한다. 그리고 동결은 반드시 시스템 기록이어야 한다 — 누가, 얼마를, 언제 해제하는지. '구두 동결'이 살인 문구다. 누군가 채팅방에서 "이 로트는 손대지 마세요"라고 말하고, 아무도 시스템에 입력하지 않으면, 스팟 주문이 그걸 먹어버린다.

취소에도 명확한 해제 경로가 필요하다. 취소된 프리세일 주문은 먼저 프리세일 풀로 재고를 되돌리고, 프리세일 풀이 가득 찼을 때만 스팟으로 넘친다. 바로 스팟으로 보내면, 아직 들어올 주문들을 위해 프리세일 풀이 말라버린다.

성수기에 포장 스테이션에서 소포를 스캔하는 창고 작업자

숫자가 새겨진 킬 스위치

모든 계산식은 가끔 틀린다. 그래서 최후의 방어선은 서킷 브레이커다. SKU의 판매 가능 수량이 임계값 아래로 떨어지면, 시스템이 자동으로 제한하거나 리스팅을 내리고, 사람의 검토만이 복구할 수 있다.

임계값은 어떻게 정하는가? 나는 두 단계를 쓴다. 프리세일 SKU는 계획 프리세일 물량의 5%에서 트립 — 20,000개 계획이라면 판매 가능 1,000개 남았을 때 자동 중단. 스팟 SKU는 평균 일 판매량의 2~3일분에서 트립. 절대 0으로 설정하지 마라. 0은 브레이커가 없다는 뜻이다. 시스템은 양수에서 음수로 직행하고, 반응할 시간이 없다.

또 하나의 함정. 브레이커는 스토어프론트 주문은 막지만, 고객 서비스의 수동 주문은 막지 못한다. KPI를 지키려고 담당자가 초과 판매 중인 SKU의 주문을 손으로 입력했고, 초과 판매는 그대로 일어났다. 브레이커는 수동 주문 입력도 커버해야 한다 — 최소한 강한 확인을 띄워야 한다.

트립 후 복구 절차는 문서화해 둬야 한다. 누가 리스팅을 복구할 수 있는지, 어떤 숫자부터 대조할지, 영향을 받은 고객에게 연락할지. 최악의 패턴은 숫자가 아직 틀렸는데 담당자가 가볍게 '판매 재개'를 클릭하는 것이다 — 한 시간에 세 번 트립하면 고객은 영원히 떠난다.

쓰라린 부분은 여기다. 초과 판매의 비용은 환불보다 크다. 마켓플레이스 페널티, 추락한 셀러 평점, 태워버린 광고비 — 합치면 보통 상품 가치의 몇 배가 된다. 그 $60,000 중 환불은 절반도 안 됐다. 나머지는 보상과 잃어버린 재구매 사업이었다. 초과 판매 1건이 그 고객의 3년치 재구매를 앗아갈 수 있다.

그러니 팀에 던지는 질문이다. 내일부터 베스트셀러 SKU의 입고가 일주일 늦어진다면, 누군가 눈치채기 전에 몇 건을 초과 판매하겠는가? 10초 안에 답할 수 없다면, 계산식을 손봐야 한다.

영어판 번역본입니다. 내용이 다를 경우 영어판을 우선합니다.