283 lines
8.9 KiB
Dart
283 lines
8.9 KiB
Dart
import 'dart:async';
|
||
import 'package:circle_app/circle_app/circle/logic.dart';
|
||
import 'package:circle_app/net/api.dart';
|
||
import 'package:circle_app/net/dio_manager.dart';
|
||
import 'package:circle_app/utils/eventBus.dart';
|
||
import 'package:circle_app/utils/util.dart';
|
||
import 'package:event_bus/event_bus.dart';
|
||
import 'package:flutter/cupertino.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||
import 'package:get/get.dart';
|
||
import 'package:in_app_purchase/in_app_purchase.dart';
|
||
import 'package:in_app_purchase_storekit/src/types/app_store_purchase_details.dart';
|
||
|
||
// iOS支付单一实例
|
||
// final iOSPayment = IOSPayment();
|
||
|
||
class IOSPayment {
|
||
IOSPayment._();
|
||
|
||
static IOSPayment? _instance;
|
||
|
||
/// The instance of the [InAppPurchase] to use.
|
||
static IOSPayment get instance => _getOrCreateInstance();
|
||
|
||
static IOSPayment _getOrCreateInstance() {
|
||
if (_instance != null) {
|
||
return _instance!;
|
||
}
|
||
_instance = IOSPayment._();
|
||
return _instance!;
|
||
}
|
||
|
||
// 应用内支付实例
|
||
InAppPurchase _inAppPurchase = InAppPurchase.instance;
|
||
|
||
// iOS订阅监听
|
||
StreamSubscription<List<PurchaseDetails>>? subscription;
|
||
|
||
//1圈子 2会员 3解锁微信 4充值
|
||
int type = 0;
|
||
//可以为解锁圈子ID、会员标识ID
|
||
String typeId = '';
|
||
|
||
String target_id = '';
|
||
|
||
String _source = '';
|
||
|
||
/// 判断是否可以使用支付
|
||
Future<bool> isAvailable() async => await _inAppPurchase.isAvailable();
|
||
|
||
// 开始订阅
|
||
void startSubscription() async {
|
||
if (subscription != null) return;
|
||
print('>>> start subscription');
|
||
// 支付消息订阅
|
||
// Stream purchaseUpdates = _inAppPurchase.purchaseStream;
|
||
Stream<List<PurchaseDetails>> purchaseUpdated =
|
||
_inAppPurchase.purchaseStream;
|
||
subscription =
|
||
purchaseUpdated.listen((List<PurchaseDetails> purchaseDetailsList) {
|
||
_listenToPurchaseUpdated(purchaseDetailsList);
|
||
}, onDone: () {
|
||
SmartDialog.dismiss();
|
||
// subscription!.cancel();
|
||
}, onError: (Object error) {
|
||
SmartDialog.dismiss();
|
||
showOKToast('出错了,请重新支付');
|
||
// handle error here.
|
||
});
|
||
}
|
||
|
||
// List<ProductDetails>AppStorePurchaseDetails
|
||
|
||
Future<void> _listenToPurchaseUpdated(
|
||
List<PurchaseDetails> purchaseDetailsList) async {
|
||
for (final PurchaseDetails purchaseDetails in purchaseDetailsList) {
|
||
if (purchaseDetails.status == PurchaseStatus.pending) {
|
||
|
||
} else {
|
||
if (purchaseDetails.status == PurchaseStatus.error) {
|
||
showOKToast('支付发生错误');
|
||
SmartDialog.dismiss();
|
||
} else if (purchaseDetails.status == PurchaseStatus.purchased) {
|
||
Map<String,dynamic> params = {
|
||
'payload': purchaseDetails.verificationData.serverVerificationData,
|
||
'transaction_id': purchaseDetails.purchaseID,
|
||
'type': type,
|
||
'source':_source,
|
||
'product_id': int.parse(typeId)
|
||
};
|
||
|
||
if (type == 3) {
|
||
params['target_id'] = target_id;
|
||
} else if (target_id.isNotEmpty) {
|
||
params['target_id'] = target_id;
|
||
}
|
||
|
||
|
||
var result = await DioManager.getInstance()
|
||
.post(url: Api.applePayCallBack, params:params);
|
||
SmartDialog.dismiss();
|
||
if (result['code'] == 200) {
|
||
|
||
try {
|
||
if (type != 4) {
|
||
Get.back();
|
||
}
|
||
} catch (e) {}
|
||
|
||
if (type == 1) {
|
||
showOKToast('解锁圈子成功');
|
||
if (Get.isRegistered<CircleLogic>()) {
|
||
var logic = Get.find<CircleLogic>();
|
||
for (var element in logic.circle.lists) {
|
||
if (element.id == int.parse(typeId)) {
|
||
element.is_limit = false;
|
||
element.isJoin = true;
|
||
}
|
||
}
|
||
logic.update();
|
||
}
|
||
EventBusManager.fire(CircleInfoRefresh(typeId));
|
||
} else if (type == 2) {
|
||
if (target_id.isNotEmpty) {
|
||
showOKToast('赠送会员成功');
|
||
sendHotAction(6, target_id);
|
||
target_id = '';
|
||
} else {
|
||
showOKToast('开通会员成功');
|
||
EventBusManager.fire(CommentVipEvent(1));
|
||
}
|
||
} else if (type == 4) {
|
||
showOKToast('充值成功');
|
||
EventBusManager.fire(AssestEvent());
|
||
} else {
|
||
showOKToast('解锁联系方式成功');
|
||
unLockWxSuccessResult(target_id);
|
||
}
|
||
}
|
||
await _inAppPurchase.completePurchase(purchaseDetails);
|
||
} else if (purchaseDetails.status == PurchaseStatus.canceled ||
|
||
purchaseDetails.status == PurchaseStatus.error) {
|
||
SmartDialog.dismiss();
|
||
if (purchaseDetails.status == PurchaseStatus.canceled) {
|
||
showOKToast('取消支付');
|
||
} else {
|
||
showOKToast('支付超时了');
|
||
}
|
||
}
|
||
|
||
await _inAppPurchase.completePurchase(purchaseDetails);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Future<void> deliverProduct(PurchaseDetails purchaseDetails) async {
|
||
// // IMPORTANT!! Always verify purchase details before delivering the product.
|
||
// if (purchaseDetails.productID == _kConsumableId) {
|
||
// await ConsumableStore.save(purchaseDetails.purchaseID!);
|
||
// final List<String> consumables = await ConsumableStore.load();
|
||
// setState(() {
|
||
// _purchasePending = false;
|
||
// _consumables = consumables;
|
||
// });
|
||
// } else {
|
||
// setState(() {
|
||
// _purchases.add(purchaseDetails);
|
||
// _purchasePending = false;
|
||
// });
|
||
// }
|
||
// }
|
||
|
||
// void handleError(IAPError error) {
|
||
// setState(() {
|
||
// _purchasePending = false;
|
||
// });
|
||
// }
|
||
|
||
Future<bool> _verifyPurchase(PurchaseDetails purchaseDetails) {
|
||
// IMPORTANT!! Always verify a purchase before delivering the product.
|
||
// For the purpose of an example, we directly return true.
|
||
return Future<bool>.value(true);
|
||
}
|
||
|
||
/// 启动支付
|
||
void iosPay(String skuInfo, String typeID, int productType,{String userId = '',String source = ''}) async {
|
||
SmartDialog.showLoading(msg: '请稍等片刻');
|
||
if (!await isAvailable()) {
|
||
SmartDialog.dismiss();
|
||
showOKToast('无法连接AppStore,请稍后再试');
|
||
return;
|
||
}
|
||
_source = source;
|
||
// 获取商品列表month_member_3
|
||
var set = [skuInfo].toSet();
|
||
ProductDetailsResponse appStoreProducts =
|
||
await _inAppPurchase.queryProductDetails(set);
|
||
String orderId = DateTime.now().millisecondsSinceEpoch.toString();
|
||
|
||
if (appStoreProducts.notFoundIDs.isNotEmpty) {
|
||
// Handle the error.
|
||
SmartDialog.dismiss();
|
||
showOKToast('启动苹果支付失败');
|
||
|
||
return;
|
||
}
|
||
|
||
target_id = userId;
|
||
type = productType;
|
||
typeId = typeID;
|
||
|
||
List<ProductDetails> products = appStoreProducts.productDetails;
|
||
|
||
// 发起支付
|
||
_inAppPurchase
|
||
.buyNonConsumable(
|
||
purchaseParam: PurchaseParam(
|
||
productDetails: products.last,
|
||
applicationUserName: orderId,
|
||
),
|
||
)
|
||
.then((value) {
|
||
if (value) {
|
||
// dismissLoading();
|
||
// showLoading(tip: '正在处理订单');
|
||
// 只要能发起,就写入
|
||
// writeStorage(sku, orderId, 'pending');
|
||
}
|
||
}).catchError((err) async {
|
||
SmartDialog.dismiss();
|
||
showOKToast('当前商品您有未完成的交易,请等待iOS系统核验后再次发起购买。');
|
||
// if (err['details'] != null) {
|
||
// Map details = err['details'];
|
||
// // "productIdentifier" -> "12rmb"
|
||
// var data = await _inAppPurchase.queryProductDetails(details['productIdentifier']);
|
||
// if (data.productDetails.isNotEmpty) {
|
||
// // await _inAppPurchase.buyConsumable(purchaseParam: purchaseParam)
|
||
// }
|
||
// }
|
||
|
||
// onError?.call('当前商品您有未完成的交易,请等待iOS系统核验后再次发起购买。');
|
||
print(err);
|
||
});
|
||
}
|
||
|
||
writeStorage(String key, String value, String status) {
|
||
// storage.write(key: key, value: '$value¥$status');
|
||
}
|
||
|
||
// 关闭交易
|
||
void finalTransaction(PurchaseDetails purchaseDetails) async {
|
||
await _inAppPurchase.completePurchase(purchaseDetails);
|
||
// 每完成一张订单进行缓存的清除
|
||
// if (!await checkStorage()) {
|
||
// stopListen();
|
||
// }
|
||
}
|
||
|
||
// 凑单机制
|
||
Future<String> foundRecentOrder(String sku) async {
|
||
String orderId = '';
|
||
// String values = await storage.read(key: sku);
|
||
//
|
||
// if (values != null) {
|
||
// orderId = values.split('¥')[0];
|
||
// }
|
||
return orderId;
|
||
}
|
||
|
||
// 校验是否还有缓存
|
||
Future<bool> checkStorage() async {
|
||
// Map<String, String> remainingValues = await storage.readAll();
|
||
return false;
|
||
}
|
||
|
||
// 关闭监听
|
||
stopListen() async {
|
||
// subscription!.cancel();
|
||
// subscription = null;
|
||
}
|
||
}
|