Hey everyone! Working on my startup and noticed that the built in RevenueCat purchase action was not very good. It provided minimal error codes which would not pass apples review and was not customizable enough for my needs.
With this action you pass in the package_id you would like to buy and it will make the purchase. It also has robust error codes to let you and your users know why a transaction failed.
// Automatic FlutterFlow imports
import '/backend/schema/structs/index.dart';
import '/backend/supabase/supabase.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/actions/index.dart'; // Imports other custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom action code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
import 'package:flutter/services.dart';
import 'package:purchases_flutter/purchases_flutter.dart';
Future<String> purchasePackage(String packageToBuy) async {
try {
// Fetch the current offerings from RevenueCat
Offerings offerings = await Purchases.getOfferings();
if (offerings.current?.availablePackages.isEmpty ?? true) {
return "No available packages found. Please try again later.";
}
Package? selectedPackage;
if (offerings.current?.availablePackages != null) {
selectedPackage = offerings.current!.availablePackages
.where((package) => package.identifier == packageToBuy)
.isNotEmpty
? offerings.current!.availablePackages
.firstWhere((package) => package.identifier == packageToBuy)
: null;
}
// Handle case where the package does not exist
if (selectedPackage == null) {
return "The selected package '$packageToBuy' is not available. Please verify the package identifier.";
}
// Initiate purchase for the selected package
CustomerInfo purchaserInfo =
await Purchases.purchasePackage(selectedPackage);
// Check entitlements to confirm successful purchase
if (purchaserInfo.entitlements.active.isNotEmpty) {
return "Purchase successful!";
} else {
return "Purchase failed. The entitlements for the package could not be activated.";
}
} on PlatformException catch (e) {
// Handle Apple Store-specific purchase errors
if (e.code == PurchasesErrorCode.purchaseCancelledError.toString()) {
return "Purchase was cancelled by the user.";
} else if (e.code ==
PurchasesErrorCode.purchaseNotAllowedError.toString()) {
return "Purchases are not allowed on this device. Please check your device settings.";
} else if (e.code ==
PurchasesErrorCode.productNotAvailableForPurchaseError.toString()) {
return "The selected product is not available for purchase on the Apple Store.";
} else if (e.code == PurchasesErrorCode.paymentPendingError.toString()) {
return "Payment is pending. Please wait for the transaction to complete.";
} else if (e.code == PurchasesErrorCode.networkError.toString()) {
return "Network error. Please ensure your device is connected to the internet and try again.";
} else if (e.code ==
PurchasesErrorCode.invalidCredentialsError.toString()) {
return "Invalid credentials for RevenueCat. Please contact support.";
} else if (e.code ==
PurchasesErrorCode.receiptAlreadyInUseError.toString()) {
return "This receipt has already been used. Please contact support for assistance.";
} else if (e.code == PurchasesErrorCode.unknownError.toString()) {
return "An unknown error occurred during the purchase. Please try again.";
} else {
return "An unexpected error occurred: ${e.message}";
}
} catch (e) {
// Handle non-specific errors
return "An unexpected error occurred: ${e.toString()}";
}
}