Skip to main content

I am developing an application in Kotlin with Jetpack Compose and implementing the code to retrieve subscription offers, which include three different plans.

I have uploaded the app to Google Play Store in production to test its functionality on a real device. However, when trying to fetch the products, an error occurs, even though the configuration appears to be correct.

@HiltViewModel
class PurchasesViewModel @Inject constructor() : ViewModel() {
var informationState: InformationUiState by mutableStateOf(InformationUiState.Hidden())
private set
var offeringState: Offering? by mutableStateOf(null)
private set
var selectedPackageState: Package? by mutableStateOf(null)
private set

init {
loadOfferings()
}

private fun loadOfferings() {
Purchases.sharedInstance.getOfferingsWith(
onSuccess = { offerings ->
val offering: Offering? = offerings.current

offeringState = offering
selectedPackageState = offering?.availablePackages?.first()
},
onError = { error ->
informationState = InformationUiState.Error(
onDismiss = { informationState = InformationUiState.Hidden() },
message = UiText.StringResource(R.string.error_loading_subscriptions)
)
Log.d("PurchasesViewModel", "${error.underlyingErrorMessage}")
}
)
}

private fun purchaseOffering(
activity: Activity,
packageToPurchase: Package
) {
Purchases.sharedInstance.purchaseWith(
PurchaseParams.Builder(activity, packageToPurchase).build(),
onError = { error, userCancelled ->
if (userCancelled) {
informationState = InformationUiState.Success(
message = UiText.StringResource(R.string.success_purchase_cancelled)
)
Log.d("PurchasesViewModel", "User cancelled purchase")
} else {
with(error) {
informationState = InformationUiState.Error(
onDismiss = { informationState = InformationUiState.Hidden() },
message =
when (code) {
PurchasesErrorCode.PurchaseNotAllowedError -> UiText.StringResource(R.string.error_purchase_not_allowed)
PurchasesErrorCode.PurchaseInvalidError -> UiText.StringResource(R.string.error_purchase_invalid)
else -> UiText.StringResource(R.string.error_purchasing_subscription)
}
)
}
Log.d("PurchasesViewModel", "${error.underlyingErrorMessage}")
}
},
onSuccess = { storeTransaction, customerInfo ->
if (customerInfo.entitlements["my_entitlement"]?.isActive == true) {
informationState = InformationUiState.Success(message = UiText.StringResource(R.string.success_purchase_completed))
Log.d("PurchasesViewModel", "Purchase successful: $storeTransaction")
}
}
)
}

private fun restorePurchases() {
Purchases.sharedInstance.restorePurchasesWith() { customerInfo ->
if (customerInfo.entitlements["entlb0f322e33f"]?.isActive == true) {
informationState = InformationUiState.Success(
message = UiText.StringResource(R.string.success_restoring_purchases)
)
Log.d("PurchasesViewModel", "Restoration successful: $customerInfo")
} else {
informationState = InformationUiState.Error(
onDismiss = { informationState = InformationUiState.Hidden() },
message = UiText.StringResource(R.string.error_restoring_purchases)
)
Log.d("PurchasesViewModel", "Restoration failed: $customerInfo")
}
}
}

fun onPurchasesEvent(event: PurchasesEvent) {
when(event) {
is PurchasesEvent.OnPurchasePackage -> {
val activity: Activity? = event.activity
val pkg: Package? = event.packageToPurchase

if (activity != null && pkg != null) {
purchaseOffering(
activity = activity,
packageToPurchase = pkg
)
} else {
informationState = InformationUiState.Error(
onDismiss = { informationState = InformationUiState.Hidden() },
message = UiText.StringResource(R.string.error_purchasing_subscription)
)
Log.d("PurchasesViewModel", "Activity or Package is null, cannot proceed with purchase")
}
}
is PurchasesEvent.OnPurchasesRestore -> {
restorePurchases()
}

is PurchasesEvent.OnPackageSelected -> {
selectedPackageState = event.pkg
}

else -> {}
}
}
}

 

Hi, it looks like you are getting the error 23 of being unable to fetch offerings which you can confirm by checking your RevenueCat debug logs here.

If this is the case, we have a troubleshooting guide you can follow here:

Some important things you’ll want to check is that your app is published in closed testing and that you are using a valid licensed tester, see our docs here.


I've already solved it, I had to upload it to Google Play and test it with my mobile.


Reply