サブスクの課金機能を実装予定として、調査しています。単回課金も大きな違いはなく、実装できると思われます。事前準備各ストアにサブスクアイテムの作成・登録購入履歴のチェック用サーバーの設定AppStore(iOS)とGooglePlayConsole(Android)で、それぞれ購入品を登録する必要があります。AppStoreは、課金アイテムにも審査があります。iOSの課金テストには、実機が必要です。アンドロイドの場合は、アルファもしくはベータにバイナリ(アプリのデータ)をGoogle Play Consoleにアップロードして審査を通過してからでないと、課金のテストができません。AppStore(iOS)とGooglePlayConsole(Android)の操作については、こちらのドキュメントが参考になると思われます。https://www.revenuecat.com/docs/ios-productshttps://www.revenuecat.com/docs/android-productsアプリ側の実装アプリ側の実装としては、購入可能な課金アイテムのIdのSetが必要になります。これをハードコーディングするのか、課金アイテムは変動するので、API経由でIdの配列を返す形で実装するのかは、決めていただく必要があると思います。アプリ側の実装は下記の流れで実装します。課金アイテムのIDのSetを引数に渡して、ProductDetailsのListを取得します。const Set<String> _kIds = <String>['product1', 'product2'].toSet();
final ProductDetailsResponse response =
await InAppPurchase.instance.queryProductDetails(_kIds);
if (response.notFoundIDs.isNotEmpty) {
// Handle the error.
}
final List<ProductDetails> products = response.productDetails;購入するアイテムのProductDetailsを引数に渡して、購入処理を行います。final PurchaseParam purchaseParam = PurchaseParam(productDetails: productDetails);
if (_isConsumable(productDetails)) {
InAppPurchase.instance.buyConsumable(purchaseParam: purchaseParam);
} else {
InAppPurchase.instance.buyNonConsumable(purchaseParam: purchaseParam);
}ユーザーの購入処理の状況を監視し、購入処理が完了した時点でレシートを検証APIに渡します。 @override
void initState() {
final Stream purchaseUpdated =
InAppPurchase.instance.purchaseStream;
_subscription = purchaseUpdated.listen((purchaseDetailsList) {
_listenToPurchaseUpdated(purchaseDetailsList);
}, onDone: () {
_subscription.cancel();
}, onError: (error) {
// handle error here.
});
super.initState();
}
@override
void dispose() {
_subscription.cancel();
super.dispose();
}
void _listenToPurchaseUpdated(List<PurchaseDetails> purchaseDetailsList) {
purchaseDetailsList.forEach((PurchaseDetails purchaseDetails) async {
if (purchaseDetails.status == PurchaseStatus.pending) {
_showPendingUI();
} else {
if (purchaseDetails.status == PurchaseStatus.error) {
_handleError(purchaseDetails.error!);
} else if (purchaseDetails.status == PurchaseStatus.purchased ||
purchaseDetails.status == PurchaseStatus.restored) {
// レシートの検証
final bool valid = await _verifyPurchase(purchaseDetails);
if (valid) {
_deliverProduct(purchaseDetails);
} else {
_handleInvalidPurchase(purchaseDetails);
}
}
if (purchaseDetails.pendingCompletePurchase) {
await InAppPurchase.instance
.completePurchase(purchaseDetails);
}
}
});
} iOSでは、上記に加えてStoreKitと連携するための処理を追加する必要があります。 if (Platform.isIOS) {
final InAppPurchaseStoreKitPlatformAddition iosPlatformAddition =
_inAppPurchase
.getPlatformAddition<InAppPurchaseStoreKitPlatformAddition>();
await iosPlatformAddition.setDelegate(ExamplePaymentQueueDelegate());
}
@override
void dispose() {
if (Platform.isIOS) {
final InAppPurchaseStoreKitPlatformAddition iosPlatformAddition =
_inAppPurchase
.getPlatformAddition<InAppPurchaseStoreKitPlatformAddition>();
iosPlatformAddition.setDelegate(null);
}
_subscription.cancel();
super.dispose();
} RevenueCatの利用についてアプリ内課金のSaasでRevenueCatというサービスがあります。こちらは、バックエンドで行うレシートの検証を代行してくれるサービスになります。料金体型はこちらです。https://www.revenuecat.com/pricing/参考サイトhttps://qiita.com/YuKiO-OO/items/a0fe8e0a256afbb69fc7Flutter公式パッケージ:https://pub.dev/packages/in_app_purchasehttps://github.com/flutter/packages/blob/main/packages/in_app_purchase/in_app_purchase/example/lib/main.dartRevenueCatのパッケージ:https://pub.dev/packages/purchases_flutterhttps://zenn.dev/moga/books/flutter_revenuecat/viewer/2-about-revenuecathttps://www.revenuecat.com/docs