> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aftersell.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Блок Subscription upgrade

> Подблок Subscription upgrade корзины Aftersell: переводите подходящие разовые строки в подписку прямо из корзины.

> Блок **Subscription upgrade** — это подблок, вкладываемый в [**Cart items**](/ru/aftersell/cart/cart-items-block). Он предлагает покупателям переключить подходящую разовую строку на подписку прямо из корзины, превращая разовую покупку в регулярную выручку в момент принятия решения, и позволяет уже подписанным покупателям изменить или отменить план на этой строке.

<div id="behavior">
  ## Поведение
</div>

* **Появляется только на подходящих строках.** Блок читает selling plans товара и ничего не отображает на строке, у товара которой нет планов подписки.
* **Никогда не предлагается на подарках-наградах.** Подписка на автоматически выданный бесплатный подарок лишила бы его статуса награды, поэтому предложение подавляется на таких строках.
* На **разовой строке** он показывает призыв к переходу на подписку.
* На **уже подписанной строке** он показывает селектор плана плюс опцию «понизить до разовой покупки».

<div id="settings">
  ## Настройки
</div>

| Настройка            | Что она контролирует                                                                                   | По умолчанию                    |
| -------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------- |
| **Button text**      | Призыв к переходу на подписку на разовой строке. Поддерживает токены `{{discount}}` и `{{plan name}}`. | `Subscribe & Save`              |
| **Unsubscribe text** | Опция, возвращающая подписанную строку к разовой покупке.                                              | `Downgrade - One time purchase` |

<div id="placement-and-limits">
  ## Размещение и ограничения
</div>

* **Родитель:** вкладывается только в Cart items.
* **Максимум:** 1 на корзину.
* Не добавляется по умолчанию. Не заблокирован, поэтому вы можете удалить или скрыть его.

Поскольку это подблок, он отображается на каждой строке, располагаясь выше или ниже содержимого товара в зависимости от того, где вы его разместите относительно строки Product. См. [как позиционируются подблоки](/ru/aftersell/cart/cart-items-block#sub-blocks-and-how-they-position).

<div id="custom-template">
  ## Пользовательский шаблон
</div>

Поддерживает [пользовательский шаблон](/ru/aftersell/cart/custom-templates) на вкладке Code, который заменяет встроенную разметку этого блока вашим JSX. Вот props, которые он получает.

Этот блок отображает одно из двух состояний, и `view.state` сообщает, какое именно. `view` никогда не бывает `null` внутри пользовательского шаблона: когда у строки нет планов, блок ничего не отображает, и ваш шаблон не вызывается.

| Prop              | Тип                                | Для чего он                                                                                                                          |
| ----------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `view`            | `object`                           | Состояние строки. Либо `{ state: 'upgrade', buttonText, planId }`, либо `{ state: 'subscribed', plans, activePlanId }`.              |
| `title`           | `string`                           | Заголовок **товара**, а не заголовок блока. Встроенный шаблон использует его только для построения доступной метки селектора планов. |
| `unsubscribeText` | `string`                           | Метка опции понижения до разовой покупки.                                                                                            |
| `busy`            | `boolean`                          | `true`, пока выполняется смена плана.                                                                                                |
| `selectPlan`      | `(planId: number \| null) => void` | Подписывает или меняет план. Передайте `null` для отписки.                                                                           |
| `onChange`        | `(event: Event) => void`           | Готовый `onChange` для `<select>`, чтобы вам не пришлось разбирать значение самостоятельно.                                          |
| `oneTimeValue`    | `string`                           | Значение-сентинел `<option>`, представляющее «разовую покупку».                                                                      |
| `line`            | `AftersellCartLine`                | [Строка корзины](/ru/aftersell/cart/sdk-cart-object#cart-lines), к которой принадлежит этот блок.                                    |
| `productId`       | `number`                           | ID товара Shopify.                                                                                                                   |
| `variantId`       | `number`                           | ID варианта Shopify.                                                                                                                 |

Каждый элемент в `view.plans` имеет вид `{ id: number, name: string, discountPercent: number }`.

```jsx theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
function CustomTemplate(props) {
  const { view } = props;

  if (view.state === 'upgrade') {
    return (
      <button type="button" onClick={() => props.selectPlan(view.planId)} disabled={props.busy}>
        {view.buttonText}
      </button>
    );
  }

  return (
    <div>
      <select
        aria-label={`Subscription plan — ${props.title}`}
        value={String(view.activePlanId)}
        onChange={props.onChange}
        disabled={props.busy}
      >
        {view.plans.map((plan) => (
          <option key={plan.id} value={String(plan.id)}>
            {plan.name}{plan.discountPercent > 0 ? ` (${plan.discountPercent}% off)` : ''}
          </option>
        ))}
        <option value={props.oneTimeValue}>{props.unsubscribeText}</option>
      </select>
    </div>
  );
}
```

<Note>
  Используйте `onChange` для `<select>` и `selectPlan` для кнопок. `onChange` уже обрабатывает сентинел `oneTimeValue`; если вы подключаете собственный обработчик к `<select>`, вам придётся сравнивать со значением `oneTimeValue` и вызывать `selectPlan(null)` самостоятельно.
</Note>

<div id="design">
  ## Дизайн
</div>

Стилизуйте этот блок в разделе **Design** его панели настроек. Это переопределения на уровне блока, которые накладываются поверх глобального дизайна и возвращаются к нему, когда не заполнены.

Что такое настройки дизайна? Подробнее здесь: [Настройки дизайна](/ru/aftersell/cart/design-settings).
