# Sincronización de tickets para reventa

## Descripción general

Cuando un usuario quiere vender un ticket, menta tech necesita saber qué tickets posee y cuáles son elegibles para reventa. **Esta sincronización solo ocurre cuando el usuario quiere vender** — no es un proceso continuo ni requiere mantener un histórico completo.

Tu plataforma sigue siendo la fuente de verdad. menta tech consulta o recibe los datos solo cuando es necesario para habilitar la reventa.

Tu plataforma expone un endpoint que menta tech consulta cuando necesita verificar el ownership de los tickets del usuario.

{% callout type="info" title="Relación con Acceso a la venta" %}
La sincronización está ligada al acceso a la venta. Cuando un usuario quiere vender, menta tech o tu plataforma inician la sincronización según el modelo elegido. Para más detalles, consulta [Acceso a la venta](/es/guides/accessToSell-into).
{% /callout %}

## Estructura del objeto Ticket

Tu plataforma debe entregar a menta tech un objeto `ticket` con la siguiente estructura:

{% columns gap="2rem" align="center" %}

{% column width="0.5" valign="center" %}
{% callout type="info" title="Estructura del objeto ticket" %}
A niveles generales, la estructura `Ticket` mantiene la siguiente forma.
{% /callout %}

<br>

```json
[
  {
    "ticketId": "444",
    "externalReferenceEventId": "123",
    "showId": "456",
    "ticketOptionId": "789",
    "priceTypeId": "101",
    "price": 100,
    "currency": "USD",
    "buyer": "user@example.com",
    "tags": ["category:vip", "source:online"]
  }
]
```
{% /column %}

{% column width="0.5" valign="center" sticky=true %}

{% codeannotation highlight-lines="3" %}
**ticketId**: El ID del boleto único en tu plataforma.
{% /codeannotation %}

{% codeannotation highlight-lines="4" %}
**externalReferenceEventId**: El ID del evento al cual pertenece el boleto.
{% /codeannotation %}

{% codeannotation highlight-lines="5" %}
**showId**: El ID de la sesión o del show al cual el ticket da acceso.
{% /codeannotation %}

{% codeannotation highlight-lines="6" %}
**ticketOptionId**: El ID de la zona o tipo de boleto.
{% /codeannotation %}

{% codeannotation highlight-lines="7" %}
**priceTypeId**: El ID del tipo de precio o nivel de precio.
{% /codeannotation %}

{% codeannotation highlight-lines="8" %}
**price**: El precio final pagado por el usuario.
{% /codeannotation %}

{% codeannotation highlight-lines="9" %}
**currency**: La moneda que utilizó el usuario para abonar.
{% /codeannotation %}

{% codeannotation highlight-lines="10" %}
**buyer**: El correo electrónico del comprador.
{% /codeannotation %}

{% codeannotation highlight-lines="11" %}
**tags**: Array de strings en formato `key:value` para etiquetar información personalizada del boleto.
{% /codeannotation %}

{% /column %}
{% /columns %}

**Campos opcionales:**
- Ubicación y seating (sección, fila y asiento)
- Propiedades adicionales (props)
- Metadata operativa
- Tags (`tags`): Array de strings en formato `key:value` para etiquetado personalizado

## Cómo funciona

La sincronización está diseñada para integrarse con Smart Access Layer. menta tech orquesta automáticamente la sincronización cuando el usuario accede a las URLs de venta o antes, para acelerar la carga. Tu plataforma solo necesita exponer el endpoint y renderizar los componentes que brinda SAL.

## Endpoint de Verificación

### Cómo funciona

Tu plataforma expone un endpoint que devuelve todos los tickets que actualmente posee un usuario. menta tech consulta este endpoint en puntos clave:

- Cuando el usuario entra al flujo de reventa
- Antes de crear una publicación
- Antes de confirmar una venta
- Antes de completar una compra de reventa

Esto asegura verificación de ownership en tiempo real y evita que se publiquen o vendan tickets cancelados, refundados o transferidos.

### Flujo con Smart Access Layer

1. Tu UI llama a SAL con los `ticketIds` del usuario.
2. SAL responde con estados y acciones disponibles.
3. Cuando el usuario accede a una URL de venta, menta tech consulta automáticamente tu endpoint.
4. La sincronización se orquesta del lado de menta tech, sin intervención adicional.

{% diagram type="sequence" height="550px" %}
{
  "nodes": [
    {
      "id": "actor-1",
      "type": "sequence-actor",
      "position": {
        "x": 21.333333333333336,
        "y": 30
      },
      "data": {
        "label": "Vendedor",
        "accentColor": "#22c55e",
        "lifelineHeight": 500
      }
    },
    {
      "id": "actor-2",
      "type": "sequence-actor",
      "position": {
        "x": 605.2162993197097,
        "y": 30
      },
      "data": {
        "label": "menta tech",
        "accentColor": "#3b82f6",
        "lifelineHeight": 550
      }
    },
    {
      "id": "actor-3",
      "type": "sequence-actor",
      "position": {
        "x": 296.5055633245897,
        "y": 30
      },
      "data": {
        "label": "Tu plataforma",
        "accentColor": "#f97316",
        "lifelineHeight": 475
      }
    },
    {
      "id": "msg-1",
      "type": "sequence-message",
      "position": {
        "x": -29.125985590712688,
        "y": 73.51690818717502
      },
      "data": {
        "label": "Usuario ingresa a la sección\nde sus tickets"
      }
    },
    {
      "id": "msg-2",
      "type": "sequence-message",
      "position": {
        "x": 214.6853374070431,
        "y": 164.12148590852757
      },
      "data": {
        "label": "Solicitas la estructura para renderizar\nbotones de venta"
      }
    },
    {
      "id": "msg-3",
      "type": "sequence-message",
      "position": {
        "x": 542.5026086166031,
        "y": 233.45543217464973
      },
      "data": {
        "label": "Retorna estructura de botones",
        "isReturn": true
      }
    },
    {
      "id": "msg-4",
      "type": "sequence-message",
      "position": {
        "x": 227.06697791581803,
        "y": 274.18210726412326
      },
      "data": {
        "label": "Dibujas los botones en el frontend\ndel usuario vendedor",
        "isReturn": true
      }
    },
    {
      "id": "msg-1765986991767",
      "type": "sequence-message",
      "position": {
        "x": -40.16298568880333,
        "y": 392.42375081594577
      },
      "data": {
        "label": "El usuario clickea el boton de vender"
      }
    },
    {
      "id": "msg-1765987013125",
      "type": "sequence-message",
      "position": {
        "x": 459.96682051132154,
        "y": 461.3755170736649
      },
      "data": {
        "label": "Solicita los tickets que posee el usuario (pull)"
      }
    },
    {
      "id": "msg-1765987128632",
      "type": "sequence-message",
      "position": {
        "x": -40.16298568880333,
        "y": 567.7917548245065
      },
      "data": {
        "label": "Completa el flujo de publicación"
      }
    },
    {
      "id": "msg-1766169147521",
      "type": "sequence-message",
      "position": {
        "x": 189.87360371053717,
        "y": 503.00268826845223
      },
      "data": {
        "label": "Retornas todos los boletos de la orden a menta tech",
        "isReturn": true
      }
    },
    {
      "id": "shape-1766170757110",
      "type": "shape",
      "position": {
        "x": -48.5792044969711,
        "y": 73.51690818717502
      },
      "data": {
        "shapeType": "rectangle",
        "width": 810,
        "height": 287,
        "borderStyle": "solid",
        "borderWidth": 1,
        "borderColor": "#ffffff",
        "backgroundColor": "#f0f6ff",
        "text": "Smart Access Layer",
        "textPosition": "top",
        "fontSize": 10,
        "textColor": "#6ca2f9",
        "zIndex": -10,
        "subtitle": "",
        "textOffsetY": 5
      }
    },
    {
      "id": "shape-1766171242413",
      "type": "shape",
      "position": {
        "x": -48.5792044969711,
        "y": 379.94817057389304
      },
      "data": {
        "shapeType": "rectangle",
        "width": 810,
        "height": 259,
        "borderStyle": "dashed",
        "borderWidth": 1,
        "borderColor": "#ffffff",
        "backgroundColor": "#fdfaff",
        "text": "Sincronización de tickets",
        "textPosition": "top",
        "fontSize": 10,
        "textColor": "#dab3e6",
        "textOffsetX": 0,
        "textOffsetY": 3,
        "zIndex": 0
      }
    }
  ],
  "edges": [
    {
      "id": "edge-1765986752562",
      "source": "msg-1",
      "target": "actor-3",
      "sourceHandle": null,
      "targetHandle": "h-0",
      "animated": true,
      "style": {
        "stroke": "#9ca3af",
        "strokeWidth": 1.5
      },
      "markerEnd": {
        "type": "arrowclosed",
        "color": "#9ca3af",
        "width": 16,
        "height": 16
      }
    },
    {
      "id": "edge-1765986794619",
      "source": "msg-2",
      "target": "actor-2",
      "sourceHandle": null,
      "targetHandle": "h-4",
      "animated": true,
      "style": {
        "stroke": "#9ca3af",
        "strokeWidth": 1.5
      },
      "markerEnd": {
        "type": "arrowclosed",
        "color": "#9ca3af",
        "width": 16,
        "height": 16
      }
    },
    {
      "id": "edge-1766169066535",
      "source": "actor-3",
      "target": "msg-3",
      "sourceHandle": "s-8",
      "targetHandle": null,
      "animated": true,
      "style": {
        "stroke": "#9ca3af",
        "strokeWidth": 1.5
      },
      "markerStart": {
        "type": "arrowclosed",
        "color": "#9ca3af",
        "width": 16,
        "height": 16
      },
      "data": {
        "isReversed": true
      }
    },
    {
      "id": "edge-1766169090822",
      "source": "actor-1",
      "target": "msg-4",
      "sourceHandle": "s-10",
      "targetHandle": null,
      "animated": true,
      "style": {
        "stroke": "#9ca3af",
        "strokeWidth": 1.5
      },
      "markerStart": {
        "type": "arrowclosed",
        "color": "#9ca3af",
        "width": 16,
        "height": 16
      },
      "data": {
        "isReversed": true
      }
    },
    {
      "id": "edge-1766169109389",
      "source": "msg-1765986991767",
      "target": "actor-2",
      "sourceHandle": null,
      "targetHandle": "h-14",
      "animated": true,
      "style": {
        "stroke": "#9ca3af",
        "strokeWidth": 1.5
      },
      "markerEnd": {
        "type": "arrowclosed",
        "color": "#9ca3af",
        "width": 16,
        "height": 16
      }
    },
    {
      "id": "edge-1766169125769",
      "source": "actor-3",
      "target": "msg-1765987013125",
      "sourceHandle": "s-20",
      "targetHandle": null,
      "animated": true,
      "style": {
        "stroke": "#9ca3af",
        "strokeWidth": 1.5
      },
      "markerStart": {
        "type": "arrowclosed",
        "color": "#9ca3af",
        "width": 16,
        "height": 16
      },
      "data": {
        "isReversed": true
      }
    },
    {
      "id": "edge-1766169207959",
      "source": "msg-1766169147521",
      "target": "actor-2",
      "sourceHandle": null,
      "targetHandle": "h-19",
      "animated": true,
      "style": {
        "stroke": "#9ca3af",
        "strokeWidth": 1.5
      },
      "markerEnd": {
        "type": "arrowclosed",
        "color": "#9ca3af",
        "width": 16,
        "height": 16
      },
      "data": {
        "isReversed": false
      }
    },
    {
      "id": "edge-1766169262499",
      "source": "msg-1765987128632",
      "target": "actor-2",
      "sourceHandle": null,
      "targetHandle": "h-22",
      "animated": true,
      "style": {
        "stroke": "#9ca3af",
        "strokeWidth": 1.5
      },
      "markerEnd": {
        "type": "arrowclosed",
        "color": "#9ca3af",
        "width": 16,
        "height": 16
      },
      "data": {
        "isReversed": false
      }
    }
  ]
}
{% /diagram %}

{% columns gap="2.5rem" %}
{% column %}
### Cuándo usar este modelo

Ideal si:
- Ya tienes un endpoint de "Mis Tickets" o historial de compras
- El estado del ticket cambia con frecuencia
- Priorizas consistencia y exactitud
- Prefieres mantener la lógica de estado en tu sistema
- Quieres que menta tech orqueste la sincronización automáticamente
{% /column %}

{% column %}
### Características clave

- menta tech no almacena inventarios históricos
- El estado se consulta siempre directo desde tu plataforma
- Mínima carga operativa
- Menor riesgo de inconsistencias
- Sincronización automática cuando el usuario quiere vender
{% /column %}
{% /columns %}

## Implementación

#### Request

En primer lugar, deberás exponer un endpoint al cual menta tech consultará enviándote el usuario identificador del usuario vendedor (normalmente el correo electrónico):

```
GET https://es.tuplataforma.com/api/tickets?user={userEmail}
```

{% columns gap="2rem" align="center" %}

{% column width="0.5" valign="center" %}
#### Respuesta

El endpoint devuelve la lista de tickets que actualmente posee el usuario:

```json
[
    {
        "eventId": "5766",
        "ticketId": "ab7a36b6",
        "showId": "11c968de",
        "paidPrice": 150.00,
        "ticketOptionId": "45",
        "ticketTypeId": "88",
        "seating": {
            "row": "D",
            "seat": "4",
            "section": "South Terrace"
        },
        "properties": {
            "orderId": "ON_hcUE2N"
        },
        "tags": ["source:online", "promo:early-bird"]
    },
    {
        "eventId": "5766",
        "ticketId": "ab7a36b7",
        "showId": "11c968de",
        "paidPrice": 150.00,
        "ticketOptionId": "45",
        "ticketTypeId": "88",
        "seating": {
            "row": "D",
            "seat": "5",
            "section": "South Terrace"
        },
        "properties": {
            "orderId": "ON_hcUE2N"
        },
        "tags": ["source:box-office", "category:vip"]
    }
]
```
{% /column %}

{% column width="0.5" valign="top" %}
### Seguridad

Dos capas recomendadas:

1. **Restricción por IP**: Crea una allowlist que solo permita tráfico desde los servidores de menta tech.
2. **Encabezado con Clave Secreta**: menta tech envía todas las solicitudes HTTPS con una clave secreta en un header.


### Cómo usa menta tech esta respuesta

- Determina qué tickets puede listar el usuario para reventa
- Valida ownership inmediatamente antes de publicar o vender
- Previene la reventa de tickets inválidos
- Asegura que el flujo siempre refleje el estado actual de tu sistema

Cada acción crítica se valida contra este endpoint. menta tech nunca asume ownership basándose en datos cacheados.

### Notas importantes

- La estructura de la respuesta debe coincidir exactamente con el esquema predefinido
- Los nombres de campos pueden diferir si los identificadores se mapean consistentemente
- El endpoint debe ser confiable y estar disponible durante los flujos de reventa

**Importante:** Solo devuelve tickets válidos y que pertenecen al usuario. Los cancelados, reembolsados, transferidos o invalidados deben *omitirse*.

{% /column %}

{% /columns %}



