✨ 배경
판매자 등록(정산관리) 흐름의 계좌 인증 API 가 프론트에서 아래 응답만 계속 반환한다.
POST https://promptplace.kro.kr/api/settlements/verify-account
{
"error": "AccountVerificationError",
"subCode": "SYSTEM_ERROR",
"message": "일시적인 오류가 발생했습니다. 잠시 후 다시 시도해 주세요.",
"statusCode": 400
}
"잠시 후 다시 시도" 문구 때문에 프론트/사용자 모두 일시적 장애로 오해하고 재시도를 반복하지만, 재시도로는 절대 복구되지 않는다.
✨ 원인 (증상 아님)
Payple 계좌실명조회(POST {HUB}/inquiry/real_name)가 T0310 인증요청 거부 - 등록된 WHITE IP 아닙니다. 를 HTTP 200 으로 반환하고 있다. 운영 크리덴셜로 직접 재현 확인:
POST https://hub.payple.kr/oauth/token → {"result":"T0000", ...} # 성공
POST https://hub.payple.kr/inquiry/real_name → {"cst_id":"promptplace", "result":"T0310",
"message":"인증요청 거부 - 등록된 WHITE IP 아닙니다."}
핵심은 /oauth/token 에는 IP 제한이 없고 /inquiry/real_name 에만 있다는 점이다. 그래서 토큰 발급은 멀쩡히 통과하고 실명조회 단계에서만 거부되며, 로그에도 "인증 실패" 로 보이지 않아 원인 추적이 어렵다.
이 응답이 parseAccountVerificationError 의 마지막 시스템 오류 분기에 그대로 흡수된다.
// src/settlements/utils/payple.ts
if (['N0111','N0199','N0499','T1999'].includes(code) || /^T0\d{3}$/.test(code)) {
return { subCode: 'SYSTEM_ERROR', message: '일시적인 오류가 발생했습니다. 잠시 후 다시 시도해 주세요.' };
}
T0310 이 /^T0\d{3}$/ 에 매칭되면서 영구적인 인프라 설정 오류가 일시적 오류로 위장된다. 결과적으로
- 사용자: 복구 불가능한 오류에 계속 재시도 → 일일 인증 5회 한도(
consumePaypleRateLimit)만 소진.
- 개발자: env 누락 / OAuth 실패 / 네트워크 오류 / IP 차단이 전부 동일한 응답 문자열이라 응답만 보고는 구분 불가.
✨ 개발 목록
✨ 기타
subCode 는 SYSTEM_ERROR 를 유지한다. 프론트 모달 매핑(모달 C)이 이미 이 값을 처리하고 있어 새 subCode 를 추가하면 프론트 대응이 선행돼야 하고, IP 화이트리스트는 어차피 최종 사용자가 조치할 수 있는 문제가 아니다. 사용자 문구만 "고객센터로 문의" 로 정정한다.
- 운영/테스트 서버가 동일 EC2 를 공유하므로(
/opt/app-backup = prod, /opt/app-dev = dev) egress IP 도 동일하다. 한 번 등록하면 양쪽 모두 해소된다.
- 서버에서 실제 코드 확인:
sudo docker logs myapp --since 24h 2>&1 | grep payple
- 같은 HUB 를 쓰는
payple-payout.ts / payple-settlement.ts(정산 cron, 지급이체)도 동일한 WHITE IP 제한을 받는다. IP 미등록 상태면 정산 자동화도 함께 실패하므로 등록 후 cron 결과도 확인 필요.
✨ 배경
판매자 등록(정산관리) 흐름의 계좌 인증 API 가 프론트에서 아래 응답만 계속 반환한다.
"잠시 후 다시 시도" 문구 때문에 프론트/사용자 모두 일시적 장애로 오해하고 재시도를 반복하지만, 재시도로는 절대 복구되지 않는다.
✨ 원인 (증상 아님)
Payple 계좌실명조회(
POST {HUB}/inquiry/real_name)가T0310 인증요청 거부 - 등록된 WHITE IP 아닙니다.를 HTTP 200 으로 반환하고 있다. 운영 크리덴셜로 직접 재현 확인:핵심은
/oauth/token에는 IP 제한이 없고/inquiry/real_name에만 있다는 점이다. 그래서 토큰 발급은 멀쩡히 통과하고 실명조회 단계에서만 거부되며, 로그에도 "인증 실패" 로 보이지 않아 원인 추적이 어렵다.이 응답이
parseAccountVerificationError의 마지막 시스템 오류 분기에 그대로 흡수된다.T0310이/^T0\d{3}$/에 매칭되면서 영구적인 인프라 설정 오류가 일시적 오류로 위장된다. 결과적으로consumePaypleRateLimit)만 소진.✨ 개발 목록
src/settlements/utils/payple.ts—T0310전용 분기 추가, 일시적 오류 버킷에서 분리src/settlements/utils/payple.ts— Payple 실패 로그에result뿐 아니라message도 남겨 재발 시 즉시 식별 가능하게pnpm build확인✨ 기타
subCode는SYSTEM_ERROR를 유지한다. 프론트 모달 매핑(모달 C)이 이미 이 값을 처리하고 있어 새 subCode 를 추가하면 프론트 대응이 선행돼야 하고, IP 화이트리스트는 어차피 최종 사용자가 조치할 수 있는 문제가 아니다. 사용자 문구만 "고객센터로 문의" 로 정정한다./opt/app-backup= prod,/opt/app-dev= dev) egress IP 도 동일하다. 한 번 등록하면 양쪽 모두 해소된다.payple-payout.ts/payple-settlement.ts(정산 cron, 지급이체)도 동일한 WHITE IP 제한을 받는다. IP 미등록 상태면 정산 자동화도 함께 실패하므로 등록 후 cron 결과도 확인 필요.