Mbtigram / 13 /

결제가 성공했는데 3분 뒤.. 응답이 없다고 뜬다??

결제가 성공했는데 3분 뒤.. 응답이 없다고 뜸??

코인은 이미 들어왔는데 3분 뒤 결제에 실패한 것처럼 안내가 떴음. 결제 결과가 두 길로 들어오는데 타이머는 한쪽 길에서만 꺼지고 있었음.

코인은 들어왔는데 갑자기 응답이 없다고 뜨는 오류

Mbtigram에서 코인을 사면 구글 플레이 결제창이 뜨고, 결제가 끝나면 코인이 들어옴. 문제는 그 뒤였음. 결제를 마치고 3분쯤 지나면 화면에 "응답이 없어요" 안내가 떴음.

코인은 이미 잔액에 있는데 실패한 것처럼 보이니, 사용자 입장에서는 돈이 나갔는지 아닌지 헷갈리기 딱 좋은 문구였음.

결과가 들어오는 길은 두 개

Mbtigram은 웹 화면을 앱 껍데기에 띄우는 구조라, 결제창은 네이티브 쪽이 열고 결과를 웹 화면에 알려 줌. 그 알림이 두 갈래였음.

결과돌아오는 곳하는 일
취소 · 오류__buyResult결제 버튼을 누른 화면에 이유를 알려 줌
성공__purchase구매 토큰을 지급 담당에게 넘김

성공을 따로 받는 건 구매가 결제창에서만 오지 않기 때문임. 지급이 덜 끝난 구매는 앱을 다시 켤 때 다시 올라오기도 함. 그래서 구매 토큰은 언제 어디서 오든 한 곳에서 받아 지급함.

한쪽에서만 꺼지는 타이머

결제 버튼을 누르면 화면은 결과를 기다리며 3분(180초) 타이머를 걺. 네이티브가 끝내 답을 안 주면 버튼이 계속 도는 걸 막으려는 안전장치임. 결과가 오면 타이머를 끔.

그런데 이 타이머를 끄는 건 __buyResult뿐이었음. 성공은 __purchase로 오니까 아무도 타이머를 끄지 않았고, 3분 뒤 그대로 "응답이 없어요"가 떴음.

고친 것 두 가지

성공도 기다림을 끝내게 했음. __purchase가 불리면 결제 버튼 쪽이 아직 기다리고 있는지 보고 "성공"으로 끝내 줌. 지급은 원래대로 지급 담당이 함.

남의 자리는 지우지 않게 했음. 기다리는 쪽은 전역 자리 하나(window.__onBuyResult)에 자기 콜백을 걸어 둠. 옛 코드는 타이머가 끝나면 그 자리를 무조건 비웠음. 그사이 사용자가 결제를 한 번 더 시작했다면 옛 타이머가 새 결제의 콜백을 지워 버리게 됨. 이제는 그 자리에 아직 내 콜백이 걸려 있을 때만 비움.

const mine = (ok, reason) => { clearTimeout(guard); ... };
const guard = setTimeout(() => {
  if (window.__onBuyResult === mine) window.__onBuyResult = null;   // 내 것일 때만
  resolve({ ok: false, reason: "timeout" });
}, 180000);
window.__onBuyResult = mine;

3분 기다리지 않고 확인하기

실제 결제를 다시 하고 3분을 기다릴 수도 있었지만, 그러면 고칠 때마다 돈이 나감. 대신 헤드리스 크롬에서 웹 화면을 띄우고 네이티브 창구를 가짜로 꽂은 뒤, 그 창구로 성공 신호를 보냈음. 결제를 시작할 때 걸린 타이머가 성공 신호 뒤에 꺼지는 것까지 확인했음.