Skip to content

Commit c765d70

Browse files
committed
fix(services/flipcash): update IapMetadata to use CurrencyCode; normalize at API level
Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent 7f8da09 commit c765d70

File tree

4 files changed

+29
-11
lines changed

4 files changed

+29
-11
lines changed

services/flipcash/src/main/kotlin/com/flipcash/services/billing/BillingClient.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,18 @@ class IapPaymentError(val code: Int, override val message: String): Throwable(me
2121
constructor(result: BillingResult): this(result.responseCode, result.debugMessage)
2222
}
2323

24+
data class ProductPrice(
25+
val amount: Double,
26+
val currency: String
27+
)
2428
interface BillingClient {
2529
val eventFlow: SharedFlow<IapPaymentEvent>
2630
val state: StateFlow<BillingClientState>
2731

2832
fun connect()
2933
fun disconnect()
3034
fun hasPaidFor(product: IapProduct): Boolean
31-
fun costOf(product: IapProduct): String
35+
fun costOf(product: IapProduct): ProductPrice?
3236
suspend fun purchase(activity: Activity, product: IapProduct)
3337
}
3438

@@ -47,7 +51,7 @@ object StubBillingClient: BillingClient {
4751
override fun connect() = Unit
4852
override fun disconnect() = Unit
4953
override fun hasPaidFor(product: IapProduct): Boolean = false
50-
override fun costOf(product: IapProduct): String = "NOT_DEFINED"
54+
override fun costOf(product: IapProduct): ProductPrice? = null
5155
override suspend fun purchase(activity: Activity, product: IapProduct) {
5256
delay(1.seconds)
5357
_eventFlow.emit(IapPaymentEvent.OnSuccess(product.productId))

services/flipcash/src/main/kotlin/com/flipcash/services/internal/billing/GooglePlayBillingClient.kt

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ import com.flipcash.services.billing.BillingClientState
2525
import com.flipcash.services.billing.IapPaymentError
2626
import com.flipcash.services.billing.IapPaymentEvent
2727
import com.flipcash.services.billing.IapProduct
28+
import com.flipcash.services.billing.ProductPrice
2829
import com.flipcash.services.internal.model.billing.IapMetadata
2930
import com.flipcash.services.internal.model.billing.Receipt
3031
import com.flipcash.services.repository.PurchaseRepository
3132
import com.flipcash.services.user.UserManager
33+
import com.getcode.opencode.model.financial.CurrencyCode
3234
import com.getcode.utils.TraceType
3335
import com.getcode.utils.trace
3436
import com.google.common.collect.ImmutableList
@@ -113,7 +115,7 @@ internal class GooglePlayBillingClient(
113115
override fun hasPaidFor(product: IapProduct) =
114116
purchases[product.productId] == PurchaseState.PURCHASED
115117

116-
override fun costOf(product: IapProduct): String {
118+
override fun costOf(product: IapProduct): ProductPrice? {
117119
printLog("checking cost of ${product.productId} in ${productDetails.entries}")
118120
var details = productDetails[product.productId]
119121
if (details == null) {
@@ -130,10 +132,15 @@ internal class GooglePlayBillingClient(
130132
)
131133
)
132134
}
133-
return " "
135+
return null
134136
}
135137

136-
return details.oneTimePurchaseOfferDetails?.formattedPrice ?: " "
138+
return details.oneTimePurchaseOfferDetails?.let {
139+
ProductPrice(
140+
amount = it.priceAmountMicros / 1_000_000.0,
141+
currency = it.priceCurrencyCode
142+
)
143+
}
137144
}
138145

139146
override suspend fun purchase(activity: Activity, product: IapProduct) {
@@ -173,21 +180,26 @@ internal class GooglePlayBillingClient(
173180
printLog("onPurchaseComplete for ${item.purchaseToken}")
174181

175182
val details = productDetails[item.products.first()]
183+
val product = item.products.first()
184+
val receipt = Receipt(item.purchaseToken)
176185
val price = details?.oneTimePurchaseOfferDetails?.priceAmountMicros
177186
?.let { priceMicros -> priceMicros / 1_000_000.0 } ?: 0.0
178-
val currency = details?.oneTimePurchaseOfferDetails?.priceCurrencyCode ?: "USD"
187+
val currencyCode = CurrencyCode.tryValueOf(details?.oneTimePurchaseOfferDetails?.priceCurrencyCode) ?: CurrencyCode.USD
188+
189+
printLog("product=$product, $receipt=$receipt, price=$price, currency=${currencyCode.name}")
179190

180191
purchaseRepository.onPurchaseCompleted(
181192
owner = userManager.accountCluster?.authority?.keyPair!!,
182-
receipt = Receipt(item.purchaseToken),
193+
receipt = receipt,
183194
metadata = IapMetadata(
184-
product = item.products.first(),
195+
product = product,
185196
amount = price,
186-
currency = currency
197+
currency = currencyCode
187198
)
188199
).onSuccess {
189200
acknowledgeOrConsume(item)
190201
}.onFailure {
202+
it.printStackTrace()
191203
_eventFlow.emit(
192204
IapPaymentEvent.OnError(
193205
item.products.firstOrNull() ?: "NONE",
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package com.flipcash.services.internal.model.billing
22

3+
import com.getcode.opencode.model.financial.CurrencyCode
4+
35
/**
46
* Additional IAP metadata, which can be trusted given a verified receipt (they can
57
* only be generated by production-signed apps).
68
*/
79
data class IapMetadata(
810
val product: String,
9-
val currency: String,
11+
val currency: CurrencyCode,
1012
val amount: Double,
1113
)

services/flipcash/src/main/kotlin/com/flipcash/services/internal/network/api/PurchaseApi.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class PurchaseApi @Inject constructor(
3232
.setReceipt(IapService.Receipt.newBuilder().setValue(receiptValue))
3333
.setMetadata(IapService.Metadata.newBuilder()
3434
.setProduct(metadata.product)
35-
.setCurrency(metadata.currency)
35+
.setCurrency(metadata.currency.name.lowercase())
3636
.setAmount(metadata.amount)
3737
)
3838
.apply { setAuth(authenticate(owner)) }

0 commit comments

Comments
 (0)