Dart core SDK
Use the Dart client on mobile, desktop, or web with a custom storefront.
Download this chapterOn this page
appvision_iap_client 0.5.0 is the public-client core for Dart and Flutter. It uses package:http across mobile, desktop, and web and requires Dart 3.8 or later. It accepts signed store evidence from your application's storefront integration; it does not launch a purchase UI.
Add the package from source
Public registry publication is disabled in this preview. Use the approved source checkout:
dependencies:
appvision_iap_client:
path: ../cherrysub/sdk/dartAdjust the path, then run dart pub get or flutter pub get. Flutter apps using the official purchase plugin can use the higher-level Flutter storefront adapter.
Configure authentication
import 'package:appvision_iap_client/appvision_iap_client.dart';
final tokens = InMemoryCustomerTokenProvider(
fetchToken: (appUserId) async {
final response = await sessionApi.createIapToken(appUserId);
return CustomerToken(
token: response.token,
expiresAt: DateTime.parse(response.expiresAt),
);
},
);
final iap = IapClient(
baseUrl: Uri.parse('https://api-staging.cherrysub.com'),
publishableKey: 'iap_pk_REPLACE_WITH_YOUR_KEY',
customerTokenProvider: tokens.provider,
);sessionApi is your own authenticated broker client. Adapt its field decoding to the HTTP expires_at token envelope. Only a publishable key belongs in this configuration; the broker keeps the app secret on your backend.
Read presentation and submit evidence
final productSet = await iap.currentProductSet(user.id);
await iap.submitGooglePurchase(
appUserId: user.id,
purchaseToken: purchaseToken,
productType: GoogleProductType.subscription,
);
final subscriber = await iap.subscriber(user.id);
final hasPro = subscriber.accessLevels['pro']?.active == true;This example submits a subscription. Use the one-time-product type for a Google in-app product. Apple submission needs the actual transaction JWS from the store bridge. The core is submit-only: your application must complete the storefront purchase only after success, or use the Flutter adapter to coordinate that ordering.
A null current product set is an explicit configuration state. A subscriber 404 before the first qualifying receipt is not a paid subscription. Your UI must handle both without inventing a fallback purchase or access grant.
Manage lifetime and resources
The token provider caches per user, refreshes 30 seconds before expiry by default, and coalesces simultaneous refreshes. Invalidating a user prevents an earlier refresh from repopulating that user's cache. The SDK performs one forced refresh after a 401 and does not universally retry other statuses.
tokens.invalidate(user.id);
iap.close();Close the client when its owning application service is disposed. An internally created HTTP client is closed by IapClient; an injected client remains caller-owned. Clear application-owned access state on logout and use server-side token revocation when your policy requires it.
Test the core and the storefront separately
Run dart test in sdk/dart for the core's transport, token lifecycle, product-set, and lossless-ID behavior. Preserve event IDs as strings on Dart Web. Then test your store bridge on the actual target platform; passing a mock HTTP test is not evidence that StoreKit/Play purchase completion is wired correctly.
See receipts and restores for retry/ownership rules and testing for end-to-end acceptance cases.