# CAPACITOR - Adapty Documentation (Full Content) This file contains the complete content of all documentation pages for this platform. Locale: ja Generated on: 2026-06-24T14:36:28.471Z Total files: 43 --- # File: capacitor-sdk-overview --- --- title: "Capacitor SDK overview" description: "Learn about Adapty Capacitor SDK and its key features." --- [![Release](https://img.shields.io/github/v/release/adaptyteam/AdaptySDK-Capacitor.svg?style=flat&logo=capacitor)](https://github.com/adaptyteam/AdaptySDK-Capacitor/releases) Welcome! We're here to make in-app purchases a breeze 🚀 We've built the [Adapty Capacitor SDK](https://github.com/adaptyteam/AdaptySDK-Capacitor/) to take the headache out of in-app purchases so you can focus on what you do best – building amazing apps. Here's what we handle for you: - Handle purchases, receipt validation, and subscription management out of the box - Create and test paywalls without app updates - Get detailed purchase analytics with zero setup - cohorts, LTV, churn, and funnel analysis included - Keep the user subscription status always up to date across app sessions and devices - Integrate your app with marketing attribution and analytics services using just one line of code :::note Before diving into the code, you'll need to integrate Adapty with App Store Connect and Google Play Console, then set up products in the dashboard. Check out our [quickstart guide](quickstart) to get everything configured first. ::: ## Get started For a fully automated integration, use the [adapty-sdk-integration skill](https://github.com/adaptyteam/adapty-sdk-integration-skill): it runs the whole integration from your AI coding tool in one command. Here's what we'll cover in the integration guide: 1. [Install & configure SDK](sdk-installation-capacitor): Add the SDK as a [dependency](https://www.npmjs.com/package/@adapty/capacitor) to your project and activate it in the code. 2. [Enable purchases through paywalls](capacitor-quickstart-paywalls): Set up the purchase flow so users can buy products. 3. [Check the subscription status](capacitor-check-subscription-status): Automatically check the user's subscription state and control their access to paid content. 4. [Identify users (optional)](capacitor-quickstart-identify): Associate users with their Adapty profiles to ensure their data is stored consistently across devices. ### See it in action Want to see how it all comes together? We've got you covered: **Sample apps**: Check out our complete examples that demonstrate the full setup: - [React](https://github.com/adaptyteam/AdaptySDK-Capacitor/tree/master/examples/basic-react-example) - [Vue.js](https://github.com/adaptyteam/AdaptySDK-Capacitor/tree/master/examples/basic-vue-example) - [Angular](https://github.com/adaptyteam/AdaptySDK-Capacitor/tree/master/examples/basic-angular-example) - [Advanced development tools](https://github.com/adaptyteam/AdaptySDK-Capacitor/tree/master/examples/adapty-devtools) ## Main concepts Before diving into the code, let's get familiar with the key concepts that make Adapty work. The beauty of Adapty's approach is that only placements are hardcoded in your app. Everything else – products, paywall designs, pricing, and offers – can be managed flexibly from the Adapty dashboard without app updates: 1. **Product** - Anything available for purchase in your app – subscription, consumable product, or lifetime access. 2. **Paywall** - The only way to retrieve products from Adapty and use it to its full power. We've designed it this way to make it easier to track how different product combinations affect your monetization metrics. A paywall in Adapty serves as both a specific set of your products and the visual configuration that accompanies them. 3. **Placement** - A strategic point in your user journey where you want to show a paywall. Think of placements as the "where" and "when" of your monetization strategy. Common placements include: - `main` - Your primary paywall location - `onboarding` - Shown during the user onboarding flow - `settings` - Accessible from your app's settings Start with the basics like `main` or `onboarding` for your first integration, then think about where else in your app users might be ready to purchase. 4. **Profile** - When users purchase a product, their profile is assigned an **access level** which you use to define access to paid features. --- # File: sdk-installation-capacitor --- --- title: "Capacitor - Adapty SDK のインストールと設定" description: "サブスクリプション型アプリ向けに Capacitor へ Adapty SDK をインストールするステップバイステップガイド。" --- Adapty SDK には、Capacitor アプリへのスムーズな統合を実現する 2 つの主要モジュールが含まれています。 - **Core Adapty**: アプリで Adapty を正しく動作させるために必須のモジュールです。 - **AdaptyUI**: クロスプラットフォームのペイウォールをノーコードで簡単に作成できるツール [Adapty ペイウォールビルダー](adapty-paywall-builder) を使用する場合に必要なモジュールです。AdaptyUI はコアモジュールと同時に自動的に有効化されます。 :::tip Adapty SDK をモバイルアプリに統合した実際の例を見たい方は、[サンプルアプリ](https://github.com/adaptyteam/AdaptySDK-Capacitor/tree/master/examples)をご確認ください。ペイウォールの表示、購入処理、その他の基本機能を含む完全なセットアップを確認できます。 ::: ## 要件 \{#requirements\} [Adapty Capacitor SDK](https://github.com/adaptyteam/AdaptySDK-Capacitor/) には以下のバージョン要件があります。 | Adapty SDK バージョン | Capacitor バージョン | iOS バージョン | |--------------------|-------------------|-------------| | 3.16.0+ | 8 | 15.0+ | | 3.15 | 7 | 14.0+ | Capacitor バージョン 6 以下はサポートされていません。 :::info SDK v3.17 以降、Adapty SDK はデフォルトで Google Play Billing Library v8.0.0 を使用します。 ::: --- no_index: true --- import Callout from '../../../components/Callout.astro'; SDKのインストールは、Adaptyセットアップのステップ5です。アプリ内で課金が機能するようにするには、アプリをストアに接続し、Adapty ダッシュボードでプロダクト、ペイウォール、プレースメントを作成する必要があります。[クイックスタートガイド](quickstart)では、必要なすべての手順を説明しています。 ## Adapty SDK のインストール \{#install-adapty-sdk\} [![Release](https://img.shields.io/github/v/release/adaptyteam/AdaptySDK-Capacitor.svg?style=flat&logo=capacitor)](https://github.com/adaptyteam/AdaptySDK-Capacitor/releases) Adapty SDK をインストールします。 ```sh npm install @adapty/capacitor npx cap sync ``` ## Adapty SDK の Adapty モジュールを有効化する \{#activate-adapty-module-of-adapty-sdk\} :::note Adapty SDK の有効化はアプリ内で一度だけ行う必要があります。 ::: **Public SDK Key** を取得するには: 1. Adapty ダッシュボードを開き、[**App settings → General**](https://app.adapty.io/settings/general) に移動します。 2. **Api keys** セクションから **Public SDK Key**(Secret Key ではない方)をコピーします。 3. コード内の `"YOUR_PUBLIC_SDK_KEY"` を置き換えます。 :::important - Adapty の初期化には必ず **Public SDK key** を使用してください。**Secret key** は[サーバーサイド API](getting-started-with-server-side-api) 専用です。 - **SDK keys** はアプリごとに固有です。複数のアプリがある場合は、正しいキーを選択してください。 ::: Adapty を有効化するために、以下のコードをアプリの任意のファイルにコピーしてください。 ```typescript showLineNumbers try { await adapty.activate({ apiKey: 'YOUR_PUBLIC_SDK_KEY', params: { // verbose logging is recommended for the development purposes and for the first production release logLevel: 'verbose', // in the development environment, use this variable to avoid multiple activation errors. Set it to your development environment variable __ignoreActivationOnFastRefresh: true, } }); console.log('Adapty activated successfully!'); } catch (error) { console.error('Failed to activate Adapty SDK:', error); } ``` :::important 他の Adapty SDK メソッドを呼び出す前に、`activate` の完了を待ってください。完全な呼び出し順序については [Capacitor SDK の呼び出し順序](capacitor-sdk-call-order) を参照してください。 ::: :::tip 開発環境での有効化エラーを避けるには、[ヒント](#development-environment-tips) を参照してください。 ::: 次に、アプリでペイウォールをセットアップします。 - [Adapty ペイウォールビルダー](adapty-paywall-builder) を使用する場合は、[ペイウォールビルダークイックスタート](capacitor-quickstart-paywalls) に従ってください。 - 独自のペイウォール UI を構築する場合は、[カスタムペイウォールのクイックスタート](capacitor-quickstart-manual) を参照してください。 ## Adapty SDK の AdaptyUI モジュールを有効化する \{#activate-adaptyui-module-of-adapty-sdk\} [ペイウォールビルダー](adapty-paywall-builder) を使用する予定がある場合は、AdaptyUI モジュールが必要です。コアモジュールを有効化すると自動的に行われるため、追加の操作は不要です。 ## オプション設定 \{#optional-setup\} ### ロギング \{#logging\} #### ロギングシステムのセットアップ \{#set-up-the-logging-system\} Adapty は何が起きているかを把握できるよう、エラーやその他の重要な情報をログに記録します。利用可能なレベルは以下の通りです。 | レベル | 説明 | | ---------- | ------------------------------------------------------------ | | `error` | エラーのみがログに記録されます | | `warn` | 重大なエラーは発生しないが注意すべき SDK のエラーやメッセージがログに記録されます | | `info` | エラー、警告、および各種情報メッセージがログに記録されます | | `verbose` | 関数呼び出し、API クエリなど、デバッグ時に役立つ追加情報がすべてログに記録されます | ログレベルは Adapty の設定前または設定中にアプリで指定できます。 ```typescript showLineNumbers // Set log level before activation adapty.setLogLevel({ logLevel: 'verbose' }); // Or set it during configuration await adapty.activate({ apiKey: 'YOUR_PUBLIC_SDK_KEY', params: { logLevel: 'verbose', } }); ``` ### データポリシー \{#data-policies\} Adapty は明示的に送信しない限りユーザーの個人データを保存しませんが、ストアや国のガイドラインに準拠するための追加のデータセキュリティポリシーを実装できます。 #### IP アドレスの収集と共有を無効にする \{#disable-ip-address-collection-and-sharing\} Adapty モジュールを有効化する際に `ipAddressCollectionDisabled` を `true` に設定すると、ユーザーの IP アドレスの収集と共有が無効になります。デフォルト値は `false` です。 IP ベースの機能がアプリに必要でない場合や、GDPR や CCPA などの地域データ保護規制に準拠する必要がある場合、あるいは不必要なデータ収集を減らしたい場合に使用してください。 ```typescript showLineNumbers await adapty.activate({ apiKey: 'YOUR_PUBLIC_SDK_KEY', params: { ipAddressCollectionDisabled: true, } }); ``` #### 広告 ID の収集と共有を無効にする \{#disable-advertising-id-collection-and-sharing\} Adapty モジュールを有効化する際に `ios.idfaCollectionDisabled`(iOS)または `android.adIdCollectionDisabled`(Android)を `true` に設定すると、広告識別子の収集が無効になります。デフォルト値は `false` です。 App Store/Play Store ポリシーへの準拠、アプリトラッキングの透明性プロンプトの非表示、または広告 ID に基づくアトリビューションや分析がアプリに不要な場合に使用してください。 ```typescript showLineNumbers await adapty.activate({ apiKey: 'YOUR_PUBLIC_SDK_KEY', params: { ios: { idfaCollectionDisabled: true, }, android: { adIdCollectionDisabled: true, }, } }); ``` #### AdaptyUI のメディアキャッシュ設定をセットアップする \{#set-up-media-cache-configuration-for-adaptyui\} デフォルトでは、AdaptyUI はパフォーマンス向上とネットワーク使用量削減のために画像や動画などのメディアをキャッシュします。カスタム設定を指定してキャッシュ設定を変更できます。 デフォルトのキャッシュ設定を上書きするには `mediaCache` を使用してください。 ```typescript showLineNumbers await adapty.activate({ apiKey: 'YOUR_PUBLIC_SDK_KEY', params: { mediaCache: { memoryStorageTotalCostLimit: 200 * 1024 * 1024, // Optional: memory cache size in bytes memoryStorageCountLimit: 2147483647, // Optional: max number of items in memory diskStorageSizeLimit: 200 * 1024 * 1024, // Optional: disk cache size in bytes }, } }); ``` パラメータ: | パラメータ | 必須 | 説明 | |-----------|----------|-------------| | memoryStorageTotalCostLimit | 任意 | メモリ内のキャッシュサイズ(バイト単位)。プラットフォーム固有のデフォルト値が使用されます。 | | memoryStorageCountLimit | 任意 | メモリストレージのアイテム数制限。プラットフォーム固有のデフォルト値が使用されます。 | | diskStorageSizeLimit | 任意 | ディスク上のファイルサイズ制限(バイト単位)。プラットフォーム固有のデフォルト値が使用されます。 | ### ローカルアクセスレベルを有効にする(Android) \{#enable-local-access-levels-android\} デフォルトでは、[ローカルアクセスレベル](local-access-levels) は iOS では有効で Android では無効です。Android でも有効にするには、`localAccessLevelAllowed` を `true` に設定してください。 ```typescript showLineNumbers await adapty.activate({ apiKey: 'YOUR_PUBLIC_SDK_KEY', params: { android: { localAccessLevelAllowed: true, }, } }); ``` ### バックアップ復元時のデータクリア \{#clear-data-on-backup-restore\} `clearDataOnBackup` を `true` に設定すると、アプリが iCloud バックアップから復元された際に SDK が検出し、キャッシュされたプロファイル情報、プロダクト詳細、ペイウォールを含むすべてのローカル SDK データを削除します。SDK はクリーンな状態で初期化されます。デフォルト値は `false` です。 :::note 削除されるのはローカルの SDK キャッシュのみです。Apple とのトランザクション履歴および Adapty サーバー上のユーザーデータは変更されません。 ::: ```swift showLineNumbers await adapty.activate({ apiKey: 'YOUR_PUBLIC_SDK_KEY', params: { ios: { clearDataOnBackup: true, }, } }); ``` ## 開発環境のヒント \{#development-environment-tips\} #### Capacitor のライブリロードでの SDK 有効化エラーのトラブルシューティング \{#troubleshoot-sdk-activation-errors-on-capacitors-live-reload\} Capacitor で Adapty SDK を開発中に、次のエラーが発生することがあります: `Adapty can only be activated once. Ensure that the SDK activation call is not made more than once.` これは Capacitor のライブリロード機能が開発中に複数回の有効化呼び出しをトリガーするために発生します。これを防ぐには、`__ignoreActivationOnFastRefresh` オプションを Capacitor の開発モードフラグに設定してください。使用するバンドルによって異なります。 ```typescript showLineNumbers try { await adapty.activate({ apiKey: 'YOUR_PUBLIC_SDK_KEY', params: { // Set your development environment variable __ignoreActivationOnFastRefresh: true, } }); } catch (error) { console.error('Failed to activate Adapty SDK:', error); // Handle the error appropriately for your app } ``` ## トラブルシューティング \{#troubleshooting\} #### iOS の最低バージョンエラー \{#minimum-ios-version-error\} iOS の最低バージョンエラーが発生した場合は、Podfile を更新してください。 ```diff -platform :ios, min_ios_version_supported +platform :ios, '14.0' # For core features only # OR +platform :ios, '15.0' # If using paywalls created in the paywall builder ``` #### Android のバックアップルール(Auto Backup の設定) \{#android-backup-rules-auto-backup-configuration\} 一部のSDK(Adaptyを含む)には、独自のAndroid Auto Backup設定が含まれています。バックアップルールを定義する複数のSDKを使用している場合、Androidのマニフェストマージャーが `android:fullBackupContent`、`android:dataExtractionRules`、または `android:allowBackup` に関するエラーで失敗することがあります。 よくあるエラーの症状: `Manifest merger failed: Attribute application@dataExtractionRules value=(@xml/your_data_extraction_rules) is also present at [com.other.sdk:library:1.0.0] value=(@xml/other_sdk_data_extraction_rules)` :::note これらの変更は、Androidプラットフォームのディレクトリ(通常はプロジェクトの `android/` フォルダー内)で行う必要があります。 ::: この問題を解決するには、以下が必要です: - バックアップ関連の属性に対して、アプリの値を使用するようマニフェストマージャーに指示する。 - AdaptyのルールとほかのSDKのルールをマージしたバックアップルールファイルを作成する。 #### 1. マニフェストに `tools` 名前空間を追加する \{#1-add-the-tools-namespace-to-your-manifest\} `AndroidManifest.xml` ファイルのルートの `` タグに tools が含まれていることを確認してください: ```xml ... ``` #### 2. `` でバックアップ属性を上書きする \{#2-override-backup-attributes-in-application\} 同じ `AndroidManifest.xml` ファイルで、`` タグを更新して、アプリが最終的な値を提供し、マニフェストマージャーにライブラリの値を置き換えるよう指示します: ```xml ... ``` いずれかのSDKが `android:allowBackup` も設定している場合は、`tools:replace` に含めてください: ```xml tools:replace="android:allowBackup,android:fullBackupContent,android:dataExtractionRules" ``` #### 3. マージしたバックアップルールファイルを作成する \{#3-create-merged-backup-rules-files\} AndroidプロジェクトのAdaptyのルールとほかのSDKのルールを組み合わせた `res/xml/` ディレクトリにXMLファイルを作成します。AndroidはOSのバージョンによって異なるバックアップルール形式を使用するため、両方のファイルを作成することで、アプリがサポートするすべてのAndroidバージョンとの互換性が確保されます。 :::note 以下の例では、サンプルのサードパーティSDKとしてAppsFlyerを使用しています。アプリで使用しているほかのSDKのルールに置き換えるか、追加してください。 ::: **Android 12以降**(新しいデータ抽出ルール形式を使用): ```xml title="sample_data_extraction_rules.xml" ``` **Android 11以前**(従来のフルバックアップコンテンツ形式を使用): ```xml title="sample_backup_rules.xml" :::tip ネイティブ Android ファイルを変更した後は、`npx cap sync android` を実行してプラットフォームを再生成した際に Capacitor が更新されたリソースを取得できるようにしてください。 ::: #### Android で別のアプリから戻った後に購入が失敗する \{#purchases-fail-after-returning-from-another-app-in-android\} 購入フローを開始する Activity が非デフォルトの `launchMode` を使用している場合、ユーザーが Google Play、銀行アプリ、またはブラウザから戻ったときに Android がその Activity を誤って再作成または再利用することがあります。これにより、購入結果が失われたりキャンセルとして処理されたりすることがあります。 購入が正しく機能するようにするには、購入フローを開始する Activity に `standard` または `singleTop` の起動モードのみを使用し、他のモードは避けてください。 `AndroidManifest.xml` で、購入フローを開始する Activity が `standard` または `singleTop` に設定されていることを確認してください。 ```xml ``` #### Podfile の SWIFT_VERSION 上書きによる Swift 6 ビルドエラー \{#swift-6-build-errors-caused-by-podfile-swift_version-override\} iOS 向けに Capacitor アプリをビルドする際に、Adapty pod ターゲットで Swift 6 のコンパイルエラーが発生することがあります。典型的な症状としては、`AdaptyUIBuilderLogic` での `@Sendable` の不一致、Adapty 型での `Sendable` 適合の欠如、またはアクター分離エラーなどがあります。 Adapty pods は `s.swift_version = '6.0'` を宣言しており、ビルドに Swift 6 が必要です。アプリ独自のコードは Swift 5 のままでも構いません。Swift 6 でのビルドが必要なのは Adapty pod ターゲット(`Adapty`、`AdaptyUI`、`AdaptyUIBuilder`、`AdaptyLogger`、`AdaptyPlugin`)のみです。 最もよくある原因は、`ios/App/Podfile` の `post_install` フックがすべての pod ターゲットの `SWIFT_VERSION` を上書きしていることです。 ```ruby showLineNumbers title="ios/App/Podfile" post_install do |installer| installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['SWIFT_VERSION'] = '5.9' end end end ``` **修正方法**: Adapty pod ターゲットを上書きから除外してください。 ```ruby showLineNumbers title="ios/App/Podfile" post_install do |installer| installer.pods_project.targets.each do |target| next if %w[Adapty AdaptyUI AdaptyUIBuilder AdaptyLogger AdaptyPlugin].include?(target.name) target.build_configurations.each do |config| config.build_settings['SWIFT_VERSION'] = '5.9' end end end ``` その後、`npx cap sync ios` を実行してリビルドしてください。 確認するには、`ios/App/Pods/Pods.xcodeproj` を開き、`Adapty` pod ターゲットを選択して **Build Settings** → **Swift Language Version** を確認します。**Swift 6** になっている必要があります。 --- # File: capacitor-quickstart-paywalls --- --- title: "Capacitor SDKでペイウォールを使って購入を有効にする" description: "Adapty SDKを使用してCapacitorアプリにペイウォールを表示する方法を学びましょう。" --- アプリ内課金を有効にするには、次の3つの主要な概念を理解する必要があります。 - **プロダクト** – ユーザーが購入できるもの(サブスクリプション、消耗型アイテム、永続アクセス) - **ペイウォール** – どのプロダクトを提供するかを定義する設定です。Adaptyではペイウォールを通じてのみプロダクトを取得できますが、この設計によりアプリのコードを変更せずにオファー内容、価格、プロダクトの組み合わせを変更できます。 - **プレースメント** – アプリ内でペイウォールをどこでいつ表示するか(`main`、`onboarding`、`settings` など)。ダッシュボードでプレースメントにペイウォールを設定し、コード内ではプレースメントIDで取得します。これによりA/Bテストの実行や、ユーザーごとに異なるペイウォールの表示が簡単になります。 Adaptyではアプリに購入機能を実装するための方法を3つ提供しています。アプリの要件に応じて選択してください。 | 実装方法 | 複雑さ | 使うタイミング | |-------------------------------|------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **Adapty ペイウォールビルダー** | ✅ 簡単 | [ノーコードビルダーで購入対応ペイウォールを作成します](quickstart-paywalls)。Adaptyが自動的にレンダリングし、複雑な購入フロー、レシート検証、サブスクリプション管理をすべて裏側で処理します。 | | `makePurchase` | 🟡 中程度 | アプリのコードでペイウォールUIを実装しますが、プロダクトオファーの柔軟性を保つためにAdaptyからペイウォールオブジェクトを取得します。[ガイド](capacitor-quickstart-manual)をご覧ください。 | | オブザーバーモード | 🔴 難しい | 購入フローを完全に自分で実装します。[ガイド](implement-observer-mode-capacitor)をご覧ください。 | :::important **以下の手順は、Adaptyペイウォールビルダーで作成したペイウォールの実装方法を示しています。** ペイウォールビルダーを使用しない場合は、[手動作成ペイウォールでの購入処理ガイド](capacitor-making-purchases)をご覧ください。 ::: Adaptyペイウォールビルダーで作成したペイウォールを表示するには、アプリのコードで次の3つの手順のみ必要です。 1. **ペイウォールを取得する**: AdaptyからペイウォールのObjectを取得します。 2. **ペイウォールを表示する(購入はAdaptyが処理)**: 取得したペイウォールコンテナをアプリに表示します。 3. **ボタンアクションを処理する**: ペイウォール上のユーザー操作とアプリの応答を関連付けます。たとえば、ユーザーがボタンをクリックしたときにリンクを開いたりペイウォールを閉じたりします。 ## 始める前に \{#before-you-start\} 始める前に、次の手順を完了してください。 1. Adaptyダッシュボードでアプリを[App Store](initial_ios)または[Google Play](initial-android)(あるいはその両方)に接続します。 2. Adaptyで[プロダクトを作成します](create-product)。 3. [ペイウォールを作成してプロダクトを追加します](create-paywall)。 4. [プレースメントを作成してペイウォールを追加します](create-placement)。 5. アプリのコードに[Adapty SDKをインストールして有効化します](sdk-installation-capacitor)。 :::tip これらの手順を最速で完了するには、[クイックスタートガイド](quickstart)に従うか、[Developer CLI](developer-cli-quickstart)を使ってペイウォールとプレースメントを作成してください。 ::: ## 1. ペイウォールを取得する \{#1-get-the-paywall\} ペイウォールはダッシュボードで設定したプレースメントに関連付けられています。プレースメントを使うことで、異なるオーディエンスに異なるペイウォールを表示したり、[A/Bテスト](ab-tests)を実行したりできます。 Adaptyペイウォールビルダーで作成したペイウォールを取得するには、次の手順が必要です。 1. `getPaywall` メソッドを使って[プレースメント](placements)IDで `paywall` オブジェクトを取得し、`hasViewConfiguration` プロパティでビルダーで作成したペイウォールかどうかを確認します。 2. `createPaywallView` メソッドを使ってペイウォールビューを作成します。このビューにはペイウォールを表示するためのUI要素とスタイリングが含まれています。 :::important ビュー設定を取得するには、ペイウォールビルダーで **Show on device** トグルをオンにする必要があります。そうしないと、空のビュー設定が返され、ペイウォールが表示されません。 ::: ```typescript showLineNumbers title="Capacitor" try { const paywall = await adapty.getPaywall({ placementId: 'YOUR_PLACEMENT_ID', }); // the requested paywall } catch (error) { // handle the error } if (paywall.hasViewConfiguration) { try { const view = await createPaywallView(paywall); } catch (error) { // handle the error } } else { // use your custom logic } ``` ## 2. ペイウォールを表示する \{#2-display-the-paywall\} ペイウォールの設定を取得したら、数行のコードを追加するだけでペイウォールを表示できます。 ペイウォールを表示するには、`createPaywallView` メソッドで作成した `view` に対して `view.present()` メソッドを呼び出します。各 `view` は一度しか使用できません。再度ペイウォールを表示する必要がある場合は、`createPaywallView` をもう一度呼び出して新しい `view` インスタンスを作成してください。 ```typescript showLineNumbers title="Capacitor" try { await view.present(); } catch (error) { // handle the error } ``` :::tip ペイウォールの表示方法についての詳細は、[ガイド](capacitor-present-paywalls)をご覧ください。 ::: ## 3. ボタンアクションを処理する \{#3-handle-button-actions\} ユーザーがペイウォール内のボタンをクリックすると、Capacitor SDKは購入、復元、ペイウォールのクローズを自動的に処理します。 ただし、カスタムまたは事前定義のIDを持つボタンはコード内でアクションを処理する必要があります。また、デフォルトの動作をオーバーライドしたい場合もあります。 たとえば、ユーザーがWebリンクを開いた後もペイウォールを開いたままにしたい場合があります。実装でどのように処理できるか見てみましょう。 :::tip ボタンの[アクション](capacitor-handle-paywall-actions)と[イベント](capacitor-handling-events)の処理方法については、各ガイドをご覧ください。 ::: ```typescript showLineNumbers title="Capacitor" const unsubscribe = view.setEventHandlers({ onUrlPress(url) { window.open(url, '_blank'); return false; }, }); ``` ## 次のステップ \{#next-steps\} --- no_index: true --- import Callout from '../../../components/Callout.astro'; ご質問やお困りのことがあれば、[サポートフォーラム](https://adapty.featurebase.app/)をご覧ください。よくある質問への回答を見つけたり、ご自身の質問を投稿することができます。チームとコミュニティがサポートいたします! ペイウォールをアプリに表示する準備ができました。[App Storeのサンドボックス](test-purchases-in-sandbox)または[Google Play Store](testing-on-android)でテスト購入を行い、ペイウォールからのテスト購入が正常に完了することを確認してください。 次に、適切なユーザーにペイウォールを表示したり有料機能へのアクセスを付与したりするため、[ユーザーのアクセスレベルを確認する](capacitor-check-subscription-status)必要があります。 ## 完全なサンプル \{#full-example\} 以下は、これらすべての手順をアプリに統合した例です。 ```typescript showLineNumbers title="Capacitor" export default function PaywallScreen() { const showPaywall = async () => { try { const paywall = await adapty.getPaywall({ placementId: 'YOUR_PLACEMENT_ID', }); if (!paywall.hasViewConfiguration) { // use your custom logic return; } const view = await createPaywallView(paywall); view.setEventHandlers({ onUrlPress(url) { window.open(url, '_blank'); return false; }, }); await view.present(); } catch (error) { // handle any error that may occur during the process console.warn('Error showing paywall:', error); } }; return (
); } ``` --- # File: capacitor-check-subscription-status --- --- title: "Capacitor SDKでサブスクリプションステータスを確認する" description: "AdaptyでCapacitorアプリのサブスクリプションステータスを確認する方法を学びましょう。" --- ユーザーが有料コンテンツにアクセスできるか、またはペイウォールを表示するかを決めるには、プロファイルの[アクセスレベル](access-level)を確認する必要があります。 この記事では、ユーザーにペイウォールを表示するか、有料機能へのアクセスを許可するかを判断するために、プロファイルの状態を取得する方法を説明します。 ## サブスクリプションステータスを取得する \{#get-subscription-status\} ペイウォールまたは有料コンテンツを表示するかどうかを判断する際、ユーザーのプロファイルにある[アクセスレベル](access-level)を確認します。方法は2つあります: - アプリ起動時など、すぐに最新のプロファイルデータが必要な場合や強制的に更新したい場合は`getProfile`を呼び出します。 - サブスクリプションのステータスが変わるたびに自動的に更新されるローカルコピーを保持するには、**自動プロファイル更新**を設定します。 ### プロファイルを取得する \{#get-profile\} サブスクリプションステータスを取得する最も簡単な方法は、`getProfile`メソッドを使ってプロファイルにアクセスすることです: ```typescript showLineNumbers try { const profile = await adapty.getProfile(); } catch (error) { // handle the error } ``` ### サブスクリプション更新をリッスンする \{#listen-to-subscription-updates\} アプリでプロファイルの更新を自動的に受け取るには: 1. `adapty.addListener('onLatestProfileLoad')`を使ってプロファイルの変化をリッスンします。ユーザーのサブスクリプションステータスが変わるたびに、Adaptyが自動的にこのメソッドを呼び出します。 2. このメソッドが呼び出されたときに更新されたプロファイルデータを保存しておくと、追加のネットワークリクエストなしにアプリ全体で利用できます。 ```typescript showLineNumbers class SubscriptionManager { private currentProfile: any = null; constructor() { // Listen for profile updates adapty.addListener('onLatestProfileLoad', (data) => { this.currentProfile = data.profile; // Update UI, unlock content, etc. }); } // Use stored profile instead of calling getProfile() hasAccess(): boolean { return this.currentProfile?.accessLevels?.['YOUR_ACCESS_LEVEL']?.isActive ?? false; } } ``` :::note Adaptyはアプリ起動時に自動的に`onLatestProfileLoad`イベントリスナーを呼び出し、デバイスがオフラインの場合でもキャッシュされたサブスクリプションデータを提供します。 ::: ## プロファイルとペイウォールのロジックを連携させる \{#connect-profile-with-paywall-logic\} ペイウォールの表示や有料機能へのアクセス許可をすぐに判断する必要がある場合は、ユーザーのプロファイルを直接確認できます。このアプローチは、アプリ起動時、プレミアムセクションへの入室時、特定コンテンツの表示前などのシナリオに役立ちます。 ```typescript showLineNumbers const checkAccessLevel = async () => { try { const profile = await adapty.getProfile(); return profile?.accessLevels?.['YOUR_ACCESS_LEVEL']?.isActive === true; } catch (error) { console.warn('Error checking access level:', error); return false; // Show paywall if access check fails } }; const getAccessLevel = () => { return profile?.accessLevels?.['YOUR_ACCESS_LEVEL']; }; const initializePaywall = async () => { try { await loadPaywall(); const hasAccess = await checkAccessLevel(); if (!hasAccess) { // Show paywall if no access } } catch (error) { console.warn('Error initializing paywall:', error); } }; ``` ## 次のステップ \{#next-steps\} サブスクリプションステータスの確認方法がわかったら、次は[ユーザープロファイルの操作](capacitor-quickstart-identify)について学び、ユーザーが購入したコンテンツに確実にアクセスできるようにしましょう。 --- # File: capacitor-quickstart-identify --- --- title: "Capacitor SDKでユーザーを識別する" description: "Capacitorでのアプリ内サブスクリプション管理のためのAdaptyセットアップ クイックスタートガイド。" --- ユーザーの購入管理方法は、アプリの認証モデルによって異なります: - アプリでバックエンド認証を使用せず、ユーザーデータを保存しない場合は、[匿名ユーザーに関するセクション](#anonymous-users)をご覧ください。 - アプリにバックエンド認証がある(または予定している)場合は、[識別済みユーザーに関するセクション](#identified-users)をご覧ください。 :::tip **主な概念**: - **プロファイル**は、SDKが機能するために必要なエンティティです。Adaptyが自動的に作成します。匿名(カスタマーユーザーIDなし)または識別済み(カスタマーユーザーIDあり)のいずれかになります。 - **カスタマーユーザーID**は、**あなたが作成する**オプションの識別子で、ユーザーをAdaptyプロファイルに紐付けるために使用します。 ::: 匿名ユーザーと識別済みユーザーの違いは次のとおりです: | | 匿名ユーザー | 識別済みユーザー | |-------------------------|------------------------------------------------------|-------------------------------------------------------------------------| | **購入管理** | ストアレベルの購入復元 | カスタマーユーザーIDを通じてデバイスをまたいで購入履歴を維持 | | **プロファイル管理** | 再インストールごとに新しいプロファイルが作成される | セッションやデバイスをまたいで同じプロファイルを使用 | | **データの永続性** | 匿名ユーザーのデータはデバイス/インストールに紐付けられる | 識別済みユーザーのデータはデバイスやセッションをまたいで保持される | ## 匿名ユーザー \{#anonymous-users\} バックエンド認証がない場合、**アプリのコードで認証を処理する必要はありません**: 1. アプリの初回起動時にSDKが有効化されると、Adaptyが**ユーザーの新しいプロファイルを作成**します。 2. ユーザーがアプリ内で何かを購入すると、その購入は**そのユーザーのAdaptyプロファイルとストアアカウントに関連付け**られます。 3. ユーザーがアプリを**再インストール**したり、**新しいデバイス**にインストールしたりすると、Adaptyは有効化時に**新しい空のプロファイルを作成**します。 4. ユーザーがアプリで以前に購入をしていた場合、デフォルトでは、SDKの有効化時にApp Storeから購入が自動的に同期されます。 :::note バックアップからの復元は、再インストールとは動作が異なります。デフォルトでは、ユーザーがバックアップから復元した場合、SDKはキャッシュされたデータを保持し、新しいプロファイルを作成しません。この動作は`clearDataOnBackup`設定で変更できます。[詳細はこちら](sdk-installation-capacitor#clear-data-on-backup-restore)。 ::: ## 識別済みユーザー \{#identified-users\} - プロファイルにまだカスタマーユーザーIDがない場合(つまり、**ユーザーがサインインしていない**場合)、カスタマーユーザーIDを送信すると、そのプロファイルに関連付けられます。 - **再インストール、サインイン、または新しいデバイスからのインストール**で、以前にそのカスタマーユーザーIDを送信したことがある場合、新しいプロファイルは作成されません。代わりに、そのカスタマーユーザーIDに関連付けられた既存のプロファイルに切り替わります。 アプリでユーザーを識別する方法は2つあります: - [**ログイン/サインアップ時:**](#during-loginsignup) アプリ起動後にユーザーがサインインする場合、認証時に`identify()`をカスタマーユーザーIDとともに呼び出します。 - [**SDK有効化時:**](#during-the-sdk-activation) アプリ起動時にすでにカスタマーユーザーIDが保存されている場合、`activate()`を呼び出す際に送信します。 :::important デフォルトでは、Adaptyが現在別のカスタマーユーザーIDに関連付けられているカスタマーユーザーIDからの購入を受け取った場合、アクセスレベルは共有され、両方のプロファイルが有料アクセスを持ちます。この設定を変更して、有料アクセスを1つのプロファイルから別のプロファイルに移動したり、共有を完全に無効にしたりすることができます。詳細は[こちらの記事](general#6-sharing-paid-access-between-user-accounts)をご覧ください。 ::: ### ログイン/サインアップ時 \{#during-loginsignup\} アプリ起動後にユーザーを識別する場合(例:アプリへのログインやサインアップ後)は、`identify`メソッドを使用してカスタマーユーザーIDを設定します。 - **このカスタマーユーザーIDを以前に使用したことがない**場合、Adaptyは自動的にそれを現在のプロファイルに紐付けます。 - **このカスタマーユーザーIDを以前にユーザーの識別に使用したことがある**場合、AdaptyはそのカスタマーユーザーIDに関連付けられたプロファイルに切り替えます。 :::tip カスタマーユーザーIDを作成する際は、ユーザーデータと一緒に保存しておくと、新しいデバイスからログインした場合やアプリを再インストールした際に同じIDを送信できます。 ::: 他のSDKメソッドを呼び出す前に、必ず`identify`を`await`してください。並行して呼び出すと`#3006 profileWasChanged`が発生するか、匿名プロファイルに対して操作が行われます。[Capacitor SDKの呼び出し順序](capacitor-sdk-call-order)を参照してください。 ```typescript showLineNumbers try { await adapty.identify({ customerUserId: "YOUR_USER_ID" }); // successfully identified } catch (error) { // handle the error } ``` ### SDK有効化時 \{#during-the-sdk-activation\} SDKを有効化するときにすでにカスタマーユーザーIDがわかっている場合は、`identify`を別途呼び出す代わりに、`activate`メソッドで送信できます。 カスタマーユーザーIDがわかっていても、有効化後にのみ設定する場合、有効化時にAdaptyは新しい空のプロファイルを作成し、`identify`を呼び出した後にのみ既存のプロファイルに切り替わります。 既存のカスタマーユーザーID(以前に使用したもの)と新しいもののどちらでも渡すことができます。新しいものを渡した場合、有効化時に作成された新しいプロファイルが自動的にそのカスタマーユーザーIDに紐付けられます。 :::tip 作成された空のプロファイルをダッシュボードのアナリティクスから除外するには、**App settings**に移動して[**Installs definition for analytics**](general#4-installs-definition-for-analytics)を設定してください。 ::: ```typescript showLineNumbers await adapty.activate({ apiKey: "YOUR_PUBLIC_SDK_KEY", params: { customerUserId: "YOUR_USER_ID" } }); ``` ### ユーザーをログアウトする \{#log-users-out\} ユーザーをログアウトするボタンがある場合は、`logout`メソッドを使用します。これにより、ユーザーに新しい匿名プロファイルIDが作成されます。 ```typescript showLineNumbers try { await adapty.logout(); // successful logout } catch (error) { // handle the error } ``` :::info ユーザーをアプリに再度ログインさせるには、`identify`メソッドを使用してください。 ::: ### ログインせずに購入を許可する \{#allow-purchases-without-login\} ユーザーがアプリにログインする前後の両方で購入できる場合、追加の設定は不要です: 仕組みは次のとおりです: 1. ログアウト状態のユーザーが購入を行うと、Adaptyはその購入を匿名プロファイルIDに紐付けます。 2. ユーザーがアカウントにログインすると、Adaptyは識別済みプロファイルに切り替えます。 - 既存のカスタマーユーザーID(すでにプロファイルに紐付けられているカスタマーユーザーID)の場合、Adaptyはトランザクションを自動的に同期します。 - 新しいカスタマーユーザーID(例:登録前に購入が行われた場合)の場合、Adaptyは現在のプロファイルにカスタマーユーザーIDを割り当て、すべての購入履歴が維持されます。 --- # File: adapty-sdk-integration-skill-capacitor --- --- title: "SDKインテグレーションスキルを使ってAdaptyをCapacitorアプリに導入する" description: "adapty-sdk-integrationスキルを使って、AIコーディングツールでCapacitorアプリにAdapty SDKをエンドツーエンドで統合する方法を説明します。" --- :::important このスキルはベータ版です。処理が止まったり予期しない動作が発生した場合は、代わりに[ステップバイステップの統合ガイド](adapty-cursor-capacitor)を参照してください。AIツールが各ステップを正しいドキュメントに沿って進められるよう案内しています。 ::: --- no_index: true --- [adapty-sdk-integration スキル](https://github.com/adaptyteam/adapty-sdk-integration-skill)は、Adapty のインテグレーションをエンドツーエンドで自動化します。ダッシュボードのセットアップ、SDK のインストール、ペイウォール、各ステージの検証まで対応しています。プラットフォームを自動検出し、各ステージで関連する Adapty ドキュメントを取得します。 **対応ツール**: Claude Code、GitHub Copilot CLI、OpenAI Codex、Gemini CLI。 インストールするには、お使いのツール向けのフォームを選択してください。完全なリストは[スキルの README](https://github.com/adaptyteam/adapty-sdk-integration-skill) をご覧ください。 **Claude Code** ``` claude plugin marketplace add adaptyteam/adapty-sdk-integration-skill claude plugin install adapty-sdk-integration@adapty ``` **GitHub Copilot CLI** ``` gh skill install adaptyteam/adapty-sdk-integration-skill ``` **Gemini CLI** ``` gemini skills install https://github.com/adaptyteam/adapty-sdk-integration-skill ``` **OpenAI Codex またはその他のツール**: リポジトリをクローンし、`plugins/adapty-sdk-integration/skills/adapty-sdk-integration/` をツールのスキルディレクトリにコピーしてください。 インストール後、プロジェクト内でスキルを実行します: ``` /adapty-sdk-integration ``` スキルがいくつかのセットアップ質問を行い、その後ダッシュボードのセットアップ、SDK のインストール、ペイウォール、検証の手順を案内します。 --- # File: adapty-cursor-capacitor --- --- title: "AIアシスタントを使ってCapacitorアプリにAdaptyを統合する" description: "Cursor、Context7、ChatGPT、Claude、その他のAIツールを使ってCapacitorアプリにAdaptyを統合するステップバイステップガイド。" --- このガイドでは、AIコーディングツールを使ってCapacitorアプリにAdaptyを段階的に統合する方法を説明します。適切なAdaptyドキュメントを適切な順序でAIに提供することで、スムーズに進められます。 For a fully automated integration, use the [adapty-sdk-integration skill](https://github.com/adaptyteam/adapty-sdk-integration-skill): it runs the whole integration from your AI coding tool in one command. ## はじめる前に:ダッシュボードの設定 \{#before-you-start-dashboard-setup\} AdaptyはSDKコードを書く前に、いくつかのダッシュボード設定が必要です。インタラクティブなLLMスキルを使うか、ダッシュボードから手動で設定できます。 ### スキルを使う方法(推奨) \{#skill-approach-recommended\} Adapty CLIスキルを使うと、LLMがアプリ、プロダクト、アクセスレベル、ペイウォール、プレースメントを直接設定できます。各ステップでダッシュボードを開く必要がありません。[ストアの接続](integrate-payments)だけダッシュボードで行う必要があります。 ``` npx skills add adaptyteam/adapty-cli --skill adapty-cli ``` スキルを追加したら、エージェントで `/adapty-cli` を実行してください。ストアの接続が必要なタイミングも含め、各ステップをガイドしてくれます。 ### ダッシュボードを使う方法 \{#dashboard-approach\} すべて手動で設定したい場合は、コードを書く前に以下の準備が必要です。LLMはダッシュボードの値を調べることはできないため、ご自身で提供する必要があります。 1. **アプリストアを接続する**: Adapty ダッシュボードで **App settings → General** に移動します。CapacitorアプリがiOSとAndroidの両方を対象とする場合は、App StoreとGoogle Playの両方を接続してください。これは購入処理に必須です。 [アプリストアを接続する](integrate-payments) 2. **パブリックSDKキーをコピーする**: Adapty ダッシュボードで **App settings → General** に移動し、**API keys** セクションを確認します。コード上では、これが `adapty.activate()` に渡す文字列です。 3. **プロダクトを少なくとも1つ作成する**: Adapty ダッシュボードの **Products** ページでプロダクトを作成します。コードからプロダクトを直接参照することはなく、Adaptyはペイウォールを通じてプロダクトを提供します。 [プロダクトを追加する](quickstart-products) 4. **ペイウォールとプレースメントを作成する**: Adapty ダッシュボードの **Paywalls** ページでペイウォールを作成し、**Placements** ページでプレースメントに割り当てます。コード上では、プレースメントIDが `adapty.getPaywall()` に渡す文字列です。 [ペイウォールを作成する](quickstart-paywalls) 5. **アクセスレベルを設定する**: Adapty ダッシュボードの **Products** ページでプロダクトごとに設定します。コード上では、`profile.accessLevels['premium']?.isActive` でチェックする文字列です。デフォルトの `premium` アクセスレベルはほとんどのアプリで機能します。プロダクトによってユーザーがアクセスできる機能が異なる場合(例:`basic` プランと `pro` プラン)は、コーディングを始める前に[追加のアクセスレベルを作成](assigning-access-level-to-a-product)してください。 :::tip この5つが揃えば、コードを書く準備ができています。LLMに「パブリックSDKキーはX、プレースメントIDはY」と伝えると、正確な初期化とペイウォール取得のコードを生成してもらえます。 ::: ### 準備ができたら設定すること \{#set-up-when-ready\} コーディングを始める前に必須ではありませんが、統合が成熟するにつれて必要になります: - **A/B テスト**: **Placements** ページで設定します。コードの変更は不要です。 [A/B テスト](ab-tests) - **追加のペイウォールとプレースメント**: 異なるプレースメントIDで `getPaywall` の呼び出しを追加します。 - **アナリティクス連携**: **Integrations** ページで設定します。セットアップは連携先によって異なります。[アナリティクス連携](analytics-integration)と[アトリビューション連携](attribution-integration)を参照してください。 ## AdaptyドキュメントをLLMに提供する \{#feed-adapty-docs-to-your-llm\} ### Context7を使う(推奨) \{#use-context7-recommended\} [Context7](https://context7.com)は、LLMが最新のAdaptyドキュメントに直接アクセスできるMCPサーバーです。質問内容に基づいて適切なドキュメントを自動的に取得するため、URLを手動で貼り付ける必要がありません。 Context7は**Cursor**、**Claude Code**、**Windsurf**、その他のMCP対応ツールで動作します。セットアップするには以下を実行してください: ``` npx ctx7 setup ``` これによりエディタが検出され、Context7サーバーが設定されます。手動セットアップの場合は[Context7 GitHubリポジトリ](https://github.com/upstash/context7)を参照してください。 設定後は、プロンプトでAdaptyライブラリを参照してください: ``` Use the adaptyteam/adapty-docs library to look up how to install the Capacitor SDK ``` :::warning Context7を使えばドキュメントのリンクを手動で貼り付ける必要はなくなりますが、実装の順序は重要です。すべてが正しく動作するよう、以下の[実装ウォークスルー](#implementation-walkthrough)をステップごとに確認してください。 ::: ### プレーンテキストのドキュメントを使う \{#use-plain-text-docs\} Adaptyのドキュメントはプレーンテキストのマークダウンとして取得できます。URLの末尾に `.md` を追加するか、記事タイトルの下にある **Copy for LLM** をクリックしてください。例:[adapty-cursor-capacitor.md](https://adapty.io/docs/ja/adapty-cursor-capacitor.md) 以下の[実装ウォークスルー](#implementation-walkthrough)の各ステージには、貼り付け用の `.md` リンクが含まれた「LLMに送るもの」ブロックがあります。 一度に複数のドキュメントが必要な場合は、以下の[インデックスファイルとプラットフォーム別サブセット](#plain-text-doc-index-files)を参照してください。 ## 実装ウォークスルー \{#implementation-walkthrough\} このガイドの残りでは、実装順序に沿ってAdapty統合を進めていきます。各ステージには、LLMに送るドキュメント、完了時に確認できること、よくある問題が含まれています。 ### 統合を計画する \{#plan-your-integration\} コードに取り掛かる前に、LLMにプロジェクトを分析して実装計画を立てるよう依頼してください。AIツールが計画モードをサポートしている場合(CursorやClaude Codeのプランモードなど)、LLMがコードを書く前にプロジェクト構造とAdaptyドキュメントの両方を確認できるよう、そのモードを使用してください。 購入処理のアプローチをLLMに伝えてください。これによって参照すべきガイドが変わります: - [**Adapty ペイウォールビルダー**](adapty-paywall-builder): Adaptyのノーコードビルダーでペイウォールを作成し、SDKが自動的にレンダリングします。 - [**手動作成のペイウォール**](capacitor-making-purchases): コードで独自のペイウォールUIを構築しますが、プロダクトの取得と購入処理にはAdaptyを使います。 - [**オブザーバーモード**](observer-vs-full-mode): 既存の購入インフラを維持し、アナリティクスと連携にのみAdaptyを使います。 どれを選べばよいかわからない場合は、[クイックスタートの比較表](capacitor-quickstart-paywalls)を参照してください。 ### SDKをインストールして設定する \{#install-and-configure-the-sdk\} npmでAdapty SDKの依存関係を追加し、パブリックSDKキーで有効化します。これが基盤となるため、これなしでは他の機能は動作しません。 **ガイド:** [Adapty SDKのインストールと設定](sdk-installation-capacitor) LLMに送るもの: ``` Read these Adapty docs before writing code: - https://adapty.io/docs/ja/sdk-installation-capacitor.md ``` :::tip[チェックポイント] - **期待される結果:** iOSとAndroidの両方でアプリがビルド・起動し、コンソールにAdaptyのアクティベーションログが表示される。 - **注意点:** "Public API key is missing" → **App settings** の実際のキーでプレースホルダーを置き換えているか確認してください。 ::: ### ペイウォールを表示して購入を処理する \{#show-paywalls-and-handle-purchases\} プレースメントIDでペイウォールを取得し、表示して、購入イベントを処理します。必要なガイドは購入処理の方法によって異なります。 進めながら各購入をサンドボックスでテストしてください — 最後まで待つ必要はありません。セットアップ手順については[サンドボックスでの購入テスト](test-purchases-in-sandbox)を参照してください。 **ガイド:** - [ペイウォールを使って購入を有効化する(クイックスタート)](capacitor-quickstart-paywalls) - [ペイウォールビルダーのペイウォールと設定を取得する](capacitor-get-pb-paywalls) - [ペイウォールを表示する](capacitor-present-paywalls) - [ペイウォールイベントを処理する](capacitor-handling-events) - [ボタンアクションに応答する](capacitor-handle-paywall-actions) LLMに送るもの: ``` Read these Adapty docs before writing code: - https://adapty.io/docs/ja/capacitor-quickstart-paywalls.md - https://adapty.io/docs/ja/capacitor-get-pb-paywalls.md - https://adapty.io/docs/ja/capacitor-present-paywalls.md - https://adapty.io/docs/ja/capacitor-handling-events.md - https://adapty.io/docs/ja/capacitor-handle-paywall-actions.md ``` :::tip[チェックポイント] - **期待される結果:** 設定したプロダクトとともにペイウォールが表示される。プロダクトをタップするとサンドボックス購入ダイアログが表示される。 - **注意点:** ペイウォールが空か `getPaywall` エラー → プレースメントIDがダッシュボードと完全に一致しているか、プレースメントにオーディエンスが割り当てられているか確認してください。 ::: **ガイド:** - [カスタムペイウォールで購入を有効化する(クイックスタート)](capacitor-quickstart-manual) - [ペイウォールとプロダクトを取得する](fetch-paywalls-and-products-capacitor) - [リモートコンフィグで設計されたペイウォールをレンダリングする](present-remote-config-paywalls-capacitor) - [購入を行う](capacitor-making-purchases) - [購入を復元する](capacitor-restore-purchase) LLMに送るもの: ``` Read these Adapty docs before writing code: - https://adapty.io/docs/ja/capacitor-quickstart-manual.md - https://adapty.io/docs/ja/fetch-paywalls-and-products-capacitor.md - https://adapty.io/docs/ja/present-remote-config-paywalls-capacitor.md - https://adapty.io/docs/ja/capacitor-making-purchases.md - https://adapty.io/docs/ja/capacitor-restore-purchase.md ``` :::tip[チェックポイント] - **期待される結果:** カスタムペイウォールにAdaptyから取得したプロダクトが表示される。プロダクトをタップするとサンドボックス購入ダイアログが表示される。 - **注意点:** プロダクト配列が空 → ダッシュボードでペイウォールにプロダクトが割り当てられているか、プレースメントにオーディエンスが設定されているか確認してください。 ::: **ガイド:** - [オブザーバーモードの概要](observer-vs-full-mode) - [オブザーバーモードを実装する](implement-observer-mode-capacitor) - [オブザーバーモードでトランザクションを報告する](report-transactions-observer-mode-capacitor) LLMに送るもの: ``` Read these Adapty docs before writing code: - https://adapty.io/docs/ja/observer-vs-full-mode.md - https://adapty.io/docs/ja/implement-observer-mode-capacitor.md - https://adapty.io/docs/ja/report-transactions-observer-mode-capacitor.md ``` :::tip[チェックポイント] - **期待される結果:** 既存の購入フローでサンドボックス購入を行った後、Adapty ダッシュボードの **Event Feed** にトランザクションが表示される。 - **注意点:** イベントが表示されない → Adaptyにトランザクションを報告しているか、両ストアのサーバー通知が設定されているか確認してください。 ::: ### サブスクリプションステータスを確認する \{#check-subscription-status\} 購入後、ユーザープロファイルのアクティブなアクセスレベルを確認して、プレミアムコンテンツへのアクセスを制御します。 **ガイド:** [サブスクリプションステータスを確認する](capacitor-check-subscription-status) LLMに送るもの: ``` Read these Adapty docs before writing code: - https://adapty.io/docs/ja/capacitor-check-subscription-status.md ``` :::tip[チェックポイント] - **期待される結果:** サンドボックス購入後、`profile.accessLevels['premium']?.isActive` が `true` を返す。 - **注意点:** 購入後に `accessLevels` が空 → ダッシュボードでプロダクトにアクセスレベルが割り当てられているか確認してください。 ::: ### ユーザーを識別する \{#identify-users\} アプリのユーザーアカウントをAdaptyプロファイルにリンクし、デバイスをまたいで購入が引き継がれるようにします。 :::important アプリに認証機能がない場合はこのステップをスキップしてください。 ::: **ガイド:** [ユーザーを識別する](capacitor-quickstart-identify) LLMに送るもの: ``` Read these Adapty docs before writing code: - https://adapty.io/docs/ja/capacitor-quickstart-identify.md ``` :::tip[チェックポイント] - **期待される結果:** `adapty.identify()` を呼び出した後、ダッシュボードの **Profiles** セクションにカスタムユーザーIDが表示される。 - **注意点:** 匿名プロファイルへのアトリビューションを避けるため、アクティベーション後、ペイウォールの取得前に `identify` を呼び出してください。 ::: ### リリース準備をする \{#prepare-for-release\} サンドボックスで統合が正常に動作したら、リリースチェックリストを確認してすべてが本番環境に対応できているか確認しましょう。 **ガイド:** [リリースチェックリスト](release-checklist) LLMに送るもの: ``` Read these Adapty docs before releasing: - https://adapty.io/docs/ja/release-checklist.md ``` :::tip[チェックポイント] - **期待される結果:** すべてのチェックリスト項目を確認済み:ストア接続、サーバー通知、購入フロー、アクセスレベルのチェック、プライバシー要件。 - **注意点:** サーバー通知が未設定 → **App settings → iOS SDK** でApp Store Server Notificationsを設定し、**App settings → Android SDK** でGoogle Play Real-Time Developer Notificationsを設定してください。 ::: ## プレーンテキストのドキュメントインデックスファイル \{#plain-text-doc-index-files\} 個別のページを超えてLLMにより広いコンテキストを提供する必要がある場合、Adaptyのすべてのドキュメントを一覧表示または統合したインデックスファイルを提供しています: - [`llms.txt`](https://adapty.io/docs/ja/llms.txt): `.md` リンク付きですべてのページを一覧表示します。LLMがウェブサイトにアクセスできるようにするための[新しい標準](https://llmstxt.org/)です。一部のAIエージェント(ChatGPTなど)では `llms.txt` をダウンロードしてチャットにファイルとしてアップロードする必要があります。 - [`llms-full.txt`](https://adapty.io/docs/ja/llms-full.txt): Adaptyのドキュメントサイト全体を1つのファイルにまとめたものです。非常に大きなファイルなので、全体像が必要な場合にのみ使用してください。 - Capacitor専用の [`capacitor-llms.txt`](https://adapty.io/docs/ja/capacitor-llms.txt) と [`capacitor-llms-full.txt`](https://adapty.io/docs/ja/capacitor-llms-full.txt): サイト全体と比べてトークンを節約できる、プラットフォーム別のサブセットです。 --- # File: capacitor-paywalls --- --- title: "Paywalls" description: "Learn how to work with paywalls in your Capacitor app with Adapty SDK." --- ## Display paywalls ### Adapty Paywall Builder :::tip To get started with the Adapty Paywall Builder paywalls quickly, see our [quickstart guide](capacitor-quickstart-paywalls). ::: ### Implement paywalls manually For more guides on implementing paywalls and handling purchases manually, see the [category](capacitor-implement-paywalls-manually). ## Useful features --- # File: capacitor-get-pb-paywalls --- --- title: "Capacitor SDKでペイウォールビルダーのペイウォールとその設定を取得する" description: "Capacitorアプリでサブスクリプション管理を強化するために、AdaptyでPBペイウォールを取得する方法を学びましょう。" --- Adapty ダッシュボードの新しいペイウォールビルダーで[ペイウォールのビジュアルデザインを作成](adapty-paywall-builder)したら、モバイルアプリに表示できます。まず、プレースメントに紐づくペイウォールとそのビュー設定を取得する必要があります。 このトピックはペイウォールビルダーでカスタマイズされたペイウォールについて説明しています。リモートコンフィグペイウォールの取得については、[モバイルアプリでリモートコンフィグペイウォールのペイウォールとプロダクトを取得する](fetch-paywalls-and-products-capacitor)トピックをご参照ください。
モバイルアプリにペイウォールを表示する前に(クリックして展開) 1. Adapty ダッシュボードで[プロダクトを作成](create-product)します。 2. Adapty ダッシュボードで[ペイウォールを作成してプロダクトを追加](create-paywall)します。 3. Adapty ダッシュボードで[プレースメントを作成してペイウォールを追加](create-placement)します。 4. モバイルアプリに[Adapty SDK](sdk-installation-capacitor)をインストールします。
## ペイウォールビルダーで作成されたペイウォールを取得する \{#fetch-paywall-designed-with-paywall-builder\} [ペイウォールビルダーでペイウォールをデザイン](adapty-paywall-builder)した場合、ユーザーに表示するためにモバイルアプリコードでレンダリングを心配する必要はありません。このようなペイウォールには、表示する内容と表示方法の両方が含まれています。ただし、プレースメントを通じてそのIDを取得し、ビュー設定を取得してからモバイルアプリに表示する必要があります。 最適なパフォーマンスを確保するには、ペイウォールと[ビュー設定](capacitor-get-pb-paywalls#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder)をできるだけ早く取得し、ユーザーに表示する前に画像のダウンロードが完了する時間を十分に確保することが重要です。 ペイウォールを取得するには、`getPaywall` メソッドを使用します: ```typescript showLineNumbers try { const paywall = await adapty.getPaywall({ placementId: 'YOUR_PLACEMENT_ID', locale: 'en', }); // the requested paywall } catch (error) { // handle the error } ``` パラメーター: | パラメーター | 必須 | 説明 | |---------|--------|-----------| | **placementId** | 必須 | 取得したい[プレースメント](placements)の識別子。Adapty ダッシュボードでプレースメントを作成する際に指定した値です。 | | **locale** |

任意

デフォルト: `en`

|

[ペイウォールのローカライゼーション](add-paywall-locale-in-adapty-paywall-builder)の識別子。このパラメーターはマイナス(**-**)文字で区切られた1つまたは2つのサブタグで構成される言語コードを指定します。最初のサブタグは言語、2番目はリージョンを表します。

例:`en` は英語、`pt-br` はブラジルポルトガル語を表します。

ロケールコードとその推奨使用方法については[ローカライゼーションとロケールコード](localizations-and-locale-codes)をご参照ください。

| | **params** | 任意 | ペイウォール取得のための追加パラメーター。 | **プロダクトIDをハードコードしないでください。** ハードコードすべき唯一のIDはプレースメントIDです。ペイウォールはリモートで設定されるため、プロダクト数や利用可能なオファーはいつでも変更される可能性があります。アプリはこれらの変更を動的に処理する必要があります。今日2つのプロダクトを返すペイウォールが明日3つを返しても、コードを変更せずにすべてを表示できるようにしてください。 レスポンスパラメーター: | パラメーター | 説明 | | :-------- |:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Paywall | プロダクトIDのリスト、ペイウォール識別子、リモートコンフィグ、その他のプロパティを含む[`AdaptyPaywall`](https://capacitor.adapty.io/interfaces/adaptypaywall)オブジェクト。 | ## ペイウォールビルダーで作成されたペイウォールのビュー設定を取得する \{#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder\} :::important ペイウォールビルダーの **Show on device** トグルを有効にしてください。このオプションがオンになっていない場合、ビュー設定を取得できません。 ::: ペイウォールを取得したら、`ViewConfiguration` が含まれているかどうかを確認します。これはペイウォールビルダーで作成されたことを示します。`ViewConfiguration` がある場合はペイウォールビルダーのペイウォールとして扱い、ない場合は[リモートコンフィグペイウォールとして処理](present-remote-config-paywalls-capacitor)します。 Capacitor SDKでは、ビュー設定を手動で取得せずに直接 `createPaywallView` メソッドを呼び出します。 :::warning `createPaywallView` メソッドの結果は一度しか使用できません。再度使用する場合は、`createPaywallView` メソッドを新たに呼び出してください。 ::: ```typescript showLineNumbers if (paywall.hasViewConfiguration) { try { const view = await createPaywallView(paywall); } catch (error) { // handle the error } } else { // use your custom logic } ``` パラメーター: | パラメーター | 必須 | 説明 | | :------------------- | :------- | :----------------------------------------------------------- | | **paywall** | 必須 | 目的のペイウォールのコントローラーを取得するための `AdaptyPaywall` オブジェクト。 | | **customTags** | 任意 | カスタムタグとその解決された値の辞書を定義します。カスタムタグはペイウォールコンテンツのプレースホルダーとして機能し、ペイウォール内のパーソナライズされたコンテンツのために特定の文字列に動的に置き換えられます。詳細はペイウォールビルダーのカスタムタグのトピックをご参照ください。 | | **prefetchProducts** | 任意 | 画面上のプロダクト表示タイミングを最適化するために有効にします。`true` の場合、AdaptyUIが必要なプロダクトを自動的に取得します。デフォルト: `false`。 | :::note 複数の言語を使用している場合は、[ペイウォールビルダーのローカライゼーション](add-paywall-locale-in-adapty-paywall-builder)の追加方法と、ロケールコードの正しい使用方法を[こちら](capacitor-localizations-and-locale-codes)で確認してください。 ::: ビューを取得したら、[ペイウォールを表示](capacitor-present-paywalls)します。 ## デフォルトオーディエンスのペイウォールをより早く取得する \{#get-a-paywall-for-a-default-audience-to-fetch-it-faster\} 通常、ペイウォールはほぼ瞬時に取得されるため、このプロセスを高速化することを心配する必要はありません。しかし、多数のオーディエンスとペイウォールがあり、ユーザーのインターネット接続が弱い場合、ペイウォールの取得に想定以上の時間がかかることがあります。そのような状況では、ペイウォールをまったく表示しないよりも、スムーズなユーザー体験を確保するためにデフォルトのペイウォールを表示したい場合があります。 これに対応するために、`getPaywallForDefaultAudience` メソッドを使用できます。このメソッドは **All Users** オーディエンス用に指定されたプレースメントのペイウォールを取得します。ただし、推奨されるアプローチは上記の[ペイウォール情報を取得する](#fetch-paywall-designed-with-paywall-builder)セクションで詳しく説明されている `getPaywall` メソッドでペイウォールを取得することです。 :::warning `getPaywall` の使用を推奨する理由 `getPaywallForDefaultAudience` メソッドには以下のような重大な欠点があります: - **後方互換性の問題**: 異なるアプリバージョン(現在と将来)で異なるペイウォールを表示する必要がある場合、現在(レガシー)バージョンをサポートするペイウォールを設計するか、現在(レガシー)バージョンのユーザーがレンダリングされないペイウォールに遭遇する可能性を受け入れる必要があります。 - **ターゲティングの喪失**: すべてのユーザーが **All Users** オーディエンス向けに設計された同じペイウォールを見ることになり、国、マーケティングアトリビューション、独自のカスタム属性などに基づいたパーソナライズされたターゲティングが失われます。 ペイウォールの取得を高速化するためにこれらの欠点を受け入れる場合は、以下のように `getPaywallForDefaultAudience` メソッドを使用してください。そうでない場合は[上記](#fetch-paywall-designed-with-paywall-builder)で説明した `getPaywall` を使用してください。 ::: ```typescript showLineNumbers try { const paywall = await adapty.getPaywallForDefaultAudience({ placementId: 'YOUR_PLACEMENT_ID', locale: 'en', }); // the requested paywall } catch (error) { // handle the error } ``` :::note `getPaywallForDefaultAudience` メソッドは Capacitor SDK バージョン 2.11.2 以降で利用可能です。 ::: | パラメーター | 必須 | 説明 | |---------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **placementId** | 必須 | [プレースメント](placements)の識別子。Adapty ダッシュボードでプレースメントを作成する際に指定した値です。 | | **locale** |

任意

デフォルト: `en`

|

[ペイウォールのローカライゼーション](add-remote-config-locale)の識別子。このパラメーターはマイナス(**-**)文字で区切られた1つ以上のサブタグで構成される言語コードを指定します。最初のサブタグは言語、2番目はリージョンを表します。

例:`en` は英語、`pt-br` はブラジルポルトガル語を表します。

ロケールコードとその推奨使用方法については[ローカライゼーションとロケールコード](capacitor-localizations-and-locale-codes)をご参照ください。

| | **params** | 任意 | ペイウォール取得のための追加パラメーター。 | ## アセットをカスタマイズする \{#customize-assets\} ペイウォール内の画像や動画をカスタマイズするには、カスタムアセットを実装します。 ヒーロー画像と動画には `hero_image` と `hero_video` という事前定義されたIDがあります。カスタムアセットバンドルでは、これらの要素をIDで指定して動作をカスタマイズします。 その他の画像や動画については、Adapty ダッシュボードで[カスタムIDを設定](custom-media)する必要があります。 例えば、以下のことができます: - 一部のユーザーに異なる画像や動画を表示する。 - リモートのメイン画像が読み込まれている間にローカルのプレビュー画像を表示する。 - 動画を再生する前にプレビュー画像を表示する。 :::important この機能を使用するには、Adapty Capacitor SDK をバージョン 3.8.0 以上にアップデートしてください。 ::: シンプルな辞書を使ってカスタムアセットを提供する例を示します: ```typescript showLineNumbers const customAssets: Record = { 'custom_image': { type: 'image', relativeAssetPath: 'custom_image.png' }, 'hero_video': { type: 'video', fileLocation: { ios: { fileName: 'custom_video.mp4' }, android: { relativeAssetPath: 'videos/custom_video.mp4' } } } }; view = await createPaywallView(paywall, { customAssets }); ``` :::note アセットが見つからない場合、ペイウォールはデフォルトの外観にフォールバックします。 ::: --- # File: capacitor-present-paywalls --- --- title: "Capacitor SDKでペイウォールビルダーのペイウォールを表示する" description: "Adaptyを使用してCapacitorアプリにペイウォールを表示します。" --- ペイウォールビルダーを使ってペイウォールをカスタマイズした場合、モバイルアプリのコードでレンダリングを行う必要はありません。ペイウォールビルダーのペイウォールには、表示内容と表示方法の両方が含まれているためです。 :::warning このガイドは**ペイウォールビルダーのペイウォール**専用です。リモートコンフィグのペイウォールを表示する場合は、手順が異なります。**リモートコンフィグのペイウォール**の表示については、[リモートコンフィグで設計されたペイウォールのレンダリング](present-remote-config-paywalls)を参照してください。 ::: ペイウォールを表示するには、[`createPaywallView`](capacitor-get-pb-paywalls#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder)メソッドで作成した`view`に対して`view.present()`メソッドを呼び出します。各`view`は一度しか使用できません。ペイウォールを再度表示する必要がある場合は、`createPaywallView`を再度呼び出して新しい`view`インスタンスを作成してください。 :::warning `view`を再作成せずに再利用すると、エラーが発生する場合があります。 ::: ```typescript showLineNumbers const view = await createPaywallView(paywall); view.setEventHandlers({ onUrlPress(url) { window.open(url, '_blank'); return false; }, }); try { await view.present(); } catch (error) { // handle the error } ``` ## デベロッパー定義タイマーの使用 \{#use-developer-defined-timer\} モバイルアプリでデベロッパー定義タイマーを使用するには、`timerId`を指定します。この例では`CUSTOM_TIMER_NY`が、Adaptyダッシュボードで設定したデベロッパー定義タイマーの**Timer ID**です。これにより、アプリは`13d 09h 03m 34s`のような正しい値(タイマーの終了時刻(例:元日)から現在時刻を引いた値)でタイマーを動的に更新できます。 ```typescript showLineNumbers const customTimers = { 'CUSTOM_TIMER_NY': new Date(2025, 0, 1) }; const view = await createPaywallView(paywall, { customTimers }); ``` この例では、`CUSTOM_TIMER_NY`はAdaptyダッシュボードで設定したデベロッパー定義タイマーの**Timer ID**です。タイマーにより、アプリは`13d 09h 03m 34s`のような正しい値(タイマーの終了時刻(例:元日)から現在時刻を引いた値)でタイマーを動的に更新します。 ## ダイアログの表示 \{#show-dialog\} Androidでペイウォールビューが表示されている場合は、ネイティブのアラートダイアログの代わりにこのメソッドを使用してください。Androidでは通常のアラートがペイウォールビューの背後に表示されるため、ユーザーには見えません。このメソッドを使用することで、すべてのプラットフォームでペイウォールの上に適切にダイアログが表示されます。 ```typescript showLineNumbers title="Capacitor" try { const action = await view.showDialog({ title: 'Close paywall?', content: 'You will lose access to exclusive offers.', primaryActionTitle: 'Stay', secondaryActionTitle: 'Close', }); if (action === 'secondary') { // User confirmed - close the paywall await view.dismiss(); } // If primary - do nothing, user stays } catch (error) { // handle error } ``` ## iOSプレゼンテーションスタイルの設定 \{#configure-ios-presentation-style\} `present()`メソッドに`iosPresentationStyle`パラメーターを渡すことで、iOSでのペイウォールの表示方法を設定できます。パラメーターには`'full_screen'`(デフォルト)または`'page_sheet'`を指定できます。 ```typescript showLineNumbers await view.present({ iosPresentationStyle: 'page_sheet' }); ``` --- # File: capacitor-handle-paywall-actions --- --- title: "Capacitor SDKでボタンアクションに応答する" description: "CapacitorでAdaptyを使用してペイウォールのボタンアクションを処理し、アプリの収益化を改善します。" --- Adaptyのペイウォールビルダーを使ってペイウォールを構築する場合、ボタンを正しく設定することが重要です: 1. [ペイウォールビルダーにボタンを追加し](paywall-buttons)、既存のアクションを割り当てるか、カスタムアクションIDを作成します。 2. 割り当てた各アクションを処理するコードをアプリに記述します。 このガイドでは、コード内でカスタムアクションや既存のアクションを処理する方法を説明します。 ## ペイウォールを閉じる \{#close-paywalls\} ペイウォールを閉じるボタンを追加するには: 1. ペイウォールビルダーでボタンを追加し、**Close** アクションを割り当てます。 2. アプリのコードに、ペイウォールを閉じる `close` アクションのハンドラーを実装します。 :::info Capacitor SDKでは、`close` アクションはデフォルトでペイウォールを閉じる動作をトリガーします。ただし、必要に応じてコードでこの動作をオーバーライドできます。たとえば、あるペイウォールを閉じたときに別のペイウォールを開くようにすることもできます。 ::: ```typescript showLineNumbers const view = await createPaywallView(paywall); const unsubscribe = view.setEventHandlers({ onCloseButtonPress() { console.log('User closed paywall'); return true; // Allow the paywall to close } }); ``` ## ペイウォールからURLを開く \{#open-urls-from-paywalls\} :::tip リンクのグループ(利用規約や購入の復元など)を追加したい場合は、ペイウォールビルダーで **Link** 要素を追加し、**Open URL** アクションが割り当てられたボタンと同じ方法で処理してください。 ::: ペイウォールからリンクを開くボタン(**Terms of use** や **Privacy policy** など)を追加するには: 1. ペイウォールビルダーでボタンを追加し、**Open URL** アクションを割り当てて、開きたいURLを入力します。 2. アプリのコードに、受け取ったURLをブラウザで開く `openUrl` アクションのハンドラーを実装します。 :::info Capacitor SDKでは、`window.open` アクションはデフォルトでURLを開く動作をトリガーします。ただし、必要に応じてコードでこの動作をオーバーライドできます。 ::: ```typescript showLineNumbers const view = await createPaywallView(paywall); const unsubscribe = view.setEventHandlers({ onUrlPress(url) { window.open(url, '_blank'); return false; // Don't close the paywall }, }); ``` ## アプリにログインする \{#log-into-the-app\} ユーザーをアプリにログインさせるボタンを追加するには: 1. ペイウォールビルダーでボタンを追加し、**Login** アクションを割り当てます。 2. アプリのコードに、ユーザーを識別する `login` アクションのハンドラーを実装します。 ```typescript showLineNumbers const view = await createPaywallView(paywall); const unsubscribe = view.setEventHandlers({ onCustomAction(actionId) { if (actionId === 'login') { // Navigate to login screen console.log('User requested login'); } } }); ``` ## カスタムアクションを処理する \{#handle-custom-actions\} その他のアクションを処理するボタンを追加するには: 1. ペイウォールビルダーでボタンを追加し、**Custom** アクションを割り当てて、IDを設定します。 2. アプリのコードに、作成したアクションIDのハンドラーを実装します。 たとえば、別のサブスクリプションオファーや買い切り購入がある場合、別のペイウォールを表示するボタンを追加できます: ```typescript showLineNumbers const unsubscribe = view.setEventHandlers({ onCustomAction(actionId) { if (actionId === 'openNewPaywall') { // Display another paywall console.log('User requested new paywall'); } }, }); ``` --- # File: capacitor-handling-events --- --- title: "Capacitor - ペイウォールイベントの処理" description: "Adapty の SDK を使って Capacitor でサブスクリプションイベントを処理する方法。" --- :::important このガイドでは、購入・復元・プロダクト選択・ペイウォールレンダリングに関するイベント処理を説明します。ボタン操作(ペイウォールを閉じる、リンクを開くなど)の処理も別途実装する必要があります。詳細は[ボタンアクションの処理に関するガイド](capacitor-handle-paywall-actions)をご覧ください。 ::: [ペイウォールビルダー](adapty-paywall-builder)で設定したペイウォールは、購入と復元を行うために追加のコードは不要です。ただし、アプリが応答できるいくつかのイベントが発生します。これらのイベントには、ボタン操作(閉じるボタン、URL、プロダクト選択など)やペイウォール上での購入関連アクションの通知が含まれます。以下でこれらのイベントへの対応方法を説明します。 モバイルアプリ内のペイウォール画面で発生するプロセスを制御・監視するには、`view.setEventHandlers` メソッドを実装してください。 ```typescript showLineNumbers const view = await createPaywallView(paywall); const unsubscribe = view.setEventHandlers({ onCloseButtonPress() { console.log('User closed paywall'); return true; // Allow the paywall to close }, onAndroidSystemBack() { console.log('User pressed back button'); return true; // Allow the paywall to close }, onAppeared() { console.log('Paywall appeared'); return false; // Don't close the paywall }, onDisappeared() { console.log('Paywall disappeared'); }, onPurchaseCompleted(purchaseResult, product) { console.log('Purchase completed:', purchaseResult); return purchaseResult.type !== 'user_cancelled'; // Close if not cancelled }, onPurchaseStarted(product) { console.log('Purchase started:', product); return false; // Don't close the paywall }, onPurchaseFailed(error, product) { console.error('Purchase failed:', error); return false; // Don't close the paywall }, onRestoreCompleted(profile) { console.log('Restore completed:', profile); return true; // Close the paywall after successful restore }, onRestoreFailed(error) { console.error('Restore failed:', error); return false; // Don't close the paywall }, onProductSelected(productId) { console.log('Product selected:', productId); return false; // Don't close the paywall }, onRenderingFailed(error) { console.error('Rendering failed:', error); return false; // Don't close the paywall }, onLoadingProductsFailed(error) { console.error('Loading products failed:', error); return false; // Don't close the paywall }, onUrlPress(url) { window.open(url, '_blank'); return false; // Don't close the paywall }, }); ```
イベントの例(クリックして展開) ```typescript // onCloseButtonPress { "event": "close_button_press" } // onAndroidSystemBack { "event": "android_system_back" } // onAppeared { "event": "paywall_shown" } // onDisappeared { "event": "paywall_closed" } // onUrlPress { "event": "url_press", "url": "https://example.com/terms" } // onCustomAction { "event": "custom_action", "actionId": "login" } // onProductSelected { "event": "product_selected", "productId": "premium_monthly" } // onPurchaseStarted { "event": "purchase_started", "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" } } // onPurchaseCompleted - Success { "event": "purchase_completed", "purchaseResult": { "type": "success", "profile": { "accessLevels": { "premium": { "id": "premium", "isActive": true, "expiresAt": "2024-02-15T10:30:00Z" } } } }, "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" } } // onPurchaseCompleted - Cancelled { "event": "purchase_completed", "purchaseResult": { "type": "user_cancelled" }, "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" } } // onPurchaseFailed { "event": "purchase_failed", "error": { "code": "purchase_failed", "message": "Purchase failed due to insufficient funds", "details": { "underlyingError": "Insufficient funds in account" } } } // onRestoreCompleted { "event": "restore_completed", "profile": { "accessLevels": { "premium": { "id": "premium", "isActive": true, "expiresAt": "2024-02-15T10:30:00Z" } }, "subscriptions": [ { "vendorProductId": "premium_monthly", "isActive": true, "expiresAt": "2024-02-15T10:30:00Z" } ] } } // onRestoreFailed { "event": "restore_failed", "error": { "code": "restore_failed", "message": "Purchase restoration failed", "details": { "underlyingError": "No previous purchases found" } } } // onRenderingFailed { "event": "rendering_failed", "error": { "code": "rendering_failed", "message": "Failed to render paywall interface", "details": { "underlyingError": "Invalid paywall configuration" } } } // onLoadingProductsFailed { "event": "loading_products_failed", "error": { "code": "products_loading_failed", "message": "Failed to load products from the server", "details": { "underlyingError": "Network timeout" } } } ```
必要なイベントハンドラーだけを登録し、不要なものは省略できます。省略した場合、そのイベントリスナーは作成されません。必須のイベントハンドラーはありません。 イベントハンドラーはブール値を返します。`true` を返すと表示プロセスが完了したとみなされ、ペイウォール画面が閉じられてこのビューのイベントリスナーが削除されます。 一部のイベントハンドラーにはデフォルトの動作があり、必要に応じてオーバーライドできます。 - `onCloseButtonPress`:閉じるボタンが押されたときにペイウォールを閉じます。 - `onAndroidSystemBack`:**戻る**ボタンが押されたときにペイウォールを閉じます。 - `onRestoreCompleted`:復元が成功した後にペイウォールを閉じます。 - `onPurchaseCompleted`:ユーザーがキャンセルした場合を除いてペイウォールを閉じます。 - `onRenderingFailed`:レンダリングに失敗した場合にペイウォールを閉じます。 - `onUrlPress`:URL をシステムブラウザで開き、ペイウォールは開いたままにします。 ### イベントハンドラー \{#event-handlers\} | イベントハンドラー | 説明 | |:----------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **onCustomAction** | ユーザーがカスタムアクションを実行したとき(例:[カスタムボタン](paywall-buttons)をクリックしたとき)に呼び出されます。 | | **onUrlPress** | ユーザーがペイウォール内の URL をクリックしたときに呼び出されます。 | | **onAndroidSystemBack** | ユーザーが Android のシステム**戻る**ボタンをタップしたときに呼び出されます。 | | **onCloseButtonPress** | 閉じるボタンが表示されており、ユーザーがタップしたときに呼び出されます。このハンドラーでペイウォール画面を閉じることを推奨します。 | | **onPurchaseCompleted** | 購入が完了したとき(成功、ユーザーによるキャンセル、または承認待ちの場合)に呼び出されます。購入が成功した場合は更新された `AdaptyProfile` が提供されます。ユーザーのキャンセルや保留中の支払い(保護者の承認が必要な場合など)は `onPurchaseFailed` ではなくこのイベントをトリガーします。 | | **onPurchaseStarted** | ユーザーが「購入」アクションボタンをタップして購入プロセスを開始したときに呼び出されます。 | | **onPurchaseCancelled** | ユーザーが購入プロセスを開始した後、手動で中断(支払いダイアログをキャンセル)したときに呼び出されます。 | | **onPurchaseFailed** | エラーにより購入が失敗したとき(支払い制限、無効なプロダクト、ネットワーク障害、トランザクション検証失敗など)に呼び出されます。ユーザーのキャンセルや保留中の支払いでは呼び出されず、それらは `onPurchaseCompleted` をトリガーします。 | | **onRestoreStarted** | ユーザーが購入の復元プロセスを開始したときに呼び出されます。 | | **onRestoreCompleted** | 購入の復元が成功し、更新された `AdaptyProfile` が提供されたときに呼び出されます。ユーザーが必要な `accessLevel` を持っている場合は画面を閉じることを推奨します。確認方法については[サブスクリプションのステータス](capacitor-listen-subscription-changes)をご覧ください。 | | **onRestoreFailed** | 復元プロセスが失敗し、`AdaptyError` が提供されたときに呼び出されます。 | | **onProductSelected** | ペイウォールビュー内のいずれかのプロダクトが選択されたときに呼び出されます。購入前にユーザーが何を選択しているかを監視できます。 | | **onAppeared** | ペイウォールビューが画面に表示されたときに呼び出されます。iOS では、ユーザーがペイウォール内の[ウェブペイウォールボタン](web-paywall#step-2a-add-a-web-purchase-button)をタップしてアプリ内ブラウザでウェブペイウォールが開いたときにも呼び出されます。 | | **onDisappeared** | ペイウォールビューが画面から消えたときに呼び出されます。iOS では、ペイウォールからアプリ内ブラウザで開いた[ウェブペイウォール](web-paywall#step-2a-add-a-web-purchase-button)が画面から消えたときにも呼び出されます。 | | **onRenderingFailed** | ビューのレンダリング中にエラーが発生し、`AdaptyError` が提供されたときに呼び出されます。このようなエラーは本来発生しないため、遭遇した場合はお知らせください。 | | **onLoadingProductsFailed** | プロダクトの読み込みに失敗し、`AdaptyError` が提供されたときに呼び出されます。ビュー作成時に `prefetchProducts: true` を設定していない場合、AdaptyUI が必要なオブジェクトをサーバーから自動的に取得します。 | --- # File: capacitor-use-fallback-paywalls --- --- title: "Capacitor - フォールバックペイウォールを使用する" description: "ユーザーがオフラインの場合やAdaptyサーバーが利用できない場合の対応方法" --- スムーズなユーザー体験を維持するために、フロー、[ペイウォール](paywalls)、[オンボーディング](onboardings)に[フォールバック](/fallback-paywalls)を設定することが重要です。この対策により、インターネット接続が部分的または完全に失われた場合でも、アプリケーションの機能を維持できます。 * **アプリケーションが Adapty サーバーにアクセスできない場合:** フォールバックのフローまたはペイウォールを表示し、ローカルのオンボーディング設定にアクセスできます。 * **アプリケーションがインターネットにアクセスできない場合:** フォールバックのフローまたはペイウォールを表示できます。オンボーディングはリモートコンテンツを含むため、動作にはインターネット接続が必要です。 :::important このガイドの手順を進める前に、Adapty からフォールバック設定ファイルを[ダウンロード](/local-fallback-paywalls)してください。 ::: ## 設定 \{#configuration\} ### Android 1. フォールバック設定ファイルをアプリケーションに追加します。以下のディレクトリのいずれかを選択してください: * **android/app/src/main/assets/** * **android/app/src/main/res/raw/** 注意:`res/raw` フォルダにはファイル命名規則があります(先頭は英字、大文字不可、アンダースコア以外の特殊文字不可、スペース不可)。 2. `FileLocation` 定数の `android` プロパティを更新します: * ファイルが `assets` ディレクトリにある場合は、そのディレクトリからの相対パスを指定します。 * ファイルが `res/raw` ディレクトリにある場合は、拡張子を除いたファイル名を指定します。 ### iOS 1. フォールバックJSONファイルをプロジェクトバンドルに追加します:XCodeの **File** メニューを開き、**Add Files to "YourProjectName"** を選択します。 2. 設定ファイルの名前を `FileLocation` 定数の `ios` プロパティに指定します。 ## 例 \{#example\} ```typescript showLineNumbers const fileLocation = { ios: { fileName: 'ios_fallback.json' }, android: { //if the file is located in 'android/app/src/main/assets/' relativeAssetPath: 'android_fallback.json' } }; await adapty.setFallback({ fileLocation }); ``` パラメータ: | パラメータ | 説明 | | :------------------- | :------------------------------------------------------- | | **fileLocation** | フォールバック設定ファイルの場所を表すオブジェクト。 | --- # File: capacitor-localizations-and-locale-codes --- --- title: "Capacitor SDKでローカライズとロケールコードを使用する" description: "Adapty SDKを使ってCapacitorアプリのペイウォールをローカライズする方法を学びましょう。" --- ## なぜこれが重要なのか \{#why-this-is-important\} ロケールコードが関係するシナリオはいくつかあります。たとえば、アプリの現在のローカライズに対応した正しいペイウォールを取得しようとする場合などです。 ロケールコードは複雑で、プラットフォームによって異なることがあるため、Adaptyでは対応するすべてのプラットフォームに共通の内部標準を採用しています。ただし、コードが複雑なため、サーバーに何を送信しているか、そして次に何が起こるかを正確に理解しておくことが非常に重要です。そうすることで、常に期待どおりの結果が得られます。 ## AdaptyのロケールコードLSの標準 \{#locale-code-standard-at-adapty\} ロケールコードについて、Adaptyは少し修正した[BCP 47標準](https://en.wikipedia.org/wiki/IETF_language_tag)を使用しています。各コードは小文字のサブタグで構成され、ハイフンで区切られます。例:`en`(英語)、`pt-br`(ポルトガル語(ブラジル))、`zh`(簡体字中国語)、`zh-hant`(繁体字中国語)。 ## ロケールコードのマッチング \{#locale-code-matching\} Adaptyがクライアント側SDKからロケールコードの呼び出しを受け取り、ペイウォールの対応するローカライズを検索するとき、以下のことが起こります: 1. 受信したロケール文字列が小文字に変換され、アンダースコア(`_`)がすべてハイフン(`-`)に置換されます 2. 完全に一致するロケールコードのローカライズを検索します 3. 一致するものが見つからなかった場合、最初のハイフンの前の部分文字列(`pt-br`の場合は`pt`)を取得し、一致するローカライズを検索します 4. それでも一致するものが見つからなかった場合、デフォルトの`en`ローカライズを返します これにより、`'pt_BR'`を送信したiOSデバイス、`pt-BR`を送信したAndroidデバイス、`pt-br`を送信した別のデバイスはすべて同じ結果を得られます。 ## ローカライズの実装:推奨する方法 \{#implementing-localizations-recommended-way\} ローカライズについて検討しているなら、すでにプロジェクト内のローカライズ済み文字列ファイルを扱っている可能性があります。その場合は、各ローカライズに対応するAdaptyのロケールコードをキーと値のペアとしてファイルに記述することをおすすめします。そして、SDKを呼び出す際にそのキーの値を取り出して使用します: ```javascript showLineNumbers // 1. Modify your localization files (e.g., using react-i18next) /* en.json */ { "adapty_paywalls_locale": "en" } /* es.json */ { "adapty_paywalls_locale": "es" } /* pt-BR.json */ { "adapty_paywalls_locale": "pt-br" } // 2. Extract and use the locale code const MyComponent = () => { const { t } = useTranslation(); const fetchPaywall = async () => { const locale = t('adapty_paywalls_locale'); // pass locale code to adapty.getPaywall or adapty.getPaywallForDefaultAudience method const paywall = await adapty.getPaywallForDefaultAudience('placement_id', locale); }; }; ``` これにより、アプリのすべてのユーザーに対してどのローカライズが取得されるかを完全にコントロールできます。 ## ローカライズの実装:別の方法 \{#implementing-localizations-the-other-way\} すべてのローカライズに対してロケールコードを明示的に定義しなくても、同様の(ただし完全に同一ではない)結果を得ることができます。それはプラットフォームが提供する別のオブジェクトからロケールコードを取り出すことを意味します: ```javascript showLineNumbers const getLocaleCode = () => { if (Capacitor.getPlatform() === 'ios') { return navigator.language || 'en'; } else { return navigator.language || 'en'; } }; const fetchPaywall = async () => { const locale = getLocaleCode(); // pass locale code to adapty.getPaywall or adapty.getPaywallForDefaultAudience method const paywall = await adapty.getPaywallForDefaultAudience('placement_id', locale); }; ``` この方法はいくつかの理由からおすすめしません: 1. iOSでは、優先言語と現在のロケールは同一ではありません。ローカライズが正しく選択されるようにするには、Appleのロジックに任せるか(推奨するローカライズ済み文字列ファイルを使用するアプローチであれば自動的に機能します)、それを自分で再現する必要があります。 2. Adaptyのサーバーが実際に何を受け取るか予測しにくいです。たとえば、iOSでは`ar_OM@numbers='latn'`のようなロケールをデバイスから取得してサーバーに送信することがあります。この場合、期待していた`ar-om`ローカライズではなく`ar`が返ってきます。これはおそらく意図しない結果です。 それでもこのアプローチを使用する場合は、関連するすべてのユースケースをカバーしていることを確認してください。 --- # File: capacitor-web-paywall --- --- title: "ウェブペイウォールの実装" description: "Adapty SDK を使用して Capacitor アプリにウェブペイウォールを実装する方法を説明します。" --- :::important 始める前に、[ダッシュボードでウェブペイウォールを設定](web-paywall)し、Adapty SDK バージョン 3.6.1 以降をインストールしていることを確認してください。 ::: ## ウェブペイウォールを開く \{#open-web-paywalls\} 自分で開発したペイウォールを使用している場合は、SDK メソッドを使ってウェブペイウォールを処理する必要があります。`.openWebPaywall` メソッドは以下を行います: 1. 特定のユーザーに表示されたペイウォールを、そのユーザーがリダイレクトされるウェブページに Adapty が紐付けるための一意の URL を生成します。 2. ユーザーがアプリに戻ったタイミングを検知し、プロファイルのアクセス権が更新されたかどうかを確認するために、短い間隔で `.getProfile` をリクエストします。 これにより、支払いが成功してアクセス権が更新されると、アプリ内でほぼ即座にサブスクリプションが有効になります。 ```typescript showLineNumbers try { await adapty.openWebPaywall({ paywallOrProduct: product }); } catch (error) { console.error('Failed to open web paywall:', error); } ``` :::note `openWebPaywall` メソッドには 2 つのバージョンがあります: 1. `openWebPaywall({ paywallOrProduct: product })` — ペイウォールに基づいて URL を生成し、プロダクトデータも URL に追加します。 2. `openWebPaywall({ paywallOrProduct: paywall })` — ペイウォールに基づいて URL を生成しますが、プロダクトデータは URL に追加しません。Adapty のペイウォールに設定されているプロダクトとウェブペイウォールのプロダクトが異なる場合に使用してください。 ::: #### エラー処理 \{#handle-errors\} | エラー | 説明 | 推奨対応 | |-----------------------------------------|--------------------------------------------------------|---------------------------------------------------------------------------| | AdaptyError.paywallWithoutPurchaseUrl | ペイウォールにウェブ購入 URL が設定されていません | Adapty ダッシュボードでペイウォールが正しく設定されているか確認してください | | AdaptyError.productWithoutPurchaseUrl | プロダクトにウェブ購入 URL が設定されていません | Adapty ダッシュボードでプロダクトの設定を確認してください | | AdaptyError.failedOpeningWebPaywallUrl | ブラウザで URL を開くことができませんでした | デバイスの設定を確認するか、代替の購入方法を提供してください | | AdaptyError.failedDecodingWebPaywallUrl | URL のパラメータのエンコードに失敗しました | URL パラメータが有効で正しい形式になっているか確認してください | ## アプリ内ブラウザでウェブペイウォールを開く \{#open-web-paywalls-in-an-in-app-browser\} :::important アプリ内ブラウザでのウェブペイウォールの表示は、Adapty SDK v3.15 以降でサポートされています。 ::: デフォルトでは、ウェブペイウォールは外部ブラウザで開きます。 シームレスなユーザー体験を提供するために、アプリ内ブラウザでウェブペイウォールを開くことができます。これにより、アプリを切り替えることなく、アプリ内でウェブ購入ページを表示してトランザクションを完了できます。 これを有効にするには、`openWebPaywall` の `openIn` に `WebPresentation.BrowserInApp` を設定します: ```typescript showLineNumbers try { await adapty.openWebPaywall({ paywallOrProduct: product, openIn: WebPresentation.BrowserInApp, // default – WebPresentation.BrowserOutApp }); } catch (error) { console.error('Failed to open web paywall:', error); } ``` --- # File: capacitor-implement-paywalls-manually --- --- title: "Implement paywalls manually" description: "Learn how to implement paywalls manually in your Capacitor app with Adapty SDK." --- ## Accept purchases If you are working with paywalls you've implemented yourself, you can delegate handling purchases to Adapty, using the `makePurchase` method. This way, we will handle all the user scenarios, and you will only need to handle the purchase results. :::important `makePurchase` works with products created in the Adapty dashboard. Make sure you configure products and ways to retrieve them in the dashboard by following the [quickstart guide](quickstart). ::: ## Observer mode If you want to implement your own purchase handling logic from scratch but still want to benefit from the advanced analytics in Adapty, you can use the observer mode. :::important Consider the observer mode limitations [here](observer-vs-full-mode). ::: --- # File: capacitor-quickstart-manual --- --- title: "Capacitor SDKのカスタムペイウォールで購入を有効にする" description: "Adapty SDKをCapacitorのカスタムペイウォールに統合して、アプリ内課金を有効にします。" --- このガイドでは、カスタムペイウォールにAdaptyを統合する方法を説明します。Adapty SDKがプロダクトの取得、新規購入の処理、過去の購入の復元を行いながら、ペイウォールの実装を完全にコントロールできます。 :::important **このガイドはカスタムペイウォールを実装する開発者向けです。** 購入を手軽に有効にしたい場合は、[Adapty ペイウォールビルダー](capacitor-quickstart-paywalls)をご利用ください。ペイウォールビルダーを使えば、ノーコードのビジュアルエディターでペイウォールを作成でき、Adaptyがすべての購入ロジックを自動的に処理するため、アプリを再公開することなく異なるデザインをテストできます。 ::: ## 始める前に \{#before-you-start\} ### プロダクトのセットアップ \{#set-up-products\} アプリ内課金を有効にするには、次の3つの主要な概念を理解する必要があります。 - [**プロダクト**](product) – ユーザーが購入できるもの(サブスクリプション、消耗型アイテム、永続アクセス) - [**ペイウォール**](paywalls) – どのプロダクトを提供するかを定義する設定。Adaptyでは、ペイウォールがプロダクトを取得する唯一の手段ですが、この設計によりアプリのコードを変更せずにプロダクト、価格、オファーを変更できます。 - [**プレースメント**](placements) – アプリ内でペイウォールを表示する場所とタイミング(`main`、`onboarding`、`settings`など)。ダッシュボードでプレースメントに対してペイウォールを設定し、コード内ではプレースメントIDで取得します。これにより、A/Bテストの実行や異なるユーザーへの異なるペイウォールの表示が簡単になります。 カスタムペイウォールを使用する場合でも、これらの概念を理解しておいてください。基本的には、アプリで販売するプロダクトを管理する方法です。 カスタムペイウォールを実装するには、**ペイウォール**を作成して**プレースメント**に追加する必要があります。この設定でプロダクトを取得できます。ダッシュボードで必要な作業を理解するには、[こちら](quickstart)のクイックスタートガイドに従ってください。 ### ユーザー管理 \{#manage-users\} バックエンド認証があってもなくても利用できます。 ただし、Adapty SDKは匿名ユーザーと識別済みユーザーを異なる方法で扱います。詳細を理解し、ユーザーを適切に扱うために[識別クイックスタートガイド](capacitor-quickstart-identify)をお読みください。 ## ステップ1. プロダクトを取得する \{#step-1-get-products\} カスタムペイウォール用のプロダクトを取得するには、次の手順に従います。 1. `getPaywall`メソッドに[プレースメント](placements)IDを渡して`paywall`オブジェクトを取得する。 2. `getPaywallProducts`メソッドを使って、このペイウォールのプロダクト配列を取得する。 ```typescript showLineNumbers async function loadPaywall() { try { const paywall: AdaptyPaywall = await adapty.getPaywall({ placementId: 'YOUR_PLACEMENT_ID' }); const products: AdaptyPaywallProduct[] = await adapty.getPaywallProducts({ paywall }); // Use products to build your custom paywall UI } catch (error) { // Handle the error } } ``` ## ステップ2. 購入を受け付ける \{#step-2-accept-purchases\} ユーザーがカスタムペイウォールのプロダクトをタップしたら、選択したプロダクトを指定して`makePurchase`メソッドを呼び出します。これにより購入フローが処理され、更新されたプロファイルが返されます。 ```typescript showLineNumbers async function purchaseProduct(product: AdaptyPaywallProduct) { try { const result: AdaptyPurchaseResult = await adapty.makePurchase({ product }); if (result.type === 'success') { // Purchase successful, profile updated } else if (result.type === 'user_cancelled') { // User canceled the purchase } else if (result.type === 'pending') { // Purchase is pending (e.g., user will pay offline with cash) } } catch (error) { // Handle the error } } ``` ## ステップ3. 購入を復元する \{#step-3-restore-purchases\} アプリストアでは、サブスクリプションを提供するすべてのアプリに対して、ユーザーが購入を復元できる手段を提供することを求めています。 ユーザーが復元ボタンをタップしたら`restorePurchases`メソッドを呼び出します。これにより購入履歴がAdaptyと同期され、更新されたプロファイルが返されます。 ```typescript showLineNumbers async function restorePurchases() { try { const profile: AdaptyProfile = await adapty.restorePurchases(); // Restore successful, profile updated } catch (error) { // Handle the error } } ``` ## 次のステップ \{#next-steps\} --- no_index: true --- import Callout from '../../../components/Callout.astro'; ご質問やお困りのことがあれば、[サポートフォーラム](https://adapty.featurebase.app/)をご覧ください。よくある質問への回答を見つけたり、ご自身の質問を投稿することができます。チームとコミュニティがサポートいたします! ペイウォールをアプリに表示する準備ができました。[App Storeサンドボックス](test-purchases-in-sandbox)または[Google Play Store](testing-on-android)でテスト購入を完了できるか確認してください。本番環境に近い実装例については、サンプルアプリの[App.tsx](https://github.com/adaptyteam/AdaptySDK-Capacitor/blob/master/examples/adapty-devtools/src/screens/app/App.tsx)を参照してください。適切なエラーハンドリング、ローディング状態、包括的なSDK統合を含む購入処理の実装例を確認できます。 次に、[ユーザーが購入を完了したかどうかを確認](capacitor-check-subscription-status)して、ペイウォールを表示するか有料機能へのアクセスを許可するかを判断します。 --- # File: fetch-paywalls-and-products-capacitor --- --- title: "Capacitor SDKでリモートコンフィグペイウォールのペイウォールとプロダクトを取得する" description: "Adapty Capacitor SDKでペイウォールとプロダクトを取得し、ユーザーの収益化を向上させましょう。" --- リモートコンフィグやカスタムペイウォールを表示する前に、それらに関する情報を取得する必要があります。このトピックはリモートコンフィグおよびカスタムペイウォールに関するものです。ペイウォールビルダーでカスタマイズしたペイウォールの取得方法については、[ペイウォールビルダーのペイウォールとその設定を取得する](capacitor-get-pb-paywalls)を参照してください。 :::tip Adapty SDK がモバイルアプリにどのように統合されているか、実際の例を見てみませんか?ペイウォールの表示、購入処理、その他の基本機能を含む完全なセットアップを実演している[サンプルアプリ](sample-apps)をご覧ください。 :::
モバイルアプリでペイウォールとプロダクトの取得を始める前に(クリックして展開) 1. Adapty ダッシュボードで[プロダクトを作成する](create-product)。 2. Adapty ダッシュボードで[ペイウォールを作成し、プロダクトをペイウォールに組み込む](create-paywall)。 3. Adapty ダッシュボードで[プレースメントを作成し、ペイウォールをプレースメントに組み込む](create-placement)。 4. モバイルアプリに[Adapty SDKをインストールする](sdk-installation-capacitor)。
## ペイウォール情報を取得する \{#fetch-paywall-information\} Adaptyでは、[プロダクト](product)はApp StoreとGoogle Playの両方のプロダクトを組み合わせたものです。これらのクロスプラットフォームプロダクトはペイウォールに統合され、特定のモバイルアプリのプレースメント内で表示できるようになります。 プロダクトを表示するには、`getPaywall`メソッドを使って、いずれかの[プレースメント](placements)から[ペイウォール](paywalls)を取得する必要があります。 ```typescript showLineNumbers try { const paywall = await adapty.getPaywall({ placementId: 'YOUR_PLACEMENT_ID', locale: 'en', params: { fetchPolicy: 'reload_revalidating_cache_data', // Load from server, fallback to cache loadTimeoutMs: 5000 // 5 second timeout } }); // the requested paywall } catch (error) { console.error('Failed to fetch paywall:', error); } ``` | パラメータ | 必須 | 説明 | |---------|--------|-----------| | **placementId** | 必須 | [プレースメント](placements)の識別子。Adapty ダッシュボードでプレースメントを作成する際に指定した値です。 | | **locale** |

任意

デフォルト: `en`

|

[ペイウォールのローカライゼーション](add-remote-config-locale)の識別子。このパラメータはマイナス(**-**)文字で区切られた1つ以上のサブタグで構成される言語コードです。最初のサブタグは言語、2番目は地域を表します。

例:`en`は英語、`pt-br`はブラジルポルトガル語を表します。

ロケールコードの詳細と推奨される使い方については、[ローカライゼーションとロケールコード](capacitor-localizations-and-locale-codes)を参照してください。

| | **params.fetchPolicy** |

任意

デフォルト: `'reload_revalidating_cache_data'`

|

デフォルトでは、SDKはサーバーからデータを読み込もうとし、失敗した場合はキャッシュデータを返します。ユーザーが常に最新のデータを取得できるため、この方法を推奨します。

ただし、ユーザーが不安定なインターネット環境を使用していると考える場合は、`'return_cache_data_else_load'`を使用して、キャッシュが存在する場合はキャッシュデータを返すようにすることを検討してください。この場合、ユーザーは最新のデータを得られない可能性がありますが、接続が不安定でも高速な読み込みを体験できます。キャッシュは定期的に更新されるため、ネットワークリクエストを避けるためにセッション中に使用しても安全です。

なお、キャッシュはアプリの再起動後も保持され、アプリの再インストールまたは手動でのクリーンアップ時にのみ削除されます。

| | **params.loadTimeoutMs** |

任意

デフォルト: 5000 ms

|

このメソッドのタイムアウト(ミリ秒)を制限します。タイムアウトに達した場合、キャッシュデータまたはローカルフォールバックが返されます。

まれに、`loadTimeoutMs`で指定した時間よりもわずかに遅くタイムアウトする場合があります。これは、この操作が内部で複数のリクエストで構成されている場合があるためです。

| **プロダクトIDをハードコードしないでください。** ハードコードすべき唯一のIDはプレースメントIDです。ペイウォールはリモートで設定されるため、プロダクトの数や利用可能なオファーはいつでも変わる可能性があります。アプリはこれらの変更を動的に処理する必要があります。今日ペイウォールが2つのプロダクトを返し、明日3つ返す場合でも、コードを変更せずにすべてを表示できるようにしてください。 レスポンスパラメータ: | パラメータ | 説明 | | :-------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | | Paywall | プロダクトIDのリスト、ペイウォール識別子、リモートコンフィグ、その他いくつかのプロパティを含む[`AdaptyPaywall`](https://capacitor.adapty.io/interfaces/adaptypaywall)オブジェクト。 | ## プロダクトを取得する \{#fetch-products\} ペイウォールを取得したら、それに対応するプロダクト配列を取得できます: ```typescript showLineNumbers try { const products = await adapty.getPaywallProducts({ paywall }); // the requested products list } catch (error) { console.error('Failed to fetch products:', error); } ``` レスポンスパラメータ: | パラメータ | 説明 | | :-------- |:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Products | プロダクト識別子、プロダクト名、価格、通貨、サブスクリプション期間、その他いくつかのプロパティを含む[`AdaptyPaywallProduct`](https://capacitor.adapty.io/interfaces/adaptypaywallproduct)オブジェクトのリスト。 | 独自のペイウォールデザインを実装する際、[`AdaptyPaywallProduct`](https://capacitor.adapty.io/interfaces/adaptypaywallproduct)オブジェクトのこれらのプロパティにアクセスする必要があるでしょう。以下に最もよく使われるプロパティを示しますが、利用可能なすべてのプロパティの詳細については、リンク先のドキュメントを参照してください。 | プロパティ | 説明 | |-------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **タイトル** | プロダクトのタイトルを表示するには、`product.localizedTitle`を使用します。ローカライゼーションはデバイスのロケールではなく、ユーザーが選択しているストアの国に基づいています。 | | **価格** | 価格のローカライズされた表示には、`product.price?.localizedString`を使用します。このローカライゼーションはデバイスのロケール情報に基づいています。`product.price?.amount`を使って数値として価格にアクセスすることもできます。値はローカル通貨で提供されます。関連する通貨記号を取得するには、`product.price?.currencySymbol`を使用します。 | | **サブスクリプション期間** | 期間(週、月、年など)を表示するには、`product.subscription?.localizedSubscriptionPeriod`を使用します。このローカライゼーションはデバイスのロケールに基づいています。プログラムでサブスクリプション期間を取得するには、`product.subscription?.subscriptionPeriod`を使用します。そこから`unit`プロパティにアクセスして期間の長さ('day'、'week'、'month'、'year'、'unknown'のいずれか)を取得できます。`numberOfUnits`の値で期間単位の数を取得できます。例えば、四半期サブスクリプションの場合、unitプロパティには`'month'`、numberOfUnitsには`3`が入ります。 | | **初回オファー** | サブスクリプションに初回オファーが含まれているかどうかを示すバッジなどのインジケーターを表示するには、`product.subscription?.offer?.phases`プロパティを確認してください。これは最大2つの割引フェーズ(無料トライアルフェーズと初回価格フェーズ)を含むリストです。各フェーズオブジェクトには以下の便利なプロパティがあります:
• `paymentMode`:`'free_trial'`、`'pay_as_you_go'`、`'pay_up_front'`、`'unknown'`の値を持つ文字列。無料トライアルは`'free_trial'`タイプになります。
• `price`:数値としての割引価格。無料トライアルの場合は`0`を確認してください。
• `localizedNumberOfPeriods`:デバイスのロケールを使ってローカライズされた、オファーの長さを示す文字列。例えば、3日間のトライアルオファーの場合、このフィールドには`'3 days'`が表示されます。
• `subscriptionPeriod`:代替として、このプロパティを使ってオファー期間の個別の詳細を取得できます。前のセクションで説明した方法と同様に機能します。
• `localizedSubscriptionPeriod`:ユーザーのロケールに合わせてフォーマットされた割引のサブスクリプション期間。 | ## デフォルトオーディエンスのペイウォールでペイウォール取得を高速化する \{#speed-up-paywall-fetching-with-default-audience-paywall\} 通常、ペイウォールはほぼ瞬時に取得されるため、このプロセスの高速化を心配する必要はありません。ただし、オーディエンスとペイウォールが多数あり、ユーザーのインターネット接続が弱い場合、ペイウォールの取得に時間がかかることがあります。そのような状況では、ペイウォールをまったく表示しないよりも、デフォルトのペイウォールを表示してスムーズなユーザー体験を確保したい場合があります。 これに対処するために、`getPaywallForDefaultAudience`メソッドを使用できます。このメソッドは、指定したプレースメントの**All Users**オーディエンス向けペイウォールを取得します。ただし、上記の[ペイウォール情報を取得する](fetch-paywalls-and-products-capacitor#fetch-paywall-information)セクションで説明した`getPaywall`メソッドでペイウォールを取得する方法が推奨アプローチであることを理解しておくことが重要です。 :::warning `getPaywall`を推奨する理由 `getPaywallForDefaultAudience`メソッドにはいくつかの重大な欠点があります: - **後方互換性の問題の可能性**:現在のバージョンと将来のバージョンで異なるペイウォールを表示する必要がある場合、課題が生じる可能性があります。現在の(レガシー)バージョンをサポートするペイウォールを設計するか、現在の(レガシー)バージョンのユーザーがレンダリングされないペイウォールに遭遇する可能性を受け入れるかのどちらかになります。 - **ターゲティングの喪失**:すべてのユーザーが**All Users**オーディエンス向けに設計された同じペイウォールを見ることになるため、パーソナライズされたターゲティング(国、マーケティングアトリビューション、独自のカスタム属性に基づくものを含む)が失われます。 これらの欠点を受け入れてでもペイウォール取得の高速化のメリットを享受したい場合は、以下のように`getPaywallForDefaultAudience`メソッドを使用してください。そうでない場合は、[上記](fetch-paywalls-and-products-capacitor#fetch-paywall-information)で説明した`getPaywall`を使用し続けてください。 ::: ```typescript showLineNumbers try { const paywall = await adapty.getPaywallForDefaultAudience({ placementId: 'YOUR_PLACEMENT_ID', locale: 'en', params: { fetchPolicy: 'reload_revalidating_cache_data' // Load from server, fallback to cache } }); // the requested paywall } catch (error) { console.error('Failed to fetch default audience paywall:', error); } ``` :::note `getPaywallForDefaultAudience`メソッドはCapacitor SDKバージョン2.11.2以降で利用可能です。 ::: | パラメータ | 必須 | 説明 | |---------|--------|-----------| | **placementId** | 必須 | [プレースメント](placements)の識別子。Adapty ダッシュボードでプレースメントを作成する際に指定した値です。 | | **locale** |

任意

デフォルト: `en`

|

[ペイウォールのローカライゼーション](add-remote-config-locale)の識別子。このパラメータはマイナス(**-**)文字で区切られた1つ以上のサブタグで構成される言語コードです。最初のサブタグは言語、2番目は地域を表します。

例:`en`は英語、`pt-br`はブラジルポルトガル語を表します。

ロケールコードの詳細と推奨される使い方については、[ローカライゼーションとロケールコード](capacitor-localizations-and-locale-codes)を参照してください。

| | **params.fetchPolicy** |

任意

デフォルト: `'reload_revalidating_cache_data'`

|

デフォルトでは、SDKはサーバーからデータを読み込もうとし、失敗した場合はキャッシュデータを返します。ユーザーが常に最新のデータを取得できるため、この方法を推奨します。

ただし、ユーザーが不安定なインターネット環境を使用していると考える場合は、`'return_cache_data_else_load'`を使用して、キャッシュが存在する場合はキャッシュデータを返すようにすることを検討してください。この場合、ユーザーは最新のデータを得られない可能性がありますが、接続が不安定でも高速な読み込みを体験できます。キャッシュは定期的に更新されるため、ネットワークリクエストを避けるためにセッション中に使用しても安全です。

なお、キャッシュはアプリの再起動後も保持され、アプリの再インストールまたは手動でのクリーンアップ時にのみ削除されます。

| --- # File: present-remote-config-paywalls-capacitor --- --- title: "Capacitor SDKでリモートコンフィグによるペイウォールをレンダリングする" description: "Adapty Capacitor SDKでリモートコンフィグペイウォールを表示し、ユーザー体験をパーソナライズする方法を解説します。" --- リモートコンフィグを使ってペイウォールをカスタマイズした場合、ユーザーに表示するためのレンダリングをアプリのコードに実装する必要があります。リモートコンフィグはニーズに合わせた柔軟な設定が可能なため、ペイウォールの内容と見た目はすべて自分でコントロールできます。リモート設定を取得するメソッドを用意しているので、リモートコンフィグで設定したカスタムペイウォールを自由に表示できます。 ## ペイウォールのリモートコンフィグを取得して表示する \{#get-paywall-remote-config-and-present-it\} ペイウォールのリモートコンフィグを取得するには、`remoteConfig` プロパティにアクセスして必要な値を抽出します。 ```typescript showLineNumbers try { const paywall = await adapty.getPaywall({ placementId: 'YOUR_PLACEMENT_ID', params: { fetchPolicy: 'reload_revalidating_cache_data', // Load from server, fallback to cache loadTimeoutMs: 5000 // 5 second timeout } }); const headerText = paywall.remoteConfig?.data?.['header_text']; } catch (error) { console.error('Failed to fetch paywall:', error); } ``` 必要な値をすべて取得したら、それらをまとめて見栄えのよいページとしてレンダリングします。さまざまな画面サイズや向きに対応したデザインにすることで、どのデバイスでも快適に使えるユーザー体験を提供しましょう。 :::warning Adapty アナリティクスがファネルや A/B テストの情報を正しく収集できるよう、必ず以下の手順で[ペイウォール表示イベントを記録](present-remote-config-paywalls-capacitor#track-paywall-view-events)してください。 ::: ペイウォールの表示が完了したら、購入フローの設定に進みます。ユーザーが購入する際は、ペイウォールのプロダクトを使って `.makePurchase()` を呼び出すだけです。`.makePurchase()` メソッドの詳細は[購入の実行](capacitor-making-purchases)をご覧ください。 インターネット接続がない場合やキャッシュが利用できない場合でもスムーズな体験を提供できるよう、[フォールバックペイウォールの作成](capacitor-use-fallback-paywalls)をおすすめします。 ## ペイウォール表示イベントを記録する \{#track-paywall-view-events\} Adapty はペイウォールのパフォーマンス測定をサポートしています。購入データは自動的に収集されますが、ペイウォールの表示ログはユーザーがいつペイウォールを見たかを把握しているのは開発者だけなので、手動で記録する必要があります。 ペイウォール表示イベントをログに記録するには、`.logShowPaywall(paywall)` を呼び出すだけです。ファネルや A/B テストのペイウォール指標に反映されます。 :::important [ペイウォールビルダー](adapty-paywall-builder)で作成したペイウォールを表示している場合は、`.logShowPaywall(paywall)` を呼び出す必要はありません。 ::: ```typescript showLineNumbers try { await adapty.logShowPaywall({ paywall }); } catch (error) { console.error('Failed to log paywall view:', error); } ``` リクエストパラメーター: | パラメーター | 必須 | 説明 | | :---------- | :------- | :--------------------------------------------------------- | | **paywall** | 必須 | [`AdaptyPaywall`](https://capacitor.adapty.io/interfaces/adaptypaywall) オブジェクト。 | --- # File: capacitor-making-purchases --- --- title: "Capacitor SDKでモバイルアプリ内で購入する" description: "Adaptyを使用してアプリ内課金とサブスクリプションを処理するためのガイド。" --- モバイルアプリ内でペイウォールを表示することは、ユーザーにプレミアムコンテンツやサービスへのアクセスを提供するために不可欠なステップです。ただし、[ペイウォールビルダー](adapty-paywall-builder)を使用してペイウォールをカスタマイズしている場合に限り、ペイウォールを表示するだけで購入をサポートできます。 ペイウォールビルダーを使用していない場合は、購入を完了してコンテンツをアンロックするために、`.makePurchase()` という別のメソッドを使用する必要があります。このメソッドは、ユーザーがペイウォールを操作して希望する取引を進めるためのゲートウェイとして機能します。 ペイウォールに、ユーザーが購入しようとしているプロダクトに対してアクティブなプロモーションオファーがある場合、Adaptyは購入時に自動的にそれを適用します。 [初期設定](quickstart)をすべてのステップをスキップせずに完了していることを確認してください。それがないと、購入を検証できません。 ## 購入する \{#make-purchase\} :::note **[ペイウォールビルダー](adapty-paywall-builder)を使用していますか?** 購入は自動的に処理されるため、このステップはスキップできます。 **ステップバイステップのガイダンスをお探しですか?** 全体的なコンテキストを含むエンドツーエンドの実装手順については、[クイックスタートガイド](capacitor-implement-paywalls-manually)を確認してください。 ::: ```typescript showLineNumbers try { const result = await adapty.makePurchase({ product }); if (result.type === 'success') { const isSubscribed = result.profile?.accessLevels['YOUR_ACCESS_LEVEL']?.isActive; if (isSubscribed) { // Grant access to the paid features console.log('User is now subscribed!'); } } else if (result.type === 'user_cancelled') { console.log('Purchase cancelled by user'); } else if (result.type === 'pending') { console.log('Purchase is pending'); } } catch (error) { console.error('Purchase failed:', error); } ``` リクエストパラメータ: | パラメータ | 必須/任意 | 説明 | | :---------- | :------- |:----------------------------------------------------------------------------------------------------------------------------| | **product** | 必須 | ペイウォールから取得した [`AdaptyPaywallProduct`](https://capacitor.adapty.io/interfaces/adaptypaywallproduct) オブジェクト。 | レスポンスパラメータ: | パラメータ | 説明 | |---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **result** | 購入結果を示す `type` フィールド(`'success'`、`'user_cancelled'`、または `'pending'`)と、購入成功時に更新された [`AdaptyProfile`](https://capacitor.adapty.io/interfaces/adaptyprofile) を含む `profile` フィールドを持つ [`AdaptyPurchaseResult`](https://capacitor.adapty.io/types/adaptypurchaseresult) オブジェクト。 | ## 購入時にサブスクリプションを変更する \{#change-subscription-when-making-a-purchase\} ユーザーが現在のサブスクリプションを更新する代わりに新しいサブスクリプションを選択する場合、その動作はアプリストアによって異なります: - App Storeの場合、サブスクリプションはサブスクリプショングループ内で自動的に更新されます。ユーザーがあるグループのサブスクリプションを購入し、すでに別のグループのサブスクリプションを持っている場合、両方のサブスクリプションが同時にアクティブになります。 - Google Playの場合、サブスクリプションは自動的に更新されません。以下で説明するように、モバイルアプリのコードで切り替えを管理する必要があります。 Androidで別のサブスクリプションに切り替えるには、追加パラメータを指定して `.makePurchase()` メソッドを呼び出します: ```typescript showLineNumbers try { const result = await adapty.makePurchase({ product, params: { android: { subscriptionUpdateParams: { oldSubVendorProductId: 'old_product_id', prorationMode: 'charge_prorated_price' }, isOfferPersonalized: true } } }); if (result.type === 'success') { const isSubscribed = result.profile?.accessLevels['YOUR_ACCESS_LEVEL']?.isActive; if (isSubscribed) { // Grant access to the paid features console.log('Subscription updated successfully!'); } } else if (result.type === 'user_cancelled') { console.log('Purchase cancelled by user'); } else if (result.type === 'pending') { console.log('Purchase is pending'); } } catch (error) { console.error('Purchase failed:', error); } ``` 追加リクエストパラメータ: | パラメータ | 必須/任意 | 説明 | | :--------- | :------- | :----------------------------------------------------------- | | **params** | 任意 | プラットフォーム固有の購入パラメータを含む [`MakePurchaseParamsInput`](https://capacitor.adapty.io/types/makepurchaseparamsinput) 型のオブジェクト。 | `MakePurchaseParamsInput` の構造は以下のとおりです: ```typescript { android: { subscriptionUpdateParams: { oldSubVendorProductId: 'old_product_id', prorationMode: 'charge_prorated_price' }, isOfferPersonalized: true } } ``` サブスクリプションと置き換えモードの詳細については、Google Developerのドキュメントを参照してください: - [置き換えモードについて](https://developer.android.com/google/play/billing/subscriptions#replacement-modes) - [置き換えモードに関するGoogleの推奨事項](https://developer.android.com/google/play/billing/subscriptions#replacement-recommendations) - 置き換えモード [`CHARGE_PRORATED_PRICE`](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.SubscriptionUpdateParams.ReplacementMode#CHARGE_PRORATED_PRICE())。注意: このメソッドはサブスクリプションのアップグレードにのみ使用できます。ダウングレードはサポートされていません。 - 置き換えモード [`DEFERRED`](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.SubscriptionUpdateParams.ReplacementMode#DEFERRED())。注意: 実際のサブスクリプション変更は、現在のサブスクリプションの請求期間が終了した時点でのみ発生します。 ### プリペイドプランの管理(Android) \{#manage-prepaid-plans-android\} アプリユーザーが[プリペイドプラン](https://developer.android.com/google/play/billing/subscriptions#prepaid-plans)(例: 数ヶ月分の非更新型サブスクリプションを購入)を利用できる場合、プリペイドプランに対して[保留中のトランザクション](https://developer.android.com/google/play/billing/subscriptions#pending)を有効にできます。 ```typescript showLineNumbers await adapty.activate({ apiKey: 'YOUR_PUBLIC_SDK_KEY', params: { android: { enablePendingPrepaidPlans: true, }, } }); ``` ## iOSでオファーコードを使う \{#redeem-offer-codes-in-ios\} --- no_index: true --- import Callout from '../../../components/Callout.astro';
オファーコードについて オファーコードを使うと、特定のユーザーに割引や無料トライアルを提供できます。自動的に適用される通常のオファーとは異なり、オファーコードはメールキャンペーン、SNS、印刷物など、アプリの外で配布します。ユーザーはApp Storeでコードを入力するか、引き換えURLを使うか、アプリ内ダイアログから利用できます。 オファーコードを設定するには、App Store Connectでサブスクリプションを開き、**Offer Codes** セクションに移動してください。オファーコードは[3種類](https://developer.apple.com/help/app-store-connect/manage-subscriptions/set-up-subscription-offer-codes)作成できます。 - **Free** — 指定した期間はサブスクリプションが無料になり、次の更新から通常価格になります。 - **Pay as you go** — 指定した期間、各請求サイクルに割引価格が適用され、その後は通常価格で更新されます。 - **Pay up front** — オファー期間全体に対して一括で割引価格を支払い、その後は通常価格で更新されます。 オファーコードをAdaptyに追加する必要はありません。Appleはオファー期間中のすべてのトランザクションにオファーコードカテゴリのタグを付与します。これには最初の引き換えとその後の割引更新がすべて含まれます。Adaptyはこのタグを検出し、各トランザクションをオファーカテゴリ `offer_code` として記録します。オファー期間が終了してサブスクリプションが通常価格で更新されると、タグは付与されなくなります。[Adapty ダッシュボード](controls-filters-grouping-compare-proceeds)のアナリティクスで **Offer Code** オファータイプによるフィルタリングが可能です。 #### 収益の差異が生じた場合のトラブルシューティング \{#revenue-discrepancy-troubleshooting\} オファーコードのトランザクションが、割引価格ではなく通常価格でAdaptyに記録されている場合は、App Store Connectで以下を確認してください。 - オファーコードに、ユーザーが引き換え可能なすべての地域に対して正しい価格が設定されているか。 - ユーザーの特定の国や地域に対してオファー価格が設定されているか。Appleはトランザクションに地域価格を含めて送信します。その地域のオファー価格が設定されていない場合、Appleは通常価格を送信することがあります。 [Adapty ダッシュボード](controls-filters-grouping-compare-proceeds)で、**Offer Code** オファータイプと **Offer Discount Type** フィルターを使ってオファーコードのトランザクションをフィルタリング・確認できます。 #### レガシープロモコード(非推奨) \{#legacy-promo-codes-deprecated\} Appleは2026年3月にアプリ内課金向けのプロモコードを廃止しました。オファーコードはより多くの機能(適格性の設定、有効期限、四半期あたり最大100万コード)を備えた後継機能です。アプリ内課金にプロモコードを使用していた場合は、App Store Connectでオファーコードに移行してください。 レガシープロモコード(アプリのバージョンごとに最大100件)は、サブスクリプションへの無料アクセスを付与していました。オファーコードとは異なり、Appleはプロモコードのトランザクションに割引情報を含めず、レシートには通常価格が記載されていました。そのため、Adaptyはこれらのトランザクションを通常価格で記録し、Adaptyアナリティクスとレポートの間に収益の差異が生じていました。 本来は無料であるべきトランザクションが通常価格で記録されている履歴がある場合、それはレガシープロモコードによるものと考えられます。これらのコードは現在廃止されているため、正確な収益追跡のためにオファーコードに移行してください。
アプリ内でコード引き換えシートを表示するには: ```typescript showLineNumbers try { await adapty.presentCodeRedemptionSheet(); } catch (error) { console.error('Failed to present code redemption sheet:', error); } ``` :::danger 私たちの観察によると、一部のアプリではオファーコード引き換えシートが正常に動作しない場合があります。ユーザーをApp Storeに直接リダイレクトすることをお勧めします。 これを行うには、以下の形式のURLを開く必要があります: `https://apps.apple.com/redeem?ctx=offercodes&id={apple_app_id}&code={code}` ::: --- # File: capacitor-restore-purchase --- --- title: "Capacitor SDK でのアプリ内購入の復元" description: "Adapty で購入を復元してシームレスなユーザー体験を実現する方法を学びましょう。" --- iOS と Android の両方における購入の復元は、ユーザーが再度料金を支払うことなく、サブスクリプションやアプリ内課金などの以前に購入したコンテンツへのアクセスを取り戻せる機能です。この機能は、アプリをアンインストールして再インストールしたり、新しいデバイスに切り替えたりして、以前に購入したコンテンツに再度アクセスしたいユーザーにとって特に便利です。 :::note [ペイウォールビルダー](adapty-paywall-builder)で作成されたペイウォールでは、追加のコードなしに購入が自動的に復元されます。その場合は、このステップをスキップできます。 ::: [ペイウォールビルダー](adapty-paywall-builder)を使用してペイウォールをカスタマイズしていない場合に購入を復元するには、`.restorePurchases()` メソッドを呼び出してください。 ```typescript showLineNumbers try { const profile = await adapty.restorePurchases(); const isSubscribed = profile.accessLevels['YOUR_ACCESS_LEVEL']?.isActive; if (isSubscribed) { // Restore access to paid features console.log('Access restored successfully!'); } else { console.log('No active subscriptions found'); } } catch (error) { console.error('Failed to restore purchases:', error); } ``` レスポンスパラメーター: | パラメーター | 説明 | |---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **profile** | [`AdaptyProfile`](https://capacitor.adapty.io/interfaces/adaptyprofile) オブジェクトです。このモデルには、アクセスレベル、サブスクリプション、および非サブスクリプション購入に関する情報が含まれます。ユーザーがアプリへのアクセス権を持っているかどうかを確認するには、**アクセスレベルのステータス**を確認してください。 | --- # File: implement-observer-mode-capacitor --- --- title: "Capacitor SDKにObserverモードを実装する" description: "Capacitor SDKでAdaptyのオブザーバーモードを実装し、ユーザーのサブスクリプションイベントを追跡します。" --- すでに独自の購入インフラを持っており、Adaptyへの完全な移行に踏み切れない場合は、[Observerモード](observer-vs-full-mode)を検討してみてください。基本的な形では、Observerモードはアトリビューションおよびアナリティクスシステムとの高度な分析とシームレスな統合を提供します。 これで要件を満たせるなら、必要な作業は以下の2点だけです: 1. `observerMode`パラメーターを`true`に設定して、Adapty SDKの設定時にObserverモードをオンにします。[Capacitor](sdk-installation-capacitor#activate-adapty-module-of-adapty-sdk)のセットアップ手順に従ってください。 2. 既存の購入インフラからAdaptyへ[トランザクションを報告](report-transactions-observer-mode-capacitor)します。 ### Observerモードのセットアップ \{#observer-mode-setup\} 購入とサブスクリプションのステータスを自分で管理し、Adaptyをサブスクリプションイベントとアナリティクスの送信にのみ使用する場合は、Observerモードをオンにしてください。 :::important Observerモードで動作している場合、Adapty SDKはトランザクションをクローズしないため、必ず自分でハンドリングするようにしてください。 ::: ```typescript showLineNumbers try { await adapty.activate({ apiKey: 'YOUR_PUBLIC_SDK_KEY', params: { observerMode: true // Enable observer mode } }); } catch (error) { console.error('Failed to activate Adapty:', error); } ``` パラメーター: | パラメーター | 説明 | | --------------------------- | ------------------------------------------------------------ | | **observerMode** | [Observerモード](observer-vs-full-mode)を制御するboolean値です。デフォルト値は`false`です。 | ## ObserverモードでAdaptyのペイウォールを使用する \{#using-adapty-paywalls-in-observer-mode\} Adaptyのペイウォールやオーディエンスベースのターゲティング機能もあわせて利用したい場合は可能ですが、Observerモードでは追加のセットアップが必要です。上記の手順に加えて、以下を行ってください: 1. [リモートコンフィグペイウォール](present-remote-config-paywalls-capacitor)の通常の方法でペイウォールを表示します。 2. 購入トランザクションに[ペイウォールを関連付け](report-transactions-observer-mode-capacitor)ます。 --- # File: report-transactions-observer-mode-capacitor --- --- title: "Capacitor SDKのオブザーバーモードでトランザクションを報告する" description: "Capacitor SDKのAdaptyオブザーバーモードで購入トランザクションを報告し、ユーザーインサイトと収益トラッキングを実現します。" --- オブザーバーモードでは、Adapty SDKは既存の購入システムを通じて行われた購入を自動で追跡できません。アプリストアからのトランザクションを手動で報告する必要があります。アナリティクスのエラーを防ぐため、アプリをリリースする**前に**この設定を行うことが重要です。 `reportTransaction` を使用して、各トランザクションをAdaptyに明示的に報告してください。 :::warning **トランザクションの報告を省略しないでください!** `reportTransaction` を呼び出さないと、Adaptyはトランザクションを認識できず、アナリティクスに表示されず、インテグレーションにも送信されません。 ::: Adaptyのペイウォールを使用している場合は、トランザクションを報告する際に `variationId` を含めてください。これにより、購入がそれを起動したペイウォールに紐付けられ、正確なペイウォールアナリティクスが確保されます。 ```typescript showLineNumbers const variationId = paywall.variationId; try { await adapty.reportTransaction({ transactionId: 'your_transaction_id', variationId: variationId }); } catch (error) { console.error('Failed to report transaction:', error); } ``` パラメーター: | パラメーター | 必須/任意 | 説明 | | ------------- | -------- | ------------------------------------------------------------ | | **transactionId** | 必須 |
  • iOS の場合: トランザクションの識別子。
  • Android の場合: 購入の文字列識別子(`purchase.getOrderId`)。ここで purchase は、ビリングライブラリの [Purchase](https://developer.android.com/reference/com/android/billingclient/api/Purchase) クラスのインスタンスです。
| | **variationId** | 任意 | バリアントの文字列識別子。[AdaptyPaywall](https://capacitor.adapty.io/interfaces/adaptypaywall) オブジェクトの `variationId` プロパティから取得できます。 | --- # File: capacitor-user --- --- title: "Users & access" description: "Learn how to work with users and access levels in your Capacitor app with Adapty SDK." --- --- # File: capacitor-identifying-users --- --- title: "Capacitor SDKでユーザーを識別する" description: "Adapty SDKを使用してCapacitorアプリでユーザーを識別する方法を学びます。" --- Adaptyはすべてのユーザーに対して内部プロファイルIDを作成します。ただし、独自の認証システムを持っている場合は、独自のCustomer User IDを設定することができます。[Profiles](profiles-crm)セクションでCustomer User IDによりユーザーを検索したり、すべてのインテグレーションに送信される[サーバーサイドAPI](getting-started-with-server-side-api)で使用したりできます。 ### 設定時にCustomer User IDを設定する \{#setting-customer-user-id-on-configuration\} 設定時にユーザーIDがある場合は、`.activate()`メソッドの`customerUserId`パラメーターとして渡すだけです: ```typescript showLineNumbers try { await adapty.activate({ apiKey: 'YOUR_PUBLIC_SDK_KEY', params: { customerUserId: 'YOUR_USER_ID' } }); } catch (error) { console.error('Failed to activate Adapty:', error); } ``` ### 設定後にCustomer User IDを設定する \{#setting-customer-user-id-after-configuration\} SDKの設定時にユーザーIDがない場合は、`.identify()`メソッドを使っていつでも後から設定できます。このメソッドの最も一般的なユースケースは、ユーザーが匿名ユーザーから認証済みユーザーに切り替わる際の登録後または認証後です。 ```typescript showLineNumbers try { await adapty.identify({ customerUserId: 'YOUR_USER_ID' }); console.log('User identified successfully'); } catch (error) { console.error('Failed to identify user:', error); } ``` リクエストパラメーター: | パラメーター | 必須/任意 | 説明 | |---------|--------|-----------| | **customerUserId** | 必須 | 文字列のユーザー識別子。 | :::warning 重要なユーザーデータの再送信 ユーザーが再度アカウントにログインする場合など、Adaptyのサーバーにすでにそのユーザーの情報が存在していることがあります。このような場合、Adapty SDKは自動的に新しいユーザーに切り替えて動作します。カスタム属性やサードパーティネットワークからのアトリビューションなど、匿名ユーザーに渡したデータがある場合は、識別されたユーザーに対してそのデータを再送信する必要があります。 また、新しいユーザーのデータが異なる可能性があるため、ユーザーを識別した後にすべてのペイウォールとプロダクトを再取得する必要があることも重要です。 ::: ### ログアウトとログイン \{#logging-out-and-logging-in\} `.logout()`メソッドを呼び出すことで、いつでもユーザーをログアウトできます: ```typescript showLineNumbers try { await adapty.logout(); console.log('User logged out successfully'); } catch (error) { console.error('Failed to logout user:', error); } ``` その後、`.identify()`メソッドを使ってユーザーをログインできます。 ## `appAccountToken`を設定する(iOS) \{#assign-appaccounttoken-ios\} [`appAccountToken`](https://developer.apple.com/documentation/storekit/product/purchaseoption/appaccounttoken(_:))は、App Storeのトランザクションを内部ユーザーIDにリンクするための**UUID**です。 StoreKitはこのトークンをすべてのトランザクションに関連付けるため、バックエンドがApp StoreのデータをユーザーIDと照合できます。 ユーザーごとに生成した安定したUUIDを使用し、同じアカウントに対してデバイスをまたいで再利用してください。 これにより、購入とApp Storeの通知が正しく紐付けられます。 トークンは2つの方法で設定できます。SDKのアクティベーション時、またはユーザーを識別する際です。 :::important `appAccountToken`は必ず`customerUserId`と一緒に渡す必要があります。 トークンのみを渡した場合、トランザクションに含まれません。 ::: ```typescript showLineNumbers // During configuration: await adapty.activate({ apiKey: 'YOUR_PUBLIC_SDK_KEY', params: { customerUserId: 'YOUR_USER_ID', ios: { appAccountToken: "YOUR_APP_ACCOUNT_TOKEN" }, } }); // Or when identifying users await adapty.identify({ customerUserId: 'YOUR_USER_ID', params: { ios: { appAccountToken: 'YOUR_APP_ACCOUNT_TOKEN' }, } }); ``` ### 難読化されたアカウントIDを設定する(Android) \{#set-obfuscated-account-ids-android\} Google Playでは、ユーザーのプライバシーとセキュリティを強化するために、特定のユースケースで難読化されたアカウントIDが必要です。これらのIDにより、Google Playはユーザー情報を匿名のまま購入を識別できます。これは不正防止や分析において特に重要です。 アプリが機密性の高いユーザーデータを扱う場合や、特定のプライバシー規制に準拠する必要がある場合は、これらのIDを設定する必要があります。難読化されたIDにより、Google Playは実際のユーザー識別子を公開せずに購入を追跡できます。 ```typescript showLineNumbers // During configuration: await adapty.activate({ apiKey: 'YOUR_PUBLIC_SDK_KEY', params: { android: { obfuscatedAccountId: 'YOUR_OBFUSCATED_ACCOUNT_ID' }, } }); // Or when identifying users await adapty.identify({ customerUserId: 'YOUR_USER_ID', params: { android: { obfuscatedAccountId: 'YOUR_OBFUSCATED_ACCOUNT_ID' }, } }); ``` ## デバイスをまたいだユーザー検出 \{#detect-users-across-devices\} --- no_index: true --- SDKが有効化されると、StoreKit(iOS)またはGoogle Play Billing(Android)からユーザーの既存のエンタイトルメントを自動的に読み取り、Adaptyバックエンドと同期します。有効なサブスクリプションは、アプリが`restorePurchases`を呼び出すことなく、Adaptyプロファイルに表示されます。 **自動では行われない**のは、新しいデバイスのプロファイルが元のデバイスと同じユーザーのものであることの認識です。AdaptyはCustomer User IDでプロファイルを照合するため、同一性の継続性はCUIDとして何を使用するかによって異なります。 **デバイス間でAdaptyが検出できること** | あなたの設定 | Adaptyが検出すること | 必要な対応 | | --- | --- | --- | | Customer User ID = `device_id`(アプリのログインなし) | 新しいデバイスは異なるCUIDを取得するため、異なるプロファイルが作成されます。サブスクリプションは**Access level updated**イベントを通じて新しいプロファイルに同期されますが、`subscription_started`は発火しません。新しいプロファイルは元の購入の継承者として扱われます。`subscription_started`に基づくアナリティクスは、リターニングユーザーをカウント不足します。 | リターニングユーザーが既存のプロファイルをデバイス間で照合できるよう、安定したアカウントIDをCustomer User IDとして使用してください。 | | Customer User ID = 安定したアカウントID(すべてのデバイスでログイン) | SDKは`activate()`でサブスクリプションを自動同期し、`identify()`がCUIDで既存のプロファイルを照合します。 | 追加の設定は不要です。IDとサブスクリプションの両方が自動的に解決されます。 | | Apple Family Sharing の継承者 | ファミリーメンバーは**Access level updated**イベントのみを通じてサブスクリプションを受け取ります。`subscription_started`は発火しません。 | **Access level updated**をリッスンしてください。完全なイベントマトリクスは[Apple Family Sharing](apple-family-sharing)を参照してください。 | | 同じApple/Googleアカウント、異なるアプリ内ユーザー | 最初に購入を記録したプロファイルが親になります。その後のプロファイルは継承者チェーンを通じてサブスクリプションを確認し、**Access level updated**イベントが1回発生します。 | ログインを必須にし、あなたのモデルに合った[共有モード](sharing-paid-access-between-user-accounts)を選択してください。 | **新しいデバイスでの購入の復元** ペイウォールにユーザーが操作できる「購入を復元」ボタンを設置してください。Apple App Review(ガイドライン3.1.1)で必須とされており、自動同期がエッジケースを見逃した場合のフォールバックとして機能します。このボタンはSDKの`restorePurchases`を呼び出す必要があります。 初回起動時にプログラムで`restorePurchases`を呼び出すことは、通常の使用では必要ありません。SDKはすでに`activate()`で同等の処理を実行しています。プログラムによる呼び出しは、`activate()`完了後にアクセスが欠落している場合のデバッグなど、強制的に新しいレシートチェックを行う場合にのみ使用してください。 --- # File: capacitor-setting-user-attributes --- --- title: "Capacitor SDKでユーザー属性を設定する" description: "Adapty SDKを使ってCapacitorアプリでユーザー属性とプロファイルデータを更新する方法を解説します。" --- メールアドレスや電話番号など、アプリのユーザーにオプションの属性を設定できます。設定した属性は、ユーザーの[セグメント](segments)作成やCRMでの閲覧に活用できます。 ### ユーザー属性の設定 \{#setting-user-attributes\} ユーザー属性を設定するには、`.updateProfile()` メソッドを呼び出します: ```typescript showLineNumbers const params = { email: 'email@email.com', phoneNumber: '+18888888888', firstName: 'John', lastName: 'Appleseed', gender: 'other', birthday: new Date().toISOString(), }; try { await adapty.updateProfile(params); console.log('Profile updated successfully'); } catch (error) { console.error('Failed to update profile:', error); } ``` `updateProfile` メソッドで以前に設定した属性はリセットされないのでご注意ください。 :::tip Adapty SDK がモバイルアプリにどのように統合されているか、実際の例を見てみませんか?ペイウォールの表示、購入処理、その他の基本機能を含む完全なセットアップを実演している[サンプルアプリ](sample-apps)をご覧ください。 ::: ### 使用可能なキーの一覧 \{#the-allowed-keys-list\} `AdaptyProfileParameters` で使用可能なキーとその値は以下の通りです: | キー | 値 | |---|-----| | **email** | 文字列 | | **phoneNumber** | 文字列 | | **firstName** | 文字列 | | **lastName** | 文字列 | | **gender** | 列挙型。使用可能な値: `'female'`、`'male'`、`'other'` | | **birthday** | ISO形式の日付文字列 | ### カスタムユーザー属性 \{#custom-user-attributes\} 独自のカスタム属性を設定することもできます。通常、アプリの利用状況に関連するものです。たとえば、フィットネスアプリなら週あたりの運動回数、語学学習アプリならユーザーの習熟度レベルなどが該当します。セグメントに活用してターゲットを絞ったペイウォールやオファーを作成したり、収益に最も影響を与えるプロダクト指標を分析することもできます。 ```typescript showLineNumbers try { await adapty.updateProfile({ codableCustomAttributes: { key_1: 'value_1', key_2: 2, }, }); console.log('Custom attributes updated successfully'); } catch (error) { console.error('Failed to update custom attributes:', error); } ``` 既存のキーを削除するには、値として `null` を渡します: ```typescript showLineNumbers try { // to remove keys, pass null as their values await adapty.updateProfile({ codableCustomAttributes: { key_1: null, key_2: null, }, }); console.log('Custom attributes removed successfully'); } catch (error) { console.error('Failed to remove custom attributes:', error); } ``` 事前に設定されているカスタム属性を確認したい場合は、`AdaptyProfile` オブジェクトの `customAttributes` フィールドを使用してください。 :::warning `customAttributes` の値は最新でない可能性があります。ユーザー属性は異なるデバイスからいつでも送信される可能性があるため、最後の同期以降にサーバー上の属性が変更されている場合があります。 ::: ### 制限事項 \{#limits\} - ユーザーあたり最大30個のカスタム属性 - キー名は最大30文字。使用できる文字は英数字と `_`、`-`、`.` のいずれか - 値は文字列または浮動小数点数で、50文字以内 --- # File: capacitor-listen-subscription-changes --- --- title: "Capacitor SDKでサブスクリプションステータスを確認する" description: "Capacitorアプリでのユーザーサブスクリプションステータスの追跡と管理により、Adaptyでの顧客維持率を向上させましょう。" --- Adaptyを使えば、サブスクリプションステータスの管理が簡単になります。プロダクトIDをコードに手動で記述する必要はありません。代わりに、有効な[アクセスレベル](access-level)を確認するだけで、ユーザーのサブスクリプションステータスを手軽に把握できます。
サブスクリプションステータスの確認を始める前に(クリックして展開) - iOSの場合は、[App Store Server Notifications](enable-app-store-server-notifications)を設定してください - Androidの場合は、[リアルタイムデベロッパー通知(RTDN)](enable-real-time-developer-notifications-rtdn)を設定してください
## アクセスレベルとAdaptyProfileオブジェクト \{#access-level-and-the-adaptyprofile-object\} アクセスレベルは[AdaptyProfile](https://capacitor.adapty.io/interfaces/adaptyprofile)オブジェクトのプロパティです。アプリの起動時(たとえば[ユーザーを識別する](capacitor-identifying-users#setting-customer-user-id-on-configuration)タイミング)にプロファイルを取得し、変更があるたびに更新することをお勧めします。こうすることで、都度リクエストを送ることなくプロファイルオブジェクトを利用できます。 プロファイルの更新通知を受け取るには、以下の[サブスクリプションステータス更新のリッスン](capacitor-listen-subscription-changes)セクションで説明している方法でプロファイルの変更をリッスンしてください。 :::tip Adapty SDK がモバイルアプリにどのように統合されているか、実際の例を見てみませんか?ペイウォールの表示、購入処理、その他の基本機能を含む完全なセットアップを実演している[サンプルアプリ](sample-apps)をご覧ください。 ::: ## サーバーからアクセスレベルを取得する \{#retrieving-the-access-level-from-the-server\} サーバーからアクセスレベルを取得するには、`.getProfile()`メソッドを使用します。 ```typescript showLineNumbers try { const profile = await adapty.getProfile(); console.log('Profile retrieved successfully'); } catch (error) { console.error('Failed to get profile:', error); } ``` レスポンスパラメーター: | パラメーター | 説明 | | --------- |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **profile** | [AdaptyProfile](https://capacitor.adapty.io/interfaces/adaptyprofile)オブジェクト。通常、ユーザーがプレミアムアクセス権を持っているかどうかを判断するには、プロファイルのアクセスレベルステータスのみを確認すれば十分です。`.getProfile`メソッドは常にAPIに問い合わせるため、最新の結果を提供します。何らかの理由(インターネット接続なし等)でAdapty SDKがサーバーから情報を取得できない場合は、キャッシュのデータが返されます。なお、Adapty SDKは`AdaptyProfile`キャッシュを定期的に更新し、情報をできる限り最新の状態に保ちます。 | `.getProfile()`メソッドはユーザープロファイルを返し、そこからアクセスレベルのステータスを取得できます。アプリごとに複数のアクセスレベルを設定できます。たとえばニュースアプリで異なるトピックのサブスクリプションを個別に販売する場合、「sports」や「science」といったアクセスレベルを作成できます。ただし、ほとんどの場合はアクセスレベルは1つで十分です。その場合はデフォルトの「premium」アクセスレベルをそのまま使用できます。 デフォルトの「premium」アクセスレベルを確認する例を以下に示します。 ```typescript showLineNumbers try { const profile = await adapty.getProfile(); const isActive = profile.accessLevels['premium']?.isActive; if (isActive) { // Grant access to premium features console.log('User has premium access'); } else { console.log('User does not have premium access'); } } catch (error) { console.error('Failed to check subscription status:', error); } ``` ### サブスクリプションステータスの更新をリッスンする \{#listening-for-subscription-status-updates\} ユーザーのサブスクリプションが変更されると、Adaptyはイベントを発火します。 Adaptyからメッセージを受け取るには、追加の設定が必要です。 ```typescript showLineNumbers // Create an "onLatestProfileLoad" event listener adapty.addListener('onLatestProfileLoad', (data) => { const profile = data.profile; const isActive = profile.accessLevels['premium']?.isActive; if (isActive) { console.log('Subscription status updated: User has premium access'); } else { console.log('Subscription status updated: User does not have premium access'); } }); ``` Adaptyはアプリ起動時にもイベントを発火します。この場合、キャッシュされたサブスクリプションステータスが渡されます。 ### サブスクリプションステータスのキャッシュ \{#subscription-status-cache\} Adapty SDKに実装されたキャッシュは、プロファイルのサブスクリプションステータスを保存します。これにより、サーバーが利用できない場合でもキャッシュデータにアクセスでき、プロファイルのサブスクリプションステータスに関する情報を提供できます。 ただし、キャッシュからデータを直接リクエストすることはできません。SDKは1分ごとに定期的にサーバーへ問い合わせ、プロファイルに関する更新や変更がないかチェックします。新しいトランザクションなどの変更があれば、サーバーと同期を保つためにキャッシュデータへ反映されます。 --- # File: capacitor-deal-with-att --- --- title: "Capacitor SDK で ATT を処理する" description: "Capacitor で Adapty を使い始めて、サブスクリプションの設定と管理を効率化しましょう。" --- アプリが AppTrackingTransparency フレームワークを使用してアプリトラッキングの認証リクエストをユーザーに表示している場合は、[認証ステータス](https://developer.apple.com/documentation/apptrackingtransparency/attrackingmanager/authorizationstatus/)を Adapty に送信する必要があります。 ```typescript showLineNumbers try { await adapty.updateProfile({ appTrackingTransparencyStatus: AppTrackingTransparencyStatus.Authorized, }); console.log('ATT status updated successfully'); } catch (error) { console.error('Failed to update ATT status:', error); } ``` :::warning この値は変更があった際にできるだけ早く送信することを強くお勧めします。そうすることで、設定済みのインテグレーションにタイムリーにデータが送信されます。 ::: --- # File: capacitor-onboardings --- --- title: "Onboardings" description: "Learn how to work with onboardings in your Capacitor app with Adapty SDK." --- --- # File: capacitor-get-onboardings --- --- title: "Capacitor SDK でオンボーディングを取得する" description: "Capacitor 向け Adapty でオンボーディングを取得する方法を説明します。" --- Adapty ダッシュボードのビルダーで[オンボーディングのビジュアルをデザイン](design-onboarding)したら、Capacitor アプリに表示できます。最初のステップは、プレースメントに紐づくオンボーディングとそのビュー設定を取得することです。 始める前に、以下を確認してください: 1. [オンボーディングを作成](create-onboarding)済みであること。 2. オンボーディングを[プレースメント](placements)に追加済みであること。 ## オンボーディングの取得 \{#fetch-onboarding\} ノーコードビルダーで[オンボーディング](onboardings)を作成すると、アプリが取得・表示する必要のある設定コンテナとして保存されます。このコンテナはコンテンツの内容・表示方法・ユーザー操作(クイズの回答やフォーム入力など)の処理方法を含む、エクスペリエンス全体を管理します。また、分析イベントを自動的に追跡するため、個別のビュートラッキングを実装する必要はありません。 パフォーマンスを最適化するため、ユーザーに表示する前に画像のダウンロードが完了するよう、早めにオンボーディング設定を取得してください。 オンボーディングを取得するには、`getOnboarding` メソッドを使用します: ```typescript showLineNumbers try { const onboarding = await adapty.getOnboarding({ placementId: 'YOUR_PLACEMENT_ID', locale: 'en', params: { fetchPolicy: 'reload_revalidating_cache_data', // サーバーから読み込み、失敗時はキャッシュを使用 loadTimeoutMs: 5000 // 5秒タイムアウト } }); console.log('Onboarding fetched successfully'); } catch (error) { console.error('Failed to fetch onboarding:', error); } ``` 次に、`createOnboardingView` メソッドを呼び出してビューインスタンスを作成します。 :::warning `createOnboardingView` メソッドの結果は一度しか使用できません。再度使用する必要がある場合は、`createOnboardingView` メソッドを新たに呼び出してください。 ::: ```typescript showLineNumbers if (onboarding.hasViewConfiguration) { try { const view = await createOnboardingView(onboarding); console.log('Onboarding view created successfully'); } catch (error) { console.error('Failed to create onboarding view:', error); } } else { // Use your custom logic console.log('Onboarding does not have view configuration'); } ``` パラメーター: | パラメーター | 必須 / 任意 | 説明 | |---------|--------|-----------| | **placementId** | 必須 | 目的の[プレースメント](placements)の識別子。Adapty ダッシュボードでプレースメントを作成した際に指定した値です。 | | **locale** |

任意

デフォルト: `en`

|

オンボーディングのローカライズ識別子。マイナス(**-**)区切りの 1 つまたは 2 つのサブタグで構成される言語コードを指定します。最初のサブタグは言語、2 番目は地域を表します。

例:`en` は英語、`pt-br` はブラジルポルトガル語を表します。

ロケールコードと推奨利用方法については、[ローカライズとロケールコード](localizations-and-locale-codes)を参照してください。

| | **params.fetchPolicy** |

任意

デフォルト: `'reload_revalidating_cache_data'`

|

デフォルトでは、SDK はサーバーからデータの読み込みを試み、失敗した場合はキャッシュデータを返します。常に最新データをユーザーに提供できるため、このオプションを推奨します。

ユーザーのインターネット接続が不安定だと思われる場合は、`'return_cache_data_else_load'` を使用すると、キャッシュが存在する場合はキャッシュデータを返します。この場合、最新データが得られないことがありますが、接続状況によらず読み込みが速くなります。キャッシュは定期的に更新されるため、セッション中にネットワークリクエストを避けるために使用しても安全です。

キャッシュはアプリを再起動しても保持され、アプリの再インストールまたは手動でのクリーンアップ時にのみ削除されます。

| | **params.loadTimeoutMs** |

任意

デフォルト: 5000 ms

|

このメソッドのタイムアウト(ミリ秒)を制限します。タイムアウトに達した場合、キャッシュデータまたはローカルフォールバックが返されます。

内部で複数のリクエストが発生する場合があるため、まれに `loadTimeoutMs` で指定した時間より少し遅くタイムアウトすることがあります。

| レスポンスパラメーター: | パラメーター | 説明 | |:----------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **onboarding** | オンボーディングの識別子・設定・リモートコンフィグなどを含む [`AdaptyOnboarding`](https://capacitor.adapty.io/interfaces/adaptyonboarding) オブジェクト。 | ## デフォルトオーディエンスオンボーディングで取得を高速化する \{#speed-up-onboarding-fetching-with-default-audience-onboarding\} 通常、オンボーディングはほぼ瞬時に取得されるため、このプロセスを速くすることを特に意識する必要はありません。ただし、オーディエンスやオンボーディングが多数あり、ユーザーのインターネット接続が弱い場合は、取得に時間がかかることがあります。そのような場合、オンボーディングを全く表示しないよりも、デフォルトのオンボーディングを表示してスムーズなユーザー体験を提供したいことがあるでしょう。 この場合、`getOnboardingForDefaultAudience` メソッドを使用できます。このメソッドは、指定したプレースメントの **All Users** オーディエンス向けオンボーディングを取得します。ただし、推奨される方法は[オンボーディングの取得](#fetch-onboarding)セクションで説明した `getOnboarding` メソッドを使用することです。 :::warning `getOnboardingForDefaultAudience` の代わりに `getOnboarding` の使用を検討してください。前者には以下の重要な制限があります: - **互換性の問題**:複数のアプリバージョンをサポートする際に問題が生じる可能性があり、後方互換性のあるデザインが必要になるか、古いバージョンで正しく表示されないことを受け入れる必要があります。 - **パーソナライズなし**:「All Users」オーディエンス向けのコンテンツのみ表示され、国・アトリビューション・カスタム属性に基づくターゲティングは行われません。 取得速度の向上がこれらのデメリットを上回る場合は、以下のように `getOnboardingForDefaultAudience` を使用してください。そうでない場合は、[上記](#fetch-onboarding)の `getOnboarding` を使用してください。 ::: ```typescript showLineNumbers try { const onboarding = await adapty.getOnboardingForDefaultAudience({ placementId: 'YOUR_PLACEMENT_ID', locale: 'en', params: { fetchPolicy: 'reload_revalidating_cache_data' // サーバーから読み込み、失敗時はキャッシュを使用 } }); console.log('Default audience onboarding fetched successfully'); } catch (error) { console.error('Failed to fetch default audience onboarding:', error); } ``` パラメーター: | パラメーター | 必須 / 任意 | 説明 | |---------|--------|-----------| | **placementId** | 必須 | 目的の[プレースメント](placements)の識別子。Adapty ダッシュボードでプレースメントを作成した際に指定した値です。 | | **locale** |

任意

デフォルト: `en`

|

オンボーディングのローカライズ識別子。マイナス(**-**)区切りの 1 つまたは 2 つのサブタグで構成される言語コードを指定します。最初のサブタグは言語、2 番目は地域を表します。

例:`en` は英語、`pt-br` はブラジルポルトガル語を表します。

ロケールコードと推奨利用方法については、[ローカライズとロケールコード](localizations-and-locale-codes)を参照してください。

| | **params.fetchPolicy** |

任意

デフォルト: `'reload_revalidating_cache_data'`

|

デフォルトでは、SDK はサーバーからデータの読み込みを試み、失敗した場合はキャッシュデータを返します。常に最新データをユーザーに提供できるため、このオプションを推奨します。

ユーザーのインターネット接続が不安定だと思われる場合は、`'return_cache_data_else_load'` を使用すると、キャッシュが存在する場合はキャッシュデータを返します。この場合、最新データが得られないことがありますが、接続状況によらず読み込みが速くなります。キャッシュは定期的に更新されるため、セッション中にネットワークリクエストを避けるために使用しても安全です。

キャッシュはアプリを再起動しても保持され、アプリの再インストールまたは手動でのクリーンアップ時にのみ削除されます。

| --- # File: capacitor-present-onboardings --- --- title: "Capacitor SDKでのオンボーディングの表示" description: "Capacitorでオンボーディングを表示してコンバージョンと収益を向上させる方法をご紹介します。" --- ビルダーでオンボーディングをカスタマイズした場合、ユーザーに表示するためにモバイルアプリのコードでレンダリングを行う必要はありません。そのようなオンボーディングには、オンボーディング内で表示される内容とその表示方法が両方含まれています。 始める前に、以下を確認してください: 1. [オンボーディングを作成](create-onboarding)している。 2. オンボーディングを[プレースメント](placements)に追加している。 ## オンボーディングを表示する \{#present-onboarding\} オンボーディングを表示するには、`createOnboardingView` メソッドで作成した `view` に対して `view.present()` メソッドを使用します。各 `view` は一度しか使用できません。オンボーディングを再度表示する必要がある場合は、`createOnboardingView` をもう一度呼び出して新しい `view` インスタンスを作成してください。 :::warning `view` を再作成せずに再利用するとエラーが発生する可能性があります。 ::: ```typescript showLineNumbers try { const view = await createOnboardingView(onboarding); view.setEventHandlers({ onClose: (actionId, meta) => { console.log('Onboarding closed:', actionId); return true; // Allow the onboarding to close }, onCustom: (actionId, meta) => { console.log('Custom action:', actionId); return false; // Don't close the onboarding } }); await view.present(); console.log('Onboarding presented successfully'); } catch (error) { console.error('Failed to present onboarding:', error); } ``` ## iOSの表示スタイルを設定する \{#configure-ios-presentation-style\} `present()` メソッドに `iosPresentationStyle` パラメーターを渡すことで、iOSでのオンボーディングの表示方法を設定できます。このパラメーターには `'full_screen'`(デフォルト)または `'page_sheet'` を指定できます。 ```typescript showLineNumbers await view.present({ iosPresentationStyle: 'page_sheet' }); ``` ## オンボーディング内のリンクの開き方をカスタマイズする \{#customize-how-links-open-in-onboardings\} :::important オンボーディング内のリンクの開き方のカスタマイズは、Adapty SDK v3.15以降でサポートされています。 ::: デフォルトでは、オンボーディング内のリンクはアプリ内ブラウザで開きます。これにより、ユーザーがアプリを切り替えることなくアプリ内でウェブページを閲覧できるシームレスなユーザー体験が提供されます。 外部ブラウザでリンクを開くことを希望する場合は、`openIn` パラメーターを `browser_out_app` に設定することでこの動作をカスタマイズできます: ```typescript showLineNumbers await view.present({ openIn: 'browser_out_app' }); // default — browser_in_app ``` ## 次のステップ \{#next-steps\} オンボーディングを表示したら、[ユーザーのインタラクションとイベントを処理](capacitor-handling-onboarding-events)しましょう。オンボーディングイベントの処理方法を学んで、ユーザーのアクションに応答し、アナリティクスを追跡してください。 --- # File: capacitor-handling-onboarding-events --- --- title: "Capacitor SDKでオンボーディングイベントを処理する" description: "Adaptyを使用してCapacitorでオンボーディング関連のイベントを処理します。" --- ビルダーで設定されたオンボーディングは、アプリが応答できるイベントを生成します。スタンドアロン画面の表示でこれらのイベントを処理するには、`setEventHandlers` メソッドを使用してください。 始める前に、以下を確認してください: 1. [オンボーディングを作成](create-onboarding)済みであること。 2. オンボーディングを[プレースメント](placements)に追加済みであること。 ## イベントハンドラーの設定 \{#set-up-event-handlers\} オンボーディングのイベントを処理するには、`view.setEventHandlers` メソッドを使用します: ```typescript showLineNumbers try { const view = await createOnboardingView(onboarding); view.setEventHandlers({ onAnalytics(event, meta) { console.log('Analytics event:', event); }, onClose(actionId, meta) { console.log('Onboarding closed:', actionId); return true; // Allow the onboarding to close }, onCustom(actionId, meta) { console.log('Custom action:', actionId); return false; // Don't close the onboarding }, onPaywall(actionId, meta) { console.log('Paywall action:', actionId); view.dismiss().then(() => { openPaywall(actionId); }); }, onStateUpdated(action, meta) { console.log('State updated:', action); }, onFinishedLoading(meta) { console.log('Onboarding finished loading'); }, onError(error) { console.error('Onboarding error:', error); }, }); await view.present(); } catch (error) { console.error('Failed to present onboarding:', error); } ``` ## イベントの種類 \{#event-types\} 以下のセクションでは、処理できるさまざまなイベントの種類を説明します。 ### カスタムアクションの処理 \{#handle-custom-actions\} ビルダーでボタンに **custom** アクションを追加し、IDを割り当てることができます。 このIDをコード内で使用し、カスタムアクションとして処理できます。たとえば、ユーザーが **Login** や **Allow notifications** などのカスタムボタンをタップすると、ビルダーの **Action ID** と一致する `actionId` パラメーターを持つイベントハンドラーがトリガーされます。"allowNotifications" のような独自のIDを作成できます。 ```typescript showLineNumbers view.setEventHandlers({ onCustom(actionId, meta) { switch (actionId) { case 'login': console.log('Login action triggered'); break; case 'allow_notifications': console.log('Allow notifications action triggered'); break; } return false; // Don't close the onboarding }, }); ```
イベントの例(クリックして展開) ```json { "actionId": "allow_notifications", "meta": { "onboardingId": "onboarding_123", "screenClientId": "profile_screen", "screenIndex": 0, "screensTotal": 3 } } ```
### オンボーディングの読み込み完了 \{#finishing-loading-onboarding\} オンボーディングの読み込みが完了すると、このイベントがトリガーされます: ```typescript showLineNumbers view.setEventHandlers({ onFinishedLoading(meta) { console.log('Onboarding loaded:', meta.onboardingId); }, }); ```
イベントの例(クリックして展開) ```json { "meta": { "onboarding_id": "onboarding_123", "screen_cid": "welcome_screen", "screen_index": 0, "total_screens": 4 } } ```
### オンボーディングを閉じる \{#closing-onboarding\} ユーザーが **Close** アクションが割り当てられたボタンをタップすると、オンボーディングは閉じられたと見なされます。 :::important ユーザーがオンボーディングを閉じたときに何が起こるかを自分で管理する必要があります。たとえば、オンボーディング自体の表示を停止する必要があります。 ::: ```typescript showLineNumbers view.setEventHandlers({ onClose(actionId, meta) { console.log('Onboarding closed:', actionId); return true; // Allow the onboarding to close }, }); ```
イベントの例(クリックして展開) ```json { "action_id": "close_button", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "final_screen", "screen_index": 3, "total_screens": 4 } } ```
### ペイウォールを開く \{#opening-a-paywall\} :::tip オンボーディング内でペイウォールを開きたい場合は、このイベントを処理してください。オンボーディングが閉じた後にペイウォールを開きたい場合は、クローズアクションを処理してイベントデータに依存せずにペイウォールを開く、よりシンプルな方法があります。 ::: オンボーディングでペイウォールを扱う最もシームレスな方法は、アクションIDをペイウォールのプレースメントIDと同じにすることです。 iOSでは、一度に1つのビュー(ペイウォールまたはオンボーディング)のみ画面に表示できることに注意してください。オンボーディングの上にペイウォールを表示する場合、バックグラウンドのオンボーディングをプログラムで操作することはできません。オンボーディングを閉じようとすると、代わりにペイウォールが閉じられ、オンボーディングが残ったままになります。これを避けるために、ペイウォールを表示する前に必ずオンボーディングビューを閉じてください。 ```typescript showLineNumbers view.setEventHandlers({ onPaywall(actionId, meta) { // Dismiss onboarding before presenting paywall view.dismiss().then(() => { openPaywall(actionId); }); }, }); async function openPaywall(placementId: string) { // Implement your paywall opening logic here } ```
イベントの例(クリックして展開) ```json { "action_id": "premium_offer_1", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "pricing_screen", "screen_index": 2, "total_screens": 4 } } ```
### ナビゲーションのトラッキング \{#tracking-navigation\} オンボーディングフロー中にさまざまなナビゲーション関連イベントが発生すると、アナリティクスイベントを受け取ります: ```typescript showLineNumbers view.setEventHandlers({ onAnalytics(event, meta) { console.log('Analytics event:', event.type, meta.onboardingId); }, }); ``` `event` オブジェクトは以下のいずれかの種類になります: |種類 | 説明 | |------------|-------------| | `onboardingStarted` | オンボーディングが読み込まれたとき | | `screenPresented` | 任意の画面が表示されたとき | | `screenCompleted` | 画面が完了したとき。オプションの `elementId`(完了した要素の識別子)とオプションの `reply`(ユーザーからの応答)を含む。ユーザーが画面を離れるアクションを実行したときにトリガーされる。 | | `secondScreenPresented` | 2番目の画面が表示されたとき | | `userEmailCollected` | 入力フィールドでユーザーのメールアドレスが収集されたときにトリガーされる | | `onboardingCompleted` | ユーザーが `final` IDを持つ画面に到達したときにトリガーされる。このイベントが必要な場合は、[最後の画面に `final` IDを割り当ててください](design-onboarding)。 | | `unknown` | 認識されないイベントタイプの場合。`name`(不明なイベントの名前)と `meta`(追加のメタデータ)を含む | 各イベントには以下の `meta` 情報が含まれます: | フィールド | 説明 | |------------|-------------| | `onboardingId` | オンボーディングフローの一意の識別子 | | `screenClientId` | 現在の画面の識別子 | | `screenIndex` | フロー内での現在の画面の位置 | | `screensTotal` | フロー内の画面の総数 |
イベントの例(クリックして展開) ```javascript // onboardingStarted { "name": "onboarding_started", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "welcome_screen", "screen_index": 0, "total_screens": 4 } } // screenPresented { "name": "screen_presented", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "interests_screen", "screen_index": 2, "total_screens": 4 } } // screenCompleted { "name": "screen_completed", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "profile_screen", "screen_index": 1, "total_screens": 4 }, "params": { "element_id": "profile_form", "reply": "success" } } // secondScreenPresented { "name": "second_screen_presented", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "profile_screen", "screen_index": 1, "total_screens": 4 } } // userEmailCollected { "name": "user_email_collected", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "profile_screen", "screen_index": 1, "total_screens": 4 } } // onboardingCompleted { "name": "onboarding_completed", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "final_screen", "screen_index": 3, "total_screens": 4 } } ```
--- # File: capacitor-onboarding-input --- --- title: "Capacitor SDKでオンボーディングのデータを処理する" description: "Adapty SDKを使ってCapacitorアプリのオンボーディングからデータを保存・活用する方法。" --- ユーザーがクイズに回答したり入力フィールドにデータを入力したりすると、`onStateUpdatedAction` メソッドが呼び出されます。コード内でフィールドの種類を保存したり処理したりできます。 例: ```typescript view.setEventHandlers({ onStateUpdated(action, meta) { // Process data }, }); ``` アクションのフォーマットは[こちら](https://capacitor.adapty.io/types/onboardingstateupdatedaction)をご覧ください。
保存データの例(実装によってフォーマットが異なる場合があります) ```javascript // Example of a saved select action { "elementId": "preference_selector", "meta": { "onboardingId": "onboarding_123", "screenClientId": "preferences_screen", "screenIndex": 1, "screensTotal": 3 }, "params": { "type": "select", "value": { "id": "option_1", "value": "premium", "label": "Premium Plan" } } } // Example of a saved multi-select action { "elementId": "interests_selector", "meta": { "onboardingId": "onboarding_123", "screenClientId": "interests_screen", "screenIndex": 2, "screensTotal": 3 }, "params": { "type": "multiSelect", "value": [ { "id": "interest_1", "value": "sports", "label": "Sports" }, { "id": "interest_2", "value": "music", "label": "Music" } ] } } // Example of a saved input action { "elementId": "name_input", "meta": { "onboardingId": "onboarding_123", "screenClientId": "profile_screen", "screenIndex": 0, "screensTotal": 3 }, "params": { "type": "input", "value": { "type": "text", "value": "John Doe" } } } // Example of a saved date picker action { "elementId": "birthday_picker", "meta": { "onboardingId": "onboarding_123", "screenClientId": "profile_screen", "screenIndex": 0, "screensTotal": 3 }, "params": { "type": "datePicker", "value": { "day": 15, "month": 6, "year": 1990 } } } ```
## ユースケース \{#use-cases\} ### ユーザープロファイルをデータで補完する \{#enrich-user-profiles-with-data\} 入力データをすぐにユーザープロファイルと紐付けて、同じ情報を二度聞かないようにするには、アクション処理時に入力データで[ユーザープロファイルを更新](capacitor-setting-user-attributes)する必要があります。 たとえば、ユーザーに `name` というIDのテキストフィールドに名前を入力してもらい、その値をユーザーの名として設定したい場合や、`email` フィールドにメールアドレスを入力してもらう場合、アプリのコードは次のようになります: ```typescript showLineNumbers view.setEventHandlers({ onStateUpdated(action, meta) { // Store user preferences or responses if (action.elementType === 'input') { const profileParams: any = {}; // Map elementId to appropriate profile field switch (action.elementId) { case 'name': if (action.value.type === 'text') { profileParams.firstName = action.value.value; } break; case 'email': if (action.value.type === 'email') { profileParams.email = action.value.value; } break; } // Update profile if we have data to update if (Object.keys(profileParams).length > 0) { adapty.updateProfile({ params: profileParams }).catch((error) => { // handle the error }); } } }, }); ``` ### 回答に基づいてペイウォールをカスタマイズする \{#customize-paywalls-based-on-answers\} オンボーディングのクイズを活用して、オンボーディング完了後にユーザーに表示するペイウォールをカスタマイズすることもできます。 たとえば、スポーツの経験について質問し、ユーザーグループごとに異なるCTAやプロダクトを表示できます。 1. オンボーディングビルダーで[クイズを追加](onboarding-quizzes)し、選択肢にわかりやすいIDを割り当てます。 2. クイズの回答をIDで処理し、ユーザーに[カスタム属性を設定](capacitor-setting-user-attributes)します。 ```typescript showLineNumbers view.setEventHandlers({ onStateUpdated(action, meta) { // Handle quiz responses and set custom attributes if (action.elementType === 'select') { const profileParams: any = {}; // Map quiz responses to custom attributes switch (action.elementId) { case 'experience': // Set custom attribute 'experience' with the selected value (beginner, amateur, pro) profileParams.codableCustomAttributes = { experience: action.value.value }; break; } // Update profile if we have data to update if (Object.keys(profileParams).length > 0) { adapty.updateProfile({ params: profileParams }).catch((error) => { // handle the error }); } } }, }); ``` 3. カスタム属性の値ごとに[セグメントを作成](segments)します。 4. [プレースメント](placements)を作成し、作成した各セグメントに[オーディエンス](audience)を追加します。 5. アプリのコードでそのプレースメントの[ペイウォールを表示](capacitor-paywalls)します。オンボーディングにペイウォールを開くボタンがある場合は、[そのボタンのアクションへのレスポンス](capacitor-handling-onboarding-events#opening-a-paywall)としてペイウォールのコードを実装してください。 --- # File: capacitor-best-practices --- --- title: "Best practices in Capacitor SDK" description: "Reference patterns for integrating Adapty SDK on Capacitor — call order, error handling, and other production-readiness rules." --- --- # File: capacitor-sdk-call-order --- --- title: "Capacitor SDKの呼び出し順序" description: "Adapty SDKのメソッドを正しい順序で呼び出すことで、プレミアムアクセスの喪失、アトリビューションの欠落、断続的な#2002エラーを回避できます。" --- `adapty.activate()` が完了してから、他のAdapty SDKメソッドを呼び出してください。解決される前は、SDKに状態がありません。`activate()` の前または並行して発行されたすべての呼び出しは、[`#2002 notActivated`](capacitor-handle-errors#custom-network-codes) で失敗します。 アプリがユーザー認証を行い、起動後にカスタマーユーザーIDを取得する場合は、その時点で `adapty.identify()` を呼び出してください。`identify` が解決されるまで、ユーザーアクションメソッドを呼び出さないでください。`identify` と競合する呼び出しは、[`#3006 profileWasChanged`](capacitor-handle-errors#custom-network-codes) で失敗するか、アクティベーション時に作成された匿名プロファイルに対して実行されます。これが発生すると、アトリビューション、`appsflyer_id` などのMMP ID、インストールの帰属が識別済みプロファイルに常に転送されるとは限りません。アプリがユーザー認証を行わない場合は、`identify` をスキップして匿名プロファイルで作業を続けてください。 MMP・アナリティクスSDK(AppsFlyer、Adjust、Branch、PostHog)も同じルールに従います。まずそれらを初期化し、UIDコールバックを待ってから `adapty.activate` を呼び出してください。そうしないと、MMP IDが一時的な匿名プロファイルに紐づき、識別済みプロファイルに常に転送されるとは限りません。AppsFlyerの詳細については、[AppsFlyer](appsflyer) を参照してください。 ## 正しい呼び出し順序 \{#the-correct-order\} どのパスを取るかは、カスタマーユーザーIDをいつ取得できるか、そしてMMPやアナリティクスSDKを使用するかどうかの2点によって決まります。 - **ステップ2と5**: すべてのアプリで必須。SDKをアクティベートしてから、SDKメソッドを呼び出します。 - **ステップ1と3**: MMPやアナリティクスSDK(AppsFlyer、Adjust、Branch、PostHog)を統合する場合のみ必須。 - **ステップ4**: アプリがユーザー認証を行い、起動後にカスタマーユーザーIDを収集する場合のみ必須。 アプリ起動時にカスタマーユーザーIDが分かっている場合は、`activate()` に直接渡してください(ステップ2a)。このパスでは匿名プロファイルが作成されないため、ステップ4は不要です。 | ステップ | 呼び出し | タイミング | 備考 | |------|---------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------| | 1 | MMPまたはアナリティクスSDKを初期化する(AppsFlyer、Adjust、PostHog、Branch) | アプリ起動時、最初に | MMPのUIDコールバック(例:`getAppsFlyerUID`)を待ちます。 | | 2a | `adapty.activate({ apiKey: '...', params: { customerUserId: '...' } })` | ステップ1の後、アプリ起動時、カスタマーユーザーIDが分かっている場合 | 推奨。匿名プロファイルは一切作成されません。 | | 2b | `adapty.activate({ apiKey: '...' })` (`customerUserId` なし) | ステップ1の後、アプリ起動時、カスタマーユーザーIDが分からない場合(または収集しない場合) | Adaptyが匿名プロファイルを作成します。 | | 3 | 各MMPに対して `adapty.setIntegrationIdentifier({ key: '...', value: '...' })` | ステップ2の後、ユーザーアクション呼び出しの前 | MMP IDが正しいプロファイルに紐づくために必須。 | | 4 | `await adapty.identify({ customerUserId: 'YOUR_USER_ID' })` | ステップ3の後(MMPがない場合はステップ2の後)、ステップ5の前 — 認証ありのパス2bのみ | 必ず `await` を使用。`identify` 中の並行呼び出しは `#3006 profileWasChanged` を引き起こします。 | | 5 | `getPaywall`、`getPaywallProducts`、`restorePurchases`、`makePurchase`、`updateAttribution`、`updateProfile` | `identify` を呼び出す場合はステップ4の後、それ以外はステップ3の後(MMPがない場合はステップ2の後) | これらの呼び出しには安定したプロファイルが必要です。 | :::important これらのステップをスキップすると、復帰ユーザーのプレミアムアクセスの喪失、プロファイルへの `appsflyer_id` の欠落、誤ったオーディエンスに対するペイウォールの返却が発生します。 ::: ## Web2appとウェブファネルのインストール \{#web2app-and-web-funnel-installs\} ユーザーがウェブチェックアウト(Stripe、Paddle)で購入した後にネイティブアプリをインストールする場合、デバイスの最初の `activate()` は新しい匿名プロファイルを作成します。このプロファイルはウェブプロファイルとリンクされていません。アプリ起動前にカスタマーユーザーIDを解決できる場合(認証フローやインストールリファラーから)、`activate()` に直接渡してください。そうでない場合、ウェブ購入は `identify({ customerUserId: 'YOUR_USER_ID' })` を呼び出してから `restorePurchases` を呼び出すまで、デバイス上では表示されません。 各ウェブチェックアウトで送信するメタデータについては、以下を参照してください: - [Stripe](stripe) - [Paddle](paddle) --- # File: capacitor-optimize-paywall-fetching --- --- title: "Capacitor SDKでペイウォール取得を最適化する" description: "Capacitorでの信頼性の高いAdaptyペイウォール取得:タイミング、キャッシュ、フォールバックパターン。" --- Capacitorで信頼性の高いペイウォール取得を実現するには、次の3つが重要です。高速なレンダリング、オーディエンスターゲティングされたペイウォールの返却、そしてネットワークが遅い場合のグレースフルなフォールバックです。以下のルールでは、それを実現するためのタイミング、キャッシュ、フォールバックパターンについて説明します。 :::tip これらのルールは、`adapty.activate()` と `adapty.identify()` がすでに解決済みであることを前提としています。詳しくは[Capacitor SDKでの呼び出し順序](capacitor-sdk-call-order)を参照してください。 ::: ## ルールと注意点 \{#rules-and-pitfalls\} | 推奨 | 非推奨 | 理由 | |---|---|---| | これから表示するプレースメントのみを取得する。 | 起動時にすべてのプレースメントをまとめてプリフェッチする。 | 一括プリフェッチはメインスレッドをブロックし、その間に画面が真っ暗になる。 | | アトリビューションが解決される時間を確保してから `getPaywall` を呼び出す(例:`activate` の1〜2秒後、または `onLatestProfileLoad` リスナーが発火した後)。 | `App.tsx` のアプリ起動時に `getPaywall` を呼び出す。 | アトリビューションがまだ反映されていないため、ペイウォールがデフォルトのオーディエンスで解決され、セグメントやASAのパーソナライズが無効にバイパスされる。 | | `loadTimeoutMs` を設定し、すべてのプレースメントに[フォールバックペイウォール](fallback-paywalls)を設定する。 | `getPaywall` を無制限に待ち続ける。 | タイムアウトがないと、通信状態の悪いユーザーはネットワークが回復するまで空白画面を見続けるか、アプリを閉じてしまう。 | `fetchPolicy` と `loadTimeoutMs` パラメーターの詳細については[ペイウォールとプロダクトの取得](fetch-paywalls-and-products-capacitor)を、適切なプレースメントの選び方については[プレースメント](placements)を参照してください。 ## 通信状態が悪い場合のチューニング \{#tune-for-poor-connectivity\} 通信状態が常に悪い市場(地方エリア、移動中、ルーティングの問題がある地域)向けには: - 初回以外のすべての取得で `fetchPolicy: 'return_cache_data_else_load'` を設定する。 - Adapty ダッシュボードですべてのプレースメントに[フォールバックペイウォール](fallback-paywalls)を設定する。 - `loadTimeoutMs` を3000〜5000ミリ秒に設定し、タイムアウト時はフォールバックを受け入れる。 - `adapty.getProfile()` の完了をペイウォール表示の条件にしない。プロファイルの遅延でUIがブロックされないよう、`getPaywall` は独立して呼び出す。 --- # File: capacitor-show-aa-targeted-paywall --- --- title: "Capacitor SDKで初回起動時にAA対象のペイウォールを表示する" description: "AdaptyProfile.appliedAttributionSourcesを使用して、Capacitorで即座にペイウォールを表示し、アトリビューションが適用されたApple Adsユーザー向けにアップグレードする方法を説明します。" --- Apple Ads(AA)のアトリビューションは、`adapty.activate()` の後に非同期で届きます。初回起動時にはまだ届いていないことが多いため、`getPaywall` はデフォルトのオーディエンスに対して解決され、Apple AdsユーザーはAAセグメント向けのペイウォールを見逃してしまいます。アトリビューションが届くまでペイウォールの表示を遅らせるのではなく、まず即座に表示しておき、AAのアトリビューションが適用されたタイミングでリフレッシュしましょう。こうすることで、Apple Adsユーザーはターゲット向けのバリアントを受け取り、それ以外のユーザーは待ち時間なくペイウォールを見ることができます。`AdaptyProfile.appliedAttributionSources` を使うと、AAのアトリビューションが適用されたタイミングを把握できます。 ## 始める前に \{#before-you-start\} 必要なもの: - Adapty Capacitor SDK **3.17.1** 以降。 - AdaptyでApple Adsがアプリに設定済みであること。[Apple Ads](apple-search-ads) を参照してください。 ## 仕組み \{#how-it-works\} `adapty.activate()` の後、SDKはバックグラウンドでAppleからApple Adsのアトリビューションを取得し、Adaptyのバックエンドに転送します。AAがプロファイルのアクティブなアトリビューションソースになると、SDKは更新された `AdaptyProfile` を `onLatestProfileLoad` リスナーに配信します。この `AdaptyProfile` の `appliedAttributionSources` 配列には `'apple_search_ads'` が含まれています。 これにより、ペイウォールの読み込みを2ステップで行うことができます: 1. すぐに `getPaywall` を呼び出します。アトリビューションがまだ適用されていない状態では、Adaptyはデフォルトのオーディエンスでリクエストを解決するため、ユーザーはすぐにペイウォールを見ることができます。 2. `'apple_search_ads'` が現れたら、再度 `getPaywall` を呼び出します。AdaptyはApple Adsのオーディエンスに対してリクエストを解決し、ターゲット向けのペイウォールを返します。これが最初のペイウォールと置き換わります。 `appliedAttributionSources` は空またはない場合があります。その場合は以下のどちらかを意味します: - このプロファイルに対するApple Adsのアトリビューションがまだ処理されていない、または - アトリビューションがまったく届いていない。 いずれの場合も、ステップ1は安全です。Adaptyは現在のプロファイル状態に一致するオーディエンス(通常はデフォルトオーディエンス)でリクエストを解決します。ステップ2は `'apple_search_ads'` が現れたときにのみ実行されます。 :::important それ以降の起動では、キャッシュされたプロファイルにすでに `appliedAttributionSources` に `'apple_search_ads'` が含まれているため、最初の `getPaywall` からApple Ads向けのセグメントペイウォールが返されます。2回目のフェッチや表示の変化は発生しません。この2ステップのフローが意味を持つのは、アトリビューションがまだ処理中の初回起動時のみです。 ::: ## 実装 \{#implementation\} まずペイウォールをすぐに表示し、`'apple_search_ads'` を監視して、届いたタイミングでペイウォールをリフレッシュします。 1. **SDKを有効化します。** [Capacitor SDKのインストールと設定](sdk-installation-capacitor) を参照してください。 2. **`getPaywall` でペイウォールを読み込んで表示します。** アトリビューションを待たずに進めてください。 3. **`adapty.addListener('onLatestProfileLoad', …)` でプロファイルの更新を購読し、**`'apple_search_ads'` を監視します。現れたら再度ペイウォールを取得し、更新されたものを表示します。リスナーをまだ設定していない場合は、[サブスクリプションの更新を監視する](capacitor-check-subscription-status#listen-to-subscription-updates) を参照してください: ```typescript const listener = await adapty.addListener('onLatestProfileLoad', async ({ profile }) => { if (!profile.appliedAttributionSources?.includes('apple_search_ads')) return; const targeted = await adapty.getPaywall({ placementId }); // present the targeted paywall in place of the first one }); // Call listener.remove() after the upgrade, or after a timeout (see below). ``` 4. **タイムアウト後にリスナーを停止します。** ほとんどのユーザーはApple Adsのアトリビューションを受け取らないため、セッション全体を通じてリスナーを開いたままにせず、一定時間後に削除してください。プレースメントに[フォールバックペイウォール](capacitor-use-fallback-paywalls)を設定しておくと、リクエストが失敗した場合でも常にユーザーに何かを表示できます。 ## 完全な例 \{#complete-example\} `onAppleAdsAttribution` は、Apple Adsのアトリビューションが適用されると解決され、`timeoutMs` 後にタイムアウトで拒否されます。以下の使用例では、まずすぐにペイウォールを読み込み、アトリビューションが届いたときに再取得します。Apple Adsユーザーはターゲット向けのペイウォールを受け取り、アトリビューションが届かない場合は最初のペイウォールがそのまま表示されます: ```typescript const APPLE_ADS_SOURCE = 'apple_search_ads'; const placementId = 'YOUR_PLACEMENT_ID'; function hasAppleAdsAttribution(profile: AdaptyProfile): boolean { return profile.appliedAttributionSources?.includes(APPLE_ADS_SOURCE) ?? false; } /** * Resolves once Apple Ads attribution is applied to the profile. * Rejects with a timeout error if attribution never arrives within `timeoutMs`. * Call after `adapty.activate()`. */ export function onAppleAdsAttribution(timeoutMs: number): Promise { return new Promise((resolve, reject) => { let timer: ReturnType | undefined; let handle: { remove: () => void } | undefined; const stop = () => { clearTimeout(timer); handle?.remove(); }; adapty .addListener('onLatestProfileLoad', ({ profile }) => { if (!hasAppleAdsAttribution(profile)) return; stop(); resolve(); }) .then(listener => { handle = listener; }); timer = setTimeout(() => { stop(); reject(new Error(`Apple Ads attribution timed out after ${timeoutMs}ms`)); }, timeoutMs); }); } let paywall = await adapty.getPaywall({ placementId }); onAppleAdsAttribution(30_000) .then(() => adapty.getPaywall({ placementId })) .then(updated => { paywall = updated; }) .catch(() => { console.log('Apple Ads attribution or loading failed'); }); ``` 初回起動時、Apple Adsユーザーはデフォルトのペイウォールをわずかな間表示した後、ターゲット向けのペイウォールに切り替わります。ペイウォールビルダーでペイウォールを表示している場合は、再表示が許容できるかどうかを検討するか、ペイウォールが表示される前にのみアップグレードを適用するようにしてください。`timeoutMs` は、リスナーをどのくらいの間維持したいかに合わせて調整してください。届くアトリビューションは通常、起動から数秒以内に届きます。 アプリが他の目的(例えば[サブスクリプションステータスの確認](capacitor-check-subscription-status#listen-to-subscription-updates))でも `onLatestProfileLoad` を監視している場合、変更は必要ありません。`adapty.addListener` は複数の独立したリスナーをサポートしているため、既存のリスナーに影響を与えることなく独自のリスナーを追加できます。 --- # File: capacitor-test --- --- title: "Test & release in Capacitor SDK" description: "Learn how to test and release your Capacitor app with Adapty SDK." --- If you've already implemented the Adapty SDK in your Capacitor app, you'll want to test that everything is set up correctly and that purchases work as expected across both iOS and Android platforms. This involves testing both the SDK integration and the actual purchase flow with Apple's sandbox environment and Google Play's testing environment. ## Test your app For comprehensive testing of your in-app purchases, see our platform-specific testing guides: [iOS testing guide](test-purchases-in-sandbox) and [Android testing guide](testing-on-android). ## Prepare for release Before submitting your app to the store, follow the [Release checklist](release-checklist) to confirm: - Store connection and server notifications are configured - Purchases complete and are reported to Adapty - Access unlocks and restores correctly - Privacy and review requirements are met --- # File: kids-mode-capacitor --- --- title: "Capacitor SDKのキッズモード" description: "AppleとGoogleのポリシーに準拠するためのキッズモードを簡単に有効化。Capacitor SDKではIDFA、GAID、広告データは収集されません。" --- Capacitorアプリが子ども向けの場合、[Apple](https://developer.apple.com/kids/)と[Google](https://support.google.com/googleplay/android-developer/answer/9893335)のポリシーに従う必要があります。Adapty SDKを使用している場合、いくつかの簡単な手順でポリシーに準拠した設定を行い、アプリストアの審査を通過できます。 ## 必要な対応 \{#whats-required\} 以下のデータ収集を無効にするよう、Adapty SDKを設定する必要があります: - [IDFA(広告識別子)](https://en.wikipedia.org/wiki/Identifier_for_Advertisers)(iOS) - [Android広告ID(AAID/GAID)](https://support.google.com/googleplay/android-developer/answer/6048248)(Android) - [IPアドレス](https://www.ftc.gov/system/files/ftc_gov/pdf/p235402_coppa_application.pdf) また、カスタマーユーザーIDの扱いには注意が必要です。``形式のユーザーIDや、メールアドレスを使用することは、個人情報の収集とみなされます。キッズモードでは、コンプライアンスを確保するために、ランダム化または匿名化された識別子(ハッシュ化されたIDやデバイス生成のUUIDなど)を使用することをお勧めします。 ## キッズモードの有効化 \{#enabling-kids-mode\} ### Adapty ダッシュボードでの設定 \{#updates-in-the-adapty-dashboard\} Adapty ダッシュボードでIPアドレスの収集を無効にする必要があります。[App settings](https://app.adapty.io/settings/general)に移動し、**Collect users' IP address**の下にある**Disable IP address collection**をクリックしてください。 ### モバイルアプリのコード変更 \{#updates-in-your-mobile-app-code\} ポリシーに準拠するため、ユーザーのIDFA、GAID、およびIPアドレスの収集を無効にしてください: ```typescript showLineNumbers try { await adapty.activate({ apiKey: 'YOUR_PUBLIC_SDK_KEY', params: { // Disable IP address collection ipAddressCollectionDisabled: true, // Disable IDFA collection on iOS ios: { idfaCollectionDisabled: true }, // Disable Google Advertising ID collection on Android android: { adIdCollectionDisabled: true } } }); console.log('Adapty activated with Kids Mode enabled'); } catch (error) { console.error('Failed to activate Adapty with Kids Mode:', error); } ``` ### プラットフォーム固有の設定 \{#platform-specific-configurations\} #### iOS:CocoaPodsでキッズモードを有効にする \{#ios-enable-kids-mode-using-cocoapods\} iOSでCocoaPodsを使用している場合、ネイティブレベルでキッズモードを有効にすることもできます: 1. Podfileを更新します: - `post_install`セクションが**ない**場合は、以下のコードブロック全体を追加してください。 - `post_install`セクションが**ある**場合は、ハイライトされた行をそのセクションに追記してください。 ```ruby showLineNumbers title="Podfile" def adapty_enable_kids_mode(installer) installer.pods_project.targets.each do |target| next unless target.name == 'Adapty' target.build_configurations.each do |config| flags = config.build_settings['OTHER_SWIFT_FLAGS'] || '$(inherited)' flags = flags.join(' ') if flags.is_a?(Array) config.build_settings['OTHER_SWIFT_FLAGS'] = "#{flags} -DADAPTY_KIDS_MODE" end target.frameworks_build_phase.files.dup.each do |bf| target.frameworks_build_phase.remove_build_file(bf) if bf.display_name.to_s.include?('AdSupport') end end installer.pods_project.save Dir.glob(File.join(installer.sandbox.root, 'Target Support Files', '**', '*.xcconfig')).each do |xc| File.write(xc, File.read(xc).gsub(/\s*-framework\s+"?AdSupport"?/, '')) end end post_install do |installer| # ... keep your existing post_install body (Flutter adds one automatically) ... adapty_enable_kids_mode(installer) # <-- enable Adapty Kids Mode end ``` 2. 変更を適用するために以下のコマンドを実行します: ```sh showLineNumbers title="Shell" pod install ``` #### Android:Gradleでキッズモードを有効にする \{#android-enable-kids-mode-using-gradle\} Androidの場合、アプリの`build.gradle`に以下を追加することで、ネイティブレベルでもキッズモードを有効にできます: ```groovy showLineNumbers title="android/app/build.gradle" android { defaultConfig { // ... existing config ... // Enable Kids Mode buildConfigField "boolean", "ADAPTY_KIDS_MODE", "true" } } ``` ## 次のステップ \{#next-steps\} キッズモードを有効にしたら、以下を確認してください: 1. アプリを十分にテストし、すべての機能が正常に動作することを確認する 2. 無効にしたデータ収集を反映するよう、アプリのプライバシーポリシーを見直す 3. キッズモードのコンプライアンスに関する明確なドキュメントを添えてアプリを審査に提出する プラットフォーム固有の要件の詳細については: - [iOS SDKのキッズモード](kids-mode)(追加のiOS設定の詳細) - [Android SDKのキッズモード](kids-mode-android)(追加のAndroid設定の詳細) --- # File: capacitor-reference --- --- title: "Reference" description: "Reference documentation for Adapty Capacitor SDK." --- This page contains reference documentation for Adapty Capacitor SDK. Choose the topic you need: - **[SDK models](https://capacitor.adapty.io/)** - Data models and structures used by the SDK - **[Handle errors](capacitor-handle-errors)** - Error handling and troubleshooting --- # File: capacitor-handle-errors --- --- title: "Capacitor SDKのエラー処理" description: "Capacitor SDKのエラー処理。" --- SDKから返されるすべてのエラーは`AdaptyError`インスタンスです。以下に例を示します: :::tip **デバッグ前に詳細ログを有効にしてください。** ほとんどの`AdaptyError`は、StoreKit・Play Billing・ネットワーク・バックエンドのエラーをラップしています。詳細ログを有効にする(`adapty.setLogLevel({ logLevel: 'verbose' })`)と — [ログ](sdk-installation-capacitor#logging)を参照 — ラップされたエラーがコンソールに出力され、実際の原因を特定しやすくなります。`AdaptyError`の`detail`プロパティはログレベルに関わらず設定されますが、詳細ログを有効にすることでコンソールにも表示されます。 ::: ```typescript showLineNumbers try { const result = await adapty.makePurchase({ product }); // Handle purchase result if (result.type === 'success') { console.log('Purchase successful:', result.profile); } else if (result.type === 'user_cancelled') { console.log('User cancelled the purchase'); } else if (result.type === 'pending') { console.log('Purchase is pending'); } } catch (error) { if (error instanceof AdaptyError) { console.error('Adapty error:', error.adaptyCode, error.localizedDescription); // Handle specific error codes switch (error.adaptyCode) { case ErrorCodeName.cantMakePayments: console.log('In-app purchases are not allowed on this device'); break; case ErrorCodeName.notActivated: console.log('Adapty SDK is not activated'); break; case ErrorCodeName.productPurchaseFailed: console.log('Purchase failed:', error.detail); break; default: console.log('Other error occurred:', error.detail); } } else { console.error('Non-Adapty error:', error); } } ``` ## エラープロパティ \{#error-properties\} `AdaptyError`クラスは以下のプロパティを提供します: | プロパティ | 型 | 説明 | |----------|------|-------------| | `adaptyCode` | `number` | 数値エラーコード(例:`cantMakePayments`の場合は`1003`) | | `localizedDescription` | `string` | ユーザー向けのエラーメッセージ | | `detail` | `string \| undefined` | 追加のエラー詳細(任意) | | `message` | `string` | コードと説明を含む完全なエラーメッセージ | ## エラーコード \{#error-codes\} SDKはエラーコードを扱うための定数とユーティリティをエクスポートしています: ### ErrorCodeName定数 \{#errorcodename-constant\} 文字列識別子を数値コードにマッピングします: ```typescript ErrorCodeName.cantMakePayments // 1003 ErrorCodeName.notActivated // 2002 ErrorCodeName.networkFailed // 2005 ``` ### ErrorCode定数 \{#errorcode-constant\} 数値コードを文字列識別子にマッピングします: ```typescript ErrorCode[1003] // 'cantMakePayments' ErrorCode[2002] // 'notActivated' ErrorCode[2005] // 'networkFailed' ``` ### ヘルパー関数 \{#helper-functions\} ```typescript // Get numeric code from string name: getErrorCode('cantMakePayments') // 1003 // Get string name from numeric code: getErrorPrompt(1003) // 'cantMakePayments' ``` ### エラーコードの比較 \{#comparing-error-codes\} **重要:** `error.adaptyCode`は**数値**なので、数値コードと直接比較してください: ```typescript // Option 1: Use ErrorCodeName constant (recommended) ✅ if (error.adaptyCode === ErrorCodeName.cantMakePayments) { console.log('Cannot make payments'); } // Option 2: Compare with numeric literal ✅ if (error.adaptyCode === 1003) { console.log('Cannot make payments'); } // NOT like this ❌ - compares number to string and will never match if (error.adaptyCode === ErrorCode[1003]) { } ``` ## グローバルエラーハンドラー \{#global-error-handler\} すべてのAdaptyエラーをキャッチするグローバルエラーハンドラーを設定できます: ```typescript showLineNumbers // Set up global error handler AdaptyError.onError = (error: AdaptyError) => { console.error('Global Adapty error:', { code: error.adaptyCode, message: error.localizedDescription, detail: error.detail }); // Handle specific error types globally if (error.adaptyCode === ErrorCodeName.notActivated) { // SDK not activated - maybe retry activation console.log('SDK not activated, attempting to reactivate...'); } }; ``` ## よくあるエラー処理パターン \{#common-error-handling-patterns\} ### 購入エラーの処理 \{#handle-purchase-errors\} ```typescript showLineNumbers async function handlePurchase(product: AdaptyPaywallProduct) { try { const result = await adapty.makePurchase({ product }); if (result.type === 'success') { console.log('Purchase successful:', result.profile); } else if (result.type === 'user_cancelled') { console.log('User cancelled the purchase'); } else if (result.type === 'pending') { console.log('Purchase is pending'); } } catch (error) { if (error instanceof AdaptyError) { switch (error.adaptyCode) { case ErrorCodeName.cantMakePayments: console.log('In-app purchases not allowed'); break; case ErrorCodeName.productPurchaseFailed: console.log('Purchase failed:', error.detail); break; default: console.error('Purchase error:', error.localizedDescription); } } } } ``` ### ネットワークエラーの処理 \{#handle-network-errors\} ```typescript showLineNumbers async function fetchPaywall(placementId: string) { try { const paywall = await adapty.getPaywall({ placementId }); return paywall; } catch (error) { if (error instanceof AdaptyError) { switch (error.adaptyCode) { case ErrorCodeName.networkFailed: console.log('Network error, retrying...'); // Implement retry logic break; case ErrorCodeName.serverError: console.log('Server error:', error.detail); break; case ErrorCodeName.notActivated: console.log('SDK not activated'); break; default: console.error('Paywall fetch error:', error.localizedDescription); } } throw error; } } ``` ## システム StoreKit コード \{#system-storekit-codes\} | エラー | コード | 説明 | |-----|----|-----------| | unknown | 0 | 不明または予期しないエラーが発生したことを示します。 | | clientInvalid | 1 | クライアントが実行しようとした操作を許可されていないことを示します。 | | paymentCancelled | 2 |

ユーザーが支払いリクエストをキャンセルしたことを示します。

特に対応は不要ですが、ビジネスロジックの観点から、ユーザーに割引を提示したり、後でリマインドしたりすることができます。

| | paymentInvalid | 3 | 支払いパラメーターのいずれかがストアに認識されなかったことを示します。 | | paymentNotAllowed | 4 |

ユーザーが支払いを承認する権限を持っていないことを示します。考えられる原因:

- ユーザーの国では支払いがサポートされていない。

- ユーザーが未成年である。

| | storeProductNotAvailable | 5 | リクエストされたプロダクトが App Store に存在しないことを示します。対象国でプロダクトが利用可能になっているか確認してください。 | | cloudServicePermissionDenied | 6 | ユーザーがクラウドサービス情報へのアクセスを許可していないことを示します。 | | cloudServiceNetworkConnectionFailed | 7 | デバイスがネットワークに接続できなかったことを示します。 | | cloudServiceRevoked | 8 | ユーザーがクラウドサービスの使用許可を取り消したことを示します。 | | privacyAcknowledgementRequired | 9 | ユーザーがストアのプライバシーポリシーにまだ同意していないことを示します。 | | unauthorizedRequestData | 10 | リクエストが正しく構築されていないことを示します。 | | invalidOfferIdentifier | 11 |

オファー識別子が無効です。考えられる原因:

- App Store でその識別子のオファーをまだ設定していない。

- オファーを取り消している。

- オファー ID を誤って入力している。

| | invalidSignature | 12 | 支払いディスカウントの署名が無効であることを示します。**In-app purchase Key ID** フィールドに入力し、**In-App Purchase Private Key** ファイルをアップロードしているか確認してください。詳細は [App Store インテグレーションの設定](app-store-connection-configuration) を参照してください。 | | missingOfferParams | 13 |

Adapty インテグレーションまたはオファーに問題があることを示します。

設定方法の詳細は [App Store インテグレーションの設定](app-store-connection-configuration) および [オファー](offers) を参照してください。

| | invalidOfferPrice | 14 | ストアで指定した価格が無効になったことを示します。オファーは常に割引価格である必要があります。 | ## カスタム Android コード \{#custom-android-codes\} | エラー | コード | 説明 | |-----|----|-----------| | adaptyNotInitialized | 20 | `Adapty.activate` メソッドで Adapty SDK を正しく設定する必要があります。設定方法は [React Native 向けのガイド](sdk-installation-reactnative) を参照してください。 | | productNotFound | 22 | 購入リクエストされたプロダクトがストアで利用できないことを示します。 | | invalidJson | 23 | ペイウォールの JSON が無効です。Adapty ダッシュボードで修正してください。修正方法の詳細は [リモートコンフィグでペイウォールをカスタマイズする](customize-paywall-with-remote-config) を参照してください。 | | currentSubscriptionToUpdateNotFoundInHistory | 24 | 更新が必要な元のサブスクリプションが見つかりません。 | | pendingPurchase | 25 | 購入状態が「購入済み」ではなく「保留中」であることを示します。詳細は Android デベロッパー ドキュメントの [保留中のトランザクションの処理](https://developer.android.com/google/play/billing/integrate#pending) を参照してください。 | | billingServiceTimeout | 97 | Google Play が応答する前にリクエストが最大タイムアウトに達したことを示します。Play Billing Library の呼び出しで要求されたアクションの実行が遅延した場合などに発生します。 | | featureNotSupported | 98 | リクエストされた機能が現在のデバイスの Play Store でサポートされていません。 | | billingServiceDisconnected | 99 | `BillingClient` 経由でのクライアントアプリと Google Play Store サービスの接続が切断されたことを示す致命的なエラーです。 | | billingServiceUnavailable | 102 | Google Play Billing サービスが現在利用できないことを示す一時的なエラーです。ほとんどの場合、クライアントデバイスと Google Play Billing サービス間のどこかでネットワーク接続に問題があることを意味します。 | | billingUnavailable | 103 |

購入プロセス中にユーザーの課金エラーが発生したことを示します。発生する状況の例:

1. ユーザーのデバイスの Play Store アプリが古い。

2. ユーザーがサポート対象外の国にいる。

3. ユーザーがエンタープライズユーザーであり、エンタープライズ管理者が購入を無効にしている。

4. Google Play がユーザーの支払い方法に課金できない(クレジットカードの有効期限切れなど)。

5. ユーザーが Play Store アプリにログインしていない。

| | developerError | 105 | API の使い方が正しくないことを示す致命的なエラーです。 | | billingError | 106 | Google Play 内部の問題を示す致命的なエラーです。 | | itemAlreadyOwned | 107 | 消耗型アイテムがすでに購入済みです。 | | itemNotOwned | 108 | アイテムに対してリクエストされたアクションが失敗したことを示します。 | ## カスタム StoreKit コード \{#custom-storekit-codes\} | エラー | コード | 説明 | |-----|----|-----------| | noProductIDsFound | 1000 |

ペイウォール内のプロダクトがいずれもストアで利用できないことを示します。

このエラーが発生した場合は、以下の手順で解決してください:

1. すべてのプロダクトが Adapty ダッシュボードに追加されているか確認する。

2. アプリの Bundle ID が Apple Connect のものと一致しているか確認する。

3. アプリストアのプロダクト識別子がダッシュボードに追加したものと一致しているか確認する。識別子にはストアにすでに含まれている場合を除き、Bundle ID を含めないこと。

4. Apple の税務設定でアプリの有料ステータスがアクティブになっているか確認する。税務情報が最新であり、証明書が有効であることを確認する。

5. アプリに銀行口座が紐付けられており、収益化の対象になっているか確認する。

6. プロダクトがすべての地域で利用可能になっているか確認する。また、プロダクトのステータスが **"Ready to Submit"** になっていることを確認する。

| | productRequestFailed | 1002 |

現時点で利用可能なプロダクトを取得できません。考えられる原因:

- キャッシュがまだ作成されておらず、同時にインターネット接続もない。

| | cantMakePayments | 1003 | このデバイスではアプリ内課金が許可されていません。 | | noPurchasesToRestore | 1004 | Google Play が復元対象の購入を見つけられなかったことを示します。 | | cantReadReceipt | 1005 |

デバイス上に有効なレシートがありません。サンドボックステスト中に発生することがあります。

特に対応は不要ですが、ビジネスロジックの観点から、ユーザーに割引を提示したり、後でリマインドしたりすることができます。

| | productPurchaseFailed | 1006 | プロダクトの購入に失敗しました。このエラーは内部の StoreKit エラーをラップしています。実際の原因を確認するには、ラップされたエラーを読み取るか(または詳細ログを有効にしてコンソールで確認)してください。ラップされたエラーは通常、上記の StoreKit コード 0〜14 のいずれかで、最も多いのは `paymentCancelled`、`paymentInvalid`、`paymentNotAllowed`、`invalidOfferPrice` です。原因が特定できない場合は、新しい[サンドボックスプロファイル](test-purchases-in-sandbox)でお試しください。それでも解決しない場合は Apple サポートにお問い合わせください。 | | refreshReceiptFailed | 1010 | レシートが受信されなかったことを示します。StoreKit 1 のみ対象です。 | | receiveRestoredTransactionsFailed | 1011 | 購入の復元に失敗しました。 | ## カスタムネットワークコード \{#custom-network-codes\} | エラー | コード | 説明 | | :------------------- | :--- | :----------------------------------------------------------- | | notActivated | 2002 | `Adapty.activate` メソッドで Adapty SDK を正しく設定する必要があります。設定方法は [React Native 向けのガイド](sdk-installation-reactnative) を参照してください。 | | badRequest | 2003 | リクエストが不正です。 | | serverError | 2004 | サーバーエラーです。 | | networkFailed | 2005 | ネットワークリクエストに失敗しました。 | | decodingFailed | 2006 | レスポンスのデコードに失敗したことを示します。 | | encodingFailed | 2009 | リクエストのエンコードに失敗したことを示します。 | | analyticsDisabled | 3000 | アナリティクスをオプトアウトしているため、アナリティクスイベントを処理できません。詳細は [アナリティクスインテグレーション](analytics-integration) を参照してください。 | | wrongParam | 3001 | パラメーターの一部が正しくないことを示します(空白にできない箇所が空白になっている、型が違うなど)。 | | activateOnceError | 3005 | `.activate` メソッドを複数回呼び出すことはできません。 | | profileWasChanged | 3006 | 操作中にユーザープロファイルが変更されました。 | | fetchTimeoutError | 3101 | 設定された制限時間内にペイウォールを取得できなかったことを示します。この状況を回避するには、[ローカルフォールバックを設定](fetch-paywalls-and-products)してください。 | | operationInterrupted | 9000 | この操作はシステムによって中断されました。 | --- # File: capacitor-sdk-migration-guides --- --- title: "Capacitor SDK Migration Guides" description: "Migration guides for Adapty Capacitor SDK versions." --- This page contains all migration guides for Adapty Capacitor SDK. Choose the version you want to migrate to for detailed instructions: - [**Migrate to v3.16**](migration-to-capacitor-316) --- # File: migration-to-capacitor-316 --- --- title: "Adapty Capacitor SDK を v3.16 に移行する" description: "より良いパフォーマンスと新しいマネタイズ機能のために Adapty Capacitor SDK v3.16 に移行します。" --- Adapty SDK v3.16.0 以降、Capacitor 8 が必要です。Capacitor 7 を使用する場合は、Adapty SDK v3.15 をご利用ください。 Capacitor SDK v3.16 にアップグレードするには、プロジェクトが Capacitor 8 を使用していることを確認してください。まだ Capacitor 7 を使用している場合は、次の 2 つの選択肢があります。 1. **Capacitor 8 にアップグレードする**: [公式 Capacitor 移行ガイド](https://capacitorjs.com/docs/updating/8-0)に従ってプロジェクトを更新し、Adapty SDK v3.16 をインストールします。 2. **Adapty SDK v3.15 を使い続ける**: Capacitor 8 へのアップグレードが難しい場合は、Capacitor 7 をサポートする Adapty SDK v3.15 を引き続き使用してください。 --- # End of Documentation _Generated on: 2026-06-24T14:36:28.495Z_ _Successfully processed: 43/43 files_