Skip to content

Commit

Permalink
Add onPurchaseFailed callback
Browse files Browse the repository at this point in the history
  • Loading branch information
a7madKaddour committed Jan 11, 2024
1 parent 7be9be3 commit e5b9992
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 0 deletions.
10 changes: 10 additions & 0 deletions app/src/main/java/com/limurse/iapsample/JavaSampleActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
Expand Down Expand Up @@ -71,6 +72,11 @@ public void onProductPurchased(@NonNull DataWrappers.PurchaseInfo purchaseInfo)
public void onProductRestored(@NonNull DataWrappers.PurchaseInfo purchaseInfo) {

}

@Override
public void onPurchaseFailed(@Nullable DataWrappers.PurchaseInfo purchaseInfo, @Nullable Integer billingResponseCode) {
Toast.makeText(getApplicationContext(), "Your purchase has been failed", Toast.LENGTH_SHORT).show();
}
});
iapConnector.addSubscriptionListener(new SubscriptionServiceListener() {
public void onSubscriptionRestored(@NonNull DataWrappers.PurchaseInfo purchaseInfo) {
Expand All @@ -85,6 +91,10 @@ public void onSubscriptionPurchased(@NonNull DataWrappers.PurchaseInfo purchaseI
public void onPricesUpdated(@NotNull Map iapKeyPrices) {

}

@Override
public void onPurchaseFailed(@Nullable DataWrappers.PurchaseInfo purchaseInfo, @Nullable Integer billingResponseCode) {
}
});

binding.btPurchaseCons.setOnClickListener(it ->
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/java/com/limurse/iapsample/KotlinSampleActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.limurse.iapsample

import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.MutableLiveData
import com.limurse.iap.BillingClientConnectionListener
Expand Down Expand Up @@ -77,6 +78,11 @@ class KotlinSampleActivity : AppCompatActivity() {
override fun onProductRestored(purchaseInfo: DataWrappers.PurchaseInfo) {
// will be triggered fetching owned products using IapConnector;
}

override fun onPurchaseFailed(purchaseInfo: DataWrappers.PurchaseInfo?, billingResponseCode: Int?) {
// will be triggered whenever a product purchase is failed
Toast.makeText(applicationContext, "Your purchase has been failed", Toast.LENGTH_SHORT).show()
}
})

iapConnector.addSubscriptionListener(object : SubscriptionServiceListener {
Expand All @@ -99,6 +105,10 @@ class KotlinSampleActivity : AppCompatActivity() {
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
}

override fun onPurchaseFailed(purchaseInfo: DataWrappers.PurchaseInfo?, billingResponseCode: Int?) {
// will be triggered whenever subscription purchase is failed
}
})

isBillingClientConnected.observe(this) {connected->
Expand Down
9 changes: 9 additions & 0 deletions iap/src/main/java/com/limurse/iap/BillingService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ class BillingService(
val responseCode = billingResult.responseCode
val debugMessage = billingResult.debugMessage
log("onPurchasesUpdated: responseCode:$responseCode debugMessage: $debugMessage")
if (!billingResult.isOk()){
updateFailedPurchases(purchases?.map { getPurchaseInfo(it) }, responseCode)
}
when (responseCode) {
BillingClient.BillingResponseCode.OK -> {
log("onPurchasesUpdated. purchase: $purchases")
Expand Down Expand Up @@ -184,6 +187,7 @@ class BillingService(
if (purchaseSuccess && purchase.products[0].isProductReady()) {
if (!isSignatureValid(purchase)) {
log("processPurchases. Signature is not valid for: $purchase")
updateFailedPurchase(getPurchaseInfo(purchase))
continue@purchases
}

Expand All @@ -207,6 +211,7 @@ class BillingService(
TAG,
"Handling consumables : Error during consumption attempt -> ${billingResult.debugMessage}"
)
updateFailedPurchase(getPurchaseInfo(purchase), billingResult.responseCode)
}
}
}
Expand All @@ -232,6 +237,7 @@ class BillingService(
TAG, "processPurchases failed. purchase: $purchase " +
"purchaseState: ${purchase.purchaseState} isSkuReady: ${purchase.products[0].isProductReady()}"
)
updateFailedPurchase(getPurchaseInfo(purchase))
}
}
} else {
Expand Down Expand Up @@ -383,6 +389,9 @@ class BillingService(

override fun onAcknowledgePurchaseResponse(billingResult: BillingResult) {
log("onAcknowledgePurchaseResponse: billingResult: $billingResult")
if(!billingResult.isOk()){
updateFailedPurchase(billingResponseCode = billingResult.responseCode)
}
}

override fun close() {
Expand Down
8 changes: 8 additions & 0 deletions iap/src/main/java/com/limurse/iap/BillingServiceListener.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,12 @@ interface BillingServiceListener {
* @param iapKeyPrices - a map with available products
*/
fun onPricesUpdated(iapKeyPrices: Map<String, List<DataWrappers.ProductDetails>>)

/**
* Callback will be triggered when a purchase was failed.
*
* @param purchaseInfo - specifier of purchase info if exists
* @param billingResponseCode - response code returned from the billing library if exists
*/
fun onPurchaseFailed(purchaseInfo: DataWrappers.PurchaseInfo?, billingResponseCode: Int?)
}
21 changes: 21 additions & 0 deletions iap/src/main/java/com/limurse/iap/IBillingService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,27 @@ abstract class IBillingService {
}
}

fun updateFailedPurchases(purchaseInfo: List<DataWrappers.PurchaseInfo>? = null, billingResponseCode: Int? = null) {
purchaseInfo?.forEach {
updateFailedPurchase(it, billingResponseCode)
} ?: updateFailedPurchase()
}

fun updateFailedPurchase(purchaseInfo: DataWrappers.PurchaseInfo? = null, billingResponseCode: Int? = null) {
findUiHandler().post {
updateFailedPurchasesInternal(purchaseInfo, billingResponseCode)
}
}

private fun updateFailedPurchasesInternal(purchaseInfo: DataWrappers.PurchaseInfo? = null, billingResponseCode: Int? = null) {
for (billingServiceListener in purchaseServiceListeners) {
billingServiceListener.onPurchaseFailed(purchaseInfo, billingResponseCode)
}
for (billingServiceListener in subscriptionServiceListeners) {
billingServiceListener.onPurchaseFailed(purchaseInfo, billingResponseCode)
}
}

abstract fun init(key: String?)
abstract fun buy(activity: Activity, sku: String, obfuscatedAccountId: String?, obfuscatedProfileId: String?)
abstract fun subscribe(activity: Activity, sku: String, obfuscatedAccountId: String?, obfuscatedProfileId: String?)
Expand Down

0 comments on commit e5b9992

Please sign in to comment.