Commit 0f7f20cd by ethanlamzs

优化

1 parent 1d8c2b03
...@@ -20,8 +20,6 @@ class SubscriptionService { ...@@ -20,8 +20,6 @@ class SubscriptionService {
final Map<String, Map<String, dynamic>> _pendingContexts = {}; final Map<String, Map<String, dynamic>> _pendingContexts = {};
final Map<String, String> _orderIdMap = {}; // key: productID, value: orderId
final InAppPurchase _iap = InAppPurchase.instance; final InAppPurchase _iap = InAppPurchase.instance;
late StreamSubscription<List<PurchaseDetails>> _purchaseUpdatedSubscription; late StreamSubscription<List<PurchaseDetails>> _purchaseUpdatedSubscription;
...@@ -61,8 +59,6 @@ class SubscriptionService { ...@@ -61,8 +59,6 @@ class SubscriptionService {
// 3. 从 App Store 获取产品信息 // 3. 从 App Store 获取产品信息
await _fetchProducts(); await _fetchProducts();
// 4. 处理待处理的交易(应用被杀掉时未完成交易)
//await _iap.restorePurchases(); // 订阅恢复也会触发 purchaseStream
} }
...@@ -86,11 +82,19 @@ class SubscriptionService { ...@@ -86,11 +82,19 @@ class SubscriptionService {
} }
Future<void> restoreSubscription() async {
try{
await _iap.restorePurchases();
}
catch(e){
onError?.call(e.toString());
}
}
// ---------- 购买订阅 ---------- // ---------- 购买订阅 ----------
Future<bool> buySubscription(ProductDetails product, String userId , String tbxStuId, String yWOrderId) async { Future<bool> buySubscription(ProductDetails product, String userId , String tbxStuId, String yWOrderId) async {
_pendingContexts[product.id] = {'userId': userId,'tbxStuId': tbxStuId,"orderId":yWOrderId}; _pendingContexts[product.id] = {'userId': userId,'tbxStuId': tbxStuId,"orderId":yWOrderId};
_orderIdMap[product.id] = yWOrderId; // 按产品 ID 存储
// 订阅必须使用 PurchaseParam 并设置购买类型为订阅 // 订阅必须使用 PurchaseParam 并设置购买类型为订阅
final PurchaseParam purchaseParam = PurchaseParam( final PurchaseParam purchaseParam = PurchaseParam(
...@@ -122,14 +126,14 @@ Future<bool> buySubscription(ProductDetails product, String userId , String tbxS ...@@ -122,14 +126,14 @@ Future<bool> buySubscription(ProductDetails product, String userId , String tbxS
} }
// 🔁 去重措施 1:根据原始交易 ID 去重,防止同一笔交易被重复处理 // 🔁 去重措施 1:根据原始交易 ID 去重,防止同一笔交易被重复处理
final transactionId = purchaseDetails.verificationData.serverVerificationData.hashCode.toString(); //final transactionId = purchaseDetails.verificationData.serverVerificationData.hashCode.toString();
// 如果能获取到 purchaseID 更可靠,这里用 purchaseID 作为唯一标识 // 如果能获取到 purchaseID 更可靠,这里用 purchaseID 作为唯一标识
final uniqueId = purchaseDetails.purchaseID; final uniqueId = purchaseDetails.purchaseID;
if (_processedTransactionIds.contains(uniqueId)) { if (_processedTransactionIds.contains(uniqueId)) {
// 已经处理过,直接结束交易并跳过 // 已经处理过,直接结束交易并跳过
if (purchaseDetails.status == PurchaseStatus.purchased || if (purchaseDetails.status == PurchaseStatus.purchased ||
purchaseDetails.status == PurchaseStatus.restored) { purchaseDetails.status == PurchaseStatus.restored) {
_iap.completePurchase(purchaseDetails); _iap.completePurchase(purchaseDetails);
} }
continue; continue;
} }
...@@ -138,13 +142,13 @@ Future<bool> buySubscription(ProductDetails product, String userId , String tbxS ...@@ -138,13 +142,13 @@ Future<bool> buySubscription(ProductDetails product, String userId , String tbxS
_processedTransactionIds.add(uniqueId); _processedTransactionIds.add(uniqueId);
} }
//var orderId = _orderIdMap.remove(purchaseDetails.productID); // 取出并删除
final ctx = _pendingContexts[purchaseDetails.productID] ; final ctx = _pendingContexts[purchaseDetails.productID] ;
print(ctx); print(ctx);
if (ctx == null) { if (ctx == null) {
// 打印错误日志,防止崩溃 // 打印错误日志,防止崩溃
print('错误:未找到 productID 对应的上下文缓存'); print('错误:未找到 productID 对应的上下文缓存');
return; debugPrint("No purchase context: ${purchaseDetails.productID}");
continue;
} }
final orderId = ctx['orderId'] as String?; final orderId = ctx['orderId'] as String?;
...@@ -180,6 +184,9 @@ Future<bool> buySubscription(ProductDetails product, String userId , String tbxS ...@@ -180,6 +184,9 @@ Future<bool> buySubscription(ProductDetails product, String userId , String tbxS
// 用户取消支付 // 用户取消支付
//_iap.completePurchase(purchaseDetails); //_iap.completePurchase(purchaseDetails);
break; break;
case PurchaseStatus.pending:
onStateChanged?.call();
break;
default: default:
break; break;
} }
...@@ -256,10 +263,14 @@ Future<bool> buySubscription(ProductDetails product, String userId , String tbxS ...@@ -256,10 +263,14 @@ Future<bool> buySubscription(ProductDetails product, String userId , String tbxS
} }
// ---------- 恢复成功处理 ---------- // ---------- 恢复成功处理 ----------
void _handleRestoreSuccess(PurchaseDetails detail,String orderId,String userId) { Future<void> _handleRestoreSuccess(PurchaseDetails detail,String orderId,String userId) async{
// 注意:这里只是处理单个 restored,但最终 UI 刷新在 _onPurchaseUpdate 统一完成 // 注意:这里只是处理单个 restored,但最终 UI 刷新在 _onPurchaseUpdate 统一完成
_verifyReceipt(detail,orderId??'',userId??'',"purchased"); final ok = await _verifyReceipt(detail,orderId??'',userId??'',"purchased");
_iap.completePurchase(detail); if(ok){
if(detail.pendingCompletePurchase){
await _iap.completePurchase(detail);
}
}
} }
// ---------- 错误处理 ---------- // ---------- 错误处理 ----------
...@@ -276,9 +287,9 @@ Future<bool> buySubscription(ProductDetails product, String userId , String tbxS ...@@ -276,9 +287,9 @@ Future<bool> buySubscription(ProductDetails product, String userId , String tbxS
onError?.call('支付已取消'); onError?.call('支付已取消');
} }
// 释放资源 // 释放资源
void dispose() { Future<void> dispose() async {
_purchaseUpdatedSubscription.cancel(); await _purchaseUpdatedSubscription.cancel();
} }
}
\ No newline at end of file \ No newline at end of file
}
name: appframe name: appframe
description: "app frame project." description: "app frame project."
publish_to: 'none' publish_to: 'none'
version: 1.1.2 version: 1.1.3
environment: environment:
sdk: ">=3.5.0 <4.0.0" sdk: ">=3.5.0 <4.0.0"
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!