I’m using the flutter SDK.
I have a simple screen that loads the current offering, iterates over each availablePackage, and outputs some details about the package.
In RevenueCat, the offering has 6 packages, and each package has a subscription product. The products are for a Web Billing provider, and each is clearly configured as a subscription (the billing cycle shows as “Yearly” or “Monthly” on the product page).
However, each of the packages has a “nonRecurring” recurrenceMode (via package.storeProduct.defaultOption.fullPricePhase). Shouldn’t that be “infiniteRecurring”?
Code for the flutter widget below:
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:purchases_flutter/purchases_flutter.dart';
import 'package:pz_common/common/widgets/async_value_widget.dart';
import 'package:pz_common/localization/string_hardcoded.dart';
import 'package:pz_common/subscription/application/subscription_service.dart';
class SubscriptionDebugScreen extends ConsumerWidget {
const SubscriptionDebugScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
// title: 'Subscription',
body: Container(
width: double.infinity,
color: Theme.of(context).colorScheme.surfaceContainerLow,
child: Row(
children: [
AsyncValueWidget(
value: ref.watch(currentOfferingProvider),
data: (offering) => offering != null
? _OfferingWidget(offering: offering)
: Text('No offering'.hardcoded),
error: (error, stackTrace) => Text(error.toString()),
loading: () => const Center(child: CircularProgressIndicator()),
),
],
),
),
);
}
}
class _OfferingWidget extends StatelessWidget {
const _OfferingWidget({required this.offering});
final Offering offering;
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
...offering.availablePackages.map(
(package) => _PackageWidget(package: package),
),
],
);
}
}
class _PackageWidget extends StatelessWidget {
const _PackageWidget({required this.package});
final Package package;
@override
Widget build(BuildContext context) {
final storeProduct = package.storeProduct;
final subscriptionOption = storeProduct.defaultOption;
final introductoryPrice = storeProduct.introductoryPrice;
final fullPricePhase = subscriptionOption?.fullPricePhase;
return Container(
margin: const EdgeInsets.all(8),
padding: const EdgeInsets.all(16),
color: Theme.of(context).colorScheme.surfaceContainerLowest,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Package:',
style: Theme.of(
context,
).textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.bold),
),
Text(storeProduct.identifier),
Text(storeProduct.priceString),
const SizedBox(height: 8),
Text('introductory price: ${introductoryPrice?.priceString}'),
const SizedBox(height: 8),
Text(
'full price phase: ${fullPricePhase?.price.formatted} / ${fullPricePhase?.recurrenceMode}',
),
],
),
);
}
}
