> ## 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 ブロック

> Aftersell Cart の Subscription upgrade サブブロック: 対象の単発購入ラインをカートからサブスクリプションに変換します。

> **Subscription upgrade** ブロックは、[**Cart items**](/ja/aftersell/cart/cart-items-block) の中にネストされるサブブロックです。対象となる単発購入のラインアイテムをカートから直接サブスクリプションに切り替えるよう購入者に促し、意思決定の瞬間に単発購入を継続収益へと変えます。また、すでに購読中の購入者は、そのラインでプランの変更やキャンセルができます。

<div id="behavior">
  ## 動作
</div>

* **対象ラインにのみ表示されます。** ブロックは商品の販売プランを読み取り、サブスクリプションプランのない商品のラインには何もレンダリングしません。
* **リワードのギフトには表示されません。** 自動付与された無料ギフトを購読に切り替えるとリワードステータスが失われるため、そうしたラインではプロンプトが抑制されます。
* **単発購入のライン**では、アップグレードのコールトゥアクションを表示します。
* **すでに購読中のライン**では、プランセレクターと「単発購入にダウングレード」オプションを表示します。

<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 row との相対的な配置に応じて商品コンテンツの上または下に表示されます。[サブブロックの配置のしくみ](/ja/aftersell/cart/cart-items-block#sub-blocks-and-how-they-position)を参照してください。

<div id="custom-template">
  ## カスタムテンプレート
</div>

Code タブから[カスタムテンプレート](/ja/aftersell/cart/custom-templates)をサポートしており、このブロックの組み込みマークアップをあなたの JSX に置き換えます。受け取る props は以下のとおりです。

このブロックは 2 つの状態のいずれかをレンダリングし、どちらかは `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`           | `<select>` 用にあらかじめ用意された `onChange`。値を自分でパースする必要がありません。                                                      |
| `oneTimeValue`    | `string`                           | 「単発購入」を表すセンチネルの `<option>` 値。                                                                               |
| `line`            | `AftersellCartLine`                | このブロックが属する[カートライン](/ja/aftersell/cart/sdk-cart-object#cart-lines)。                                          |
| `productId`       | `number`                           | Shopify の商品 ID。                                                                                             |
| `variantId`       | `number`                           | Shopify のバリアント ID。                                                                                          |

`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>
  `<select>` には `onChange` を、ボタンには `selectPlan` を使ってください。`onChange` は `oneTimeValue` のセンチネルをすでに処理しています。`<select>` に独自のハンドラーを接続する場合は、自分で `oneTimeValue` と比較して `selectPlan(null)` を呼ぶ必要があります。
</Note>

<div id="design">
  ## デザイン
</div>

このブロックのスタイルは、設定パネルの **Design** セクションで調整します。これらはブロック単位のオーバーライドで、グローバルデザインの上に重なり、空欄の場合はグローバル設定にフォールバックします。

デザイン設定とは何か? 詳しくはこちら: [デザイン設定](/ja/aftersell/cart/design-settings)。
