우체국 계좌 검증 오류와 잘못된 실패 메시지 개선
목차
우체국 계좌 검증, 왜 자꾸 터졌나
파트너 출금 요청 흐름에서 우체국 계좌만 유독 실패율이 높았음. 다른 은행은 깔끔하게 통과하는데 우체국 쪽만 검증 단계에서 5xx 가 떨어지거나, 응답을 받았는데도 내부 파싱에서 NPE 가 나는 경우가 잦았음.
원인을 추적해 보니 두 가지가 겹쳐 있었음.
- 외부 검증 API 의 응답 스키마가 케이스별로 달랐음. 정상/실패/점검 시점마다 필드 구성이 다른데, 우리 쪽은 "정상" 한 가지만 가정하고 짠 코드.
- 검증 서버 자체가 간헐적으로 5xx 를 뱉는데, 그걸 그대로 사용자에게 노출. 사용자는 "내 계좌가 잘못됐나?" 오해하고 CS 로 들어옴.
이번에 손본 부분
| 구분 | 변경 전 | 변경 후 |
|---|---|---|
| 응답 파싱 | 정상 스키마만 가정 | 케이스별 분기 + 누락 필드 방어 |
| 5xx 처리 | 그대로 throw | "일시 점검" 메시지로 매핑 |
| 재시도 | 없음 | 1회 백오프 후 재요청 |
| 로깅 | 메시지만 | 요청·응답 본문 마스킹 후 적재 |
기존엔 한 검증 핸들러에 분기가 다 몰려있어서, 헬퍼로 쪼개고 결과를 enum 으로 강제했음. 호출부에서 분기 누락하면 컴파일이 막히도록.
val outcome = when {
response == null -> UPSTREAM_DOWN
response.code in 500..599 -> UPSTREAM_DOWN
body?.ok == true -> VERIFIED
body?.code in softFailCodes -> RETRYABLE
else -> INVALID
}
사용자 메시지 정리
VERIFIED→ 다음 단계 진행INVALID→ "예금주/계좌번호를 다시 확인" (구체 사유는 숨김, 피싱 우려)RETRYABLE/UPSTREAM_DOWN→ "잠시 후 다시 시도" + 내부 알림- 5xx 가 일정 횟수 누적되면 운영 채널로 자동 알림
기존엔 RETRYABLE 도 INVALID 처럼 보여서, 멀쩡한 계좌인데 사용자가 자기 계좌가 잘못된 줄 알고 새 계좌를 등록하는 사고가 있었음. 지원팀에서 같은 패턴 문의가 반복되길래 이참에 한꺼번에 정리.
회고
- 외부 API 는 "정상 케이스"만 보고 짜면 반드시 터진다. 점검/장애/타임아웃 케이스까지 enum 으로 뽑아두는 게 결국 싸게 먹힘.
- 5xx 를 사용자 메시지로 그대로 흘리면 CS 비용으로 돌아옴. 업스트림 상태와 사용자 메시지는 레이어를 분리해야 했음.
- 응답 본문 로깅은 처음부터 마스킹 정책을 정해두자. 운영 올라간 뒤 빼는 게 훨씬 귀찮음.
- "특정 은행만 실패" 류 이슈는 십중팔구 우리 코드보다 그쪽 응답 변종이 원인. 의심 순서를 바꾸니 디버깅 시간이 절반으로 줄었음.
다음
댓글 0
첫 댓글 달아줘.