CMS 자동이체 기반 구독 시스템

결과를 알 수 없는 출금을 미확정으로 분리하고 대사 배치로 확정해 중복 출금 차단

출금 결과를 알 수 없을 때 미확정으로 남기고, 바로 조회와 대사 배치로 결과를 확정하는 흐름

첫 출금에서 결과를 알 수 없어 미확정 출금이 생기는 흐름 5분마다 도는 대사 배치가 미확정 출금의 결과를 조회해 확정하는 구조

문제와 배경

  • 첫 출금과 정기 출금은 출금 대행사인 효성CMS의 실시간 출금 API를 동기 방식으로 호출해 응답으로 결과를 받음.
  • 출시 전 효성 스펙을 검토하다 은행 연동 장애 응답(효성 응답 코드 R066)은 요청이 은행까지 전달됐지만 처리 결과가 확정되지 않은 상태라는 걸 확인함. 타임아웃도 효성 쪽 처리가 이미 끝났을 수 있어 실제로 출금됐는지 알 수 없음.
  • 당시 설계는 응답을 성공과 실패로만 나눠 이런 출금도 실패로 안내하게 되어 있었음. 실패 안내를 본 사장님이 다시 시도하면 이미 빠져나간 구독료가 한 번 더 출금될 수 있었음.
  • 실제 결과는 효성CMS 출금 결과 조회 API로만 알 수 있는데, 조회해도 같은 장애 응답이 나올 수 있어 조회 한 번으로 확정할 수 없었음.

해결 과정

결과를 알 수 없는 출금 처리 방식 비교

후보장점단점과 제약판단
실패로 처리 (당시 설계)구현이 단순하고 사장님이 바로 다시 시도할 수 있음실제로 출금됐다면 재시도로 한 번 더 출금됨
결과가 나올 때까지 폴링하며 응답 대기사장님이 한 번에 최종 결과를 봄장애가 길면 응답이 그만큼 지연되고, 폴링해도 장애 응답이 계속 나올 수 있음
미확정으로 두고 바로 조회 + 대사 배치바로 조회로 결과가 나오면 즉시 확정하고, 안 나와도 배치가 끝까지 추적결과가 늦게 나오는 동안 사장님이 기다려야 함채택
  • 동기 응답은 바로 조회 한 번까지만 기다리고 남은 건은 배치가 비동기로 확정하면, 응답을 붙잡지 않고도 결과를 끝까지 확정할 수 있어 채택.

  • 출금 기록은 효성CMS를 호출하기 전에 요청됨으로 먼저 커밋해, 호출 중 서버가 죽어도 나간 돈에는 기록이 남게 함.

  • 타임아웃이나 은행 연동 장애 응답을 받으면 실패 대신 미확정으로 두고 출금 결과 조회 API를 바로 한 번 호출함.

  • 그래도 결과가 없으면 사장님에게 처리 중이며 결과는 알림으로 알려 준다고 안내하고, 그동안 같은 마트의 새 출금은 막음(첫 출금은 거절, 정기 출금은 보류).

  • 남은 미확정 건은 5분 주기 대사 배치가 다시 조회해 성공과 실패로 확정함. 요청됨으로 남은 건도 대상에 넣어 호출 중 서버가 죽은 건까지 회수함.

  • 요청 후 1시간이 지나도 결과가 없으면 관리자 확인 대기로 넘기고 자동 처리를 중단함.

결과

  • 결과를 알 수 없는 출금을 실패로 안내하지 않게 되어 사장님의 재시도로 중복 출금이 생길 경로를 출시 전에 막음.
  • 미확정 출금은 바로 조회나 대사 배치가 결과를 확정하고, 1시간 넘게 남으면 관리자 확인 대기로 넘어가 결과를 모른 채 방치되는 출금이 없음.