aptoide_iap_android 0.1.4 copy "aptoide_iap_android: ^0.1.4" to clipboard
aptoide_iap_android: ^0.1.4 copied to clipboard

PlatformAndroid

Flutter plugin for the Aptoide Android Billing SDK. Supports in-app purchases, subscriptions, and free trials via the Aptoide Connect platform.

aptoide_iap_android #

pub version license: MIT

Flutter plugin for the Aptoide Android Billing SDK.
Integrates in-app purchases (consumables & non-consumables) and subscriptions (including free trials) for apps distributed via Aptoide Connect.


Platform support #

Android iOS Web

Minimum Android SDK: 21


Installation #

# pubspec.yaml
dependencies:
  aptoide_iap_android: ^0.1.0
flutter pub get

Android project setup #

In your project-level build.gradle, add the JitPack repository:

allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url "https://jitpack.io" }  // required by Aptoide Billing SDK
    }
}

The plugin automatically adds the Aptoide Billing SDK dependency to your app.
No additional build.gradle changes are needed in your app module.


Setup #

1. Get your public key #

Log in to Aptoide Connect → Your App → IAB Key.

2. Initialize once at app startup #

Initialize before any UI interaction, ideally in main() or your root widget's initState.
Subscribe to streams before calling initialize to avoid missing the first events.

import 'package:aptoide_iap_android/aptoide_iap_android.dart';

const _publicKey = 'YOUR_APTOIDE_CONNECT_PUBLIC_KEY';

Future<void> setupBilling() async {
  // Subscribe to real-time purchase updates first
  AptoideIapAndroid.purchasesUpdatedStream.listen((event) async {
    if (event.billingResult.isOk) {
      for (final purchase in event.purchases) {
        await _handlePurchase(purchase);
      }
    } else {
      print('Purchase error: ${event.billingResult.debugMessage}');
    }
  });

  // Connect
  final result = await AptoideIapAndroid.initialize(publicKey: _publicKey);

  if (result.isOk) {
    // Check for purchases that weren't processed in a previous session
    await _checkPendingConsumables();
    await _checkActiveSubscriptions();
  }
}

The 4-step integration #

Step 1 — Connection #

// Connect
final BillingResult result = await AptoideIapAndroid.initialize(
  publicKey: 'YOUR_KEY',
);

// Check readiness before making purchases
final bool ready = await AptoideIapAndroid.isReady;

// Disconnect when done (e.g. app shutdown)
await AptoideIapAndroid.endConnection();

Listen to connection state changes:

AptoideIapAndroid.billingStateStream.listen((event) {
  if (event.state == BillingConnectionState.connected) {
    print('Billing ready');
  } else {
    print('Billing disconnected');
  }
});

Step 2 — Query products #

Always fetch product details from Aptoide Connect and use the returned prices in your UI.
This is mandatory for app review.

// One-time in-app products
final QueryProductDetailsResult result =
    await AptoideIapAndroid.queryProductDetails(
  productIds: ['coins_100', 'remove_ads'],
  productType: ProductType.inapp,
);

for (final product in result.productDetailsList) {
  final price = product.oneTimePurchaseOfferDetails?.formattedPrice ?? '';
  print('${product.title} — $price');
}

// Subscriptions
final QueryProductDetailsResult subResult =
    await AptoideIapAndroid.queryProductDetails(
  productIds: ['premium_monthly'],
  productType: ProductType.subs,
);

for (final product in subResult.productDetailsList) {
  final phase =
      product.subscriptionOfferDetails?.first.pricingPhases.first;
  print('${product.title} — ${phase?.formattedPrice}/${phase?.billingPeriod}');
}

// Handle products that failed to load
for (final unfetched in result.unfetchedProductList) {
  print('Failed to load ${unfetched.productId}: ${unfetched.responseCode}');
}

Step 3 — Launch a purchase #

// One-time purchase
await AptoideIapAndroid.launchBillingFlow(
  productId: 'coins_100',
  productType: ProductType.inapp,
  obfuscatedAccountId: currentUserId,   // optional, but recommended
  developerPayload: 'order-ref-abc123', // optional, for your own tracking
);

// Subscription with free trial
final freeTrialSupported =
    await AptoideIapAndroid.isFeatureSupported(FeatureType.freeTrials) == 0;

await AptoideIapAndroid.launchBillingFlow(
  productId: 'premium_monthly',
  productType: ProductType.subs,
  obfuscatedAccountId: currentUserId, // required for free trials
  freeTrial: freeTrialSupported,
);

The purchase result is delivered via purchasesUpdatedStream (not from the launchBillingFlow return value).


Step 4 — Process & consume purchases #

Future<void> _handlePurchase(Purchase purchase) async {
  // 1. Validate server-side (strongly recommended)
  //    https://docs.catappult.io/docs/iap-validators-server-to-server-check-client
  final valid = await myServer.validatePurchase(
    purchaseToken: purchase.purchaseToken,
    packageName: purchase.packageName,
  );
  if (!valid) return;

  // 2. Deliver the item to the user
  await myStore.grantItem(purchase.products.first);

  // 3. Consume to allow re-purchase (consumables) or activate (subscriptions)
  final ConsumeResult result = await AptoideIapAndroid.consumePurchase(
    purchaseToken: purchase.purchaseToken,
  );

  if (!result.billingResult.isOk) {
    print('Consume failed: ${result.billingResult.debugMessage}');
  }
}

Handle purchases from previous sessions on startup:

Future<void> _checkPendingConsumables() async {
  final result = await AptoideIapAndroid.queryPurchases(ProductType.inapp);
  for (final purchase in result.purchases) {
    await _handlePurchase(purchase);
  }
}

Future<void> _checkActiveSubscriptions() async {
  final result = await AptoideIapAndroid.queryPurchases(ProductType.subs);
  // purchases present = active or pending subscriptions
  // purchases absent  = subscription expired; revoke access
  final activeIds = result.purchases.map((p) => p.products).expand((i) => i).toSet();
  await myStore.syncSubscriptions(activeIds);
}

Complete API reference #

AptoideIapAndroid (static) #

Method / Property Return type Description
initialize({publicKey}) Future<BillingResult> Connect to the Aptoide Billing service
endConnection() Future<void> Disconnect and release resources
isReady Future<bool> Whether the client is connected
queryProductDetails({productIds, productType}) Future<QueryProductDetailsResult> Fetch product metadata & prices
launchBillingFlow({productId, productType, …}) Future<BillingResult> Start the Aptoide purchase UI
queryPurchases(productType) Future<QueryPurchasesResult> List active/pending purchases
consumePurchase({purchaseToken}) Future<ConsumeResult> Consume / acknowledge a purchase
isFeatureSupported(FeatureType) Future<int> 0 = supported
purchasesUpdatedStream Stream<PurchaseUpdateEvent> Real-time purchase events
billingStateStream Stream<BillingStateEvent> Connect / disconnect events

Enums #

Type Values
ProductType inapp, subs
FeatureType freeTrials, obfuscatedAccountId
BillingConnectionState connected, disconnected

Key BillingResponseCode constants #

Constant Value Meaning
ok 0 Success
userCanceled 1 User dismissed the purchase UI
serviceUnavailable 2 Network problem
itemAlreadyOwned 7 Non-consumable already purchased
tooManyRequests 1429 Rate limit exceeded — use exponential back-off

Important guidelines #

Rule Reason
Initialize in the root widget / Application, not inside an Activity Context lifecycle issues if the Activity is destroyed
Always consume purchases after delivery Unconsumed purchases are auto-refunded after 48 hours
Display API-provided prices Mandatory for Aptoide app review approval
Avoid SDK calls on the main thread This plugin handles threading internally
Validate purchases server-side before delivery Prevents fraud
Use exponential back-off on 1429 errors Avoids being blocked by rate limiting

Testing without an Aptoide Connect account #

Use the sandbox credentials provided in the official docs:

applicationId : com.appcoins.sample
IAB_KEY       : MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyEt94j9rt0UvpkZ2jPMZZ16y
                UrBOtjpIQCWi/F3HN0+iwSAeEJyDw7xIKfNTEc0msm+m6ud1kJpLK3oCsK61syZ8bYQ
                lNZkUxTaWNof1nMnbw3Xu5nuYMuowmzDqNMWg5jNooy6oxwIgVcdvbyGi5RIlxqbo2vS
                AwpbAAZE2HbUrysKhLME7IOrdRR8MQbSbKEy/9MtfKz0uZCJGi9h+dQb0b69H7Yo+/BN
                /ayBSJzOPlaqmiHK5lZsnZhK+ixpB883fr+PgSczU7qGoktqoe6Fs+nhk9bLElljCs5ZI
                l9/NmOSteipkbplhqLY7KwapDmhrtBgrTetmnW9PU/eCWQIDAQAB

apitoide_android_iap #

0
likes
160
points
200
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Flutter plugin for the Aptoide Android Billing SDK. Supports in-app purchases, subscriptions, and free trials via the Aptoide Connect platform.

Homepage
Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter

More

Packages that depend on aptoide_iap_android

Packages that implement aptoide_iap_android