크로스플랫폼 결제 모듈입니다. Android 는 Google Play Billing, iOS 는 StoreKit 2
를 사용하며 L1 BillingEngine 계약으로 통합되어 있습니다.
- Kotlin 2.0.20, Compose Multiplatform 1.7.x, AGP 8.6.x, Gradle 8.10, Java 21.
- Play Console + App Store Connect 제품 ID 구성
(예:
pro_monthly,pro_yearly). - 유효한
moonLicenseKey. - Koin 4.1.0.
(저장소 블록은 auth/ko.md §2 와 동일합니다.)
implementation("io.moondeveloper:moon-firebase-billing-kmp:1.0.0")- 매니페스트에
com.android.vending.BILLING권한을 선언합니다. - 실결제 테스트를 위해 내부 테스트 트랙에 앱을 게시합니다.
- 영수증 검증을 위해 Firebase 측에 서비스 계정 키가 필요합니다.
- Xcode 타겟에서 StoreKit capability 를 활성화합니다.
- 디버그 빌드 결제에는 샌드박스 테스터 계정이 필요합니다.
import io.moondev.firebase.billing.firebaseBillingModule
startKoin {
modules(firebaseBillingModule /*, ... */)
}모듈 내부에서 createBillingEngine(...) 을 사용해 플랫폼별 구현을 선택합니다.
class SubscriptionStore(private val billing: BillingEngine) {
suspend fun load(): List<Product> =
billing.queryProducts(listOf("pro_monthly", "pro_yearly"))
suspend fun buy(id: String): PurchaseResult =
billing.launchPurchase(id)
}@Composable
fun SubscriptionScreen(store: SubscriptionStore = koinInject()) {
// LaunchedEffect 에서 store.load() 호출, 제품 렌더링, 구매 버튼 연결.
}- "Product not found" — 테스터 트랙에 제품이 아직 게시되지 않았거나 테스터가 아닌 계정으로 로그인되어 있습니다.
- 기기에서는 결제가 성공하지만 권한이 갱신되지 않음 — 서버의 영수증 검증 웹훅이 결제를 확인하지 않고 있습니다.
- 시뮬레이터에서 결제 불가 — iOS 는 샌드박스 테스터 계정의 실기기, Android 는 내부 테스트 트랙을 사용해야 합니다.
- 권한을
uid에 묶기 위해 moon-firebase-auth-kmp 와 결합합니다. - 샘플 참조:
SubscriptionScreen.kt.