1.6.2
This commit is contained in:
parent
142dcebaae
commit
3872dc03b1
@ -524,7 +524,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/RunnerRelease.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/RunnerRelease.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 161;
|
CURRENT_PROJECT_VERSION = 162;
|
||||||
DEVELOPMENT_TEAM = S9YG87C297;
|
DEVELOPMENT_TEAM = S9YG87C297;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@ -533,7 +533,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.6.1;
|
MARKETING_VERSION = 1.6.2;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@ -715,7 +715,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/RunnerDebug.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/RunnerDebug.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 161;
|
CURRENT_PROJECT_VERSION = 162;
|
||||||
DEVELOPMENT_TEAM = S9YG87C297;
|
DEVELOPMENT_TEAM = S9YG87C297;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@ -724,7 +724,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.6.1;
|
MARKETING_VERSION = 1.6.2;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@ -744,7 +744,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/RunnerRelease.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/RunnerRelease.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 161;
|
CURRENT_PROJECT_VERSION = 162;
|
||||||
DEVELOPMENT_TEAM = S9YG87C297;
|
DEVELOPMENT_TEAM = S9YG87C297;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@ -753,7 +753,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.6.1;
|
MARKETING_VERSION = 1.6.2;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import 'package:firebase_core/firebase_core.dart';
|
|||||||
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
||||||
import 'package:fluro/fluro.dart' as fluro;
|
import 'package:fluro/fluro.dart' as fluro;
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
@ -299,6 +300,7 @@ class _YumiApplicationState extends State<YumiApplication>
|
|||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
_initRouter();
|
_initRouter();
|
||||||
unawaited(_initLink());
|
unawaited(_initLink());
|
||||||
|
unawaited(_reconcilePendingGooglePurchases(force: true));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,6 +327,24 @@ class _YumiApplicationState extends State<YumiApplication>
|
|||||||
context.read<RtcProvider>().releaseRtcEngineForAppTermination(),
|
context.read<RtcProvider>().releaseRtcEngineForAppTermination(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (state == AppLifecycleState.resumed) {
|
||||||
|
unawaited(_reconcilePendingGooglePurchases());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _reconcilePendingGooglePurchases({bool force = false}) async {
|
||||||
|
if (!Platform.isAndroid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await context
|
||||||
|
.read<AndroidPaymentProcessor>()
|
||||||
|
.reconcilePendingGooglePurchases(context: context, force: force);
|
||||||
|
} catch (error) {
|
||||||
|
if (kDebugMode) {
|
||||||
|
debugPrint('reconcile pending google purchases failed: $error');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@ -15,6 +15,7 @@ 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/dialog/dialog_base.dart';
|
||||||
import 'package:yumi/ui_kit/components/sc_tts.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/data_sources/sources/repositories/sc_config_repository_imp.dart';
|
||||||
|
import 'package:yumi/shared/business_logic/models/res/sc_google_pay_res.dart';
|
||||||
import 'package:yumi/shared/business_logic/models/res/sc_product_config_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/sc_product_config_res.dart';
|
||||||
import 'package:yumi/modules/wallet/recharge/recharge_page.dart';
|
import 'package:yumi/modules/wallet/recharge/recharge_page.dart';
|
||||||
|
|
||||||
@ -33,6 +34,9 @@ class AndroidPaymentProcessor extends ChangeNotifier {
|
|||||||
|
|
||||||
// 维护商品类型映射
|
// 维护商品类型映射
|
||||||
final Map<String, String> _productTypeMap = {};
|
final Map<String, String> _productTypeMap = {};
|
||||||
|
final Set<String> _verifyingPurchaseKeys = {};
|
||||||
|
bool _isReconcilingPastPurchases = false;
|
||||||
|
DateTime? _lastPastPurchaseReconcileAt;
|
||||||
|
|
||||||
// 公开访问器
|
// 公开访问器
|
||||||
bool get isAvailable => _isAvailable;
|
bool get isAvailable => _isAvailable;
|
||||||
@ -60,12 +64,7 @@ class AndroidPaymentProcessor extends ChangeNotifier {
|
|||||||
SCTts.show("Google Play payment service is unavailable");
|
SCTts.show("Google Play payment service is unavailable");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_subscription?.cancel();
|
_ensurePurchaseStreamListener();
|
||||||
// 设置购买流监听
|
|
||||||
_subscription = iap.purchaseStream.listen(
|
|
||||||
_handlePurchase,
|
|
||||||
onError: (error, stackTrace) => _handleError(error, stackTrace),
|
|
||||||
);
|
|
||||||
|
|
||||||
// 先获取商品配置
|
// 先获取商品配置
|
||||||
await fetchProductConfiguration();
|
await fetchProductConfiguration();
|
||||||
@ -75,6 +74,7 @@ class AndroidPaymentProcessor extends ChangeNotifier {
|
|||||||
|
|
||||||
// 最后恢复购买,处理未完成交易
|
// 最后恢复购买,处理未完成交易
|
||||||
await recoverTransactions();
|
await recoverTransactions();
|
||||||
|
await reconcilePendingGooglePurchases(force: true);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
SCTts.show("init fail: $e");
|
SCTts.show("init fail: $e");
|
||||||
_errorMessage = 'init fail: ${e.toString()}';
|
_errorMessage = 'init fail: ${e.toString()}';
|
||||||
@ -84,6 +84,13 @@ class AndroidPaymentProcessor extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _ensurePurchaseStreamListener() {
|
||||||
|
_subscription ??= iap.purchaseStream.listen(
|
||||||
|
_handlePurchase,
|
||||||
|
onError: (error, stackTrace) => _handleError(error, stackTrace),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
///用户获取商店配置的商品列表
|
///用户获取商店配置的商品列表
|
||||||
Future fetchProductConfiguration() async {
|
Future fetchProductConfiguration() async {
|
||||||
productMap.clear();
|
productMap.clear();
|
||||||
@ -155,6 +162,9 @@ class AndroidPaymentProcessor extends ChangeNotifier {
|
|||||||
|
|
||||||
// 获取商品类型
|
// 获取商品类型
|
||||||
String _getProductType(String productId) {
|
String _getProductType(String productId) {
|
||||||
|
if (productId.startsWith('coins.')) {
|
||||||
|
return 'consumable';
|
||||||
|
}
|
||||||
return _productTypeMap[productId] ?? 'nonConsumable';
|
return _productTypeMap[productId] ?? 'nonConsumable';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +293,7 @@ class AndroidPaymentProcessor extends ChangeNotifier {
|
|||||||
|
|
||||||
case PurchaseStatus.restored:
|
case PurchaseStatus.restored:
|
||||||
// 处理恢复的购买
|
// 处理恢复的购买
|
||||||
_verifyPayment(purchase);
|
_verifyPayment(purchase, forceSubmit: true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -304,21 +314,20 @@ class AndroidPaymentProcessor extends ChangeNotifier {
|
|||||||
listen: false,
|
listen: false,
|
||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
// 如果是消耗型商品,尝试消耗
|
await reconcilePendingGooglePurchases(force: true, showToast: true);
|
||||||
if (_getProductType(purchase.productID) == 'consumable') {
|
profileManager.balance();
|
||||||
await consumePurchase(purchase);
|
_refreshFirstRechargeRewardState(firstRechargeManager);
|
||||||
// 消耗后重新获取余额
|
|
||||||
profileManager.balance();
|
|
||||||
_refreshFirstRechargeRewardState(firstRechargeManager);
|
|
||||||
SCTts.show('outstanding purchases have been reinstated');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('handle already-owned purchase failed: $e');
|
debugPrint('handle already-owned purchase failed: $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证支付凭证
|
// 验证支付凭证
|
||||||
Future<void> _verifyPayment(PurchaseDetails purchase) async {
|
Future<void> _verifyPayment(
|
||||||
|
PurchaseDetails purchase, {
|
||||||
|
bool forceSubmit = false,
|
||||||
|
bool showToast = true,
|
||||||
|
}) async {
|
||||||
final profileManager = Provider.of<SocialChatUserProfileManager>(
|
final profileManager = Provider.of<SocialChatUserProfileManager>(
|
||||||
context,
|
context,
|
||||||
listen: false,
|
listen: false,
|
||||||
@ -331,12 +340,22 @@ class AndroidPaymentProcessor extends ChangeNotifier {
|
|||||||
// 1. 基本验证
|
// 1. 基本验证
|
||||||
if (purchase.verificationData.serverVerificationData.isEmpty) {
|
if (purchase.verificationData.serverVerificationData.isEmpty) {
|
||||||
_errorMessage = '无效的支付凭证';
|
_errorMessage = '无效的支付凭证';
|
||||||
SCTts.show("Invalid payment voucher");
|
if (showToast) {
|
||||||
|
SCTts.show("Invalid payment voucher");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 检查是否已经处理过这个购买
|
// 2. 正常购买流依赖 pendingCompletePurchase;启动/回前台补偿流需要允许
|
||||||
if (!purchase.pendingCompletePurchase) {
|
// 已确认但仍未消费的一次性商品再次上报后端,否则用户付款后退出 App 会漏单。
|
||||||
|
if (!forceSubmit && !purchase.pendingCompletePurchase) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final purchaseKey =
|
||||||
|
purchase.purchaseID ??
|
||||||
|
purchase.verificationData.serverVerificationData;
|
||||||
|
if (purchaseKey.isNotEmpty && !_verifyingPurchaseKeys.add(purchaseKey)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,7 +368,7 @@ class AndroidPaymentProcessor extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 4. 服务器验证
|
// 4. 服务器验证
|
||||||
await SCConfigRepositoryImp().googlePay(
|
await _submitGooglePayVerification(
|
||||||
purchase.productID,
|
purchase.productID,
|
||||||
signature,
|
signature,
|
||||||
purchaseData,
|
purchaseData,
|
||||||
@ -371,16 +390,125 @@ class AndroidPaymentProcessor extends ChangeNotifier {
|
|||||||
profileManager.balance();
|
profileManager.balance();
|
||||||
_refreshFirstRechargeRewardState(firstRechargeManager);
|
_refreshFirstRechargeRewardState(firstRechargeManager);
|
||||||
|
|
||||||
SCTts.show('purchase successful');
|
if (showToast) {
|
||||||
|
SCTts.show('purchase successful');
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
SCTts.show("verification failed: $e");
|
if (showToast) {
|
||||||
|
SCTts.show("verification failed: $e");
|
||||||
|
}
|
||||||
_errorMessage = '验证失败: ${e.toString()}';
|
_errorMessage = '验证失败: ${e.toString()}';
|
||||||
} finally {
|
} finally {
|
||||||
|
final purchaseKey =
|
||||||
|
purchase.purchaseID ??
|
||||||
|
purchase.verificationData.serverVerificationData;
|
||||||
|
if (purchaseKey.isNotEmpty) {
|
||||||
|
_verifyingPurchaseKeys.remove(purchaseKey);
|
||||||
|
}
|
||||||
SCLoadingManager.hide();
|
SCLoadingManager.hide();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> reconcilePendingGooglePurchases({
|
||||||
|
BuildContext? context,
|
||||||
|
bool force = false,
|
||||||
|
bool showToast = false,
|
||||||
|
}) async {
|
||||||
|
if (!Platform.isAndroid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (context != null) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
if (_isReconcilingPastPurchases) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final lastCheck = _lastPastPurchaseReconcileAt;
|
||||||
|
if (!force &&
|
||||||
|
lastCheck != null &&
|
||||||
|
DateTime.now().difference(lastCheck) < const Duration(seconds: 20)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isReconcilingPastPurchases = true;
|
||||||
|
_lastPastPurchaseReconcileAt = DateTime.now();
|
||||||
|
try {
|
||||||
|
_ensurePurchaseStreamListener();
|
||||||
|
_isAvailable = await iap.isAvailable();
|
||||||
|
if (!_isAvailable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final InAppPurchaseAndroidPlatformAddition androidAddition =
|
||||||
|
iap.getPlatformAddition<InAppPurchaseAndroidPlatformAddition>();
|
||||||
|
final response = await androidAddition.queryPastPurchases();
|
||||||
|
if (response.error != null) {
|
||||||
|
debugPrint('query past google purchases failed: ${response.error}');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final purchases =
|
||||||
|
response.pastPurchases.where((purchase) {
|
||||||
|
final isPurchased =
|
||||||
|
purchase.status == PurchaseStatus.purchased ||
|
||||||
|
purchase.status == PurchaseStatus.restored;
|
||||||
|
final productType = _getProductType(purchase.productID);
|
||||||
|
final isUnacknowledged =
|
||||||
|
purchase.pendingCompletePurchase ||
|
||||||
|
!purchase.billingClientPurchase.isAcknowledged;
|
||||||
|
// Google 只会返回未消费的一次性商品;即使它已确认,也说明仍可补上报后端。
|
||||||
|
return isPurchased &&
|
||||||
|
(isUnacknowledged || productType == 'consumable');
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
if (purchases.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_purchases = purchases;
|
||||||
|
for (final purchase in purchases) {
|
||||||
|
await _verifyPayment(purchase, forceSubmit: true, showToast: showToast);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('reconcile pending google purchases failed: $e');
|
||||||
|
} finally {
|
||||||
|
_isReconcilingPastPurchases = false;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<SCGooglePayRes> _submitGooglePayVerification(
|
||||||
|
String product,
|
||||||
|
String signature,
|
||||||
|
String purchaseData,
|
||||||
|
) async {
|
||||||
|
const api = 'order/purchase-pay/google';
|
||||||
|
final paramsForLog = <String, dynamic>{
|
||||||
|
'product': product,
|
||||||
|
'signature': _clipForDebugLog(signature),
|
||||||
|
'purchaseData': _clipForDebugLog(purchaseData),
|
||||||
|
};
|
||||||
|
if (kDebugMode) {
|
||||||
|
debugPrint('[GooglePay] request api=$api params=$paramsForLog');
|
||||||
|
}
|
||||||
|
final result = await SCConfigRepositoryImp().googlePay(
|
||||||
|
product,
|
||||||
|
signature,
|
||||||
|
purchaseData,
|
||||||
|
);
|
||||||
|
if (kDebugMode) {
|
||||||
|
debugPrint('[GooglePay] response api=$api result=${result.toJson()}');
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String _clipForDebugLog(String value) {
|
||||||
|
if (value.length <= 240) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return '${value.substring(0, 120)}...${value.substring(value.length - 80)}';
|
||||||
|
}
|
||||||
|
|
||||||
// 交付商品
|
// 交付商品
|
||||||
Future<void> _deliverProduct(String productId) async {
|
Future<void> _deliverProduct(String productId) async {
|
||||||
// 实现您的业务逻辑
|
// 实现您的业务逻辑
|
||||||
@ -506,7 +634,7 @@ class AndroidPaymentProcessor extends ChangeNotifier {
|
|||||||
if (productType == 'consumable') {
|
if (productType == 'consumable') {
|
||||||
success = await iap.buyConsumable(
|
success = await iap.buyConsumable(
|
||||||
purchaseParam: purchaseParam,
|
purchaseParam: purchaseParam,
|
||||||
autoConsume: kReleaseMode, // 生产环境自动消耗,调试时手动控制
|
autoConsume: false,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
success = await iap.buyNonConsumable(purchaseParam: purchaseParam);
|
success = await iap.buyNonConsumable(purchaseParam: purchaseParam);
|
||||||
@ -528,6 +656,8 @@ class AndroidPaymentProcessor extends ChangeNotifier {
|
|||||||
// 新增:检查未完成的购买
|
// 新增:检查未完成的购买
|
||||||
Future<void> _checkPendingPurchases() async {
|
Future<void> _checkPendingPurchases() async {
|
||||||
try {
|
try {
|
||||||
|
await reconcilePendingGooglePurchases();
|
||||||
|
|
||||||
// 恢复购买以获取所有未完成交易
|
// 恢复购买以获取所有未完成交易
|
||||||
await iap.restorePurchases();
|
await iap.restorePurchases();
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import 'dart:async';
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
@ -1336,7 +1335,7 @@ class _RoomRedPacketRechargeSheetState
|
|||||||
SCLoadingManager.show();
|
SCLoadingManager.show();
|
||||||
final success = await processor.iap.buyConsumable(
|
final success = await processor.iap.buyConsumable(
|
||||||
purchaseParam: PurchaseParam(productDetails: product.produc),
|
purchaseParam: PurchaseParam(productDetails: product.produc),
|
||||||
autoConsume: kReleaseMode,
|
autoConsume: false,
|
||||||
);
|
);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
SCTts.show('Purchase failed, please check your network connection');
|
SCTts.show('Purchase failed, please check your network connection');
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
@ -367,7 +366,7 @@ class _RoomRechargeBottomSheetState extends State<RoomRechargeBottomSheet> {
|
|||||||
SCLoadingManager.show();
|
SCLoadingManager.show();
|
||||||
final success = await processor.iap.buyConsumable(
|
final success = await processor.iap.buyConsumable(
|
||||||
purchaseParam: PurchaseParam(productDetails: product.produc),
|
purchaseParam: PurchaseParam(productDetails: product.produc),
|
||||||
autoConsume: kReleaseMode,
|
autoConsume: false,
|
||||||
);
|
);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
SCTts.show('Purchase failed, please check your network connection');
|
SCTts.show('Purchase failed, please check your network connection');
|
||||||
|
|||||||
@ -42,6 +42,6 @@ android {
|
|||||||
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "com.tencent.tav:libpag:4.3.68"
|
implementation "com.tencent.tav:libpag:4.5.70"
|
||||||
implementation 'com.jakewharton:disklrucache:2.0.2'
|
implementation 'com.jakewharton:disklrucache:2.0.2'
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 1.6.1+161
|
version: 1.6.2+162
|
||||||
|
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user