2026.08.20 작업일지 v1.0.0
19:18, 나는 우리 앱에서 실제로 결제 버튼을 눌렀다. 29,000원이 빠져나갔다. 그런데 상품은 오지 않았다. 그날 밤, 우리는 돈을 되돌릴 수 없는 결제 시스템의 구멍을 손으로 밟아 확인했다.
“작업은 열심히 하는데 결과물이 안 보인다”는 3주치 회고 끝에, 사장이 직접 실사용자처럼 유료 결제를 눌러봤다. 그 한 번의 테스트가 가장 아픈 방식으로 진짜 버그를 잡아냈다. 이날은 그 사고를 수습하고, 동시에 함대의 두뇌를 새 일꾼으로 옮기는 긴 이사를 이어간 하루였다.
1. 검증에 실패했는데 결제는 완료됐다
iOS 결제의 흐름은 이래야 한다 — 애플이 영수증을 검증해 통과하면, 그때만 상품을 지급 완료 처리한다. 그런데 우리 앱은 애플 검증이 실패(코드 21002)했는데도 완료 처리를 호출했다. 그 호출이 애플의 재전달 경로를 끊어버려서, 돈은 나갔는데 상품도 안 오고 복구도 막혔다. 안드로이드였으면 개발자가 바로 환불할 수 있지만, 애플은 그것조차 별도 절차와 계약 동의가 필요했다.
수리는 세 겹으로 갔다. 서버가 영수증(JWS)을 제대로 검증하도록 고치고 실패 기록을 보존하게 했으며(1c44eec), 앱은 검증 실패 시 완료 처리를 절대 못 하도록 막았다(fd98704). 밤늦게 iOS 수리판(1.0.3+7)을 심사에 올렸다 — 결과는 최대 48시간 뒤.
배운 것 — “완료 처리”는 검증이 성공한 뒤에만 불러야 한다. 순서가 뒤집히면 돈은 나가고 상품은 사라진다.
2. 아무 그물에도 안 걸린 사각
더 무서웠던 건, 이 사고가 어떤 경보에도 안 걸렸다는 점이다. 정상 주문이 0건이라 “매출이 떨어졌다”는 어떤 감시에도 잡히지 않았다. 그래서 매출 경로의 침묵 자체를 감지하는 장치(9311bd8)를 새로 세웠다. 아무 일도 안 일어나는 것이 곧 사고일 수 있다는 걸, 돈을 잃고 나서야 계기로 만들었다.
3. 두뇌 이사: 새 일꾼으로 갈아타기
8월 말 요금제 전환을 앞두고, 함대의 여러 창구를 새 일꾼(Grok)으로 옮기는 작업을 종일 이어갔다. 새 일꾼용 텔레그램 봇 5개를 만들고 자격을 배선했으며, 지식 인프라(메모리·검색)를 새 일꾼이 이어받도록 변환기를 붙였다. 카톡봇의 ‘두뇌’도 새 일꾼의 격리 상자로 옮기기로 하고, 상자 안에서 인터넷 검색이 살아 있는지까지 실제로 확인했다 — 검색 질문에 출처 링크가 붙은 답이 돌아왔다. 실제 전환 스위치는 이날 밤 승인을 받아 넘기는 중이다.
4. 카톡봇이 검색과 사진을 헷갈리던 버그
카톡봇에서 ”!뉴스”를 물으면 몇 시간 전에 올라온 사진이 자동으로 딸려붙어, 봇이 검색 대신 그림 읽기로 새는 문제가 있었다. 오래된 사진 흔적의 ‘신선도’를 판별해, 질문과 무관한 낡은 사진은 떼어내고 검색을 살리도록 고쳤다. 반대로 방금 올린 사진에 “뭐라고 적혔어”라고 물으면 원본 화질로 글자를 정확히 읽는 것도 그대로 유지됨을 확인했다.
5. 그래서 뭐가 남았나
가장 아픈 실피해(결제 유실)를 세 겹으로 수리해 재발을 막고 iOS 재심사를 올렸으며, 매출 침묵을 감지하는 계기를 새로 세웠다. 새 일꾼으로의 두뇌 이사는 봇 배선·지식 인프라·검색 확인까지 진척됐고, 카톡봇의 검색/사진 혼선도 잡았다. 사고로 시작했지만, 그 사고가 결제·감시·품질 세 축을 한꺼번에 단단하게 만든 하루였다. 이사는 아직 밤까지 이어지는 중이다.
다음 이야기는 새 일꾼이 함대를 넘겨받는 이야기.
— 강대종 / @ssamssae