home

[칼럼] 소프트웨어로 귀찮음 덜기

문제 상황

저희 회사 서비스에는 스마트 무통장 이라는 결제 수단이 존재합니다. 제가 설계하고 핵심 로직을 개발해서 애착이 가는 시스템인데요. 간단하게 말하자면 기존의 무통장 입금의 불편함을 없앤 결제 수단입니다. 스마트 무통장을 결제 수단으로 선택한 뒤 상품 구매를 진행하면 ‘이름 + 숫자 세 자리’ 조합의 임시 입금자명이 생기고, 해당 입금자명으로 무통장 입금을 하게되면 매칭 로직을 통해서 자동으로 입금 확인이 되는 간편한 시스템입니다.

출시된지 얼마 되지 않았고 수수료도 높지만, 높은 안정성과 편리함으로 기존의 유료 기존 결제 수단인 안심 결제의 수입을 벌써 따라 잡을 만큼 효자 노릇을 톡톡히 하고 있습니다.

해당 시스템이 돌아가기 위해서는 총 두 개의 서드파티 API가 필요합니다. 하나는 계좌를 스캔해서 입금 목록을 얻는 API와, 실제로 송금하기 위한 펌뱅킹 API 이 두 가지 입니다. 우선 이 입금 목록을 얻는 API를 사용한 계좌 스캔 로직은, 일정 주기에 맞춰 5분에 한번씩 작동하고, 여기서 얻은 데이터를 매칭 로직에 전달하여 매칭이 이루어지도록 해주는 시스템의 첫번째 트리거 역할을 하고 있습니다.

달리 말하자면, 계좌 스캔 로직의 주기에 따라서 전체 시스템의 매칭 간격이 정해진다는 것을 의미합니다. 하지만 계좌를 스캔해 주는 서드파티 API의 계좌 갱신 주기는 돈을 지불한 만큼 간격이 정해기에, 계좌 스캔 로직 주기를 아무리 줄여도 이 서드파티 API의 주기보다 작으면 최신의 계좌 상태를 받을 수 없게 됩니다.

여기서 예상될 수 있는 문제점이 자연스럽게 도출될 수 있습니다. 바로 결제 취소 에서 발생하는 문제입니다. 다음과 같은 상황을 가정해봅시다.

  1. 구매자가 스마트 무통장을 결제 수단으로 한 뒤, 주문서를 제출한다.
  2. 그리고 제출한 주문서의 가격대로, TMM의 계좌로 계좌 송금을 진행한다.
  3. 아차! 까먹고 옵션 하나를 추가하지 않아 서둘로 결제 취소를 누른다..
  4. 하지만 현재 계좌 스캔 로직이 돌기 이전이라 주문 취소는 되지만, 해당 입금 건은 매칭이 되지 않게 된다.

이러한 상황처럼 매칭이 되지 않고 떠도는 입금 건을 우리는 미아 입급건 이라고 부르며, 추후에 고객문의를 통해서 운영팀이 수동으로 찾아서 환불해 줘야 합니다. 구매자는 고객문의를 할 때, 이 입금 건이 본인이 송금한 것이 맞는지 저희가 확인을 하기 위해서 은행 앱에 들어가 송금확인증을 얻은 뒤 첨부해야 하는 불편함이 발생합니다.

즉, 이러한 상황이 발생하면 운영하는 사람들도, 구매하는 사람들도 귀찮은 최악의 상황이 벌어지게 되는 것이죠.

그래서 고안된 여러 해결 방안들

이러한 문제에 대한 쉬운 해결 방안으로 누군가는 이렇게 말할 수 있습니다.

어차피 나중에 매칭될 건데 취소되더라도 그냥 돈을 미리 보내주면 되지 않느냐?

하지만 중요한 것은 펌뱅킹 API는 무료가 아니라는 것 입니다. ‘몇 백원 단위의 돈을 기업입장에서 그냥 부담할 수 있는 것 아니야?’ 라고 생각할 수 있지만, 이것이 축적되면 배보다 배꼽이 커지는 상황이 발생합니다. API 이용 수수료가 입금 금액보다 높을 수도 있기 때문이죠.

그렇다면 이런 방법은 어떨까요?

주문서 제출 이후에, 스캔 로직이 도는 최사 단위인 5분 동안 주문 취소 버튼을 숨기면 되지 않느냐

이러한 방법은 이 스마트 무통장을 설계할 때부터 나왔던 이야기였습니다. 하지만 아예 주문 취소 버튼을 숨기게 되면 환불 건을 원천 차단할 수 있지만 사용자 경험에 부정적일 수 있습니다. 정말 바로 주문을 취소해야 하는 상황(판매자 요청에 따른 취소, 재고 문제)이라면 구매자는 물론 판매자 또한 곤란을 겪을 것이기 때문이죠.

그래서 이러한 문제를 해결하기 전까지는 이렇게 여러 번의 확인 메시지로 사용자에게 ‘당신의 돈을 빨리 돌려주지 못할 수도 있어요’라는 사실을 상기 시켜주는 방식을 택했습니다.

문제는 사용자들은 글을 제대로 읽지 않는다는 것입니다. 실제로 입금을 하고, 매칭이 되지 않은 채로 취소를 한 주문 건이 결제 수단 오픈 두 달 만에 총 33번이나 발생했습니다. 달리 말하면 운영팀은 바쁜 와중에 환불 관련 고객 문의가 들어오면, 수동으로 송금 사실을 확인하고, 복잡한 보안 프로그램을 통과하여 은행 시스템에 들어가 계좌번호를 치고, 송금하는 작업을 33번을 진행했다는 뜻이기도 합니다.

이는 너무 불필요한 작업입니다. 저희는 작은 팀이기에 한명 한명의 시간이 소중했습니다. 따라서 운영에서 오는 귀찮음을 최대한 줄이고자, 사용자도 덜 불편하고 운영팀이 귀찮지 않는 묘수를 생각하게 됐습니다.

선택: SQS 지연큐 활용하기

제가 생각해낸 방법은 지연 큐를 사용하는 것 입니다. SQS는 메시지 지연을 통해서 개별 메시지를 보낼 때 시간을 딜레이시킬 수 있는 기능이 있습니다.

큐 자체에도 대기열 지연이라는 기본 지연 시간을 대기열 생성 시 설정할 수 있습니다. 그리고 큐에 메시지를 보낼 때 파라미터를 통해서 개별 메시지 지연을 보낼 수 있고, 이것은 기본 지연 시간을 덮어쓰게 됩니다.

처음에는 대기열 지연을 5분으로 설정해서 모든 메시지를 5분 지연시키는 방법을 생각했으나, 더 좋은 사용자 경험을 위하여 개별 메시지 지연을 사용해 개인 맞춤 딜레이 시간을 계산하였습니다.

개별 메시지 지연을 통해서 5분 - (현재시간 - 주문서 제출 시간) 으로 DelaySeconds을 설정한 뒤, 취소 메시지를 담아서 SQS 큐로 전송합니다. 그리고 redis에 해당 주문서 id로 취소 예약 키를 만들어 해당 주문서가 취소 예약이 되었음을 잠시 저장시켜줍니다.

remaining_seconds = TOTAL_WAIT_TIME - int((datetime.now() - form_data.crt_date).total_seconds())

message = {
	    "api": "cancel",
	    "form_id": form_id
    }
}
sqs_client = boto3.client('sqs', region_name='ap-northeast-2')
try:
    response = sqs_client.send_message(
        QueueUrl=DELAY_QUEUE_URL,
        MessageBody=json.dumps(message),
        DelaySeconds=remaining_seconds
    )
except Exception as e:
    raise SQSResponseException

key=f"cancel_reservation:{form_id}"
redis_client.set(key, "1", remaining_seconds)

그리고 이렇게 요청을 확인 중이라는 화면을 보여줍니다.

딜레이 시간에 임박하면 SQS에서 주문 취소 API로 메시지 보냅니다. 이렇게 되면 사용자가 따로 어떤 액션을 취하지 않아도 자동으로 주문 취소가 이루어지고, 푸시 알림을 통해서 사용자는 주문 취소가 된 것을 알 수 있게 됩니다.

‘임금하셨나요?’ 의 답변에 ‘네’ 를 선택하게 되면 일종의 취소 예약 상태가 됩니다. 실제 취소가 바로 이루어지지 않기 때문에, 매칭 전에 주문서 취소로 인해 미아 입금 건이 발생하는 비율을 현저히 낮춰주게 됩니다. 매칭 로직에서는 레디스로 취소 예약키를 조회해하여 만약 해당 주문 건이 취소 예약 상태라면 해당 입금 건의 송금액은 모두 환불 로직으로 전달해 줘서 환불이 진행됩니다.

환불 로직에서는 펌뱅킹을 통한 실제 송금이 아닌, 사용자가 직접 환급이 가능한 TMM 머니로 환불을 진행하게 해주어 펌뱅킹 수수료를 내지 않아도 되는 장점도 얻게 됩니다.

또한 ‘임금하셨나요?’ 의 답변에 ‘아니요’ 를 택하게 되면, 기존 처럼 즉시 주문 취소가 가능합니다.

결론

SQS의 지연 큐를 사용해 문제를 해결하여 여러 이득을 얻을 수 있었습니다. 사용자 입장에서는 아예 5분 동안 주문 취소 버튼을 막는 방법 보다, 5분 후에 자동으로 주문이 취소되는 편리함, 또 미아 입금 건이 발생하여 송금 확인증을 다운 받은 후 고객문의를 넣는 수고를 덜 수 있었습니다. 또 운영을 하는 입장에서는 수동 입금 건수를 현저히 줄일 수 있음은 물론이거니와 TMM 머니로 환불이 되기 때문에 환불 시 펌뱅킹 수수료도 아낄 수 있는 이득을 얻을 수 있었습니다.

물론, 입금자명을 잘못 입력하여 미아건이 되는 입금건은 이렇게 개선을 하였어도 어찌할 도리가 없다는 한계점도 존재하긴 합니다. 그렇지만 복잡했던 수동 환불 업무를 줄여주고, 사용자에게도 귀찮음을 덜어줄 수 있는 일석 이조의 효과를 보았습니다. 가장 중요한 건 소프트웨어로 귀찮음을 해결해주었다! 라는 쾌거를 얻을 수 있었다는게 가장 큰 소득이었던 것 같습니다.

지연 대기열에 대한 정보는 AWS 공식 사이트에서 얻을 수 있습니다. Amazon SQS 지연 대기열 - AWS 공식 docs