BillDog Flutter SDK

Monetization, paywalls, and subscription management for Flutter apps with WebView-based rendering for 100% visual parity across iOS, Android, and Web.

Installation

dependencies:
  billdog_flutter: ^2.0.0
flutter pub get

Quick Start

import 'package:billdog_flutter/billdog_flutter.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await BillDog.configure(
    'bd_live_your_api_key',
    options: BillDogOptions(enableLogging: true),
  );

  runApp(MyApp());
}

Presenting a Paywall

// Present a paywall configured for a placement
BillDog.shared.registerPlacement(
  'onboarding_end',
  handler: PaywallPresentationHandler(
    onPresent: (info) => print('Paywall shown: ${info.identifier}'),
    onDismiss: (info) => print('Paywall dismissed'),
    onSkip: () => print('No paywall for this placement'),
  ),
);

Inline Widget

PaywallView(
  identifier: 'premium_offer',
  onPurchase: (productId, data) {
    print('Purchase requested: $productId');
  },
  onDismiss: () => Navigator.pop(context),
  loadingWidget: Center(child: CircularProgressIndicator()),
)

Identity Management

// After login
BillDog.shared.identify('user_123');

// Set attributes for targeting
BillDog.shared.setUserAttributes({
  'plan': 'free',
  'signup_date': '2024-01-15',
});

// On logout
BillDog.shared.reset();

Custom Purchase Handling

class MyPurchaseController extends PurchaseController {
  @override
  Future<PurchaseResult> purchaseFromAppStore(String productId) async {
    // Your StoreKit 2 implementation
    return PurchaseResult.purchased(transactionId: 'txn_123');
  }

  @override
  Future<PurchaseResult> purchaseFromGooglePlay(
    String productId, {
    String? basePlanId,
    String? offerId,
  }) async {
    // Your Google Play Billing implementation
    return PurchaseResult.purchased(transactionId: 'txn_456');
  }

  @override
  Future<RestorationResult> restorePurchases() async {
    return RestorationResult.restored(restoredCount: 2);
  }
}

// Use it
await BillDog.configure(
  'bd_live_your_api_key',
  purchaseController: MyPurchaseController(),
);

Subscription Status

// Check status
if (BillDog.shared.subscriptionStatus == SubscriptionStatus.active) {
  // User is subscribed
}

// Manually set (when using custom purchase controller)
BillDog.shared.subscriptionStatus = SubscriptionStatus.active;

Customer Info

final info = await BillDog.shared.getCustomerInfo();

if (info.hasEntitlement('premium')) {
  // Unlock premium features
}

Analytics

BillDog.shared.trackEvent('level_completed', properties: {
  'level': 5,
  'score': 1200,
});

Architecture

The Flutter SDK follows a thin bridge architecture:

┌─────────────────────────────────┐
│         Flutter (Dart)          │
│  BillDog.shared / PaywallView   │
│         MethodChannel           │
├─────────────────────────────────┤
│    iOS: BillDogFlutterPlugin    │
│    → Delegates to BillDog SDK   │
├─────────────────────────────────┤
│  Android: BillDogFlutterPlugin  │
│    → Delegates to BillDog SDK   │
└─────────────────────────────────┘

Paywalls are rendered via the unified WebView renderer — the same HTML bundle used by the iOS and Android native SDKs — ensuring pixel-perfect visual parity.

Requirements

  • Flutter >= 3.10.0
  • Dart >= 3.0.0
  • iOS >= 13.0
  • Android API >= 21

License

MIT

Libraries

billdog_flutter
BillDog Flutter SDK