import 'dart:async'; import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:in_app_purchase/in_app_purchase.dart'; import 'package:in_app_purchase_android/in_app_purchase_android.dart'; import 'package:yumi/app_localizations.dart'; import 'package:yumi/services/auth/user_profile_manager.dart'; import 'package:provider/provider.dart'; import 'package:yumi/shared/tools/sc_string_utils.dart'; import 'package:yumi/shared/tools/sc_loading_manager.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:yumi/ui_kit/components/dialog/dialog_base.dart'; import 'package:yumi/ui_kit/components/sc_tts.dart'; import 'package:yumi/shared/data_sources/sources/repositories/sc_config_repository_imp.dart'; import 'package:yumi/shared/business_logic/models/res/sc_product_config_res.dart'; import 'package:yumi/modules/wallet/recharge/recharge_page.dart'; class AndroidPaymentProcessor extends ChangeNotifier { StreamSubscription>? _subscription; final InAppPurchase iap = InAppPurchase.instance; // 状态管理变量 bool _isAvailable = false; String _errorMessage = ''; List _products = []; List _purchases = []; ///商品列表 List productConfigs = []; // 维护商品类型映射 final Map _productTypeMap = {}; // 公开访问器 bool get isAvailable => _isAvailable; String get errorMessage => _errorMessage; List get products => _products; List get purchases => _purchases; late BuildContext context; Map productMap = {}; Map productTypes = {}; // 初始化支付系统 Future initializePaymentProcessor(BuildContext context) async { this.context = context; try { SCLoadingManager.show(context: context); // 检查支付是否可用 _isAvailable = await iap.isAvailable(); if (!_isAvailable) { _errorMessage = 'Google Play payment service is unavailable'; SCTts.show("Google Play payment service is unavailable"); return; } _subscription?.cancel(); // 设置购买流监听 _subscription = iap.purchaseStream.listen( _handlePurchase, onError: (error, stackTrace) => _handleError(error, stackTrace), ); // 先获取商品配置 await fetchProductConfiguration(); // 然后获取谷歌商品信息 await _fetchProducts(); // 最后恢复购买,处理未完成交易 await recoverTransactions(); } catch (e) { SCTts.show("init fail: $e"); _errorMessage = 'init fail: ${e.toString()}'; } finally { SCLoadingManager.hide(); notifyListeners(); } } ///用户获取商店配置的商品列表 Future fetchProductConfiguration() async { productMap.clear(); productConfigs = await SCConfigRepositoryImp().productConfig(); int index = 0; for (var value in productConfigs) { productMap[value.productPackage!] = value; productTypes[value.productPackage!] = "consumable"; index = index + 1; } notifyListeners(); } // 获取商品信息 Future _fetchProducts() async { try { SCLoadingManager.show(context: context); notifyListeners(); Set productIds = productTypes.keys.toSet(); ProductDetailsResponse response = await iap.queryProductDetails( productIds, ); if (response.notFoundIDs.isNotEmpty) { _errorMessage = '未找到商品: ${response.notFoundIDs.join(', ')}'; } var dtails = response.productDetails; if (dtails.isNotEmpty) { dtails.sort((a, b) { int ia = 0; int ib = 0; if (a.id.contains(".")) { ia = SCStringUtils.convertToInteger(a.id.split(".").last); } if (b.id.contains(".")) { ib = SCStringUtils.convertToInteger(b.id.split(".").last); } return ia.compareTo(ib); }); } int index = 0; _products.clear(); for (var v in dtails) { if (index == 0) { _products.add(SelecteProductConfig(v, true)); } else { _products.add(SelecteProductConfig(v, false)); } index++; } // 初始化商品类型映射 for (var product in _products) { if (productTypes.containsKey(product.produc.id)) { _productTypeMap[product.produc.id] = productTypes[product.produc.id]!; } else { _productTypeMap[product.produc.id] = 'nonConsumable'; // 默认类型 } } // 打印商品信息用于调试 for (var product in _products) {} } catch (e) { SCTts.show("Failed to retrieve the product: $e"); _errorMessage = '获取商品失败: ${e.toString()}'; } finally { SCLoadingManager.hide(); notifyListeners(); } } // 获取商品类型 String _getProductType(String productId) { return _productTypeMap[productId] ?? 'nonConsumable'; } // 发起购买 Future processPurchase() async { ProductDetails? product; _products.forEach((d) { if (d.isSelecte) { product = d.produc; } }); if (product == null) { SCTts.show(SCAppLocalizations.of(context)!.pleaseSelectaItem); return; } SmartDialog.show( tag: "showConfirmDialog", alignment: Alignment.center, debounce: true, animationType: SmartAnimationType.fade, builder: (_) { return MsgDialog( title: SCAppLocalizations.of(context)!.tips, msg: SCAppLocalizations.of(context)!.areYouRureRoRecharge, btnText: SCAppLocalizations.of(context)!.confirm, onEnsure: () { _goBuy(product!); }, ); }, ); } // 处理购买结果 void _handlePurchase(List purchases) { _purchases = purchases; for (var purchase in purchases) { switch (purchase.status) { case PurchaseStatus.purchased: _verifyPayment(purchase); break; case PurchaseStatus.error: if (purchase.error != null) { _handleIAPError(purchase.error!); // 特别处理 "item-already-owned" 错误 if (purchase.error!.code == 'item-already-owned') { _handleAlreadyOwnedItem(purchase); } } break; case PurchaseStatus.pending: break; case PurchaseStatus.restored: // 处理恢复的购买 _verifyPayment(purchase); break; default: break; } } notifyListeners(); } // 新增:处理已拥有商品的情况 Future _handleAlreadyOwnedItem(PurchaseDetails purchase) async { try { // 如果是消耗型商品,尝试消耗 if (_getProductType(purchase.productID) == 'consumable') { await consumePurchase(purchase); // 消耗后重新获取余额 Provider.of( context, listen: false, ).balance(); SCTts.show('outstanding purchases have been reinstated'); } } catch (e) {} } // 验证支付凭证 Future _verifyPayment(PurchaseDetails purchase) async { try { // 1. 基本验证 if (purchase.verificationData.serverVerificationData.isEmpty) { _errorMessage = '无效的支付凭证'; SCTts.show("Invalid payment voucher"); return; } // 2. 检查是否已经处理过这个购买 if (!purchase.pendingCompletePurchase) { return; } // 3. 获取购买数据 String purchaseData = purchase.verificationData.localVerificationData; String signature = ""; if (purchase is GooglePlayPurchaseDetails) { signature = purchase.billingClientPurchase.signature; } // 4. 服务器验证 await SCConfigRepositoryImp().googlePay( purchase.productID, signature, purchaseData, ); // 5. 交付商品 await _deliverProduct(purchase.productID); // 6. 完成购买 await iap.completePurchase(purchase); // 7. 如果是消耗型商品,确保消耗 if (_getProductType(purchase.productID) == 'consumable') { await _ensurePurchaseConsumed(purchase); } // 8. 更新用户余额 Provider.of( context, listen: false, ).fetchUserProfileData(); Provider.of( context, listen: false, ).balance(); SCTts.show('purchase successful'); } catch (e) { SCTts.show("verification failed: $e"); _errorMessage = '验证失败: ${e.toString()}'; } finally { SCLoadingManager.hide(); notifyListeners(); } } // 交付商品 Future _deliverProduct(String productId) async { // 实现您的业务逻辑 // 例如:增加用户余额、解锁功能等 } // 新增:确保购买被消耗 Future _ensurePurchaseConsumed(PurchaseDetails purchase) async { try { // 等待一段时间确保购买完成 await Future.delayed(Duration(seconds: 1)); // 尝试消耗购买 await consumePurchase(purchase); } catch (e) {} } void _handleError(Object error, StackTrace stackTrace) { SCTts.show("Payment error: $error"); if (error is IAPError) { // 处理IAP特定错误 _handleIAPError(error); } else { // 处理其他类型的错误 _errorMessage = '未知错误: ${error.toString()}'; SCTts.show(_errorMessage); } } // 添加了专门的IAP错误处理方法 void _handleIAPError(IAPError error) { _errorMessage = '支付错误: ${error.message} (${error.code})'; // 处理特定错误代码 switch (error.code) { case 'payment-invalid': SCTts.show( 'Payment configuration error, please contact customer service', ); break; case 'item-already-owned': SCTts.show('Unfinished purchase detected, processing...'); break; case 'user-cancelled': SCTts.show('Purchase cancelled'); break; case 'service-timeout': case 'service-unavailable': SCTts.show( 'Google Play services are temporarily unavailable, please try again later', ); break; default: SCTts.show('Payment failed: ${error.message}'); break; } SCLoadingManager.hide(); notifyListeners(); } // 恢复购买 Future recoverTransactions() async { try { SCLoadingManager.show(context: context); notifyListeners(); await iap.restorePurchases(); // 给恢复操作一些时间 await Future.delayed(Duration(milliseconds: 1000)); } catch (e) { _errorMessage = '恢复购买失败: ${e.toString()}'; SCTts.show("Failed to restore purchase: ${e.toString()}"); } finally { SCLoadingManager.hide(); notifyListeners(); } } // 消耗型商品手动消耗 Future consumePurchase(PurchaseDetails purchase) async { try { if (Platform.isAndroid) { final InAppPurchaseAndroidPlatformAddition androidAddition = iap.getPlatformAddition(); await androidAddition.consumePurchase(purchase); } } catch (e) { _errorMessage = '消耗商品失败: ${e.toString()}'; } } // 购买流程 void _goBuy(ProductDetails product) async { try { SCLoadingManager.show(context: context); notifyListeners(); // 购买前检查是否有未完成的购买 await _checkPendingPurchases(); final PurchaseParam purchaseParam = PurchaseParam( productDetails: product, applicationUserName: null, ); String productType = _getProductType(product.id); bool success; if (productType == 'consumable') { success = await iap.buyConsumable( purchaseParam: purchaseParam, autoConsume: kReleaseMode, // 生产环境自动消耗,调试时手动控制 ); } else { success = await iap.buyNonConsumable(purchaseParam: purchaseParam); } if (!success) { _errorMessage = '购买启动失败,请检查网络连接'; SCTts.show(_errorMessage); } } catch (e) { SCTts.show("Purchase failed: $e"); _errorMessage = '购买失败: ${e.toString()}'; } finally { SCLoadingManager.hide(); notifyListeners(); } } // 新增:检查未完成的购买 Future _checkPendingPurchases() async { try { // 恢复购买以获取所有未完成交易 await iap.restorePurchases(); // 给一点时间处理恢复的购买 await Future.delayed(Duration(milliseconds: 550)); } catch (e) {} } // 添加调试方法 void logCurrentPurchaseStatus() { for (var purchase in _purchases) {} } // 释放资源 @override void dispose() { _subscription?.cancel(); super.dispose(); } void chooseProductConfig(int index) { for (var v in _products) { v.isSelecte = false; } _products[index].isSelecte = true; notifyListeners(); } }