약 2년 전부터 고객사가 사용 중인 솔루션이 있었다.

해당 서비스는 선사용 후결제 시스템으로 '신용카드 한도초과' 또는 '체크카드 잔액부족' 등으로 인해 결제가 실패하는 경우가 발생한다. 결제 실패 시, 사용자는 해당 건의 미수금을 납부할 때까지 해당 서비스를 이용하지 못한다.

 

미수금 결제를 위해 결제 실패 시각을 기준으로 두 종류 (1시간, 1일 후)의 데이터를 생성한다.

두 종류의 배치 시스템이 돌면서, 조건에 부합하는 미수금에 대한 자동 결제를 시도하게 한다. 

두 번의 자동 결제에도 결제가 완료되지 못하면, 관리자가 직접 사용자와 통화하여 조치 후에 개발자에게 연락하여 수동으로 처리해달라고 요청한다.

여기까지가 해당 솔루션의 미수금 결제 흐름이다.

 

그렇다고 미수금이 자주 발생하는 것은 아니다. 어쩔 때는 몇 달간 단 한 건도 발생하지 않은 적도 있다.

그런데, 갑자기 그 달에만 몇 건이나 미수금이 발생했고 배치가 돌 때, 은행 점검 시간이 겹쳐 결제가 되지 않아 관리자가 직접 몇 번 전화를 했던 것 같다. 그래서 사용자에게 미수금이 발생하면, 카카오톡 알림톡을 보내는 기능을 추가해달라고 요청이 왔다.

해당 솔루션에 이미 카카오톡을 발송하는 기능이 있었기 때문에 새로운 템플릿만 생성해서 알맞게 메시지 틀을 만들기만 하면 됐었다.

 

테스트 코드도 없고, 고객사의 호스팅 DB에 데이터를 insert하고 고객사의 시스템에 의해 카카오톡이 발송되는 프로세스였기 때문에 완벽하게 카카오톡 발송 여부를 확인할 수는 없었다. 그래도 고객사 개발자와 전화를 통해 1차 실패에 대한 메시지 발송을 확인하고 이를 반영하였다.

 

하지만 쫄리기 때문에 매일 미수금이 생겼나 안생겼나 DB를 확인하게 된 나를 발견하였다...
(사실, 정산에 관련해서 완전히 나의 잘못이라고는 생각이 들지는 않지만, 큰 파장을 발생시켰었기 때문에 돈과 관련된 문제에 대해서는 굉장히 예민해져버렸다.)

 

한 달 쯤 지났나, 주말 간에 미수 결제가 생겼고 월요일에 확인했기 때문에 두 번의 배치 시스템이 다 돈 상태였다.

DB를 확인해보았는데, 두 번째 배치에 대한 알림톡이 발생되지 않은 것이었다. 

쿼리와 로그를 살펴보다가 스프링 스케줄러 Job 설정 시, <value> 값을 넣어주는데 MyBatis 동적 쿼리 조건이 정상적으로 동작하지 않는 것을 확인했다.

[BEFORE]
<if test=" flag.equals('2nd') and flag == '2nd' ">

[AFTER]
<if test=" flag eq '2nd'.toString() ">

이전에 작성된 코드처럼 조건을 작성하면, WHERE 절이 생성되지 않는 것이었다.

여태껏 하루에 한 번만 정상 동작하고 있었던 것이다. (두 번째 배치는 돌지 않고 있었던 것이다.)

하지만 첫 번째 배치는 매시간마다 동작하기 때문에 아래의 조건이 아니어도 처음 생성된 데이터는 무조건 배치 시스템에 의해 결제 프로세스를 타기 때문에 큰 문제가 되지는 않았었다. 

 

그래서 아무도 몰랐던 거였나..?

사실 나 또한, 카카오톡 기능을 추가하고 정상 동작을 확인하면서 이러한 문제점을 알게 되었다.

 

이제, 수정한 시스템이 실제로 정상적으로 동작하는지 확인해야 했다.

한 2주가 흘렀나, 평일 저녁에 결제에 실패한 이력이 생겼었다. 그런데, 두 번째 배치가 동작하지 않은 것이었다.

두 번째 배치는 하루에 한 번 새벽에 동작하기 때문에, 동작 시점을 기준으로 -24시간 안에 존재하는 첫 번째 배치 시스템에 실패한 이력에 대해서 자동 결제를 시도한다. (정책)

그러면, 당연히 아침에 왔을 때는 동작했어야 하는 시스템에 왜 데이터가 안 걸렸는지 로그를 살펴보았다.

 

역시 쿼리를 왜 실패했을까라는 생각을 하면서 보니까 알 수 있었다. (평소에는 틀렸는지 전혀 몰랐다.)

[BEFORE]
2nd_time BETWEEN DATE_ADD(NOW(), INTERVAL -1440 MINUTE) 
AND NOW()

두 번째 배치의 데이터 조회 조건이 {배치 동작 시간 - 24시간} ~ {배치 동작 시간}이었다.

만약, 오전 5시에 결제에 실패했으면, 두 번째 배치 시간이 내일 오전 5시인 것이다.

이게 어떤 문제가 있냐면, 다음날 새벽에 두 번째 배치에 저 데이터가 안 걸리고 하루가 더 지난 다음에야 해당 데이터가 두 번째 배치 조건에 걸리게 되는 것이다.

즉, 첫 번째 배치에 실패하면 하루하고도 그 특정 새벽 시간까지 서비스 이용을 못한다는 것이다.

해당 서비스는 사용자에 따라 사용 시간이 다르더라도, 동일 시간에  매일 사용되기 때문에 이는 큰 문제이다. 

[AFTER]
2nd_time BETWEEN DATE_ADD( DATE_ADD(NOW(), INTERVAL 1 DAY), INTERVAL -1440 MINUTE ) 
AND DATE_ADD(NOW(), INTERVAL 1 DAY)

그래서 두 번째 배치의 데이터 조회 조건을 {배치 동작 시간 +1일 - 24시간} ~ {배치 동작 시간 + 1일}로 수정하였다.

이로 인해, 오늘 실패한 결제가 내일 새벽 특정 시간까지 해서 두 번의 자동 결제를 할 수 있게 되었다.

 

사실, 두 번째 조건은 헷갈릴 것 같긴 하다.

그리고 운이 좋게도 그다음 날 바로 결제 실패 이력이 생겼고, 두 번째 배치까지 정상적으로 동작하여 하루 안에 두 번의 카카오톡이 발송되는 것까지 확인하였다.

 

결제 실패가 많은 달이어서, 빨리 운영에서 동작 여부를 확인할 수 있어서 다행이었던 것 같다.

그리고 복잡한 조건을 수정한 것은 아니지만, 그래도 꽤나 뿌듯한 일을 한 것 같아 기분이 좋았다.

+ Recent posts