배민선물하기팀은 선물하는 이의 마음과 받는 이의 즐거움을 잇는 ‘배민선물하기’ 서비스를 담당하며, 배달의민족(이하 배민) 앱 내 상품권 발행부터 외부 채널과의 유통망 연동을 관리하고 있습니다.
이번에 소개할 프로젝트는 카카오톡에서 선물 받은 브랜드 교환권을 배민 앱에 직접 등록해 결제에 사용할 수 있도록 구현한 ‘외부 교환권 연동 서비스’입니다.
그동안 많은 고객분들이 “카카오톡으로 받은 선물인데, 왜 배민에서는 못 쓰지?”라는 의문을 가져왔습니다. 고객 입장에서 이 당연해 보이는 연결고리를 완성하기 위해 배민선물하기팀에서 마주했던 플랫폼 간의 기술적 간극과 복잡한 이해관계, 그리고 그 단절된 경험을 매끄럽게 잇기 위해 분투했던 과정들을 솔직하게 기록해 보려 합니다. 저희의 시행착오와 해결 과정이 어쩌면 비슷한 고민을 하고 계실 다른 동료분들께 조금이나마 실질적인 도움이 되기를 바랍니다.
“왜 안돼?”질문에서 시작된 프로젝트
모든 프로젝트는 질문에서 시작됩니다. 하지만 그 질문이 언제나 고객의 입에서 나오는 것은 아닙니다. 카카오톡 교환권을 배민에서 사용하게 만드는 프로젝트는 고객의 불편함이라는 표면적인 문제와 비즈니스의 성장을 위한 내부적인 전략적 필요성이 교차하는 지점에서 시작하였습니다.
사용자 불편함: 해결해야 할 문제
출처: Naver 지식iN물론 오래전부터 사용자 VOC(Voice of Customer, 고객의 소리)가 있었습니다. “카톡 선물로 케이크 받았는데, 배민 앱에서는 왜 사용할 수가 없나요?”, “선물 받은 브랜드 교환권을 배민에서 주문할 때 쓰고 싶어요.” 이러한 고객의 소리는 단순히 기능 추가 요청을 넘어, 단절된 사용자 경험에 대한 아쉬움이 있었습니다. 사용자 입장에서 배민 앱은 이미 익숙한 주문 채널인데, 선물을 쓰기 위해 굳이 브랜드의 자사 앱을 설치하여 주문해야 하거나 직접 매장을 방문해야만 사용할 수 있는 번거로움은 명백한 페인포인트(Pain Point)였습니다. 이러한 불편함을 해소함으로써 고객에게 ‘역시 배민이 편하다’는 인식을 심어주고 싶었습니다.
비즈니스 목표: 외부 주문을 배민 플랫폼 안으로 흡수
고객의 불편함만 해결한다면 바로 서비스할 수 있을까요? PM으로서 주목해야하는 것은 사용자 불편함 이면의 비즈니스적 가치였습니다. 단순히 고객의 불편함을 해결하는 것을 넘어, 이 프로젝트가 가질 ‘비즈니스적 파급력’에 주목했습니다. 그동안 플랫폼 경계에 머물러 있던 외부 교환권 수요를 배민 앱 안으로 온전히 수용함으로써 새로운 구매 전환의 접점을 확보하고 배민앱의 플랫폼 경험을 한 단계 확장할 수 있는 기회라고 판단했기 때문입니다.카카오톡 교환권 연동은 단순한 기능 추가를 넘어, 잠재된 주문 수요를 배민의 활성 에너지로 전환하는 강력한 성장 동력이 될 것이라는 확신을 얻게 되었습니다.
- 신규 고객 유입 및 락인(Lock-in) : 타 플랫폼/브랜드 발행 교환권으로 유입되는 신규 고객이 배민 앱에 자연스럽게 안착하도록 유도
- 주문 경험 통합 : 고객이 어떤 교환권을 가지고 있든 배민 앱 하나로 모든 주문을 해결할 수 있는 편리한 경험 제공
결국 이 프로젝트는 ‘고객 경험 개선’ 이라는 강력한 명분과 함께 동시에 외부의 잠재적 트래픽을 배민 플랫폼 안으로 흡수하는 비즈니스 목표가 더해져 시작할 수 있었습니다.
스스로 정의한 프로젝트의 본질: 플랫폼 간의 장벽을 넘어선 새로운 연결
명확한 문제 정의와 비즈니스 목표가 있다면 프로젝트는 시작될 수 있습니다. 하지만 프로젝트의 규모가 크고 참여하는 조직이 많을수록, 즉 ‘사공이 많은 배’일수록 우리가 하는 ‘일의 본질’을 단단하게 정의하는 과정이 선행되어야 합니다.
이번 프로젝트는 여러 유관 부서가 참여하다 보니 각자의 우선순위에 따라 현안을 바라보는 시각이 나누어지기도 했습니다. 기술적 제약, 운영의 편의성, 비즈니스 수익성 등 수많은 목소리가 충돌할 때 우리를 다시 하나로 모아준 것은 ‘플랫폼 간의 장벽을 넘어 사용자에게 끊김 없는 연결을 제공한다’는 프로젝트의 본질이었습니다.
스스로 정의하고 팀원들과 합의한 이 본질은 단순히 구호에 그치지 않았습니다. 치열한 논의 끝에 어려운 의사결정을 내려야 하는 순간마다, 우리는 “이 결정이 우리의 본질인 ‘연결’에 부합하는가?”를 자문하며 흔들리지 않고 나아갈 수 있었습니다.
우리는 이 프로젝트의 의미가 단순히 매출 증대나 트래픽 확보에 그친다고 생각하지 않았습니다. 고립되어 있던 각자의 생태계(플랫폼)을 연결하여, 사용자에게 ‘경험의 단절이 없는 새로운 가치’를 제공하는 선례를 만드는 것에 진정한 의미가 있었습니다. 여러 회사의 연동 개발 과정은 명백한 기술적 도전이었지만, 본질적으로는 ‘플랫폼 중심 사고’에서 벗어나 사용자 편의성을 극대화하는 ‘사용자 중심 사고’로 전환하는 시도를 통해 비로소 가능했던 일이었다고 생각합니다.
복잡한 다자간 협업에서 살아남는 ‘소통의 기술’
이 프로젝트의 본질은 플랫폼 간의 경계를 허무는 ‘연결’에 있었고, 카카오톡 교환권을 배민에서 사용하도록 구현하는 일은 기술적 완성도만큼이나 복잡한 대외 협업이 핵심이었습니다. 카카오라는 플랫폼사, 그리고 카카오톡 선물하기에 입점한 수많은 F&B(Food & Beverage) 브랜드사, 그리고 이들 사이를 잇는 연동사(쿠폰사)까지 얽혀 있는 거대한 생태계를 조율해야 했기 때문입니다. 협업의 대상은 외부 파트너사뿐만이 아니었습니다. 기존 주문 로직 전반에 영향을 주는 과제였던 만큼, 배민 내부의 여러 핵심 팀과도 시스템 리스크와 업무 부담을 조율하는 긴밀한 과정이 필요했습니다.
서로 다른 시스템 언어와 이해관계를 가진 파트너들 사이에서 합의점을 찾아가는 과정은 마치 여러 국가가 참여하는 정상회담을 조율하는 일과 같았습니다. 이 프로젝트를 통해 다시 한번 깨달은 것은 기술적인 구현 능력 만큼이나 다양한 조직을 하나의 목표로 움직이게 하는 커뮤니케이션의 힘이었습니다. 다양한 이해관계자(카카오, 쿠폰사, 배민 내부 팀 등)와 협업하며 체득한 실질적인 교훈들을 다음과 같이 정리하였습니다.
명확한 ‘왜?’를 상기하기
각 조직은 저마다의 KPI와 우선순위가 있습니다. 카카오는 플랫폼 안정성을, 쿠폰사는 정산의 명확성을, 배민 내부에서는 고객에게 약속한 시점에 안정적인 서비스를 제공하여 끊김 없는 경험을 완성하는 것을 가장 중요한 목표로 삼았습니다. 이처럼 이해관계가 충돌할 때, “고객 경험 개선과 새로운 가치 창출”이라는 프로젝트의 대의명분을 지속적으로 상기시키는 작업이 필요했습니다.
또한, 계속해서 추가되는 비즈니스 요구사항들을 마주했을 때, 고객 경험 개선에 도움이 되더라도 핵심 기능이 아닌 부수적인 개선은 아닌지 끊임없이 점검했습니다. 중요도가 낮은 요구사항들에 대해서는 시의적절한 의사결정(우선순위 조정 또는 제외)이 중요했습니다.
특히 일정이 충분하지 않은 상황에서 의사결정이 길어지거나 방향성을 잃을 때는 기술 스펙 대신 “이 결정이 사용자에게 어떤 가치를 주는가?”라는 본질적인 질문으로 돌아가서 판단하였습니다. 프로젝트 시작단계에서 스스로 정의한 프로젝트의 본질이 중요해지는 때인 것 같습니다. 명확한 비전은 복잡한 논의를 단순화하고 모두를 한 방향으로 이끄는 힘이 있다는 것을 상기할 수 있었습니다.
상대방의 언어로 소통하기
너무도 당연한 이야기겠지만, 서로 다른 배경을 가진 팀과의 소통에서는 방식이 중요했습니다. 배민 내부의 백엔드 개발자에게는 API 응답 속도와 에러 핸들링을 중심으로 이야기해야 했고, 브랜드사와 연동사의 비즈니스 담당자에게는 제휴 조건과 정산 프로세스를 중심으로 소통해야 했습니다.
이 과정에서 상호 존중의 태도 역시 필수적이었습니다. 단순히 “우리 시스템이 맞다”는 식의 접근보다는, “상대방의 시스템은 왜 그렇게 설계되었을까?”를 이해하려는 태도가 중요했습니다. 배민에서는 카카오톡 교환권이 ‘등록’되고 ‘사용’되지만, 연동사의 입장에서는 ‘조회’되고 ‘승인’되는 기본적인 용어부터 비즈니스 로직까지 모든 것이 달랐습니다. 서로의 시스템이 다르다는 인지에서 대화를 시작하여 상이한 용어와 구현 및 처리 방식에 대해서도 꼼꼼히 확인하고 맞춰가는 과정은 복잡하고 이해할 수 없었던 각각의 시스템이 하나로 연결되는 열쇠가 되었습니다.
배민에서는 최대한 다양한 연동사 연결을 받아들일 수 있되 새로운 교환권 사용 경험을 표준화하기 위한 노력을 하였으며, 이를 위해 단순히 공통 스펙을 요구사항으로 전달하기 보다는 상대의 도메인 지식 수준과 관심사를 파악하고, 이해하기 쉬운 언어와 관점에서 이야기하는 ‘맞춤형 커뮤니케이션’이 필요하였습니다. 이 과정에서 PM은 기술팀과 비즈니스팀 사이의 ‘전문 통역사’ 역할을 자처해야 함을 알게되었습니다.
‘가교’를 넘어 ‘선장’으로 주도적인 문제 해결자 되기
서로 다른 시스템과 정책을 가진 두 회사가 하나의 목표를 향해 나아가는 과정은 결코 순탄치 않았습니다. 기술적인 요구사항(API 스펙 정의, 에러 대응 정책 등)을 주고받는 과정에서 발생할 수 있는 오해와 지연을 최소화하기 위해 다음과 같은 전략을 사용했습니다.
- 기술적 요구사항 조율 : 양사의 기술팀이 합리적인 선에서 타협점을 찾을 수 있도록 기술적 배경지식을 바탕으로 조율했습니다.
- 일정 관리 : 복잡한 의존 관계를 가진 작업들의 우선순위를 설정하고 전체 일정을 관리하며 프로젝트의 지연을 막았습니다.
- 니즈 충족을 위한 주도적인 역할 : 각 사의 비즈니스 니즈(예: 정산 방식, 장애 처리 정책)를 모두 충족시키기 위해 주도적으로 대안을 제시하고 합의를 이끌어냈습니다.
문서화의 마법: 오해를 줄이는 투명한 기록 남기기
말로 한 합의는 시간이 지나면 해석이 달라지기 마련입니다. 특히 여러 회사가 얽힌 프로젝트에서는 “그때 그렇게 말씀하시지 않았나요?”라는 난감한 상황이 발생하기도 합니다. 난감한 상황을 예상해서는 아니었지만 다양한 이슈에 대해 모두 기억할 자신이 없었던 저는 API 명세서부터 정책 결정 회의록까지, 모든 합의 사항을 문서로 남겼습니다. 이러한 문서는 단순히 리스크 관리를 넘어, 정보의 비대칭성을 해소하고 모두가 같은 지도를 보고 움직이게 하는 내비게이션 역할을 톡톡히 해냈습니다.
또한, 수개월에 걸친 긴 호흡의 프로젝트에서는 문서를 통해 과거의 히스토리를 명확히 파악할 수 있었습니다. 프로젝트 중간에 발생하는 스펙 변경이나 새로운 요구사항은 별도 이슈트래커 문서에 기록해두었습니다. 서비스를 오픈하고 남은 개선사항이 무엇인지 이들의 우선순위가 어떤지 빠르게 점검할 수 있었습니다. 이를 통해 예전의 의사결정 내용과 그 배경을 쉽게 파악하고 프로젝트를 이해할 수 있어 불필요한 재확인 과정을 줄이고 효율적으로 협업할 수 있었습니다.
이 프로젝트를 통해 PM에게 가장 중요한 역량 중 하나는 기술적인 구현 능력만큼이나, 다양한 사람과 조직을 하나의 목표로 움직이게 하는 커뮤니케이션 능력이었음을 다시 한번 깨달았습니다.
이탈 없는 교환권 사용 경험을 위해: 바코드 이미지 인식을 통한 UX 최적화
이번 프로젝트는 외부에서 발행된 카카오톡 교환권을 배민 앱에 등록하여 사용할 수 있도록 하는 기능으로, 외부 고객 유입을 기대할 수 있는 프로젝트였습니다. 때문에 사용편의성이 중요한 화두였는데요. 단순히 교환권의 바코드 번호를 수동으로 입력하는 방식은 사용자에게 그다지 매력적이지 않을 가능성이 높았습니다. 그래서 사용편의성을 극대화하기 위해 교환권의 이미지를 업로드하면 바코드 번호를 자동으로 인식하는 기능을 필수 요구사항으로 구현하게 되었습니다.
우선, 기능 구현을 위해서는 웹 환경에서 바코드 이미지를 인식할 수 있어야 하는데, 짧은 검토를 거친 결과 JavaScript 기반의 바코드 인식 라이브러리인 zxing.js를 사용하는 것이 좋겠다고 판단했습니다. ZXing(Zebra Crossing)은 2007년에 Google 소속 엔지니어인 Sean Owen이 시작한 오픈소스 바코드 디코딩 라이브러리입니다. Google의 인쇄 광고 팀 내부 프로젝트로 시작되어 안드로이드 진영에서 꾸준히 사랑받아 온 만큼, 라이브러리의 신뢰도 측면에서는 더할 나위 없이 좋은 선택이었습니다. 참고로, zxing.js는 ZXing을 JavaScript 환경에서 사용할 수 있도록 포팅한 구현체입니다. 이 라이브러리를 활용하면 다양한 바코드를 디코딩할 수 있는데, 이 글에서는 카카오톡 교환권에 포함된 1차원 바코드로 내용을 한정하도록 하겠습니다.
출처: https://developers.googleblog.com/en/zxing-1d2d-barcode-decoding-source-code-released/문제 케이스 인식 과정
요구사항 자체는 간단, 명확했습니다. 이미지에서 바코드를 인식하여 번호를 뽑아내는 것이었습니다. 라이브러리 자체가 워낙 사용하기 쉽게 구성되어 있어 구현 과정에 큰 어려움이 없었고, 초기 테스트 시 모든 환경에서 바코드를 안정적으로 인식하는 듯 보였습니다. 실제로 카카오톡 바코드 캡처 이미지뿐만 아니라 다른 연동사의 바코드 이미지에서도 번호 추출이 정상적으로 이루어졌기 때문입니다.
하지만 한 가지 예상하지 못한 변수가 있었는데, 바로 카카오톡 선물하기의 ‘내 앨범에 저장’ 버튼을 통해 다운로드한 이미지를 인식하는 케이스였습니다. 팀원들과 함께 기능을 테스트하던 중, 해당 경로로 다운로드한 이미지는 바코드를 제대로 인식하지 못하는 현상을 발견했습니다. 기존 테스트를 모두 일반적인 휴대폰 화면 캡처 이미지로만 진행했기에, 해당 버튼이 존재한다는 사실을 미처 고려하지 못했던 것입니다.
문제 원인을 논의한 결과, ‘내 앨범에 저장’ 버튼을 사용했을 때는 이미지 가장자리에 노란색 테두리가 생성된다는 차이점을 찾아낼 수 있었습니다. 이후 테스트 삼아 해당 테두리 영역을 잘라내고 바코드 인식을 시도해 본 결과, 숫자가 정상적으로 추출되는 것을 확인할 수 있었습니다.
교환권 가장자리에 노란색 테두리가 생성된 모습코드 분석을 통한 문제 원인 추정
사실 가장자리에 있는 노란색 테두리만 잘라내면 문제는 즉시 해결할 수 있었습니다. 가장자리로부터 일정 픽셀만큼 이미지를 잘라내거나, 노란색 컬러 값을 인식하여 해당 범위를 잘라내는 식으로 구현하면 됩니다. 하지만 이는 문제의 근본적인 원인을 해결하는 방식이 아닐뿐더러, 예상치 못한 부작용이 발생할 우려가 있었습니다. 가령, 가장자리에서 일정 픽셀을 일괄적으로 잘라내는 방식은 ‘내 앨범에 저장하기’ 버튼으로 다운로드한 이미지가 아닌 경우 형태를 예측할 수 없기에 바코드 영역 자체가 손실될 위험이 있었습니다. 노란색 영역을 인식하여 잘라내는 방식 역시, 향후 카카오톡 선물하기의 디자인이 변경되어 이미지 내 다른 영역에 노란색이 사용될 경우 문제가 발생할 여지가 있었습니다. 결국 보다 근본적인 원인 파악이 필요하다는 결론에 도달했고, 이를 위해 zxing.js의 코드를 살펴보기로 했습니다. 라이브러리가 이미지를 어떻게 처리하여 바코드 번호를 추출하는지에 대한 파악이 필요했기 때문입니다.
zxing.js가 바코드 이미지를 처리하는 과정을 요약하면 다음과 같습니다.
- 이미지를 Canvas에 올려서 각 픽셀의 RGBA 데이터를 담은 1차원 배열인 ImageData를 추출한다.
- RGBLuminanceSource에서 RGBA 데이터에 가중치를 적용하여 하나의 ‘밝기값’을 계산한다. (그레이스케일 적용)
- 변환된 밝기값을 HybridBinarizer에서 0(검은색)이나 1(흰색)로 이진화한다.
- 이진화된 결과를 BinaryBitmap으로 감싸서 디코더가 사용하기 적합한 방식으로 변환하여 전달한다.
- OneDReader(1차원 바코드 해석기)가 BinaryBitmap을 받아 이미지의 중앙 행을 뜯어내어 BitArray(0과 1의 배열)를 추출한 후 디코딩을 시도한다.
- 실패하면 중앙에서 위아래로 퍼져나가며 다음 행을 스캔한다. 성공하면 결과를 텍스트와 같은 Result로 반환한다.
여기서 추정할 수 있는, 문제가 될 만한 과정은 바로 3번 과정입니다. HybridBinarizer는 이진화를 담당하는 클래스인데, 8×8의 블록 단위로 이미지를 나누어 각 블록의 임곗값을 계산합니다. 이 임곗값을 구하는 과정에서 밝은 노란색이 영향을 끼쳤을 가능성이 있습니다. 그러면 이진화를 할 때 이 임곗값으로 인해 바코드가 유실되어 인식에 실패했을 것이라는 추정이 가능하게 됩니다.
우선, RGBLuminanceSource에서 밝기값을 계산하는 공식은 (R + 2G + B) / 4 입니다. ColorZilla로 추출한 카카오톡 교환권의 노란색 테두리 색상값은 RGB로 (255, 222, 33)인데, 여기에 공식을 대입하면 밝기값은 거의 200에 가까운 값으로 나옵니다. 이 밝기값을 블록별로 평균내어 임곗값을 산출하는데, 만약 주변 픽셀들과의 대비가 부족하다면 단순히 (블록 내 최소 밝기값 / 2)를 임곗값으로 정합니다.
RGBLuminanceSource의 밝기값 계산과 HybridBinarizer의 블록별 임곗값 산출(Nano Banana AI이미지 생성)
이렇게 산출된 블록별 임곗값은 이후 주변 5×5 블록들의 임곗값과 다시 한번 평균을 내는 일종의 평탄화 과정을 거칩니다. 아마 여기에서 문제가 생겼을 거라고 추정합니다. 기존에 모바일 화면을 캡처한 이미지처럼 단순 흰 배경만 존재하는 경우에는 블록 내 픽셀들의 대비가 부족하므로(255 / 2)가 임곗값이 될 텐데, 적당하게 대비되는 노란색 테두리가 더해지면서 평균값을 임곗값으로 사용하게 되었을 가능성이 있습니다. 이미지에 더해진 노란색 테두리 영역이 꽤나 넓기 때문에 전체적인 임곗값을 끌어올리기에는 충분했을 것이고, 그러면 이진화에 사용되는 최종 임곗값 역시 위로 끌려올라가게 됩니다. 테스트에 사용된 JPEG 이미지의 바코드를 확대하면 바코드 막대의 가장자리 픽셀들이 회색으로 연하게 번져있는 모습을 볼 수 있습니다. 높아진 임곗값으로 인해 이 부분이 이진화 과정에서 흰색으로 변환되어 바코드 막대가 얇아지는 등의 문제가 발생했다는 것이 제 추정의 결론입니다. 실제로, HybridBinarizer로 이진화된 이미지를 직접 그려보면 아래와 같이 몇몇 바코드 막대의 두께가 원본보다 얇아진 모습을 볼 수 있습니다. 즉, 이는 바코드의 일부분이 유실된 것으로, 결국 기존 바코드와 흑백 비율이 달라져 에러가 발생한 것으로 추정해볼 수 있겠습니다.
원본 바코드
HybridBinarizer로 이진화한 모습이진화 로직 변경을 통한 개선
제 추정을 요약해보면 ‘이진화에 사용되는 임곗값이 너무 높아져서 바코드 패턴의 일부가 유실되었다’라는 것입니다. 그렇다면 정확히 중간값을 임곗값으로 잡아 이진화를 적용하면 문제가 해결될거라는 단순한 결론에 도달했고, 임곗값을 128로 잡아 직접 이진화를 적용했습니다. 구현은 간단했습니다. zxing.js와 동일하게 canvas 위로 이미지를 올려서 ImageData를 추출한 다음, 그레이스케일 공식을 적용하여 밝기값을 뽑아내고 임곗값을 128로 하여 이진화를 적용하면 됩니다. 아래 이미지를 보면, 이전에 HybridBinarizer에서와는 다르게 바코드가 유실 없이 흑백 비율을 유지하는 모습을 볼 수 있습니다. 이렇게 간단한 개선을 마친 후 테스트를 진행한 결과, 문제가 되었던 노란색 테두리 이미지에 더해 기존의 모바일 캡처 이미지들 또한 바코드가 잘 인식되는 것을 확인할 수 있었습니다. 구현도 크게 어렵지 않아 팀원들에게 리뷰까지 수월하게 마칠 수 있었습니다.
중앙값 이진화를 적용한 모습이후 배포까지 성공적으로 마치고 안도감을 느끼던 와중, 한 팀원이 우는 얼굴로 제게 카카오톡 교환권 이미지를 하나 보내주었습니다. 사실, ZXing이 기존에 블록 단위로 임곗값을 산출하고, 여러 블록의 임곗값을 평균내고 하는 것은 결국 다양한 환경에서의 바코드 인식률을 높이기 위함입니다. 하지만 저는 단순 중간값 이진화로 로직을 변경했기 때문에 바코드 인식률이 낮아질 수 있었고, 거기서 이슈가 발생한 것으로 보였습니다. 다행히도 운영 환경에서 장애가 발생한 것은 아니었고, 테스트용 이미지를 이것저것 집어넣다가 문제가 발견된 것이었습니다. 그래서 배포 전에 빠르게 문제를 해결하고자 바로 원인 분석에 들어갔습니다.
문제를 일으킨 테스트용 이미지바코드 형태에 따라 다른 최적의 이진화 방식
그렇다면 이번에 문제가 된 이미지에는 어떤 특징이 있었을까요? 한참을 고민하다가 생각난 특징 한 가지는 바로 바코드에 유독 얇은 막대가 많고 흰 영역의 비율이 높다는 점이었습니다. 생각해보면, 실제로 매장에 가서 직접 바코드를 찍을 때도 인식이 안되는 경우가 종종 있습니다. 이는 곧 바코드의 모양 자체가 문제가 될 수도 있겠다는 가설로 이어졌고, 검증을 위해 바로 테스트를 진행해보았습니다.
HybridBinarizer로 이진화한 모습
중앙값 이진화를 적용한 모습첫 번째 이미지가 HybridBinarizer로 이진화한 모습이고, 두 번째 이미지가 중앙값으로 이진화한 모습입니다. ZXing이 바코드를 텍스트로 디코딩할 때는 [검은 막대, 흰 공백, 검은 막대, 흰 공백] 의 묶음이 하나의 숫자를 이룹니다. 이때, 각 영역의 비율을 계산하여 숫자로 변환하기 때문에 바코드의 각 영역이 비율을 잘 유지해야 문제없이 디코딩할 수 있습니다. 하지만 위 바코드의 얇은 막대들을 자세히 보면, 이전과는 다르게 오히려 중앙값 이진화에서 제 모습을 유지하지 못하고 더 얇아져 흑백 비율이 왜곡된 모습을 볼 수 있는데요. 특히 우측에 흰 공백이 많은 부분에서 그 정도가 더욱 심해지는 모습을 볼 수 있습니다. 결국, 중앙값 이진화를 거치면서 얇은 막대들 중 일부 영역이 유실되었고, 이러한 비율 왜곡이 누적되어 디코딩 실패로 이어졌다고 추정할 수 있겠습니다.
그러면 내용을 종합해보았을 때, 어떤 이미지는 HybridBinarizer가 유리하고 어떤 이미지는 중앙값 이진화가 유리하다는 것인데, 둘 사이에서 어떻게 조율을 해주면 좋을까요? 한참을 고민하다가 내린 결론은, 그냥 둘 다 시도하는 것이었습니다. ‘내 앨범에 저장하기’ 버튼으로 바코드 이미지를 다운로드하는 사용자 비율이 높다는 가정 하에, 먼저 중앙값 이진화를 통해 디코딩을 시도한 뒤 에러가 발생하면 그 즉시 HybridBinarizer로 이진화하여 다시 디코딩을 시도하게끔 구현해주면 됩니다. 전체 디코딩 과정 자체가 소요 시간이 짧기 때문에, 두 번 시도한다고 해서 시간이 오래 걸린다거나 하지는 않았습니다. 구현을 마친 뒤 테스트를 해보니, 이제껏 문제가 발생했던 케이스들을 전부 성공적으로 디코딩하여 바코드 번호를 추출해낼 수 있었습니다.
일련의 디버깅 과정을 통해 느낀 점은, 첫 번째 에러를 디버깅한 경험이 두 번째 에러를 대응하는 데에 많은 도움이 되었다는 점입니다. 처음 에러가 발생했을 때, 명확하진 않지만 그래도 어느 정도 근본적인 원인을 찾으려고 노력했는데요. 만약 이때 임시방편으로 문제만 해결하고 넘어갔다면, 그다음 에러를 디버깅하는 데에 꽤나 오랜 시간을 소모했을 것입니다. 하지만 부족하게나마 동작 과정을 이해하려 노력했고, 그러다 보니 다른 에러가 발생했을 때 ‘혹시 설마 이게 원인인가..?’ 하고 접근 방법을 빠르게 떠올릴 수 있었습니다. 개똥도 약에 쓴다(?)더니, ‘이걸 어디다 써먹나’ 투덜대면서 디버깅한 경험이 얼마 지나지 않아 바로 다시 쓸모가 생겨서 머쓱하면서도 나름의 배움이 있는 즐거운 경험이었습니다.
낯선 기능을 익숙한 편리함으로: 서비스 수용도를 높이기 위한 고객향 메시지의 고민
카카오톡 선물하기에서 구매한 모바일 교환권을 배달의민족에서 사용할 수 있도록 한 것은 고객분들께는 지금까지는 없었던 옵션을 제공하는 것이었습니다. 때문에 이같이 새롭고 편리한 기능을 어떻게 하면 고객분들께서 자연스럽게 이해하고 체득하실지 고민하며 인앱 프로모션의 키메시지와 그 내용을 구상했습니다.
새로운 기능, 단 세 장면으로 이해시킬 수 있을까?
이번 인앱 프로모션의 목적, 해결해야 할 문제에 대한 질문은 단순했습니다. “고객이 이미 가지고 있는 모바일 교환권을 배민에서 쓸 수 있다는 사실을 어떻게 해야 쉽게 이해하실까?”
카카오톡 선물하기로 받은 모바일 교환권은 많은 고객에게 이미 익숙한 형태입니다. 새로운 기능을 설명하기보다는, 이미 알고 있는 것을 익숙한 배민 앱에서 그대로 사용할 수 있다는 혜택을 빠르게 인지시키는 데 초점을 맞췄습니다.
신규 기능의 주요 플로우 UI위 이미지를 보시면 이 기능을 사용하기 위해 배민앱에서 고객이 실제로 거쳐야 하는 단계는 생각보다 많습니다. 카카오톡 선물함에서 교환권을 확인하고, 배민 앱에 교환권을 등록한 뒤, 주문할 때 사용하는 흐름입니다. 기획자나 내부 구성원에게는 자연스러운 과정이지만, 고객 입장에서는 한 번쯤 멈칫할 수 있는 지점이기도 했습니다.
그래서 모든 과정을 상세히 설명하기보다는, 고객이 가장 익숙하게 느낄 수 있는 경험을 화면 중심으로 단순화하는 데 집중했습니다. 때문에 이 설명은 단 세 개의 지면이면 충분했습니다.
먼저 카카오톡 선물하기 선물함에 있는, 모두가 한 번쯤 봤을 법한 바코드 형태의 모바일 교환권 화면을 떠올리도록 유도했습니다. 그 다음은 배민 앱에서 교환권을 등록하는 화면, 그리고 마지막으로 주문할 때 적용해 자연스럽게 사용하는 익숙한 사용 경험까지 세 가지 화면만을 가져와 표현했습니다.
주요 플로우 중 대표적인 세 지면이 세 장면만 머릿속에 그려지면, “아, 그 교환권을 여기다 등록해서 주문할 때 쓰는 거구나”라고 한 번에 이해할 수 있으시리라 판단했습니다.
공급자 아닌 고객 입장에서 명확한 키메시지를 설계하기
인앱 프로모션에서 소구할 키메시지 설계에서도 같은 원칙을 적용했습니다. 사용 가능한 브랜드나 상품을 나열하는 방식보다, 무엇이 달라졌는지를 가장 직관적으로 전달하는 문장이 필요했습니다.
강조할 수 있는 키워드는 다양했습니다. 먼저 새로운 기능 제공에 초점을 맞춘 내용으로, 배민앱에서 5개 브랜드의 카카오톡 교환권을 사용할 수 있게 되었다는 점. 기존에 제공하고 있던 선물함에서 카카오톡 교환권 이미지로도 등록할 수 있다는 점입니다. 그리고 제휴한 브랜드와 배민앱에서 사용할 수 있는 카카오톡 교환권 옵션에 대해 혜택감 있게 풀어낼 수도 있습니다. 올해 9월 15일 배민앱에서 처음 기능을 런칭했을 때에는 5개 브랜드의 메뉴 교환권 일부만을 사용할 수 있었습니다. 때문에 배민앱에서 사용 가능한 카카오톡 교환권 브랜드의 수 혹은 이 브랜드의 카카오톡 교환권 중 가장 인기 있는 교환권만을 엄선해 들여온 점을 강조할 수도 있습니다. 이같이 여러 소구점을 고심한 끝에 가장 명확하다고 느낀 키메시지는 다음과 같습니다.
“ 카톡에서 받은 선물, 배민앱에서 주문 가능 ”
기능을 제공하는 입장에서는 ‘무엇을 할 수 있는지’ 혹은 ‘무엇을 제공하는지’에 초점을 맞췄겠지만, 고객 입장으로 다시 한번 생각했을 때 ‘이미 가지고 있는 그것을 사용하면 된다’는 점을 전면에 세우는 것이 옳겠다고 판단했습니다. 선물하기 고객뿐만 아니라 배민앱 고객은 이미 배민앱에서 카카오톡 교환권을 사용할 수 없다는 것을 인지하고 있습니다. 하지만 이제는 가능하다는 점을 알려주기만 해도 새로운 기능을 알리는 데 가장 큰 효과를 줄 수 있겠다고 생각했습니다. 등록과 사용 방법은 앞서 말씀드린 세 가지 지면을 활용해 프로모션 페이지 안에서 충분히 안내할 수 있다고 판단해, 키메시지를 최대한 단순하게 가져갔습니다.
더불어 기능 인지 이후의 행동까지 이어지게 하기 위해, 오픈 초반에는 사업팀에서 보유한 카카오페이 쿠폰을 활용한 프로모션을 함께 운영했습니다. 카카오톡 교환권을 배민앱에 등록하고 주문시 사용한 고객분들 1만명 대상으로 카카오페이 5천원 쿠폰을 지급하는 이벤트로 교환권 등록과 실제 사용까지 자연스럽게 이어질 수 있도록 설계했습니다.
단순한 혜택 제공이라기보다는, “한번 등록해 볼 이유”를 만들어주는 장치에 가까웠습니다. 그 결과 오픈 초반 등록과 사용을 빠르게 부스팅하는 역할을 할 수 있었습니다.
쿠폰 지급 이벤트는 14일 동안 진행할 예정이었으나, 준비한 1만개의 5천원 쿠폰이 단 9일만에 선착순 소진되었습니다. 보유한 교환권을 앱에 등록하는 것이 아닌, 주문까지 해야만 얻을 수 있는 혜택인데도 불구하고 9일 동안 수십 만 명의 고객이 프로모션페이지에 방문하였고, 예상했던 소진 기간보다 앞당겨졌었습니다. 또한 프로모션페이지 내에 카카오톡 선물함으로 랜딩하는 버튼을 삽입해 내가 보유한 선물 중 배민앱에서 사용할 수 있는 카카오톡 교환권이 있을지 살펴보도록 액션을 유도하는 모험을 해보았습니다. 그리고 이 버튼을 클릭한 고객님의 약 90% 이상이이 다시 돌아와 프로모션페이지를 열람하는 모습을 확인할 수 있었습니다.
이번 프로모션에서 가장 많이 고민했고, 결과적으로 만족스러운 것은 새로운 기능을 설명하려 하기보다 등록과 사용 과정을 핵심 지면 세 장으로 고객분들께 명확하게 인식시켰다는 점입니다. 고객이 스스로 상상하거나 추측하지 않아도, 직접 주문할 때 사용하는 흐름을 저절로 알 수 있도록 구성하는 데 집중했습니다.
물론 아쉬운 점도 있었습니다. 아직 첫 발자국을 내딛게 된 기능인 만큼, 아래 이미지처럼 사용시 유의사항 안내 문구가 다소 깁니다. 정보를 빠짐없이 전달하려다 보니 생긴 트레이드오프였습니다.
카카오톡 교환권 유의사항 안내 문구마지막으로, 최근 카카오톡 선물하기에서 모바일 교환권을 판매하는 6개 브랜드의 잔액권까지도 사용 가능한 기능이 추가로 오픈되었습니다. 앞으로 더 많은 브랜드가 입점하고 사용 가능한 교환권 범위가 넓어진다면, 이번 경험을 바탕으로 보다 규모감 있는 대고객 마케팅을 집행해 배달의민족의 많은 고객분들이 사랑하는 브랜드 모바일 교환권을 사용해 댁에서 편리하게 따뜻한 음식을 받아보실 수 있다는 것을 널리 알리고, 등록과 주문 사용률을 한 단계 더 끌어올리고자 합니다.
지속적인 개선으로 완성해가는 고객 경험
2025년 9월 16일 서비스 오픈 이후, 고객분들이 기다렸던 만큼 많은 카카오톡 교환권이 배민을 통해 사용되며 비즈니스 성장을 견인하고 있습니다. 프로젝트 팀은 단순 오픈에 그치지 않고 초기 2개월간의 VOC를 면밀히 분석했습니다. 사용법 문의를 제외하고 가장 비중이 높았던 ‘브랜드 확대’ 니즈를 충족하기 위해, 11월과 12월에 걸쳐 상품군 및 교환권 유형 확대를 신속하게 진행했습니다.
일부 브랜드로 시작했으나, 향후 파트너십 확대를 통해 교환권 사용률은 더욱 가파르게 성장할 것으로 기대합니다. 지속적인 브랜드 확장과 사용성 개선을 통해 고객분들의 이용 편의를 극대화할 예정입니다.
지금 카카오톡 선물함에 잠들어 있는 교환권이 있다면, 배민에서 더 편리하게 사용해 보시기 바랍니다.











English (US) ·