결제 승인 거짓 성공으로 인한 정산 오류 수정
목차
거짓 성공(false SUCCESS) 한 건이 부른 사고
결제대행사 두 곳의 응답 핸들러에서 승인 실패인데 SUCCESS 로 찍히는 케이스를 잡았음. 정산 다음 날 파트너 잔액이 비어있다는 문의로 발견. 회고 정리.
무엇이 문제였나
핸들러가 결제대행사의 raw 응답을 파싱할 때, 일부 에러 케이스에서 결과 코드가 비어 들어옴. 비어있으면 디폴트 분기를 타도록 짜놓은 게 원흉.
- 결과 코드 null → 디폴트 처리
- 디폴트 처리 = "정상 흐름으로 가정"
- 따라서 거래 상태가 SUCCESS 로 마킹
원래 의도는 "비정상이면 막아라" 였는데 디폴트가 SUCCESS 쪽이라 정반대로 작동함. 두 핸들러가 동일한 패턴을 공유하고 있어서 한꺼번에 새는 구조.
어떻게 바꿨는가
판정을 whitelist 방식으로 뒤집음. 명시적으로 SUCCESS 조건을 만족할 때만 통과, 그 외는 전부 FAIL.
| 변경 전 | 변경 후 |
|---|---|
| 코드 매칭 안 되면 SUCCESS | 코드 매칭 안 되면 FAIL |
| null/empty 허용 | null/empty 즉시 FAIL |
| 결과 코드만 검사 | 코드 + 금액 + 서명 동시 검증 |
// 의사코드
if (resultCode == EXPECTED_OK
&& amountMatched
&& signatureValid) {
return SUCCESS;
}
return FAIL; // 그 외 전부
서명·금액 검증을 묶어 세 조건 AND 로 강제. 한 가지라도 빠지면 무조건 실패.
운영에서 배운 것
- 디폴트는 항상 안전한 쪽으로. 결제·정산 도메인에서 디폴트 SUCCESS 는 폭탄.
- 결제대행사별 핸들러는 서로 다른 시점에 짠다 해도 공통 검증 베이스를 강제해야 함. 두 곳이 똑같이 새는 건 우연이 아니었음.
- 정산 직후가 아니라 승인 직후 단계에서 차단해야 잔액이 안 꼬임. 뒤로 갈수록 복구 비용이 기하급수.
후속 조치
- 핸들러 단위 테스트에 "이상한 응답 → FAIL" 케이스 8종 추가
- raw 응답과 판정 결과를 같이 적재해서, 다음 의심 건 발생 시 바로 비교 가능하게 정비
- 재무 쪽에 영향 거래 리스트 전달, 수기 정정 진행
다음
댓글 0
첫 댓글 달아줘.