Flutter-如何验证InAppPurchases(iOS)



我曾尝试实现非消耗品的应用内购买,但我至少在iOS上无法验证购买
每当我使函数"_verifyPurchase()"返回true时,一切都很好
这就是为什么我认为验证过程是个问题。

Future<bool> _verifyPurchase(String productID) async {
final appState = Provider.of<AppState>(context);
PurchaseDetails purchase = await _hasPurchased(productID);
SharedPreferences prefs = await SharedPreferences.getInstance();
print('verify'+purchase?.productID.toString()+(purchase?.error).toString());
if (purchase != null &&
(purchase.status == PurchaseStatus.purchased || purchase.transactionDate != null) &&
_kProductIds.contains(productID)) {
if(productID == _kProductIds[0]) {
print('has purchased remove ads');
prefs.setBool(productID, true);
setState(() {
appState.setBoughtRemoveAds = true;
});
}else if(productID == _kProductIds[1]){
print('has purchased premium');
prefs.setBool(productID, true);
setState(() {
appState.setBoughtPremium = true;
});
}
return true;
}
return false;
}

我不想验证购买服务器,并认为"_hasPurchased()"函数很可能已损坏

Future<PurchaseDetails> _hasPurchased(String productID) async {
final QueryPurchaseDetailsResponse response = await InAppPurchaseConnection.instance.queryPastPurchases();
return response.pastPurchases.firstWhere((purchase) => purchase.productID == productID,
orElse: () => null);
}

我遵循了Fireship.io 的教程

编辑:代码中的小错误。

花了几个小时终于解决了这个问题,不幸的是,flutter的两个插件(in_app_purchase和flutter_inapp_purchase)都没有非常清楚地共享如何验证您的购买收据的信息,这是示例代码。

解决方案1:从应用程序(不推荐)发出张贴请求

Future<http.Response> validateReceiptIos(receiptBody,isTest) async {
final String url = isTest
? 'https://sandbox.itunes.apple.com/verifyReceipt'
: 'https://buy.itunes.apple.com/verifyReceipt';
return  await http.post(
Uri.parse(url),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: json.encode(receiptBody),
);
}

传递函数参数

var receiptBody = {
'receipt-data': purchaseDetails.verificationData.localVerificationData, // receipt key you will receive in request purchase callback function 
'exclude-old-transactions':true,
'password':'You can get this from App store-> In app purchase-> App specific shared secert'
};

解决方案2:(推荐解决方案)在API服务器上创建一个API并调用[沙箱]或用于[生产]3这个,然后在你的应用程序中使用这个api。

虽然我喜欢fireship.io。本教程的不足之处在于,他没有教你如何正确验证购买。

我也遵循了教程,但发现它在验证方面有所欠缺。我专注于Android订阅,我发现了这些文档https://developer.android.com/google/play/billing/billing_library_overview#Verify这有点难以理解,因为我想尝试在设备上进行验证。

我换了RevenueCathttps://pub.dev/packages/purchases_flutter他们在服务器端为您处理验证,我发现这要容易得多。

我希望这能有所帮助!

我认为您应该在嵌套的if语句中移动return true行,因为该函数将验证用户是否已经购买了所有产品,即使他/她可能刚刚购买了一个。此外,嵌套if语句中的条件相同,都是productID == _kProductIds[0]

if (purchase != null &&
(purchase.status == PurchaseStatus.purchased || purchase.transactionDate != null) &&
_kProductIds.contains(productID)) {
if(productID == _kProductIds[0]) {
print('has purchased remove ads');
prefs.setBool(productID, true);
setState(() {
appState.setBoughtRemoveAds = true;
});
return true;
}else if(productID == _kProductIds[0]){
print('has purchased premium');
prefs.setBool(productID, true);
setState(() {
appState.setBoughtRemoveAds = true;
});
return true;
}
return false;
}
return false;

如果我相互检查购买ID,我得到的函数"_hasPurchase"可以工作。再次相互检查整个对象失败。可以运行比id更多的比较。

所以我添加了这个:

bool _comparePurchaseDetails(PurchaseDetails pd0, PurchaseDetails pd1){
if(pd0.purchaseID != pd1.purchaseID)return false;
if(pd0.verificationData.serverVerificationData != pd1.verificationData.serverVerificationData)return false;
if(pd0.verificationData.localVerificationData != pd1.verificationData.localVerificationData)return false;
return true;

}

最新更新