Skip to content

Commit ae56869

Browse files
authored
[PC-1331] 결제 모듈 리팩토링 (#168)
* [PC-1331] 파일 구조 변경 및 함수명 수정 * [PC-1331] BillingHelper 뷰모델 scope로 변경 * [PC-1331] billinHelper 안에 paymentRepository 주입. StoreViewModel 까지 수정. * [PC-1331] core/data 모듈의 billingclient 의존성 제거 * [PC-1331] API 호출에 대한 책임을 viewModel로 변경 * [PC-1331] 패키지 구조 변경 및 gradle 세팅 수정
1 parent 96a587c commit ae56869

File tree

12 files changed

+58
-42
lines changed

12 files changed

+58
-42
lines changed

core/billing/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ android {
1010
dependencies {
1111
implementation(projects.core.common)
1212
implementation(projects.core.domain)
13+
implementation(projects.core.network)
1314

1415
implementation(libs.android.billingclient)
1516
}

core/data/src/main/java/com/puzzle/data/billing/BillingHelperImpl.kt renamed to core/billing/src/main/java/com/puzzle/billing/data/BillingHelperImpl.kt

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,47 @@
1-
package com.puzzle.data.billing
1+
package com.puzzle.billing.data
22

33
import android.app.Activity
44
import android.content.Context
55
import android.util.Log
66
import com.android.billingclient.api.BillingClient
7-
import com.android.billingclient.api.BillingClient.BillingResponseCode
87
import com.android.billingclient.api.BillingClientStateListener
98
import com.android.billingclient.api.BillingFlowParams
109
import com.android.billingclient.api.BillingResult
11-
import com.android.billingclient.api.ConsumeParams
1210
import com.android.billingclient.api.PendingPurchasesParams
1311
import com.android.billingclient.api.ProductDetails
1412
import com.android.billingclient.api.PurchasesUpdatedListener
1513
import com.android.billingclient.api.QueryProductDetailsParams
16-
import com.android.billingclient.api.QueryPurchasesParams
1714
import com.android.billingclient.api.queryProductDetails
18-
import com.puzzle.billing.BillingHelper
15+
import com.puzzle.billing.domain.BillingHelper
16+
import com.puzzle.billing.domain.PaymentRepository
1917
import com.puzzle.billing.model.NormalProduct
2018
import com.puzzle.billing.model.PieceProduct
2119
import com.puzzle.billing.model.PromotionProduct
20+
import com.puzzle.common.suspendRunCatching
21+
import com.puzzle.domain.model.error.ErrorHelper
2222
import com.puzzle.domain.model.payment.CashProduct
2323
import com.puzzle.domain.model.payment.Product
2424
import com.puzzle.domain.model.payment.PurchaseProduct
2525
import dagger.hilt.android.qualifiers.ApplicationContext
26+
import dagger.hilt.android.scopes.ViewModelScoped
2627
import kotlinx.collections.immutable.ImmutableList
28+
import kotlinx.collections.immutable.persistentListOf
2729
import kotlinx.collections.immutable.toImmutableList
30+
import kotlinx.coroutines.CoroutineScope
2831
import kotlinx.coroutines.Dispatchers
32+
import kotlinx.coroutines.SupervisorJob
2933
import kotlinx.coroutines.flow.MutableStateFlow
3034
import kotlinx.coroutines.flow.StateFlow
3135
import kotlinx.coroutines.flow.asStateFlow
36+
import kotlinx.coroutines.launch
3237
import kotlinx.coroutines.suspendCancellableCoroutine
3338
import kotlinx.coroutines.withContext
3439
import javax.inject.Inject
3540
import kotlin.coroutines.resume
3641
import kotlin.coroutines.resumeWithException
3742

3843
class BillingHelperImpl @Inject constructor(
44+
private val paymentRepository: PaymentRepository,
3945
@ApplicationContext context: Context,
4046
) : BillingHelper {
4147
private val _purchaseProduct = MutableStateFlow<PurchaseProduct?>(null)
@@ -44,7 +50,7 @@ class BillingHelperImpl @Inject constructor(
4450
private val purchasesUpdatedListener = PurchasesUpdatedListener { result, purchases ->
4551
Log.d("purchasesUpdateListener", "$result $purchases")
4652

47-
if (result.responseCode == BillingResponseCode.OK && !purchases.isNullOrEmpty()) {
53+
if (result.responseCode == BillingClient.BillingResponseCode.OK && !purchases.isNullOrEmpty()) {
4854
purchases.forEach { purchase ->
4955
val token = purchase.purchaseToken
5056
val uuid = purchase.products.firstOrNull() ?: return@forEach
@@ -63,7 +69,9 @@ class BillingHelperImpl @Inject constructor(
6369
.enableAutoServiceReconnection()
6470
.build()
6571

66-
override suspend fun getAvailableProducts(cashProducts: CashProduct): ImmutableList<PieceProduct> {
72+
override suspend fun getAvailableProducts(): CashProduct = paymentRepository.getAvailableProduct()
73+
74+
override suspend fun processAvailableProducts(cashProducts: CashProduct): ImmutableList<PieceProduct> {
6775
connectGooglePlayIfNeeded()
6876

6977
val productList = cashProducts.products.map {
@@ -108,11 +116,14 @@ class BillingHelperImpl @Inject constructor(
108116

109117
val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)
110118

111-
if (billingResult.responseCode != BillingResponseCode.OK) {
119+
if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
112120
Log.e("Billing", "Purchase failed: ${billingResult.debugMessage}")
113121
}
114122
}
115123

124+
override suspend fun verifyPurchaseProduct(purchaseProduct: PurchaseProduct) =
125+
paymentRepository.verifyPurchaseProduct(purchaseProduct)
126+
116127
private suspend fun connectGooglePlayIfNeeded() = suspendCancellableCoroutine { continuation ->
117128
if (billingClient.isReady) {
118129
continuation.resume(Result.success(Unit))
@@ -121,7 +132,9 @@ class BillingHelperImpl @Inject constructor(
121132

122133
billingClient.startConnection(object : BillingClientStateListener {
123134
override fun onBillingSetupFinished(result: BillingResult) {
124-
if (result.responseCode == BillingResponseCode.OK) continuation.resume(Unit)
135+
if (result.responseCode == BillingClient.BillingResponseCode.OK) continuation.resume(
136+
Unit
137+
)
125138
else continuation.resumeWithException(Exception("Billing setup failed: ${result.debugMessage}"))
126139
}
127140

@@ -160,4 +173,5 @@ class BillingHelperImpl @Inject constructor(
160173
}
161174
}
162175
}
163-
}
176+
177+
}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
package com.puzzle.data.repository
1+
package com.puzzle.billing.data
22

3+
import com.puzzle.billing.domain.PaymentRepository
34
import com.puzzle.domain.model.payment.CashProduct
45
import com.puzzle.domain.model.payment.PurchaseProduct
5-
import com.puzzle.domain.repository.PaymentRepository
66
import com.puzzle.network.source.payment.PaymentDataSource
77
import javax.inject.Inject
88

@@ -12,6 +12,6 @@ class PaymentRepositoryImpl @Inject constructor(
1212
override suspend fun getAvailableProduct(): CashProduct =
1313
paymentDataSource.getAvailableProduct().toDomain()
1414

15-
override suspend fun purchaseProduct(purchaseProduct: PurchaseProduct) =
16-
paymentDataSource.purchaseProduct(purchaseProduct)
17-
}
15+
override suspend fun verifyPurchaseProduct(purchaseProduct: PurchaseProduct) =
16+
paymentDataSource.verifyPurchaseProduct(purchaseProduct)
17+
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.puzzle.billing
1+
package com.puzzle.billing.domain
22

33
import android.app.Activity
44
import com.puzzle.billing.model.PieceProduct
@@ -9,6 +9,8 @@ import kotlinx.coroutines.flow.StateFlow
99

1010
interface BillingHelper {
1111
val purchaseProduct: StateFlow<PurchaseProduct?>
12-
suspend fun getAvailableProducts(cashProducts: CashProduct): ImmutableList<PieceProduct>
12+
suspend fun getAvailableProducts(): CashProduct
13+
suspend fun processAvailableProducts(cashProducts: CashProduct): ImmutableList<PieceProduct>
1314
fun purchaseProduct(activity: Activity, purchaseProduct: PieceProduct)
14-
}
15+
suspend fun verifyPurchaseProduct(purchaseProduct: PurchaseProduct)
16+
}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
package com.puzzle.domain.repository
1+
package com.puzzle.billing.domain
22

33
import com.puzzle.domain.model.payment.CashProduct
44
import com.puzzle.domain.model.payment.PurchaseProduct
55

66
interface PaymentRepository {
77
suspend fun getAvailableProduct(): CashProduct
8-
suspend fun purchaseProduct(purchaseProduct: PurchaseProduct)
9-
}
8+
suspend fun verifyPurchaseProduct(purchaseProduct: PurchaseProduct)
9+
}

core/data/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,4 @@ dependencies {
1515
implementation(projects.core.billing)
1616

1717
implementation(libs.androidx.exifinterface)
18-
implementation(libs.android.billingclient)
1918
}

core/data/src/main/java/com/puzzle/data/di/DataModule.kt

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
package com.puzzle.data.di
22

3-
import com.puzzle.billing.BillingHelper
4-
import com.puzzle.data.billing.BillingHelperImpl
3+
import com.puzzle.billing.domain.BillingHelper
4+
import com.puzzle.billing.data.BillingHelperImpl
55
import com.puzzle.data.image.ImageResizeProcessor
66
import com.puzzle.data.image.ImageResizeProcessorImpl
77
import com.puzzle.data.repository.AuthRepositoryImpl
88
import com.puzzle.data.repository.ConfigureRepositoryImpl
99
import com.puzzle.data.repository.ErrorRepositoryImpl
1010
import com.puzzle.data.repository.MatchingRepositoryImpl
1111
import com.puzzle.data.repository.NotificationRepositoryImpl
12-
import com.puzzle.data.repository.PaymentRepositoryImpl
12+
import com.puzzle.billing.data.PaymentRepositoryImpl
1313
import com.puzzle.data.repository.ProfileRepositoryImpl
1414
import com.puzzle.data.repository.TermsRepositoryImpl
1515
import com.puzzle.data.repository.TokenManagerImpl
@@ -19,14 +19,16 @@ import com.puzzle.domain.repository.ConfigureRepository
1919
import com.puzzle.domain.repository.ErrorRepository
2020
import com.puzzle.domain.repository.MatchingRepository
2121
import com.puzzle.domain.repository.NotificationRepository
22-
import com.puzzle.domain.repository.PaymentRepository
22+
import com.puzzle.billing.domain.PaymentRepository
2323
import com.puzzle.domain.repository.ProfileRepository
2424
import com.puzzle.domain.repository.TermsRepository
2525
import com.puzzle.domain.repository.UserRepository
2626
import com.puzzle.network.interceptor.TokenManager
2727
import dagger.Binds
2828
import dagger.Module
2929
import dagger.hilt.InstallIn
30+
import dagger.hilt.android.components.ViewModelComponent
31+
import dagger.hilt.android.scopes.ViewModelScoped
3032
import dagger.hilt.components.SingletonComponent
3133
import javax.inject.Singleton
3234

@@ -99,9 +101,14 @@ abstract class DataModule {
99101
abstract fun bindTokenManager(
100102
tokenManagerImpl: TokenManagerImpl,
101103
): TokenManager
104+
}
105+
106+
@Module
107+
@InstallIn(ViewModelComponent::class)
108+
abstract class BillingModule {
102109

103110
@Binds
104-
@Singleton
111+
@ViewModelScoped
105112
abstract fun bindBillingHelper(
106113
billingHelperImpl: BillingHelperImpl
107114
): BillingHelper

core/network/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,4 @@ dependencies {
5656
implementation(libs.okhttp.logging)
5757
implementation(libs.firebase.config)
5858
implementation(libs.firebase.messaging)
59-
implementation(libs.android.billingclient)
6059
}

core/network/src/main/java/com/puzzle/network/source/payment/PaymentDataSource.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ import com.puzzle.network.model.payment.GetAvailableProductResponse
55

66
interface PaymentDataSource {
77
suspend fun getAvailableProduct(): GetAvailableProductResponse
8-
suspend fun purchaseProduct(purchaseProduct: PurchaseProduct)
8+
suspend fun verifyPurchaseProduct(purchaseProduct: PurchaseProduct)
99
}

core/network/src/main/java/com/puzzle/network/source/payment/PaymentDataSourceImpl.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ class PaymentDataSourceImpl @Inject constructor(
1313
override suspend fun getAvailableProduct(): GetAvailableProductResponse =
1414
pieceApi.getAvailableProduct().unwrapData()
1515

16-
override suspend fun purchaseProduct(purchaseProduct: PurchaseProduct) =
16+
override suspend fun verifyPurchaseProduct(purchaseProduct: PurchaseProduct) =
1717
pieceApi.verifyPurchaseProduct(purchaseProduct.toDto()).unwrapData()
1818
}

0 commit comments

Comments
 (0)