import 'dart:io'; import 'package:apple_pay/apple_pay.dart'; import 'package:classify_photo/classify_photo.dart'; import 'package:clean/data/repositories/user_repository.dart'; import 'package:clean/module/store/payment_status_manager.dart'; import 'package:clean/router/app_pages.dart'; import 'package:clean/utils/error_handler.dart'; import 'package:flutter/Material.dart'; import 'package:get/get.dart'; import 'package:in_app_purchase/in_app_purchase.dart'; import '../../base/base_controller.dart'; import '../../data/api/response/order_pay_response.dart'; import '../../data/bean/payment_way.dart'; import '../../data/bean/store_item.dart'; import '../../data/consts/constants.dart'; import '../../data/consts/event_report_id.dart'; import '../../data/repositories/store_repository.dart'; import '../../dialog/loading_dialog.dart'; import '../../handler/event_handler.dart'; import '../../sdk/pay/agile_pay.dart'; import '../../sdk/pay/applepay/apple_pay_info.dart'; import '../../sdk/pay/assist/product_type.dart'; import '../../utils/toast_util.dart'; class StoreController extends BaseController implements PaymentStatusCallback { final RxList storeItems = [].obs; final RxList paymentWays = [].obs; final Rxn currentSelectedStoreItem = Rxn(); final Rxn currentSelectedPaymentWay = Rxn(); var freeAppleId = ""; RxBool isFree = false.obs; @override Future onInit() async { super.onInit(); initStoreIndexData(); } @override void onReady() { EventHandler.report(EventId.event_02001); super.onReady(); } @override void onClose() { // TODO: implement onClose super.onClose(); if (isFirstIntoStore() && !userRepository.isVip()) { Get.toNamed(RoutePath.discount); setFirstIntoStore(false); } } void initStoreIndexData() { LoadingDialog.showLoading(); storeRepository.storeIndex().then((indexData) async { storeItems.clear(); storeItems.addAll(indexData.items); currentSelectedStoreItem.value = storeItems.isNotEmpty ? storeItems.first : null; paymentWays.clear(); paymentWays.addAll(indexData.paymentWays); currentSelectedPaymentWay.value = paymentWays.isNotEmpty ? paymentWays.first : null; var freeAppleId = ""; for (var item in storeItems) { if (item.freeTrialName != null) { freeAppleId = item.appleGoodsId; } } isFree.value = await ApplePay().check(freeAppleId); LoadingDialog.hide(); }); } Future onRestoreClick() async { EventHandler.report(EventId.event_02004); PaymentWay? paymentWay = currentSelectedPaymentWay.value; if (paymentWay == null) { // ToastUtil.showToast(StringName.storeChoicePayment.tr); return; } int payPlatform = paymentWay.payPlatform; int payMethod = paymentWay.payMethod; LoadingDialog.showLoading(); Future.delayed(const Duration(seconds: 20), () { LoadingDialog.hide(); ToastUtil.show("Restore record not found"); }); final result = await ApplePay().restore(); if (result["success"] == true) { // LoadingDialog.hide(); var receipt = result['receipt']; print('查找恢复记录成功: ${result['receipt']}'); checkRestoreStatus(receipt); } else { LoadingDialog.hide(); ToastUtil.show("Pay Error"); print('恢复失败: ${result['error']}'); } } void onBuyClick() async { EventHandler.report(EventId.event_02002); StoreItem? storeItem = currentSelectedStoreItem.value; if (storeItem == null) { // ToastUtil.showToast(StringName.storeChoiceGoods.tr); return; } PaymentWay? paymentWay = currentSelectedPaymentWay.value; if (paymentWay == null) { // ToastUtil.showToast(StringName.storeChoicePayment.tr); return; } int payPlatform = paymentWay.payPlatform; int payMethod = paymentWay.payMethod; LoadingDialog.showLoading(); try { // OrderPayResponse response = storeRepository.orderPay(storeItem.id, payPlatform, payMethod).then((response) async { dynamic payInfo; String outTradeNo = response.outTradeNo; if (payPlatform == PayPlatform.apple) { payInfo = ApplePayInfo( storeItem.appleGoodsId, storeItem.subscribable == 1 ? ProductType.nonConsumable : ProductType.consumable, response.appAccountToken); } final result = await ApplePay().purchase(productId: storeItem.appleGoodsId, appAccountToken: response.appAccountToken); if (result["success"] == true) { var receipt = result['receipt']; print('购买成功: ${result['receipt']}'); checkPaymentStatus(outTradeNo, paymentWay, storeItem, receiptData: receipt); } else { LoadingDialog.hide(); ToastUtil.show("Pay Error, Please try again"); print('购买失败: ${result['error']}'); } }).catchError((error) { LoadingDialog.hide(); ErrorHandler.toastError(error); }); } catch (error) { LoadingDialog.hide(); // ToastUtil.showToast(StringName.storePayError.tr); } } void closeBackClick(){ EventHandler.report(EventId.event_02003); Get.back(); } // 检查恢复订阅结果 Future checkRestoreStatus(String? receiptData) async { PaymentWay? paymentWay = currentSelectedPaymentWay.value; if (paymentWay == null) { // ToastUtil.showToast(StringName.storeChoicePayment.tr); return; } if (receiptData == null) { return; } int payPlatform = paymentWay.payPlatform; int payMethod = paymentWay.payMethod; // var code = await storeRepository.resume(payPlatform, payMethod, receiptData); storeRepository.resume(payPlatform, payMethod, receiptData).then((data) { LoadingDialog.hide(); ToastUtil.show("Restore success"); userRepository.getUserInfo(); Get.back(); }).catchError((error) { LoadingDialog.hide(); ToastUtil.show("Restore fail"); }); // if (code == 0) { // LoadingDialog.hide(); // ToastUtil.show("Restore success"); // userRepository.getUserInfo(); // Get.back(); // } else { // LoadingDialog.hide(); // ToastUtil.show("Restore fail"); // } } void checkPaymentStatus( String orderNo, PaymentWay paymentWay, StoreItem storeItemBean, {String? receiptData}) { paymentStatusManager.registerPaymentSuccessCallback(orderNo, this); paymentStatusManager.checkPaymentStatus(orderNo, paymentWay, storeItemBean, receiptData: receiptData); } @override void onPaymentSuccess(String orderNo, PaymentWay paymentWay, StoreItem storeItemBean) { // TODO: implement onPaymentSuccess LoadingDialog.hide(); ToastUtil.show("Pay success"); // 300ms后关闭弹窗 Future.delayed(Duration(seconds: 3), () { userRepository.getUserInfo(); }); Get.back(); } @override void onPaymentError(Error error) { // TODO: implement onPaymentError LoadingDialog.hide(); ErrorHandler.toastError(error); } }