**TL;DR.** Los requisitos de resultados enriquecidos de productos de Google para 2026 añadieron `hasMerchantReturnPolicy` y `shippingDetails` como campos necesarios para la elegibilidad de fragmentos enriquecidos. Los productos que no los tienen pierden precio, disponibilidad y estrellas de reseñas en los resultados de búsqueda. Ordiko emite ambos por defecto una vez que configuras las políticas a nivel de tienda; los competidores requieren trabajo de tema/plugin.

## Qué cambió en 2026

A lo largo de 2024 y 2025, Google implementó nuevos requisitos para los datos estructurados de productos. La línea base de 2026:

| Campo                           | ¿Requerido para resultado enriquecido? | Efecto si falta                        |
| ------------------------------- | -------------------------------------- | -------------------------------------- |
| `name`, `image`, `description`  | Sí (de larga data)                    | Resultado no elegible                  |
| `offers.price`, `priceCurrency` | Sí (de larga data)                    | Fragmento de precio oculto             |
| `offers.availability`            | Sí (de larga data)                    | Disponibilidad no mostrada             |
| `aggregateRating` o `review`    | Recomendado                            | Calificación estelar no mostrada       |
| **`hasMerchantReturnPolicy`**    | **Sí (2026)**                          | **Resultado enriquecido no elegible**  |
| **`offers.shippingDetails`**     | **Sí (2026)**                          | **Resultado enriquecido no elegible**  |
| `brand`, `sku`, `gtin`           | Recomendado                            | Reduce la credibilidad / coincidencia  |
| `material`, `color`, `size`      | Recomendado                            | Reduce la filtrabilidad                 |

Fuente: [Google Search Central — Datos estructurados de productos](https://developers.google.com/search/docs/appearance/structured-data/product).

## hasMerchantReturnPolicy

La estructura completa del campo:

```json
{
  "@type": "MerchantReturnPolicy",
  "@id": "https://example.com/#return-policy",
  "applicableCountry": ["US", "CA"],
  "returnPolicyCountry": "US",
  "returnPolicyCategory": "https://schema.org/MerchantReturnFiniteReturnWindow",
  "merchantReturnDays": 30,
  "returnMethod": "https://schema.org/ReturnByMail",
  "returnFees": "https://schema.org/FreeReturn"
}
```

Valores válidos:

- `returnPolicyCategory`: `MerchantReturnFiniteReturnWindow`, `MerchantReturnUnlimitedWindow`, `MerchantReturnNotPermitted`, `MerchantReturnUnspecified`.
- `returnMethod`: `ReturnByMail`, `ReturnInStore`, `ReturnAtKiosk`.
- `returnFees`: `FreeReturn`, `OriginalShippingFees`, `ReturnFeesCustomerResponsibility`, `RestockingFees`, `ReturnShippingFees`.

Si tienes una política de devolución gratuita de 30 días por correo (el común y amigable para el consumidor):

```json
{
  "@type": "MerchantReturnPolicy",
  "applicableCountry": ["US", "CA"],
  "returnPolicyCountry": "US",
  "returnPolicyCategory": "https://schema.org/MerchantReturnFiniteReturnWindow",
  "merchantReturnDays": 30,
  "returnMethod": "https://schema.org/ReturnByMail",
  "returnFees": "https://schema.org/FreeReturn"
}
```

## shippingDetails

La estructura completa del campo:

```json
{
  "@type": "OfferShippingDetails",
  "shippingRate": {
    "@type": "MonetaryAmount",
    "value": "4.99",
    "currency": "USD"
  },
  "shippingDestination": {
    "@type": "DefinedRegion",
    "addressCountry": "US"
  },
  "deliveryTime": {
    "@type": "ShippingDeliveryTime",
    "handlingTime": {
      "@type": "QuantitativeValue",
      "minValue": 0,
      "maxValue": 1,
      "unitCode": "DAY"
    },
    "transitTime": {
      "@type": "QuantitativeValue",
      "minValue": 2,
      "maxValue": 5,
      "unitCode": "DAY"
    }
  }
}
```

Emite un `shippingDetails` por cada región de destino que sirvas. Una tienda de EE. UU.-Canadá envía a dos destinos, por lo que necesita dos entradas.

## Patrón de referencia (recomendado)

Definir la política de devolución y el envío por producto produce HTML verboso. El patrón más limpio es definirlos una vez en el esquema de `Organization` con `@id`s estables y referenciarlos desde cada producto:

```json
// Una vez en cada página (o solo en la principal):
{
  "@type": "Organization",
  "@id": "https://example.com/#organization",
  "name": "Ejemplo Tienda",
  "hasMerchantReturnPolicy": {
    "@type": "MerchantReturnPolicy",
    "@id": "https://example.com/#return-policy",
    "applicableCountry": ["US", "CA"],
    "returnPolicyCountry": "US",
    "returnPolicyCategory": "https://schema.org/MerchantReturnFiniteReturnWindow",
    "merchantReturnDays": 30,
    "returnMethod": "https://schema.org/ReturnByMail",
    "returnFees": "https://schema.org/FreeReturn"
  }
}

// Por página de producto:
{
  "@type": "Product",
  "name": "Bolso de Cuero",
  "offers": {
    "@type": "Offer",
    "price": "149.00",
    "priceCurrency": "USD",
    "availability": "https://schema.org/InStock",
    "hasMerchantReturnPolicy": { "@id": "https://example.com/#return-policy" },
    "shippingDetails": { "@id": "https://example.com/#shipping-us" }
  }
}
```

Esto valida exactamente igual que las políticas en línea, pero mantiene cada PDP más pequeña y más fácil de almacenar en caché.

## Anulaciones por producto

Algunos productos necesitan excepciones:

- **Artículos de gran tamaño** (muebles, colchones): política de devolución diferente (a menudo `OriginalShippingFees`).
- **Materiales peligrosos** (baterías, aerosoles): `MerchantReturnNotPermitted` o solo en tienda.
- **Hechos a medida** (grabados, monogramas): `MerchantReturnNotPermitted`.
- **Productos digitales**: `MerchantReturnNotPermitted`.

Anula a nivel de producto:

```ts
// Pseudocódigo para un producto Ordiko
{
  id: "prod_xyz",
  slug: "reloj-grabado-personalizado",
  returnPolicy: {
    category: "MerchantReturnNotPermitted",
    applicableCountry: ["US"],
  },
}
```

El orden de resolución: anulación de producto → política de tienda → ninguna.

## Validación

1. **Por página**: [Google Rich Results Test](https://search.google.com/test/rich-results) en PDPs representativos. Confirma "elegible" sin advertencias sobre devolución/envío.
2. **A gran escala**: [Schema Markup Validator](https://validator.schema.org) para sintaxis.
3. **En producción**: Google Search Console → Mejoras → Productos → informe de cobertura.

## Cómo Ordiko implementa esto

Ordiko emite `hasMerchantReturnPolicy` y `shippingDetails` en cada PDP automáticamente una vez que configuras:

- **Configuraciones → SEO → Política de Devolución** (un formulario, ~5 campos).
- **Configuraciones → SEO → Políticas de Envío** (una fila por destino).

El resolvedor en `src/lib/seo/return-policy.ts` se cascada: anulación de producto → política de tienda → ninguna. El renderizador emite el patrón de referencia con `@id`s estables en la Organización.

Sin trabajo de tema. Sin plugins. Sin escritura de JSON-LD.

## Errores comunes

1. **Duplicación en línea de la política de devolución en cada producto.** Valida pero produce 10–50KB de JSON redundante por PDP. Usa el patrón de referencia.
2. **Falta `applicableCountry`.** Esto es requerido. Especifica los países a los que se aplica la política.
3. **Enum de categoría incorrecto.** Usa la URL completa (`https://schema.org/MerchantReturnFiniteReturnWindow`), no el nombre corto.
4. **Políticas de envío que no coinciden con las tarifas de envío visibles.** El esquema y el contenido de la página deben coincidir o Google suprime el resultado enriquecido.
5. **Sin política de envío en absoluto.** Incluso las tiendas con envío gratuito deben emitir `shippingDetails` con un `shippingRate.value` de `0`.

## Preguntas frecuentes

**¿Cuándo se volvió obligatorio hasMerchantReturnPolicy?**
Google anunció el requisito en 2024 con la aplicación implementándose a lo largo de 2025 y principios de 2026. A partir de 2026, la falta de hasMerchantReturnPolicy en el esquema de Producto resulta en la pérdida de elegibilidad para resultados enriquecidos: tu producto ya no muestra precio, disponibilidad o estrellas de reseñas en SERPs.

**¿Puedo emitir una sola política para toda la tienda?**
Sí. Define hasMerchantReturnPolicy una vez en el esquema de Organización con un @id estable, luego refiérete a ella desde cada oferta de Producto a través de @id. Este es el patrón más limpio y lo que Ordiko emite por defecto.

**¿Qué pasa si mis productos tienen diferentes reglas de envío?**
Anula por producto. La mayoría de las tiendas tienen más del 90% de productos bajo la misma política y un 5–10% que necesitan anulaciones (sobredimensionados, materiales peligrosos, hechos a medida). Ordiko admite políticas por producto anulables que retroceden a la política de tienda.

**¿Esto afecta las citas de búsqueda de IA?**
Sí, indirectamente. Los motores de IA (Perplexity, ChatGPT, Claude) analizan el mismo JSON-LD que Google. Completar las políticas de devolución y envío mejora la citabilidad: los motores de IA prefieren páginas con datos estructurados completos porque pueden responder preguntas de los usuarios directamente.