연락처 송금 결제 재시도 멱등화와 만료 알림 도입
목차
문제 상황
- 연락처 송금에서 결제대행사 호출이 간헐적으로 깨졌는데, 한 번 실패하면 거래가 그대로 죽어버림
- 사용자는 송금 링크를 다시 눌러도 같은 거래가 살아나지 않아 새로 발급받아야 했음
- 송금 URL은 발급 후 일정 시간이 지나면 만료되는데, 만료 사실을 모른 채 계속 시도하는 케이스가 CS로 쌓임
개선한 부분
재시도를 멱등하게 다듬고, 만료 직전·직후에 알림을 쏘도록 손봤음.
| 항목 | Before | After |
|---|---|---|
| 재시도 트리거 | 사용자 수동 클릭만 | 백오프 자동 재시도 + 수동 |
| 만료 알림 | 없음 | T-30분, T-0 두 단계 |
| 멱등성 | 동일 거래키 중복 결제 위험 | 거래키 기준 dedup |
| 로그 | 단일 라인 | 시도 횟수/사유 코드 분리 기록 |
조회 시 행 잠금을 잡아 동시에 두 번 재시도 큐에 들어가는 상황을 차단함.
SELECT transfer_id, status, retry_count
FROM 연락처송금
WHERE transfer_id = :id
AND status IN ('PENDING','RETRYING')
FOR UPDATE
만료 알림 큐
- 만료 30분 전: "곧 만료" 푸시 + SMS
- 만료 직후: "재발급 필요" 안내, 재발급 링크 한 번에 제공
- 발송 이력을 별도 테이블에 마킹해서 중복 발송을 막음
처음엔 5분 단위 폴러로 돌렸는데 임박한 거래가 늦게 잡혀 1분으로 줄였음. 폴러 주기를 줄였더니 부하가 걱정돼서 인덱스를 만료시각 기준으로 다시 깎았고, 결과적으로 스캔 비용은 거의 안 늘었음.
관리자 화면 상세
- 재시도 이력을 시간순으로 박아넣어서 CS 대응이 빨라짐
- 시도별로 사유 코드 + 결제대행사 응답을 그대로 노출
- 재발급 버튼은 만료된 거래에서만 활성화, 살아있는 거래에는 회색 처리
이력 테이블을 따로 두기보다 기존 거래 테이블에 시도 횟수만 누적하면 충분하다고 봤는데, 막상 CS가 "몇 번째 시도에서 실패했는지" 자주 물어봤음. 결국 시도 단위 행을 따로 쌓는 구조로 갔고, 이게 정답이었음.
회고
- 멱등키 빠뜨리면 결제대행사 쪽에서 막아주긴 하나, 거기 의존하면 안 됨. 우리 계층에서 먼저 막아야 안전함
- 알림은 "보내는 것"보다 "안 보내는 조건"을 정의하는 게 더 어려움. 중복 방지/사용자 거부/만료 후 N분 등 케이스가 많았음
- 관리자 화면에 박은 재시도 이력 덕분에 CS 대응 시간이 체감 절반으로 줄었음. 백엔드만 잘 짜고 끝내지 말고 운영 화면까지 묶어서 끝내야 진짜 끝임을 다시 확인함
다음
댓글 0
첫 댓글 달아줘.