교환을 반품으로 바꿔 달라는 요청이 둘 왔다. 하나는 됐고 하나는 실패 팝업이 떴다.
Table of contents
Open Table of contents
증상 — 같은 유형의 두 건
두 건의 반품 상태를 봤다.
건 A collected (회수 완료)
건 B complete (교환 완료)
collected 와 complete 로 서로 달랐다.
같은 유형의 요청인데 화면에서의 결과가 갈린 이유가 여기 있을 것 같았다. 그래서 updateReturnsType 이 이 값을 어떻게 다루는지 봤다.
원인 — 상태별로 갈렸다
전환 로직에 상태 분기가 있었다.
public function updateReturnsType($return, $newType)
{
if ($return->return_status === 'complete') {
return $this->fail('철회 불가');
}
// collected 면 타입 직접 변경
$return->return_type = $newType;
...
}
complete 면 철회 불가로 막고 collected 면 타입을 그대로 바꾼다.
complete 까지 간 건은 되돌릴 수 없으니 그 자리에서 막는 것이 정책상 맞았다. 그런데 건 B 는 철회가 안 되자 반품 신청 자체를 시도했고 거기서도 실패했다.
제약 — 가능 수량과 재출고 항목
반품 신청 검증을 봤다.
$returnableQty = $this->calcReturnableQty($option);
if ($returnableQty <= 0) {
return $this->fail('반품 가능 수량 없음');
}
calcReturnableQty 가 0을 내면 신청이 거부된다.
계산 안쪽에 조건이 하나 더 있었다.
private function calcReturnableQty($option)
{
if (!$option->status75) {
return 0;
}
...
}
원본 옵션의 status75 가 0이면 가능 수량이 0이 된다.
더 보니 조건이 하나 더 있었다. 교환 재출고 항목이 이미 출고 완료 상태였다.
재출고 항목 status 55 (출고 완료)
55 면 그 항목을 먼저 취소해야 한다.
물건이 나갔는데 반품으로 바꾸면 나간 물건의 처리가 안 정해진다. 55 인 항목의 취소가 선행되지 않으면 그것이 어디에도 속하지 않는 상태로 남는다.
전체 흐름 — 셋이 순서였다
조건이 셋이고 순서가 있었다.
1. 반품 상태 확인 → 완료면 직접 처리 필요
2. 재출고 항목 확인 → 출고 완료면 취소 선행
3. 원본 플래그 확인 → 0 이면 가능 수량 0
1 이 통과해야 2 를 보는 순서이고 하나라도 안 맞으면 거기서 막힌다.
그런데 화면에서는 실패만 보인다. 어느 조건에서 막혔는지를 안 알려 주니 운영자는 문의를 넣는 수밖에 없다.
검증 — 셋을 한 번에 뽑는 쿼리
이 유형의 문의를 받으면 셋을 함께 뽑는다.
-- 1. 반품 상태
SELECT return_status FROM order_returns WHERE id = ?;
-- 2. 재출고 항목
SELECT id, status FROM order_item_options
WHERE origin_order_item_option_id = ?;
-- 3. 원본 플래그
SELECT status75 FROM order_item_options WHERE id = ?;
return_status 와 재출고 항목의 status 와 status75 가 한 번에 나온다.
세 값을 나란히 놓으면 어디서 막혔는지가 바로 갈린다. 막힌 자리마다 대응도 달랐다.
1 에서 막힘 → 직접 처리 (정식 경로 불가)
2 에서 막힘 → 재출고 취소 선행
3 에서 막힘 → 플래그 확인. 왜 0 인지 조사
화면의 같은 실패 팝업이 실제로는 세 가지 다른 상황을 덮고 있었다.
대응 — 메시지에 조건을 담기
근본은 실패 팝업이 이유를 안 알려 주는 데 있었다.
[보이는 것] 실패했습니다
[실제] 조건 셋 중 하나에서 막힘
메시지에 조건을 표시하면 문의 자체가 줄어든다.
"교환 완료 상태에서는 철회할 수 없습니다"
"재출고 항목이 출고 완료 상태입니다"
"반품 가능 수량이 없습니다"
같은 실패인데 세 가지로 다르게 안내된다.
회수가 끝나 전환할 수 없다는 것과 수량이 남지 않았다는 것은 받는 쪽에서 할 일이 다르다. 이것을 별도 개선 항목으로 적었다.
정리
- 같은 요청이 상태에 따라 되고 안 된다
- 전환 조건이 여럿이고 순서가 있다
- 반품 상태와 재출고 항목과 원본 플래그 셋을 확인한다
- 하나라도 안 맞으면 막히는데 화면은 실패만 보여 준다
- 진단 쿼리 셋을 한 번에 뽑으면 어디서 막혔는지 나온다
- 같은 실패인데 대응이 셋으로 갈린다
- 메시지에 조건을 표시하면 문의가 준다