반응형

이번 포스트에서는 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
반응형

+ Recent posts