Skip to documentation
Open dashboard
Docs/Build your integration

Dart core SDK

Use the Dart client on mobile, desktop, or web with a custom storefront.

Download this chapter
On 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:

yaml
dependencies:
  appvision_iap_client:
    path: ../cherrysub/sdk/dart

Adjust 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

dart
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

dart
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.

dart
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.