Skip to content

Commit

Permalink
Merge pull request #122 from kf99916/subscription-period
Browse files Browse the repository at this point in the history
Support multiple price phases, subscription period, obfuscatedAccountId and obfuscatedProfileId
  • Loading branch information
akshaaatt authored Jul 17, 2023
2 parents d9d69cc + 394ba64 commit 3580b5d
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 37 deletions.
12 changes: 6 additions & 6 deletions app/src/main/java/com/limurse/iapsample/JavaSampleActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,27 +88,27 @@ public void onPricesUpdated(@NotNull Map iapKeyPrices) {
});

binding.btPurchaseCons.setOnClickListener(it ->
iapConnector.purchase(this, "base")
iapConnector.purchase(this, "base", null, null)
);

binding.btnMonthly.setOnClickListener(it ->
iapConnector.subscribe(this, "subscription")
iapConnector.subscribe(this, "subscription", null, null)
);

binding.btnYearly.setOnClickListener(it ->
iapConnector.subscribe(this, "yearly")
iapConnector.subscribe(this, "yearly", null, null)
);

binding.btnQuite.setOnClickListener(it ->
iapConnector.purchase(this, "quite")
iapConnector.purchase(this, "quite", null, null)
);

binding.btnModerate.setOnClickListener(it ->
iapConnector.purchase(this, "moderate")
iapConnector.purchase(this, "moderate", null, null)
);

binding.btnUltimate.setOnClickListener(it ->
iapConnector.purchase(this, "plenty")
iapConnector.purchase(this, "plenty", null, null)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class KotlinSampleActivity : AppCompatActivity() {
})

iapConnector.addPurchaseListener(object : PurchaseServiceListener {
override fun onPricesUpdated(iapKeyPrices: Map<String, DataWrappers.ProductDetails>) {
override fun onPricesUpdated(iapKeyPrices: Map<String, List<DataWrappers.ProductDetails>>) {
// list of available products will be received here, so you can update UI with prices if needed
}

Expand Down Expand Up @@ -96,7 +96,7 @@ class KotlinSampleActivity : AppCompatActivity() {
}
}

override fun onPricesUpdated(iapKeyPrices: Map<String, DataWrappers.ProductDetails>) {
override fun onPricesUpdated(iapKeyPrices: Map<String, List<DataWrappers.ProductDetails>>) {
// list of available products will be received here, so you can update UI with prices if needed
}
})
Expand Down
54 changes: 35 additions & 19 deletions iap/src/main/java/com/limurse/iap/BillingService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class BillingService(
private val context: Context,
private val nonConsumableKeys: List<String>,
private val consumableKeys: List<String>,
private val subscriptionSkuKeys: List<String>
private val subscriptionSkuKeys: List<String>,
) : IBillingService(), PurchasesUpdatedListener, AcknowledgePurchaseResponseListener {

private lateinit var mBillingClient: BillingClient
Expand Down Expand Up @@ -78,25 +78,25 @@ class BillingService(
processPurchases(subsResult.purchasesList, isRestore = true)
}

override fun buy(activity: Activity, sku: String) {
override fun buy(activity: Activity, sku: String, obfuscatedAccountId: String?, obfuscatedProfileId: String?) {
if (!sku.isProductReady()) {
log("buy. Google billing service is not ready yet. (SKU is not ready yet -1)")
return
}

launchBillingFlow(activity, sku, BillingClient.ProductType.INAPP)
launchBillingFlow(activity, sku, BillingClient.ProductType.INAPP, obfuscatedAccountId, obfuscatedProfileId)
}

override fun subscribe(activity: Activity, sku: String) {
override fun subscribe(activity: Activity, sku: String, obfuscatedAccountId: String?, obfuscatedProfileId: String?) {
if (!sku.isProductReady()) {
log("buy. Google billing service is not ready yet. (SKU is not ready yet -2)")
return
}

launchBillingFlow(activity, sku, BillingClient.ProductType.SUBS)
launchBillingFlow(activity, sku, BillingClient.ProductType.SUBS, obfuscatedAccountId, obfuscatedProfileId)
}

private fun launchBillingFlow(activity: Activity, sku: String, type: String) {
private fun launchBillingFlow(activity: Activity, sku: String, type: String, obfuscatedAccountId: String?, obfuscatedProfileId: String?) {
sku.toProductDetails(type) { productDetails ->
if (productDetails != null) {

Expand All @@ -105,11 +105,19 @@ class BillingService(
.setProductDetails(productDetails)

if(type == BillingClient.ProductType.SUBS){
builder.setOfferToken(productDetails.subscriptionOfferDetails!![0].offerToken)
productDetails.subscriptionOfferDetails?.getOrNull(0)?.let {
builder.setOfferToken(it.offerToken)
}
}
productDetailsParamsList.add(builder.build())
val billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(productDetailsParamsList).build()
val billingFlowParamsBuilder = BillingFlowParams.newBuilder().setProductDetailsParamsList(productDetailsParamsList)
if (obfuscatedAccountId != null) {
billingFlowParamsBuilder.setObfuscatedAccountId(obfuscatedAccountId)
}
if (obfuscatedProfileId != null) {
billingFlowParamsBuilder.setObfuscatedAccountId(obfuscatedProfileId)
}
val billingFlowParams = billingFlowParamsBuilder.build()

mBillingClient.launchBillingFlow(activity, billingFlowParams)
}
Expand Down Expand Up @@ -293,22 +301,30 @@ class BillingService(
entry.value?.let {
when(it.productType){
BillingClient.ProductType.SUBS->{
entry.key to DataWrappers.ProductDetails(
title = it.title,
description = it.description,
priceCurrencyCode = it.subscriptionOfferDetails?.get(0)?.pricingPhases?.pricingPhaseList?.get(0)?.priceCurrencyCode,
price = it.subscriptionOfferDetails?.get(0)?.pricingPhases?.pricingPhaseList?.get(0)?.formattedPrice,
priceAmount = it.subscriptionOfferDetails?.get(0)?.pricingPhases?.pricingPhaseList?.get(0)?.priceAmountMicros?.div(1000000.0)
)
entry.key to (it.subscriptionOfferDetails?.getOrNull(0)?.pricingPhases?.pricingPhaseList?.map { pricingPhase ->
DataWrappers.ProductDetails(
title = it.title,
description = it.description,
priceCurrencyCode = pricingPhase.priceCurrencyCode,
price = pricingPhase.formattedPrice,
priceAmount = pricingPhase.priceAmountMicros.div(1000000.0),
billingCycleCount = pricingPhase.billingCycleCount,
billingPeriod = pricingPhase.billingPeriod,
recurrenceMode = pricingPhase.recurrenceMode
)
} ?: listOf())
}
else->{
entry.key to DataWrappers.ProductDetails(
entry.key to listOf(DataWrappers.ProductDetails(
title = it.title,
description = it.description,
priceCurrencyCode = it.oneTimePurchaseOfferDetails?.priceCurrencyCode,
price = it.oneTimePurchaseOfferDetails?.formattedPrice,
priceAmount = it.oneTimePurchaseOfferDetails?.priceAmountMicros?.div(1000000.0)
)
priceAmount = it.oneTimePurchaseOfferDetails?.priceAmountMicros?.div(1000000.0),
billingCycleCount = null,
billingPeriod = null,
recurrenceMode = ProductDetails.RecurrenceMode.NON_RECURRING
))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ interface BillingServiceListener {
*
* @param iapKeyPrices - a map with available products
*/
fun onPricesUpdated(iapKeyPrices: Map<String, DataWrappers.ProductDetails>)
fun onPricesUpdated(iapKeyPrices: Map<String, List<DataWrappers.ProductDetails>>)
}
3 changes: 3 additions & 0 deletions iap/src/main/java/com/limurse/iap/DataWrappers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ class DataWrappers {
val price: String?,
val priceAmount: Double?,
val priceCurrencyCode: String?,
val billingCycleCount: Int?,
val billingPeriod: String?,
val recurrenceMode: Int?
)

data class PurchaseInfo(
Expand Down
8 changes: 4 additions & 4 deletions iap/src/main/java/com/limurse/iap/IBillingService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ abstract class IBillingService {
}
}

fun updatePrices(iapKeyPrices: Map<String, DataWrappers.ProductDetails>) {
fun updatePrices(iapKeyPrices: Map<String, List<DataWrappers.ProductDetails>>) {
findUiHandler().post {
updatePricesInternal(iapKeyPrices)
}
}

private fun updatePricesInternal(iapKeyPrices: Map<String, DataWrappers.ProductDetails>) {
private fun updatePricesInternal(iapKeyPrices: Map<String, List<DataWrappers.ProductDetails>>) {
for (billingServiceListener in purchaseServiceListeners) {
billingServiceListener.onPricesUpdated(iapKeyPrices)
}
Expand All @@ -99,8 +99,8 @@ abstract class IBillingService {
}

abstract fun init(key: String?)
abstract fun buy(activity: Activity, sku: String)
abstract fun subscribe(activity: Activity, sku: String)
abstract fun buy(activity: Activity, sku: String, obfuscatedAccountId: String?, obfuscatedProfileId: String?)
abstract fun subscribe(activity: Activity, sku: String, obfuscatedAccountId: String?, obfuscatedProfileId: String?)
abstract fun unsubscribe(activity: Activity, sku: String)
abstract fun enableDebugLogging(enable: Boolean)

Expand Down
8 changes: 4 additions & 4 deletions iap/src/main/java/com/limurse/iap/IapConnector.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ class IapConnector @JvmOverloads constructor(
getBillingService().removeSubscriptionListener(subscriptionServiceListener)
}

fun purchase(activity: Activity, sku: String) {
getBillingService().buy(activity, sku)
fun purchase(activity: Activity, sku: String, obfuscatedAccountId: String? = null, obfuscatedProfileId: String? = null) {
getBillingService().buy(activity, sku, obfuscatedAccountId, obfuscatedProfileId)
}

fun subscribe(activity: Activity, sku: String) {
getBillingService().subscribe(activity, sku)
fun subscribe(activity: Activity, sku: String, obfuscatedAccountId: String? = null, obfuscatedProfileId: String? = null) {
getBillingService().subscribe(activity, sku, obfuscatedAccountId, obfuscatedProfileId)
}

fun unsubscribe(activity: Activity, sku: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ interface PurchaseServiceListener : BillingServiceListener {
*
* @param iapKeyPrices - a map with available products
*/
override fun onPricesUpdated(iapKeyPrices: Map<String, DataWrappers.ProductDetails>)
override fun onPricesUpdated(iapKeyPrices: Map<String, List<DataWrappers.ProductDetails>>)

/**
* Callback will be triggered when a product purchased successfully
Expand Down

0 comments on commit 3580b5d

Please sign in to comment.