Flutter 内购实现

Jared Yuan Lv2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import 'dart:async';
import 'dart:io';
import 'package:in_app_purchase_storekit/in_app_purchase_storekit.dart';
import 'package:in_app_purchase_storekit/store_kit_wrappers.dart';
import 'package:flutter/cupertino.dart';
import 'package:in_app_purchase/in_app_purchase.dart';

/// 适用于ios端的内购处理方法
class InAppPurchaseUtils {
late final InAppPurchase _inAppPurchase;
late StreamSubscription<List<PurchaseDetails>> _subscription;
late final Stream<List<PurchaseDetails>> purchaseUpdated;
/// 产品id
static const List<String> productIds = [];
List<ProductDetails> _products = <ProductDetails>[];

/// 初始化
InAppPurchaseUtils.init() {
_inAppPurchase = InAppPurchase.instance;
purchaseUpdated = _inAppPurchase.purchaseStream;
initStoreInfo();
}

/// 查询产品信息
/// 返回的数据类型是ProductDetailsResponse
/// 获取详细的产品数据:productDetailResponse.productDetails
/// Example:
/// if (productDetailResponse.error != null) {
// setState(() {
// _queryProductError = productDetailResponse.error!.message;
// _isAvailable = isAvailable;
// _products = productDetailResponse.productDetails;
// _purchases = <PurchaseDetails>[];
// _notFoundIds = productDetailResponse.notFoundIDs;
// _consumables = <String>[];
// _purchasePending = false;
// _loading = false;
// });
// return;
// }
Future<ProductDetailsResponse> queryProductDetails() async{
return await _inAppPurchase.queryProductDetails(productIds.toSet());
}

List<ProductDetails> get products => _products;

/// 初始化商品(ios端,未集成Android)
Future<void> initStoreInfo() async{
if(await isAvailable) {
if (Platform.isIOS) {
final InAppPurchaseStoreKitPlatformAddition iosPlatformAddition =
_inAppPurchase
.getPlatformAddition<InAppPurchaseStoreKitPlatformAddition>();
await iosPlatformAddition.setDelegate(ExamplePaymentQueueDelegate());
}
queryProductDetails().then((value) {
if(value.error != null) {
_products = value.productDetails;
}
});
}
}

/// 内购监听
void addPurchaseListener({required PurchaseListener listener, ValueChanged? onError}) {
_subscription = purchaseUpdated.listen((List<PurchaseDetails> purchaseDetailsList) {
_listenToPurchaseUpdated(purchaseDetailsList, listener: listener);
},onDone: (){
_subscription.cancel();
},onError: (Object err){
if(onError != null) onError(err);
});
}

/// 购买消耗产品(金币)
void buyConsumable(ProductDetails productDetails){
if(Platform.isIOS) {
_inAppPurchase.buyConsumable(purchaseParam: PurchaseParam(productDetails: productDetails));
}
}

/// 订阅
void buyNonConsumable(ProductDetails productDetails){
if(Platform.isIOS) {
_inAppPurchase.buyNonConsumable(purchaseParam: PurchaseParam(productDetails: productDetails));
}
}

/// 处理内购
Future<void> _listenToPurchaseUpdated(
List<PurchaseDetails> purchaseDetailsList, {required PurchaseListener listener}) async {
for (final PurchaseDetails purchaseDetails in purchaseDetailsList) {
if (purchaseDetails.status == PurchaseStatus.pending) {
if(listener.onPending != null) listener.onPending!();
// showPendingUI();
} else {
if(listener.onPendingComplete != null) listener.onPendingComplete!();
if (purchaseDetails.status == PurchaseStatus.error) {
if(listener.onError != null) listener.onError!(purchaseDetails.error);
} else if (purchaseDetails.status == PurchaseStatus.purchased ||
purchaseDetails.status == PurchaseStatus.restored) {
listener.onPurchased(purchaseDetails);
// final bool valid = await _verifyPurchase(purchaseDetails);
// if (valid) {
// deliverProduct(purchaseDetails);
// } else {
// _handleInvalidPurchase(purchaseDetails);
// return;
// }
}
// if (Platform.isAndroid) {
// if (!_kAutoConsume && purchaseDetails.productID == _kConsumableId) {
// final InAppPurchaseAndroidPlatformAddition androidAddition =
// _inAppPurchase.getPlatformAddition<
// InAppPurchaseAndroidPlatformAddition>();
// await androidAddition.consumePurchase(purchaseDetails);
// }
// }
if (purchaseDetails.pendingCompletePurchase) {
await _inAppPurchase.completePurchase(purchaseDetails);
}
}
}
}

/// 内购服务是否可用
Future<bool> get isAvailable async => await _inAppPurchase.isAvailable();

/// 取消内购服务监听
/// dispose 时可调用
void cancel(){
if (Platform.isIOS) {
final InAppPurchaseStoreKitPlatformAddition iosPlatformAddition =
_inAppPurchase
.getPlatformAddition<InAppPurchaseStoreKitPlatformAddition>();
iosPlatformAddition.setDelegate(null);
}
_subscription.cancel();
}
}

class PurchaseListener {
/// 等待
VoidCallback? onPending;
ValueChanged? onError;
/// 购买事件
late ValueChanged<PurchaseDetails> onPurchased;
///等待结束
VoidCallback? onPendingComplete;
PurchaseListener({required this.onPurchased,this.onPending,this.onError,this.onPendingComplete});
}

class ExamplePaymentQueueDelegate implements SKPaymentQueueDelegateWrapper {
@override
bool shouldContinueTransaction(
SKPaymentTransactionWrapper transaction, SKStorefrontWrapper storefront) {
return true;
}

@override
bool shouldShowPriceConsent() {
return false;
}
}
  • Title: Flutter 内购实现
  • Author: Jared Yuan
  • Created at : 2023-09-22 12:04:46
  • Updated at : 2023-09-22 12:06:20
  • Link: https://redefine.ohevan.com/2023/09/22/Flutter/Flutter-内购实现/
  • License: This work is licensed under CC BY-NC-SA 4.0.
On this page
Flutter 内购实现