우아한형제들에서는 배달의민족 앱의 배달, 장보기와 같은 서비스와 더불어서 배달의민족 앱 외부에서 제공되는 배민상회 등 다양한 서비스 들이 제공되고 있습니다. 이러한 서비스들이 공통점으로 가지고 있는 것이 있는데요. 그것은 바로 "결제"입니다. 고객이 주문을 완료하기 위해서는 결제는 필수적으로 구현해야 하는 중요한 요소 중 하나입니다.
서비스의 비즈니스 구조, 지향하는 목표에 따라 내부적으로 주문시스템이 분리되어 있는데요. 각 주문시스템을 담당하는 부서에서 직접 결제를 구현하는 것은 굉장히 불필요한 작업일 것입니다. 결제를 구현하기 위해서는 PG(Payment Gateway)사 라고 불리우는 외부 업체와의 계약 및 협업도 필요하고, 장애를 방지하기 위해서 여러 PG사를 다중화도 해야 합니다. 예를 들어 배달의민족 앱에서 제공되는 결제수단인 신용/체크카드는 3개의 PG사를 이용하고 있으며, 네이버페이/카카오페이와 같은 간편결제도 각각의 PG사와 계약을 별도로 체결하고 있습니다. 결제를 연동하기 위해서는 각 PG사에서 제공하는 연동규격에 맞게 연동을 하는 작업이 필요하기 때문에 각각의 주문시스템들이 결제 기능을 손쉽게 연동할 수 있도록, 결제 연동을 플랫폼 형태로 제공하고 중개하는 시스템이 필요했고, 그것이 "결제플랫폼"이었습니다.
하지만 동시에 중요하게 생각해야 하는 문제도 있었는데요. 바로 장애입니다. 하나의 시스템을 통해 결제 서비스가 제공되는 만큼 고객의 결제경험은 결제플랫폼에 달려있고, 그렇기 때문에 결제플랫폼을 담당하는 부서에서는 장애를 빠르게 인지하고 대응하는 것이 매우 중요합니다. 결제플랫폼 담당자들은 어떻게 장애에 대응하고 있는지 공유해 드리겠습니다.
들어가기 전에, 결제 장애는 어떤 영향이 있을까?
배달의민족에서 주문을 하다보면 한번쯤 위와 같이 주문이 완료되지 못했다는 화면을 보신적이 있을 텐데요. 주문이 완료되지 못하는 사유에는 여러가지가 있겠지만 일반적으로는 일시적인 카드사나 은행의 문제로 결제가 실패하여 발생하는 경우가 많습니다. 단순히 결제만 실패되어 다시 주문해야 하는 것뿐만 아니라 보통 장애 상황에서는 실제로 돈이 출금되는 경우도 발생합니다.
통상적으로 PG사에서는 결제내역을 실시간이 아닌 다음날 제공해 주는 것이 일반적이며, 그렇다 보니 주문 실패 건들에 대해서는 다음날 우리가 보유하고 있는 결제내역을 비교하여 차이가 나는 건들을 확인하고 취소처리 하는 방식으로 운영이 되고 있습니다. 이를 대사 작업이라고 부르고 있습니다. 고객 입장에서는 주문도 실패했는데 환불은 다음날 진행되는 불편한 상황에 놓이게 됩니다.
결제가 실패하는 경험, 실제로 돈이 출금되는 경험 모두 고객들에게는 부정적인 경험이지만 카드사나 은행의 장애를 방지하는 것은 어렵습니다. 그래서 최대한 부정적인 결제경험을 방지 하기 위해서는 장애를 빠르게 인지하고 조치하여 영향도를 최소화 하는 것과 더불어 결제 취소를 빠르게 지원하는 것이 필요했습니다. 먼저 장애를 빠르게 인지하기 위해 어떤 노력을 했는지부터 살펴보겠습니다.
장애를 인지하기 위한 노력들
1. 외부 PG사에 장애 문자 / API 연동 받기
결제를 구현하기 위해서는 외부 업체를 이용한다고 했는데요. 가장 쉽게 장애를 인지할 수 있는 방법은 결제 원천 서비스를 제공하는 외부 업체를 통해서 연락을 받는 것이라고 생각했습니다. 아무래도 원천사다 보니 장애 인지도 빠를 것이고, 그만큼 알림에 대한 신뢰도가 높을 것 같았습니다.
하지만 외부 업체에서는 문자를 통해 장애 알림을 하고 있었고, 문자라는 수단 특성상 한정된 담당자들만 연락을 받을 수 있다는 단점이 있었습니다. 또한 조직개편 등으로 담당자가 달라질 경우 연락처 수정 등에 필요한 시간도 고려하지 않을 수 없었고요.
그래서 장애 발생 시 내용을 연동 받을 수 있는 API를 외부 업체에 제공하여 연동을 요청 했습니다.
[그림 1] PG사에 제공한 API를 통해서 연동 받은 장애 알림
하지만 두 가지 문제가 있었는데요. 첫 번째는 장애 알림이 우리가 생각했던 것만큼 빠르지 않았습니다. 장애 알림보다 고객 문의가 더 빠르게 접수되는 경우가 있었습니다.(외부 업체를 통해서 제공받는 특성상 문자/API의 발송 메커니즘을 정확하게 알기는 어렵지만, 아무래도 모니터링 담당부서를 통해서 전파/승인 되는 형태로 많이 구성되는 것 같습니다.)
두 번째는 이 장애가 정말 배달의민족 결제에 영향이 있을지 알 수 없었습니다. OO카드 장애가 있다고 문자가 왔지만 저희 쪽 모니터링에서는 아무런 문제가 잡히지 않았던 경우가 있어서 향후 확인해보니 특정 회선에서만 발생하는 문제였던 상황도 있었습니다.
2. Grafana를 이용한 대시보드 및 Slack 알림 구성
외부 업체를 통한 알림은 참고할 수 있겠지만, 장애 인지 속도와 데이터의 신뢰를 믿기에는 부족한 점이 있었습니다. 그래서 내부에서도 모니터링 할 수 있는 수단을 여러 방면으로 검토해보았고, 적용했었는데요. 현재 가장 잘 사용하고 있는 모니터링 툴은 Grafana라는 시각화 툴입니다. Loki를 이용하여 로그를 수집하고, Grafana로 시각화 및 알림을 구성 했습니다.
장애를 감지하기 위해 여러 가지 조건을 설정해두었고, 대표적으로는 아래와 같은 케이스 위주로 알림을 받고 있습니다.
•
고객이 결제를 진행까지는 하는데 카드사나 은행, PG사 측의 문제로 결제 실패율이 올라가는 경우
•
동일한 에러 메시지가 일정 비중 이상 반복되는 경우
•
고객이 결제 시도는 많이 하는데, 실제로 처리되는 결제 승인 비중이 떨어지는 경우
•
시스템 CPU 등에 과부하가 발생하는 경우
[그림 2] 조건에 걸려서 발생한 결제 장애 알림. OO카드에서 동일한 실패 메시지가 다량 발생한 예시.
알림이 발생하면 가장 먼저 발견한 사람이 이모지를 슬랙에 남기고 장애 여부를 Grafana 대시보드를 통해 확인합니다. 장애가 지속되고 있는지, 순간적이었는지 등을 판단하고 필요에 따라 장애를 전파하고 조치합니다.
[그림 3] 결제플랫폼 시스템 운영지표 대시보드 중 일부. 결제수단별 에러 메시지 확인 지표
장애에 대응하기
먼저 Grafana로 온 알림이 실제 장애가 맞다면 빠르게 대처하기 위해서 담당자들을 호출합니다. 그리고 장애를 전파할 사람과 조치할 사람을 나눠서 빠르게 실행으로 옮깁니다.
1. 장애 전파하기
우아한형제들에서는 Slack 채널을 이용해 장애를 전파하는데요. 장애를 전파하고 각 시스템별로 영향도를 파악하기 위한 내부 채널과 고객센터에서 상담 응대 시 참고할 수 있도록 공유하는 외부 협력 채널로 나뉩니다.
내부 채널에서는 주요 내용들을 전달하기 위한 포맷이 정해져 있는데, 장애 시점에는 사람들의 머리가 하얗게 되길 마련이죠. 그래서 Slack에 워크플로 기능을 활용하여 장애 전파를 조금 더 쉽게 할 수 있도록 구성해두었습니다.
[그림 4] Slack 워크플로 실행 시 팝업되는 입력 양식. 내용을 작성하고 Submit을 누르면 내부/외부 협력 채널에 전파된다.
[그림 5] 워크플로를 통해 전파된 내용 예시
2. 장애 조치하기
먼저 결제에 대한 장애 조치는 문제가 되는 결제수단을 차단하는 것이 중요합니다. 문제가 되는 결제수단으로 계속 결제가 발생할 경우 위에서 이야기한 것처럼 실제로 돈은 출금됐지만 시스템적으로는 처리되지 않아 주문이 들어가지 않는 등의 부정적인 경험이 가중화될 수 있습니다.
결제수단을 차단하는 방법은 상황에 따라, 결제수단에 따라서 조금씩 다릅니다. 신용/체크카드, 휴대폰은 안정성을 위해서 여러 개의 PG사를 운영하고 있고, 네이버페이, 카카오페이와 같은 간편결제는 각 PG사로부터 서비스를 제공받기 때문이죠.
[그림 6] 왼쪽은 간편결제, 오른쪽은 배민페이 카드가 비활성화된 예시
구분 | 조치 내용 |
카드나 은행의 장애가 발생한 경우 | 장애 발생 내용을 주문서에 장애 공지 문구로 등록하고, 배민페이에서 해당 카드사나 은행의 결제수단을 비활성화합니다. |
특정 PG사에 장애가 발생한 경우 – 신용/체크카드, 휴대폰 | 장애가 발생한 PG사에서 결제가 진행되지 않도록 PG 배분율을 조정합니다. 예를 들어서 신용/체크카드에서 나이스페이먼츠 PG사가 장애가 발생한 경우에는 케이씨피, 토스페이먼츠로만 결제가 진행되도록 결제플랫폼 백오피스에서 조정할 수 있습니다. |
특정 PG사에 장애가 발생한 경우 – 간편결제 | 장애 발생 내용을 주문서에 장애 공지 문구로 등록하고, 주문서에서 해당 간편결제를 비활성화합니다. |
위와 같이 결제수단을 차단했다면 더 이상의 추가 장애 상황은 발생하지 않을 텐데요. 문제는 조치하는 동안 발생한 실제 출금 건에 대한 처리입니다. 결제플랫폼에서는 이런 건들을 처리하기 위해서(장애가 발생하지 않더라도 간헐적으로 카드사/은행 등의 이슈로 발생할 수 있기에), 대사시스템을 구축해두었습니다.
위에서 잠깐 언급했던 것처럼 "대사"라는 것은 각기 다른 시스템 간 결제상태를 비교하는 작업을 의미하는데요. PG사로부터 다음날 결제 데이터를 제공받아 결제플랫폼에서 인지하고 있는 결제 데이터와 최종 상태가 일치하는지 확인합니다.
하지만 이 작업은 거래가 발생한 다음날부터 가능하기 때문에 VOC가 발생할 수 있어서, 장애 건이 대량으로 발생하는 경우에는 수기로 장애 대상 건을 추려서 배치로 취소작업을 하곤 했는데요. 현재는 장애 등으로 발생한 결제실패 건들의 실시간 결제 상태를 조회하여 1시간 이내에 취소가 될 수 있도록 기능을 구성하여, 고객의 불편을 최대한 빠르게 해소할 수 있도록 개선했습니다.
[그림 7] 현재의 장애 대응 프로세스
마무리를 하며, 앞으로의 계획
누군가 결제시스템은 "안정성"이 가장 중요하다고 이야기 하지만, 결제라는 도메인 특성상 외부 요인이 많아 장애가 많을 수 밖에 없는 시스템이라고 생각합니다. 그만큼 어떻게 하면 장애를 더 빠르게 대응할 수 있는지가 중요하겠지요.
개선해야 하는 비효율이 아직은 많이 남았습니다. 특히 장애가 발생한 결제수단을 조치하는 것은 온전히 담당자에 판단에 따르는 부분이 대표적일 것 같아요. 내년에는 로그 및 정책을 세분화하여 결제수단을 조치하는 것도 자동화하려고 하고, 실시간으로 취소하는 기능을 고도화해 고객들의 불편함을 최소화하는 것을 목표로 하고 있습니다.
앞으로도 더욱 좋은 서비스를 제공하기 위해 노력하는 결제플랫폼 담당자 분들을 응원하며 여기서 글을 마치도록 하겠습니다.