---
title: "Capacitor - Обработка событий пейвола"
description: "Обрабатывайте события подписок в Capacitor с помощью SDK Adapty."
---

:::important
Этот гайд охватывает обработку событий для покупок, восстановлений, выбора продукта и рендеринга пейвола. Вам также необходимо реализовать обработку кнопок (закрытие пейвола, открытие ссылок и т. д.). Подробнее — в [гайде по обработке действий кнопок](capacitor-handle-paywall-actions).
:::

Пейволы, настроенные с помощью [Paywall Builder](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
  },
});
```

<Details>
<summary>Примеры событий (нажмите, чтобы раскрыть)</summary>

```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"
    }
  }
}
```
</Details>

Вы можете зарегистрировать только нужные обработчики событий и пропустить ненужные — в этом случае лишние слушатели событий не будут созданы. Обязательных обработчиков нет.

Обработчики событий возвращают булево значение. Если возвращается `true`, процесс отображения считается завершённым: экран пейвола закрывается, а слушатели событий для данного представления удаляются.

Некоторые обработчики событий имеют поведение по умолчанию, которое при необходимости можно переопределить:
- `onCloseButtonPress`: закрывает пейвол при нажатии кнопки закрытия.
- `onAndroidSystemBack`: закрывает пейвол при нажатии кнопки **Back**.
- `onRestoreCompleted`: закрывает пейвол после успешного восстановления.
- `onPurchaseCompleted`: закрывает пейвол, если покупка не была отменена пользователем.
- `onRenderingFailed`: закрывает пейвол при сбое рендеринга.
- `onUrlPress`: открывает URL в системном браузере и оставляет пейвол открытым.

### Обработчики событий \{#event-handlers\}

| Обработчик события          | Описание                                                                                                                                                                                                                                                                                                         |
|:----------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **onCustomAction**          | Вызывается, когда пользователь выполняет пользовательское действие, например нажимает [кастомную кнопку](paywall-buttons).                                                                                                                                                                                       |
| **onUrlPress**              | Вызывается, когда пользователь нажимает на URL в вашем пейволе.                                                                                                                                                                                                                                                  |
| **onAndroidSystemBack**     | Вызывается, когда пользователь нажимает системную кнопку **Back** на 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 самостоятельно загрузит необходимые объекты с сервера.                                                                                                 |