So, the big picture is I am developing one app on both platforms iOS and Android, using Swift and Kotlin respectively.
In the case of the iOS app, the Swift flow for subscriptions was very straight-forward and it works without any issues. The process is the following:
- The app has 2 sections that require subscriptions.
- Both sections have a "paywall" View on top of everything which obstructs access to the app's content.
- In said view you have 4 buttons, monthly, quarterly, biannual and annual subscription options.
- When you click on each option the flow differs a little bit between platforms, but the end result is the same. You get the dialog that slides up on your screen indicating the subscription type, period and cost.
- You activate the subscription, the payment processes and if everything is okay, the "paywall" container is hidden, so you can have access to the premium content.
The problem I am having is specifically in Android. On step 5 nothing happens after I confirm the payment. Everything gets processed, the subscription is assigned to my profile, if I try to click it again it says I already have it and sends me to the Manage screen. The code I have is the following:
My Kotlin app uses a MainActivity and the code I run is inside a fragment since I am using a storyboard type navigation.
The Fragment where I run the code
Inside onCreateView() I have
billingClient = BillingClient.newBuilder(requireContext())
.enablePendingPurchases()
.setListener(PurchasesUpdatedListener { billingResult, purchases ->
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) {
for (purchase in purchases) {
if(purchase.purchaseState == Purchase.PurchaseState.PURCHASED && !purchase.isAcknowledged()) {
val acknowledgePurchaseParams = AcknowledgePurchaseParams
.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build()
billingClient.acknowledgePurchase(
acknowledgePurchaseParams
) { billingResult: BillingResult ->
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
session.indicarPremium(true)
indicarSuscripcion(usuario.get(SessionManager.KEY_EMAIL)!!, "Android", "")
esconderPaywall()
}
}
}
}
} else if (billingResult.responseCode == BillingClient.BillingResponseCode.USER_CANCELED) {
// Handle an error caused by a user cancelling the purchase flow.
} else {
// Handle any other error codes.
}
})
.build()
billingStoreConnect()
esconderPaywall()
The esconderPaywall() function
private fun esconderPaywall()
{
if(session.isPremium()) {
lunaHoyView?.paywall_container!!.visibility = View.INVISIBLE
}
}
The session related functions inside my session class
companion object {
...
val IS_PREMIUM : String = "isPremium"
...
}
fun indicarPremium(estatus : Boolean) {
editor.putBoolean(IS_PREMIUM, estatus)
}
fun isPremium() : Boolean {
return pref.getBoolean(IS_PREMIUM, false)
}
The indicarSuscripcion()
function does an async API call to send information about the subscriber.
What am I doing wrong here? It's literally the last step for this to work, the complicated part with the subscriptions works, but I am not sure where the problem is here.
Also I am not sure how to test the app on my physical phone without having to create test tracks and upload builds. It's much easier on iOS.
Any ideas on how to fix this?
CodePudding user response:
It looks like you are using the correct code to handle a successful purchase. You should check to make sure that the purchase is being acknowledged properly. You can do this by checking the response code of the acknowledgePurchase() method. If it is not BillingClient.BillingResponseCode.OK, then there may be a problem with acknowledging the purchase.
One thing you could try is to log the response code of the acknowledgePurchase() method to see if it is returning an error. You could also check the logcat output for any error messages related to the purchase.
As for testing the app on your physical Android device, you can install the app on your device by connecting your device to your computer and running the app from Android Studio. You can also build an APK file and manually install it on your device.
CodePudding user response:
It's possible that there is an issue with the purchase itself. You can check the purchase object for any errors or issues.
You can also try using the queryPurchases() method to check for any purchases that have not yet been acknowledged. Here is an example of how you can do this:
val purchasesResult = billingClient.queryPurchases(BillingClient.SkuType.SUBS)
val purchases = purchasesResult.purchasesList
if (purchases != null) {
for (purchase in purchases) {
if (!purchase.isAcknowledged()) {
// Acknowledge the purchase
}
}
}
As for testing the billing functionality, you will need to set up a test account and purchase items using that account. You can find more information on how to do this in the Google Play Console documentation.