> ## 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.

# Bloque de mejora a suscripción

> El sub-bloque Subscription upgrade de Aftersell Cart: convierte líneas elegibles de compra única en una suscripción desde el carrito.

> El bloque **Subscription upgrade** es un sub-bloque que se anida dentro de [**Cart items**](/es/aftersell/cart/cart-items-block). Invita a los compradores a cambiar una línea elegible de compra única a una suscripción directamente desde el carrito, convirtiendo una compra única en ingresos recurrentes en el momento de la decisión, y permite a los compradores que ya están suscritos cambiar o cancelar su plan en esa línea.

<div id="behavior">
  ## Comportamiento
</div>

* **Solo aparece en líneas elegibles.** El bloque lee los planes de venta del producto y no renderiza nada en una línea cuyo producto no tiene planes de suscripción.
* **Nunca se ofrece en regalos de recompensa.** Suscribirse a un regalo gratis otorgado automáticamente le quitaría su estado de recompensa, así que la invitación se suprime en esas líneas.
* En una **línea de compra única**, muestra la llamada a la acción de mejora.
* En una **línea ya suscrita**, muestra un selector de plan más la opción de "bajar a compra única".

<div id="settings">
  ## Ajustes
</div>

| Ajuste               | Qué controla                                                                                                       | Predeterminado                  |
| -------------------- | ------------------------------------------------------------------------------------------------------------------ | ------------------------------- |
| **Button text**      | La llamada a la acción de mejora en una línea de compra única. Admite los tokens `{{discount}}` y `{{plan name}}`. | `Subscribe & Save`              |
| **Unsubscribe text** | La opción que revierte una línea suscrita a una compra única.                                                      | `Downgrade - One time purchase` |

<div id="placement-and-limits">
  ## Ubicación y límites
</div>

* **Padre:** se anida solo dentro de Cart items.
* **Máximo:** 1 por carrito.
* No se agrega de forma predeterminada. No está bloqueado, así que puedes quitarlo u ocultarlo.

Como es un sub-bloque, se renderiza por línea, posicionado encima o debajo del contenido del producto según dónde lo coloques respecto a la fila Product. Consulta [cómo se posicionan los sub-bloques](/es/aftersell/cart/cart-items-block#sub-blocks-and-how-they-position).

<div id="custom-template">
  ## Plantilla personalizada
</div>

Admite una [plantilla personalizada](/es/aftersell/cart/custom-templates) desde su pestaña Code, que reemplaza el marcado integrado de este bloque con tu JSX. Estas son las props que recibe.

Este bloque renderiza uno de dos estados, y `view.state` te dice cuál. `view` nunca es `null` dentro de una plantilla personalizada: cuando una línea no tiene planes, el bloque no renderiza nada y tu plantilla no se invoca.

| Prop              | Tipo                               | Para qué sirve                                                                                                                                         |
| ----------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `view`            | `object`                           | El estado de la línea. O `{ state: 'upgrade', buttonText, planId }` o `{ state: 'subscribed', plans, activePlanId }`.                                  |
| `title`           | `string`                           | El título del **producto**, no un encabezado del bloque. La plantilla integrada lo usa solo para construir la etiqueta accesible del selector de plan. |
| `unsubscribeText` | `string`                           | Etiqueta para la opción de bajar a compra única.                                                                                                       |
| `busy`            | `boolean`                          | `true` mientras un cambio de plan está en curso.                                                                                                       |
| `selectPlan`      | `(planId: number \| null) => void` | Suscribe o cambia de plan. Pasa `null` para cancelar la suscripción.                                                                                   |
| `onChange`        | `(event: Event) => void`           | `onChange` listo para usar en un `<select>`, para que no tengas que analizar el valor tú mismo.                                                        |
| `oneTimeValue`    | `string`                           | El valor centinela del `<option>` que representa "compra única".                                                                                       |
| `line`            | `AftersellCartLine`                | La [línea de carrito](/es/aftersell/cart/sdk-cart-object#cart-lines) a la que pertenece este bloque.                                                   |
| `productId`       | `number`                           | ID de producto de Shopify.                                                                                                                             |
| `variantId`       | `number`                           | ID de variante de Shopify.                                                                                                                             |

Cada entrada en `view.plans` es `{ 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>
  Usa `onChange` para un `<select>` y `selectPlan` para botones. `onChange` ya maneja el centinela `oneTimeValue`; si conectas tu propio handler a un `<select>`, tienes que comparar contra `oneTimeValue` y llamar a `selectPlan(null)` tú mismo.
</Note>

<div id="design">
  ## Diseño
</div>

Da estilo a este bloque con su sección **Design** en el panel de ajustes. Son overrides por bloque que se superponen a tu diseño global y recurren a él cuando están en blanco.

¿Qué son los ajustes de diseño? Obtén más información aquí: [Ajustes de diseño](/es/aftersell/cart/design-settings).
