Flutter应用内购买插件in_app_purchaser的使用
in_app_purchaser
在Flutter中实现应用内购买功能,可以使用in_app_purchaser
插件。该插件支持多种支付网关,并提供了简洁的API来处理购买流程。
示例代码
以下是一个完整的示例,展示如何使用in_app_purchaser
插件来实现应用内购买功能。
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:in_app_purchaser/in_app_purchaser.dart';
import 'package:in_app_purchaser_revenue_cat_delegate/in_app_purchaser_revenue_cat_delegate.dart';
// 替换为您的Revenue Cat API密钥
const kQonversionApiKey = "";
void main() {
runApp(
PurchaseProvider(
delegate: const RevenueCatDelegate(
apiKey: kQonversionApiKey,
),
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'In App Purchaser',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const PurchasePaywall(),
);
}
}
class PurchasePaywall extends StatelessWidget {
const PurchasePaywall({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey.shade100,
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(32),
child: Stack(
children: [
ListenableBuilder(
listenable: Purchaser.i,
builder: (context, child) {
return const PurchaseButton();
},
),
],
),
),
),
);
}
}
class PurchaseButton extends StatefulWidget {
const PurchaseButton({
super.key,
});
@override
State<PurchaseButton> createState() => _PurchaseButtonState();
}
class _PurchaseButtonState extends State<PurchaseButton> {
int selected = 0;
@override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.only(left: 15, right: 15, bottom: 5),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text(
'Get Unlimited Access',
style: TextStyle(
fontSize: 16,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 20),
Column(
children: List.generate(Purchaser.i.products.length, (index) {
final product = Purchaser.i.products.elementAtOrNull(index);
final priceString = product?.priceString ?? '0 BDT';
final monthlyPrice = (product?.price ?? 0) / 12;
return MonthlyPlan(
leftSideString: priceString,
selected: selected == index,
rightSideString: monthlyPrice.toString(),
discount: "25%",
onTap: () => setState(() => selected = index),
);
}),
),
const SizedBox(height: 5),
CupertinoButton(
padding: EdgeInsets.zero,
onPressed: () => Purchaser.i.purchaseAt(selected),
child: Container(
height: 65,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(1000),
color: Colors.black,
),
padding: const EdgeInsets.symmetric(
horizontal: 20,
),
alignment: Alignment.center,
child: Builder(builder: (context) {
if (Purchaser.i.products.isEmpty) {
return const SizedBox.square(
dimension: 24,
child: CircularProgressIndicator(
color: Colors.white,
strokeWidth: 3,
),
);
}
return const FittedBox(
child: Text(
'Continue',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.w700,
),
),
);
}),
),
),
Padding(
padding: const EdgeInsets.only(top: 10, bottom: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
GestureDetector(
child: const Text(
'Terms ',
style: TextStyle(
fontSize: 10,
color: Colors.grey,
fontWeight: FontWeight.w600,
decoration: TextDecoration.underline,
decorationColor: Colors.grey,
),
),
),
GestureDetector(
onTap: Purchaser.i.restore,
child: const Text(
'Restore ',
style: TextStyle(
fontSize: 10,
color: Colors.grey,
fontWeight: FontWeight.w600,
decoration: TextDecoration.underline,
decorationColor: Colors.grey,
),
),
),
GestureDetector(
child: const Text(
'Privacy ',
style: TextStyle(
fontSize: 10,
color: Colors.grey,
fontWeight: FontWeight.w600,
decoration: TextDecoration.underline,
decorationColor: Colors.grey,
),
),
),
GestureDetector(
child: const Text(
'User ID ',
style: TextStyle(
fontSize: 10,
color: Colors.grey,
fontWeight: FontWeight.w600,
decoration: TextDecoration.underline,
decorationColor: Colors.grey,
),
),
),
],
),
)
],
),
),
);
}
}
class MonthlyPlan extends StatelessWidget {
final String leftSideString;
final bool selected;
final String rightSideString;
final String? discount;
final VoidCallback onTap;
const MonthlyPlan({
super.key,
required this.leftSideString,
required this.selected,
required this.rightSideString,
required this.onTap,
this.discount,
});
@override
Widget build(BuildContext context) {
return CupertinoButton(
padding: EdgeInsets.zero,
onPressed: onTap,
child: Container(
height: 76,
margin: const EdgeInsets.only(bottom: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: selected ? Colors.black : Colors.transparent,
width: 3,
),
),
padding: const EdgeInsets.only(
right: 20,
left: 15,
),
child: Stack(
clipBehavior: Clip.none,
alignment: Alignment.centerLeft,
children: [
Text(
leftSideString,
style: const TextStyle(
fontSize: 16,
color: Colors.black,
),
),
Align(
alignment: Alignment.centerRight,
child: Text.rich(
textScaler: TextScaler.noScaling,
TextSpan(
children: [
TextSpan(
text: rightSideString,
style: const TextStyle(
fontSize: 15,
color: Colors.black,
fontWeight: FontWeight.w700,
),
),
],
),
),
),
if ((discount ?? '').isNotEmpty) ...[
Positioned(
top: -15,
right: -0,
child: Container(
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(105),
),
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
child: Text(
discount!,
style: const TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.w600,
),
),
),
),
],
],
),
),
);
}
}
说明
- 依赖配置:
在
pubspec.yaml
中添加以下依赖:dependencies: in_app_purchaser: ^latest_version in_app_purchaser_revenue_cat_delegate: ^latest_version
1 回复
更多关于Flutter应用内购买插件in_app_purchaser的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
in_app_purchase
是 Flutter 官方提供的一个插件,用于在应用中实现应用内购买功能。它支持 Android 和 iOS 平台,并且提供了统一的 API 来处理应用内购买流程。以下是如何使用 in_app_purchase
插件的基本步骤:
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 in_app_purchase
插件的依赖:
dependencies:
flutter:
sdk: flutter
in_app_purchase: ^3.0.6 # 请使用最新版本
然后运行 flutter pub get
来安装依赖。
2. 配置应用内购买
Android
在 android/app/build.gradle
文件中,确保 minSdkVersion
至少为 16:
defaultConfig {
minSdkVersion 16
targetSdkVersion 30
...
}
iOS
在 ios/Runner/Info.plist
文件中,添加以下内容以启用应用内购买:
<key>SKPaymentQueueShouldAddStorePayment</key>
<true/>
3. 初始化 InAppPurchase
在你的 Dart 文件中,导入 in_app_purchase
插件并初始化它:
import 'package:in_app_purchase/in_app_purchase.dart';
class MyApp extends StatefulWidget {
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final InAppPurchase _inAppPurchase = InAppPurchase.instance;
[@override](/user/override)
void initState() {
super.initState();
_initialize();
}
Future<void> _initialize() async {
final bool available = await _inAppPurchase.isAvailable();
if (!available) {
// 处理应用内购买不可用的情况
return;
}
// 监听购买更新
_inAppPurchase.purchaseStream.listen((List<PurchaseDetails> purchaseDetailsList) {
_handlePurchase(purchaseDetailsList);
});
}
void _handlePurchase(List<PurchaseDetails> purchaseDetailsList) {
for (var purchaseDetails in purchaseDetailsList) {
if (purchaseDetails.status == PurchaseStatus.purchased) {
// 处理购买成功的情况
} else if (purchaseDetails.status == PurchaseStatus.error) {
// 处理购买失败的情况
}
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('In-App Purchase Example'),
),
body: Center(
child: ElevatedButton(
onPressed: _buyProduct,
child: Text('Buy Product'),
),
),
),
);
}
Future<void> _buyProduct() async {
const String productId = 'your_product_id';
final ProductDetailsResponse response = await _inAppPurchase.queryProductDetails({productId});
if (response.notFoundIDs.isNotEmpty) {
// 处理未找到产品的情况
return;
}
final ProductDetails productDetails = response.productDetails.first;
final PurchaseParam purchaseParam = PurchaseParam(productDetails: productDetails);
await _inAppPurchase.buyConsumable(purchaseParam: purchaseParam);
}
}