연락처 입금 상세에 주문·핀코드·입금 로그 매칭 추가
목차
연락처 입금 상세 화면에 매칭된 주문, 핀코드, 입금 로그를 한 번에 보여주는 작업을 했다. 작업 규모 자체는 크지 않았는데, 손대고 나니 운영 측면에서 생각할 거리가 꽤 나왔다.
연락처 송금 흐름 전체를 다시 들여다보면서
기존에도 이 플로우는 돌아가고 있었다. 다만 상세 화면에서 "이 입금 건이 어느 주문과 붙었고, 어떤 핀코드를 거쳤으며, 로그는 어디 있는지"를 한 눈에 볼 수 없었다. 운영팀이 문의 대응할 때마다 주문 테이블, 핀코드 테이블, 로그 테이블을 각각 뒤져야 했던 거다. 이번에 그걸 상세 뷰 하나로 묶었다.
흐름 자체는 이렇다.
입금 알림 수신 (Android 앱)
→ 서버로 원본 메시지 전송
→ 주문 매칭 (금액 + 발신자 + 시간)
→ 은행 핸들러 실행 (Playwright)
→ 로그인 → 수취인 입력 → 이체 → 완료 감지
→ 주문 상태 업데이트
→ 알림 발송
이 중에서 매칭 단계가 핵심인데, 금액만으로 매칭하면 동시에 같은 금액 입금이 들어왔을 때 틀리게 붙는다. 그래서 발신자 식별자와 시간 윈도우를 함께 본다. 시간 윈도우를 너무 좁히면 지연 알림을 놓치고, 너무 넓히면 오매칭 가능성이 올라가는 트레이드오프가 있다.
은행 핸들러는 추상 클래스를 상속받아 은행별로 구현하는 구조다. 은행마다 웹 UI 구조가 달라서 셀렉터가 다 다른데, 이걸 코드에 하드코딩하면 은행 UI 업데이트할 때마다 배포가 필요해진다. 셀렉터를 DB에 캐시해두고 성공한 케이스로 자가학습하는 방식을 붙여둔 게 여기서 힘을 발휘한다. 현장에서 새 셀렉터를 확인하고 DB 업데이트만 해도 핸들러가 다음 실행부터 새 값을 쓰게 된다.
class BankHandler(ABC):
def get_selector(self, key: str) -> str:
cached = self.selector_cache.get(key)
if cached:
return cached
return self.default_selectors[key]
def record_success(self, key: str, selector: str):
self.selector_cache.set(key, selector, ttl=86400)
대략 이런 모양이다. 성공한 셀렉터를 캐시에 남기고, 다음 실행에서 캐시 히트가 나면 그걸 우선 쓴다. 은행이 UI를 조금 바꿔도 한 번만 수동으로 잡아주면 이후는 자동으로 적응한다.
수수료 분배는 유통 계층 구조에 따라 차액을 위로 전달하는 방식이다. 각 계층의 요율 차이가 해당 계층의 수익이 된다. 구조 자체는 단순한데, 계층이 깊어질수록 계산 순서와 반올림 처리가 결과에 영향을 미친다는 게 함정이다.
정산 계산에서 원 단위 처리가 생각보다 중요함
수수료 계산은 금전 관련이라 오류가 나면 바로 신뢰 손상으로 이어진다. 계층별 요율을 다르게 적용하면서 원 단위 올림/버림을 어떻게 처리하느냐가 누적되면 꽤 달라진다.
일반적인 관행은 수수료를 내는 쪽에 유리한 방향으로 처리하는 것이다.
| 대상 | 처리 방식 | 이유 |
|---|---|---|
| 수수료 납부자 | 내림(floor) | 더 적게 내도록 |
| 수수료 수취자 | 올림 없이 정확히 수령 | 분쟁 방지 |
| 중간 계층 차액 | 내림 후 차이로 계산 | 합산 오차 최소화 |
이렇게 하면 각 계층에서 페니 단위 오차가 생길 수 있지만, 반대로 하면 사용자가 계산기로 직접 두드렸을 때 숫자가 안 맞아서 클레임이 온다. 어느 쪽이 낫냐면 클레임 안 오는 쪽이 낫다.
정산 배치는 멱등성을 반드시 보장해야 한다. 같은 기간을 두 번 실행해도 결과가 달라지면 안 된다. 실수로 중복 실행했을 때 데이터가 두 배로 쌓이는 상황이 생기면 복구가 굉장히 번거롭다. INSERT OR IGNORE나 ON CONFLICT DO NOTHING을 쓰거나, 정산 실행 자체에 유니크 키를 달아서 중복 실행을 DB 레벨에서 막는 방식이 안전하다.
상세 화면에서 숫자를 보여주는 방식
정산 화면에서 사람들이 실제로 보는 건 결국 숫자다. 총 거래액, 수수료, 실수령액. 이걸 명확하게 보여주는 게 기능 자체보다 중요할 때가 있다.
- 천 단위 구분자와 '원' 단위를 일관되게 적용한다.
1,234,500원형태. - 마이너스 금액은 빨간색으로 처리해서 직관적으로 구분되게 한다. 색 하나 차이인데 운영팀 반응이 확실히 달라진다.
- 매칭된 주문 번호, 핀코드, 입금 로그를 같은 화면 안에서 바로 눌러볼 수 있게 링크로 연결해두면 CS 대응 속도가 확실히 줄어든다.
이번 작업 자체는 크지 않았지만, 손대면서 주변 코드를 다시 읽게 됐고 매칭 로직이나 정산 반올림 처리 같은 부분이 생각보다 손이 많이 가는 영역이라는 걸 다시 확인했다. 작은 화면 변경 하나가 시스템 전체 흐름을 처음부터 다시 따라가게 만드는 계기가 되는 경우가 종종 있다.
댓글 0
첫 댓글 달아줘.