반응형
이번 포스트에서는 Android 인앱결제 구독 동기화를 위한 Google RTDN (Real-time Developer Notifications) 개발 과정과 고민했던 내용들을 정리해보았습니다.
이전 글에서 공유한 iOS ASN 개발기에 이어, Android에서도 실시간 구독 상태 동기화가 필요해 RTDN을 도입하게 되었어요.
왜 RTDN을 도입했을까?
Google API를 통해 수동으로 구독 상태를 검증하고 있었습니다. 하지만 이 방식은 앱 접속 시점에만 동기화가 가능해 실시간성이 부족했습니다.
- 앱을 켜지 않으면 구독 상태 동기화 불가능
- 자동갱신/ 유예/ 취소 등의 상태 반영 지연 같은 문제로 실시간성이 떨어졌습니다.
이를 해결하고자 Google에서 제공하는 RTDN을 도입하게 되었습니다.
인프라 구성: Google RTDN → Pub/Sub → Backend
Google은 RTDN을 Pub/Sub 방식으로 제공합니다. 이 메시지를 백엔드에 안전하게 전달하기 위해 아래 구조로 구성했습니다:
Google Play RTDN → Google Cloud Pub/Sub → Backend 서버
- Pub/Sub: Google이 메시지를 발행하는 통로
- Backend: 구독 상태 업데이트 및 DB 반영
개발 중 겪었던 고민들
1. Pub/Sub 환경 구성
- IOS와 아키텍처를 통일해서 Pub/Sub → AWS API Gateway → SQS를 구조를 구성해야 하나 고민을 하였지만 Pub/Sub도 충분 히 신뢰성 있는 메시징 서비스이고, 데드 레터 처리가 가능해서 Gateway → SQS 구조를 과감하게 배제
2. 환불(Refund) RTDN 이슈
- voidedPurchaseNotification 값 뿐만아니라 SUBSCRIPTION_REVOKED 상태값에서도 환불이 들어옴
3. 테스트 환경 RTDN 수신 문제
- Google은 Push 구독의 엔드포인트를 한 개만 운영 등록 가능하기 때문에, 개발 환경에서는 RTDN 수신 테스트가 어려움.
- Pub/Sub의 구독을 개발용으로 생성해서 개발 엔드포인트에도 동시에 푸시 받는 구조로 해결.
구현 포인트 정리
- notificationType 기반으로 상태 분기 처리
→ SUBSCRIPTION_RENEWED, CANCELED, EXPIRED 등 - subscriptionState 기반으로 보조 판단
→ 실제 상태가 IN_GRACE_PERIOD 인데 RENEWED라고 오면 이중 체크 - voidedPurchaseNotification 수신 시 환불 처리
- 구독권 비교 시 orderId 기준으로 최신 구독 여부 판단
→ 기존 DB orderId ≠ RTDN orderId → 상태 재조회 + 동기화 - 테스트 결제 구분 (res.testPurchase 확인 후 production 에선 무시)
마무리
향후에 메시징 서비스를 한쪽으로 통합해서 IOS, AOS 결제를 한 번 가공해서 백엔드 엔드 포인트로 넘기는 구조로 개선한다면 백엔드 비즈니스 코드가 유지 보수성이 개선될 수도 있을 것 같습니다!
728x90
반응형
'아키텍처 고민' 카테고리의 다른 글
랜덤 문제 풀이 이거 간단하거 아니었네? (0) | 2025.03.27 |
---|---|
Node.js 버전 차이로 인한 장애 대응기 (0) | 2025.03.17 |
iOS In-App Purchase와 Apple Server Notification(ASN) 개발기 (0) | 2025.03.14 |