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(', ')}'; debugPrint(_errorMessage); } 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) { debugPrint( '商品: ${product.produc.id}, 类型: ${_productTypeMap[product.produc.id]}, 价格: ${product.produc.price}', ); } } catch (e) { SCTts.show("Failed to retrieve the product: $e"); _errorMessage = '获取商品失败: ${e.toString()}'; debugPrint(_errorMessage); } 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: debugPrint('支付处理中: ${purchase.productID}'); break; case PurchaseStatus.restored: // 处理恢复的购买 _verifyPayment(purchase); break; default: break; } } notifyListeners(); } // 新增:处理已拥有商品的情况 Future _handleAlreadyOwnedItem(PurchaseDetails purchase) async { try { debugPrint('检测到已拥有商品: ${purchase.productID},尝试消耗'); // 如果是消耗型商品,尝试消耗 if (_getProductType(purchase.productID) == 'consumable') { await consumePurchase(purchase); // 消耗后重新获取余额 Provider.of(context, listen: false).balance(); SCTts.show('outstanding purchases have been reinstated'); } } catch (e) { debugPrint('处理已拥有商品失败: $e'); } } // 验证支付凭证 Future _verifyPayment(PurchaseDetails purchase) async { try { // 1. 基本验证 if (purchase.verificationData.serverVerificationData.isEmpty) { _errorMessage = '无效的支付凭证'; SCTts.show("Invalid payment voucher"); return; } // 2. 检查是否已经处理过这个购买 if (!purchase.pendingCompletePurchase) { debugPrint('购买已处理过: ${purchase.productID}'); 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'); debugPrint('购买成功: ${purchase.productID}'); } catch (e) { SCTts.show("verification failed: $e"); _errorMessage = '验证失败: ${e.toString()}'; debugPrint(_errorMessage); } finally { SCLoadingManager.hide(); notifyListeners(); } } // 交付商品 Future _deliverProduct(String productId) async { debugPrint('交付商品: $productId'); // 实现您的业务逻辑 // 例如:增加用户余额、解锁功能等 } // 新增:确保购买被消耗 Future _ensurePurchaseConsumed(PurchaseDetails purchase) async { try { // 等待一段时间确保购买完成 await Future.delayed(Duration(seconds: 1)); // 尝试消耗购买 await consumePurchase(purchase); debugPrint('商品已成功消耗: ${purchase.productID}'); } catch (e) { debugPrint('消耗商品失败,可能已自动消耗: $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': debugPrint('支付无效: 商品ID可能配置错误'); SCTts.show( 'Payment configuration error, please contact customer service', ); break; case 'item-already-owned': debugPrint('商品已拥有,尝试消耗商品'); SCTts.show('Unfinished purchase detected, processing...'); break; case 'user-cancelled': debugPrint('用户取消购买'); SCTts.show('Purchase cancelled'); break; case 'service-timeout': case 'service-unavailable': debugPrint('Google Play服务不可用'); SCTts.show( 'Google Play services are temporarily unavailable, please try again later', ); break; default: SCTts.show('Payment failed: ${error.message}'); break; } debugPrint(_errorMessage); 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()}'; debugPrint(_errorMessage); 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); debugPrint('已消耗商品: ${purchase.productID}'); } } catch (e) { _errorMessage = '消耗商品失败: ${e.toString()}'; debugPrint(_errorMessage); } } // 购买流程 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()}'; debugPrint(_errorMessage); } finally { SCLoadingManager.hide(); notifyListeners(); } } // 新增:检查未完成的购买 Future _checkPendingPurchases() async { try { // 恢复购买以获取所有未完成交易 await iap.restorePurchases(); // 给一点时间处理恢复的购买 await Future.delayed(Duration(milliseconds: 550)); } catch (e) { debugPrint('检查未完成购买时出错: $e'); } } // 添加调试方法 void logCurrentPurchaseStatus() { debugPrint('=== 当前购买状态 ==='); debugPrint('可用商品数量: ${_products.length}'); debugPrint('未完成购买数量: ${_purchases.length}'); for (var purchase in _purchases) { debugPrint('商品: ${purchase.productID}, 状态: ${purchase.status}'); debugPrint('待完成: ${purchase.pendingCompletePurchase}'); } debugPrint('=================='); } // 释放资源 @override void dispose() { _subscription?.cancel(); super.dispose(); } void chooseProductConfig(int index) { for (var v in _products) { v.isSelecte = false; } _products[index].isSelecte = true; notifyListeners(); } }