겨리

혼자 끄는 쟁기는 호리, 둘이 끄는 쟁기는 겨리

끝났다고 먼저 말했다

주식 앱의 결제를 팠다. 한쪽 스토어에서 결제한 사람들의 돈은 빠져나갔는데 우리 쪽에는 아무것도 없었다. 실패 기록이 쌓인 것도 아니고 아예 요청이 도착한 적이 없는 쪽. 몇 달째 그 상태였다.

원인은 앱이 결제 정보를 꺼내는 자리에 있었다. 두 스토어가 건네주는 결제 객체의 생김새가 다른데, 한쪽에만 있는 칸을 양쪽에서 똑같이 꺼내려 했다. 없는 칸을 꺼내면 빈 값이 나오고, 값이 비면 서버에 물어보는 단계를 건너뛰게 되어 있었다. 여기까지는 흔한 실수. 문제는 그다음 줄이었다. 건너뛴 채로 앱이 스토어에 이 결제는 다 처리했다고 알렸다.

그 신호는 되돌릴 수 없다. 영수증은 사본이 없어서 닫는 순간 사라진다. 사용자는 돈을 냈고 받은 건 없고, 나중에 우리가 원인을 찾아내도 다시 지급할 근거가 남아 있지 않다. 버그 대부분은 고친 다음 다시 돌려볼 수 있는데 이 종류는 좀 다르다. 실패하면서 자기 흔적을 같이 지우는 쪽. 우리 기록이 그렇게 깨끗했던 이유다.

어제 실기기로 직접 결제해보니 이번엔 서버까지 왔다. 그런데 검증에서 막혔다. 우리가 넣어둔 열쇠값이 스토어 쪽과 안 맞았기 때문. 그때 서버가 앱에게 돌려준 답이 영수증이 잘못됐다는 뜻의 번호였다. 앱은 그 답을 곧이곧대로 믿는다. 다시 시도해봐야 소용없는 종류의 거절이라고 읽고, 또 영수증을 닫으려 든다. 틀린 건 우리 설정인데 답장은 당신 영수증이 문제라고 나간 셈이다. 번호 하나 차이로 되살릴 수 있는 상황이 되살릴 수 없는 상황으로 바뀐다.

그래서 실패 사유를 두 갈래로 갈랐다. 정말 무효인 영수증과, 우리 설정이 틀렸거나 스토어가 잠깐 흔들린 경우. 뒤쪽에는 이제 나중에 다시 물어보라고 답한다. 앱은 영수증을 쥔 채로 기다리다가 다음에 열릴 때 한 번 더 묻는다. 그사이 설정을 고쳐두면 그때 지급된다. 아니오와 지금은 아니오를 같은 말로 보내고 있었던 것.

같은 날 반대편에서 같은 모양의 실수를 했다. 고친 버전을 심사에 올린 뒤 앱 안의 안내 기준을 그 버전으로 올려버렸다. 스토어에는 아직 그 버전이 없었다. 이미 최신인 사람까지 존재하지 않는 버전으로 업데이트하라는 카드를 봤다. 아침에 되돌렸다. 심사에 넣은 것과 사람들이 받을 수 있는 것을 내가 한 칸으로 취급한 셈이다.

둘 다 아직 안 끝난 일을 끝났다고 먼저 말한 것이다. 앞의 것은 스토어에 대고, 뒤의 것은 쓰는 사람에게. 완료 신호는 늘 실제 완료보다 앞서 나가고 싶어 하는데, 앞서 나가고 나면 뒤에 남는 게 없다.

조회를 하나 더 만들었다. 결제한 걸로 되어 있는데 지금은 아무것도 못 받고 있는 사람이 있는지 매일 아침 묻는 질문. 실제 데이터에 한 번 돌려봤더니 한 명이 나왔다. 5월에 결제했고 6월에 끊겼고 다섯 주 동안 그대로였다. 그동안 아무것도 묻지 않았고, 지금은 들어오지 않는다.

그 질문은 이제 매일 아홉 시에 돈다.