Repository navigation
[GMSS-343,346] Google Play 결제 연동 BillingClient 생성 및 단위 테스트 구축 - #79
Merged
Merged
Conversation
- BillingClient 연결 상태, 상품 조회, 구매 플로우 실행, 미처리 구매 복구, consume을 처리하는 BillingRepository/PlayBillingRepository 구현 - 구매 콜백과 미처리 구매 복구 조회 결과를 공통된 BillingPurchaseOutcome으로 매핑하는 BillingPurchaseOutcomeMapper 추가 - ForwardingPurchasesUpdatedListener로 BillingClient 생성 시점과 리스너 처리 주체(PlayBillingRepository)의 생성 순서 의존성을 해소하고 Hilt 모듈로 바인딩
- Google 정적 테스트 상품으로 BillingClient 연결·상품 조회·구매 플로우를 수동 검증하는 디버그 화면 추가 - 구매 콜백, 미처리 구매 복구 조회, consume 처리 결과를 로그로 확인 가능 - adb로만 실행 가능한 디버그 빌드 전용 액티비티로 매니페스트에 등록
- BillingPurchaseOutcomeMapper의 응답코드·구매상태별 매핑 결과(Purchased/Pending/UserCanceled/AlreadyOwned/Error)를 검증 - PlayBillingRepository의 연결 상태 전환, 미처리 구매 자동 재조회, 구매 콜백 및 ITEM_ALREADY_OWNED 복구 흐름을 검증 - queryProductDetails가 캐시 없이 매 호출마다 Play에 재조회함을 검증
- 실기기 user 빌드에서 shell UID로 액티비티를 실행할 수 있도록 exported를 활성화 - 런처 인텐트 필터가 없음을 명시해 디버그 전용 진입 경로를 유지
- BillingClient 콜백과 API 호출을 데이터소스로 캡슐화 - 리포지토리가 연결 상태와 구매 결과 도메인 처리만 담당하도록 개선 - 데이터소스 Fake를 도입하고 연결 종료 동작을 테스트에 반영
seunghee17
marked this pull request as ready for review
November 6, 2026 04:01
soyeonLee126
reviewed
Nov 6, 2026
soyeonLee126
left a comment
Collaborator
There was a problem hiding this comment.
(P3) 작업 유형에서 refactor: 리팩토링 (동작 변경 없음)이 체크되어 있습니다. 이번 PR은 새 모듈과 디버그 화면을 추가한 것이라 기존 코드를 리팩터링한 부분은 없는 것 같습니다. 체크를 해제하면 좋을 것 같습니다!
…ture/billing-client
- android.test.* 상품이 queryProductDetailsAsync로 조회되지 않아 구매창·콜백·consume 흐름은 미검증임을 명시 - Google 공식 문서가 License Tester + 실제 등록 상품 방식만 안내한다는 배경 추가
- queryPurchases/consumePurchase 반환형을 Pair/BillingResult 대신 PurchasesResult/ConsumeResult로 변경하고 queryPurchasesAsync/consumePurchase KTX 확장 함수로 구현 단순화 - PlayBillingRepository의 consumePurchase는 ConsumeResult.billingResult를 반환하도록 수정
- BillingConnectionState.CLOSED 상태와 이를 사용하는 endConnection API를 Repository/DataSource 전 계층에서 제거
- ITEM_ALREADY_OWNED는 구매 정보가 없는 실패 코드이므로 AlreadyOwned를 data class에서 data object로 변경 - 매퍼와 테스트에서 불필요한 productIds = emptyList() 인자 제거
- BillingResult 노출을 제거하고 isSuccess/responseCode를 담은 BillingOperationResult로 대체 - BillingProduct의 ProductDetails를 internal로 숨기고 productId를 별도 필드로 공개 - 테스트와 디버그 화면을 새 필드(callResult, productId)에 맞춰 갱신
- consumePurchase가 서버 지급 검증 이후에만 호출되어야 함을 문서화 - _purchaseResults를 extraBufferCapacity 대신 replay + DROP_OLDEST로 구성해 늦은 구독자도 최근 구매 결과를 받을 수 있게 변경
soyeonLee126
reviewed
Nov 9, 2026
- BillingResult/ProductDetails가 공개 API로 노출되지 않도록 billing-ktx 의존성 범위를 축소
- 구매 결과가 여러 곳에서 collect될 경우 분산 전달될 수 있다는 점을 문서화 - MutableSharedFlow(replay) 대신 Channel + receiveAsFlow로 각 결과를 정확히 한 번만 전달하도록 변경
soyeonLee126
approved these changes
Nov 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
작업 개요
Google Play 결제 연동(Billing Library 9.1.0)을 위한
core:billing모듈을 추가했습니다. 이번 PR 범위는 BillingClient 생성(DI) + 단위 테스트 구축까지이며, 실제 구매 화면/서버 연동은 포함하지 않습니다.작업 유형
변경 사항
core:billing모듈 신규 추가 —BillingRepository(connect/endConnection/queryProductDetails/launchPurchaseFlow/queryUnfinishedPurchases/consumePurchase)PlayBillingDataSource/PlayBillingDataSourceImpl로 BillingClient SDK 콜백 호출 계층을 분리 — Repository는 SDK를 몰라도 되고, 테스트에서 Fake로 교체 가능BillingPurchaseOutcomeMapper— 응답코드(OK+PURCHASED/PENDING, USER_CANCELED, ITEM_ALREADY_OWNED 등)를 도메인 상태로 매핑PlayBillingRepositoryTest10개,BillingPurchaseOutcomeMapperTest6개) —FakeBillingDataSource기반BillingDebugActivity추가 — 구글 정적 테스트 상품으로 연결/상품조회/구매/복구조회/consume을 수동 검증 (adb로만 실행, 프로덕션 미노출)관련 이슈
관련 작업 (Notion)
스크린샷 / 동작 화면
체크리스트
develop으로 설정되어 있다:core:billing:testDebugUnitTest,:core:billing:detekt,:app:compileDebugKotlin통과, 실기기에서 디버그 화면 실행 확인)feat:,fix:등)을 따른다리뷰 요청 사항
PlayBillingRepository.endConnection()호출 후에도 내부 Flow 구독 코루틴이 취소되지 않아, SDK가 뒤늦게 보내는 연결 콜백(onBillingServiceDisconnected)이CLOSED상태를 덮어쓸 수 있는 레이스가 있습니다. 현재는endConnection()을 호출하는 생명주기 연동 코드가 없어 실질적 영향은 없지만, 실제 화면/앱 생명주기 연동 시점에 다시 다룰 예정입니다.android.test.*)은queryProductDetailsAsync(Billing Library v5+)로 조회되지 않아 디버그 화면에서 실제 구매창까지는 확인하지 못했습니다. Play Console 상품 등록 + License Testing이 필요한 별도 작업입니다.ActivityLifecycleCallbacks) 연동, 서버 검증·지급 API, 실제 구매 화면은 이번 PR 범위 밖입니다.