payment_sdk.dart
3.6 KB
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
import 'dart:async';
import 'package:Parlando/apis/api_order.dart';
import 'package:Parlando/membership/models/membership_entity.dart';
import 'package:common_utils/common_utils.dart';
import 'package:in_app_purchase/in_app_purchase.dart';
class PaymentSdk {
PaymentSdk._privateConstructor();
static final PaymentSdk _instance = PaymentSdk._privateConstructor();
static PaymentSdk get instance {
return _instance;
}
static const Set<String> _kIds = <String>{'yearly_yiyan_vip', 'monthly_yiyan_vip'};
StreamSubscription<List<PurchaseDetails>>? _subscription;
List<ProductDetails> products = [];
Function? onPaySuccess;
Function? onPending;
Function? onFailed;
Function? onCancel;
initState({
Function? onPaySuccess,
Function? onPending,
Function? onFailed,
Function? onCancel,
}) {
this.onPaySuccess = onPaySuccess;
this.onPending = onPending;
this.onFailed = onFailed;
this.onCancel = onCancel;
final Stream<List<PurchaseDetails>> purchaseUpdated = InAppPurchase.instance.purchaseStream;
_subscription = purchaseUpdated.listen((purchaseDetailsList) {
_listenToPurchaseUpdated(purchaseDetailsList);
}, onDone: () {
_subscription?.cancel();
}, onError: (error) {
// handle error here.
});
}
Future<List<ProductDetails>> queryProducts() async {
final bool available = await InAppPurchase.instance.isAvailable();
if (!available) {
return [];
}
final ProductDetailsResponse response = await InAppPurchase.instance.queryProductDetails(_kIds);
return products = response.productDetails;
}
buy(ProductDetails details, MembershipDataGoodsList e) {
OrderApi.request.createOrder(e.id.toString()).then((value) {
var orderId = value?['data']?['data']?['order_sn'];
if (TextUtil.isEmpty(orderId)) {
onFailed?.call();
return;
}
final PurchaseParam purchaseParam = PurchaseParam(productDetails: details, applicationUserName: orderId);
if (_isConsumable(details)) {
InAppPurchase.instance.buyConsumable(purchaseParam: purchaseParam);
} else {
InAppPurchase.instance.buyNonConsumable(purchaseParam: purchaseParam);
}
});
}
void _listenToPurchaseUpdated(List<PurchaseDetails> purchaseDetailsList) async {
for (var purchaseDetails in purchaseDetailsList) {
if (purchaseDetails.status == PurchaseStatus.pending) {
onPending?.call();
} else {
if (purchaseDetails.status == PurchaseStatus.error) {
_handleError(purchaseDetails.error!);
} else if (purchaseDetails.status == PurchaseStatus.purchased || purchaseDetails.status == PurchaseStatus.restored) {
bool valid = await _verifyPurchase(purchaseDetails);
if (valid) {
_deliverProduct(purchaseDetails);
} else {
_handleInvalidPurchase(purchaseDetails);
}
} else {
onCancel?.call();
}
if (purchaseDetails.pendingCompletePurchase) {
await InAppPurchase.instance.completePurchase(purchaseDetails);
}
}
}
}
_verifyPurchase(PurchaseDetails purchaseDetails) async {
return true;
}
void _deliverProduct(PurchaseDetails purchaseDetails) {
onPaySuccess?.call();
}
void _handleInvalidPurchase(PurchaseDetails purchaseDetails) {
onFailed?.call();
}
void _handleError(IAPError iapError) {
onFailed?.call();
}
bool _isConsumable(ProductDetails details) {
return true;
}
void dispose() {
onPaySuccess = null;
onPending = null;
onFailed = null;
onCancel = null;
_subscription?.cancel();
}
}