결제 라우터 제거로 PG 의존 흐름 전면 정리
목차
레거시 라우터 하나를 제거했는데, 결국 시스템 전체 결제 흐름을 다시 그린 작업이 됐다.
배경: 왜 PgPaymentRouter가 문제였나
PgPaymentRouter는 아마 처음 도입될 때 그럴듯한 이유가 있었을 거다. 여러 PG사를 동적으로 선택해야 할 때, 라우터 하나가 분기 로직을 다 가져가는 구조는 꽤 직관적으로 보인다. 그런데 이런 클래스는 시간이 지나면서 조건 분기가 쌓이고, 결국 "이게 왜 여기 있지?"를 설명하기 어려운 코드가 된다.
이번에 건드린 파일은 charge, order, partner, member, co/order, co/payment — 결제 흐름과 연관된 거의 모든 웹 레이어였다. 어떤 단일 컴포넌트 하나만 고친 게 아니라, 이 라우터에 의존하던 여섯 개 맥락이 전부 영향을 받았다는 뜻이다. 거꾸로 말하면 PgPaymentRouter가 그만큼 여러 곳에 걸쳐 있었다는 거고, 그게 제거를 미뤄온 이유이기도 했을 거다.
작업 내용
크게 세 가지를 동시에 진행했다.
| 작업 | 내용 | 주요 영향 범위 |
|---|---|---|
| PgPaymentRouter 제거 | 레거시 라우터 클래스 삭제 | charge / order / partner 레이어 |
| Provider 단일화 | 분산된 PG Provider 접근 방식을 하나로 정리 | co/payment, co/order |
| silent 폴백 안티패턴 제거 | 예외를 삼키는 fallback 로직 정리 | member, co/member |
Provider 단일화는 라우터 제거의 자연스러운 후속 작업이다. 라우터가 사라지면 각 호출 지점이 Provider를 직접 참조하거나, 아니면 단일화된 진입점을 통해서 접근하거나 둘 중 하나다. 여기서 "그냥 각자 직접 쓰자"를 선택하면 라우터를 없앤 의미가 없어진다. Provider를 단일화해서 의존 방향을 정리하는 게 맞는 방향이었다.
가장 신경 쓴 건 silent 폴백 정리였다.
// 안티패턴: 예외를 삼키고 기본값으로 조용히 넘어감
try {
return pgProvider.resolve(paymentType);
} catch (Exception e) {
log.warn("provider resolve failed, fallback to default");
return defaultProvider; // 이게 문제
}
이 패턴이 왜 위험하냐면, 결제 맥락에서는 "기본값으로 넘어감"이 그냥 UX 문제가 아니라 잘못된 PG사로 요청이 흘러가는 문제가 될 수 있다. 장애가 발생해도 겉으로 정상처럼 보이다가, 한참 뒤에 정산 불일치로 터지는 유형이 딱 이거다. silent fallback은 모니터링도 안 잡히고, 알람도 안 오고, 로그도 warn 한 줄로 끝난다.
// 수정 후: 예외를 명시적으로 올려서 호출자가 판단하게
return pgProvider.resolve(paymentType);
// resolve 실패 시 예외 전파 → 상위에서 처리
팀 관점 회고
이런 작업은 혼자 결정하기 어렵다. 여섯 개 컨텍스트를 동시에 건드리면 리뷰어한테도 부담이 크고, "이거 지금 꼭 해야 해요?"라는 질문이 나올 수밖에 없다. 내가 이 작업을 묶어서 한 번에 진행한 이유는 PgPaymentRouter 제거와 Provider 단일화, silent 폴백 정리가 서로 연동된 작업이라 쪼개서 하면 중간 상태가 더 위험했기 때문이다.
- 라우터만 지우고 Provider 정리를 미루면 → 임시 직접 참조 코드가 생김
- Provider 단일화만 하고 silent 폴백을 남기면 → 단일화된 Provider가 조용히 실패하는 구조가 유지됨
- 세 가지를 묶어야 비로소 "결제 어댑터가 명확한 실패 경로를 가진다"는 상태가 됨
코드 리뷰에서는 변경 파일 목록을 먼저 보여주면서 "이 여섯 군데가 모두 같은 맥락"임을 설명하는 데 시간을 썼다. 파일 수가 많다고 커밋을 여러 개로 쪼개면 오히려 리뷰어가 맥락을 잃는다. 변경의 의도가 하나면, 커밋도 하나가 맞다.
레거시 라우터 하나를 지우는 데 여섯 파일이 따라온다는 게 이 시스템이 그동안 어느 정도로 결합되어 있었는지를 잘 보여준다. 정리하고 나서는 오히려 각 레이어가 결제 Provider에 어떻게 의존하는지가 명확하게 보인다. 그게 이번 작업의 진짜 성과다.
다음은 이 Provider 단일화 이후 각 레이어별 통합 테스트 커버리지를 보강하는 작업이 이어진다.
🛒 이 글과 어울리는 추천 상품
*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.
댓글 0
첫 댓글 달아줘.