[ペイウォールのローカライゼーション](add-paywall-locale-in-adapty-paywall-builder)の識別子。このパラメーターはマイナス(**-**)文字で区切られた1つまたは2つのサブタグで構成される言語コードを指定します。最初のサブタグは言語、2番目はリージョンを表します。
ロケールコードとその推奨使用方法については[ローカライゼーションとロケールコード](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** | [ペイウォールのローカライゼーション](add-remote-config-locale)の識別子。このパラメーターはマイナス(**-**)文字で区切られた1つ以上のサブタグで構成される言語コードを指定します。最初のサブタグは言語、2番目はリージョンを表します。
ロケールコードとその推奨使用方法については[ローカライゼーションとロケールコード](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_