Add this two permission in AndroidManifest.xml
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="android.permission.INTERNET" />
# Subscription plan
------
### create dart file for key
dart
///add play consol key
String weekly = "weekly";
String monthly = "moonthly";
### create purchase scree
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState(["remove_ads"], BtcPurchase.INAPP, [weekly, monthly], BtcPurchase.SUBS);
}
class _MyAppState extends BtcPurchaseWidget<MyApp> {
_MyAppState(super.purchase_ids, super.purchase_type);
@override
Widget build(BuildContext context) {
return MaterialApp(),
);
}
}
### launch Purchase bottomsheet
// in Listview builder
launchPurchase(
BtcPurchase.productsList[index]?.productId ?? "",
purchaseType: SUBS);
// in Single Subscription launch
launchPurchase('moonthly', purchaseType: SUBS);
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
getAlreadyPurchase();
});
getAlreadyPurchase() {
print("object 001");
BtcPurchase.instance.getAlreadyPurchasedList([
removeAds,
], BtcPurchase.INAPP, this).then((value) => {
AppController.to.purchaseLength.value = value?.length ?? 0,
print("purchase length ::: ${AppController.to.purchaseLength.value}"),
connectionCheck()
});
}
### Get Price of Subscription
// listview builder
BtcPurchase.productsList[index]?.subscriptionOfferDetails[0] ?.pricingPhases.last ?.formattedPrice ??""
### Purchase or not check
// class exttent same follow
BtcPurchase.purchaseList.length;
Note: Before test in_app_purchase implement make sure your app published in playstore or not
Add below code when your application in Splash Screen
import 'dart:convert';
import 'dart:io';
import 'package:btc_purchase/PurchaseListener.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:dialog_pp_flutter/api_call.dart';
import 'package:dialog_pp_flutter/dialog_pp_flutter.dart';
import 'package:dialog_pp_flutter/get_controller.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:btc_purchase/btc_purchase.dart';
import 'package:google_applovin_unity_ads/google_applovin_unity_ads.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:switzerland_iptv/screen/check_internet_screen.dart';
import '../globle__file/const.dart';
import '../globle__file/provider.dart';
import 'get_start_screen.dart';
class SplashScreen extends StatefulWidget {
const SplashScreen({Key? key}) : super(key: key);
@override
State<SplashScreen> createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> implements PurchaseListener{
var fetchPrize;
var isAlreadyPurchased;
String purchaseKey = 'remove_ads';
final btcPurchasePlugin = BtcPurchase();
bool isPurchased = false;
@override
void initState() {
super.initState();
Future.delayed(Duration.zero, () {
PPDialog.internetDialogCheck(callback: () {
PPDialog.autoUpdate();
initPlatformState().then((value) {
loadData();
});
});
});
}
/// in_app_purchase initialize Method for check your (Old Purchase history)
Future<void> initPlatformState() async {
fetchPrize = await btcPurchasePlugin
.getPurchaseList(purchaseKey, this);
isAlreadyPurchased = await btcPurchasePlugin
.getAlreadyPurchasedList(purchaseKey, this);
if (fetchPrize?.isNotEmpty == true) {
setState(() {
/// Check previous purchase history
if (isAlreadyPurchased == purchaseKey) {
isPurchased = true;
}
purchasestatus();
});
}
if (!mounted) return;
}
purchasestatus() async {
if (isPurchased == true) {
/// remove ads in your application add code here
}
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
return false;
},
child: Scaffold(
body: SizedBox(
width: double.infinity,
child: Image.asset(commonImage, fit: BoxFit.fill)),
),
);
}
loadData() async {
await fetchAlbum();
await fetchAdsSettings(
appVersionCode: int.parse(AppDetailsPP.to.buildNumber.value),
settingsUrl: settingsUrl,
keyName: "com.bitlinks.switzerland.iptv.m3ulist")
.then((value) async {
modelApi = getAdsSettings();
await purchasestatus(); ///set method after api data integrated successfully
initOpenAds(onOpenAdLoaded: () => {showOpenAds()});
if (value?.adsSequence?.contains("app_lovin") ?? false) {
if ((getAdsSettings()?.appLovin?.sdkKey ?? "").isNotEmpty) {
await AppLovinAds.instance
.initialize(value!.appLovin!.sdkKey!)
.then((value) async {
await checkData();
});
} else {
await checkData();
}
} else {
await checkData();
}
});
}
showDialogPop() async {
await Future.delayed(const Duration(seconds: 1));
showDialog(
barrierDismissible: false,
context: context,
builder: (aa) {
return WillPopScope(
onWillPop: () async {
return false;
},
child: AlertDialog(
elevation: 0,
backgroundColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(30.h))),
actions: [
Container(
alignment: Alignment.center,
width: double.infinity,
decoration: BoxDecoration(
color: themeButtonColor,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.h),
topRight: Radius.circular(30.h))),
height: 40.h,
child: Text(
"Agreement",
style: TextStyle(color: Colors.white, fontSize: 20.w),
),
),
Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20),
bottomRight: Radius.circular(20))),
child: Column(
children: [
SizedBox(
height: 20.h,
),
Padding(
padding: EdgeInsets.all(10.h),
child: const Text(
"Before you download please read carefully we are not providing TV Channel and it’s not TV channel app and this app gives you channel URL or File and QR code also",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.grey),
)),
SizedBox(
height: 20.h,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
InkWell(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
onTap: () async {
Get.back();
SharedPreferences pref =
await SharedPreferences.getInstance();
await pref.setBool("aggrement", true);
Future.delayed(const Duration(seconds: 2), () {
Get.off(const GetStartScreen());
});
},
child: Container(
alignment: Alignment.center,
width: 100.w,
padding: EdgeInsets.all(10.h),
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(
Radius.circular(14)),
color: themeButtonColor),
child: Text(
"Accept",
style: TextStyle(
color: Colors.white, fontSize: 16.w),
),
),
),
InkWell(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
onTap: () {
exit(0);
},
child: Container(
alignment: Alignment.center,
width: 100.w,
padding: EdgeInsets.all(8.h),
decoration: BoxDecoration(
border: Border.all(color: Colors.red),
borderRadius: const BorderRadius.all(
Radius.circular(14))),
child: Text(
"Cancel",
style: TextStyle(
color: Colors.red, fontSize: 16.w),
),
),
),
]),
SizedBox(
height: 10.h,
),
],
),
)
],
),
);});
}
checkData() async {
SharedPreferences pref = await SharedPreferences.getInstance();
var value = pref.getBool("aggrement");
if (value == true) {
Future.delayed(const Duration(seconds: 2), () {
Get.off(const GetStartScreen());
});
} else {
showDialogPop();
}
}
/// detect your purchase history
@override
void OnPurchaseListener() {
setState(() {
isPurchased = true;
});
purchasestatus();
}
}
class inAppPurchased extends StatefulWidget {
const inAppPurchased({Key? key}) : super(key: key);
@override
State<inAppPurchased> createState() => _inAppPurchasedState();
}
class _inAppPurchasedState extends AdsWidget<inAppPurchased> with WidgetsBindingObserver
implements PurchaseListener {
/// in app purchase data ///
Widget? buyButton;
var isAlreadyPurchased;
String? fetchPrize;
String purchaseKey = 'remove_ads';
final btcPurchasePlugin = BtcPurchase();
bool isPurchased = false;
@override
void initState() {
Future.delayed(
const Duration(seconds: 0),
() {initPlatformState();
updateBuyRemoveAdsButton();
fetchOldPurchaseDetails();
});
super.initState();
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
Get.back();
return false;
},
child: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.transparent,
centerTitle: true,
elevation: 0,
actions: [
/// create button for In App Purchase
buyButton!,
],
title: Text("In App Purchase Demo", style: TextStyle(fontSize: 20.h)),
),
body: Container()
),
);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
print("AppLifeCycle State ===>>> $state");
btcPurchasePlugin.PurchaseSync();
btcPurchasePlugin
.getAlreadyPurchasedList(purchaseKey, this)
.then((value) => {
print("Already Purchase ===>>> $value"),
if (value == purchaseKey)
{
setState(() {
isPurchased = true;
})
}
});
}
}
Future<void> initPlatformState() async {
fetchPrize = await btcPurchasePlugin.getPurchaseList(purchaseKey, this);
isAlreadyPurchased =
await btcPurchasePlugin.getAlreadyPurchasedList(purchaseKey, this);
if (fetchPrize?.isNotEmpty == true) {
setState(() {
if (isAlreadyPurchased == purchaseKey) {
isPurchased = true;
}
updateBuyRemoveAdsButton();
});
}
if (!mounted) return;
}
Widget? updateBuyRemoveAdsButton() {
if (isPurchased) {
buyButton = Container();
return buyButton;
} else {
buyButton = InkWell(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: () {
showModalBottomSheet(
context: context,
backgroundColor: Colors.transparent,
builder: (context) {
return Container(
padding: const EdgeInsets.all(10),
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(25),
topRight: Radius.circular(25)),
color: Colors.white,
),
child: Column(
children: [
ListTile(
title: const Text("Switzerland IPTV",
style: TextStyle(
fontSize: 18,
)),
subtitle: const Text(
"No ad will display on this app be safe from annoying popup ads ",
style: TextStyle(fontSize: 12),
),
trailing: InkWell(
onTap: () async {
Navigator.pop(context);
await btcPurchasePlugin
.launchPurchase(purchaseKey);
},
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 10, horizontal: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: const Color(0xff048c13),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.25),
blurRadius: 1.0,
),
]),
child: Text("$fetchPrize",
style: const TextStyle(
fontSize: 15, color: Colors.white)),
),
))
],
),
);
},
);
},
child: Center(
child: Text(
"Remove\nAds",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 12.sp),
).marginOnly(right: 10)));
return buyButton;
}
}
fetchOldPurchaseDetails() async {
var purchasePrice =
await btcPurchasePlugin.getPurchaseList(ControllerGetX.to.purchaseKey.value, this);
var alreadypurchased =
await btcPurchasePlugin.getAlreadyPurchasedList(ControllerGetX.to.purchaseKey.value, this);
setState(() {
fetchPrize = purchasePrice;
isAlreadyPurchased = alreadypurchased;
print("OldHistoryPurchase ===>>> $isAlreadyPurchased");
if (isAlreadyPurchased == purchaseKey) {
isPurchased= true;
}
updateBuyRemoveAdsButton();
});
}
@override
void OnPurchaseListener() {
setState(() {
isPurchased = true;
});
updateBuyRemoveAdsButton();
Future.delayed(
const Duration(milliseconds: 100),
() {
Restart.restartApp();
},
);
print("isPurchase print ===>>>${isPurchased}");
}
}