# API PassKit de Apple Wallet

La API PassKit Designer le permite crear, actualizar, descargar y gestionar [pases de Apple Wallet](/es/product/messaging-channels/apple-wallet-passes/) de forma programática. Admite las mismas operaciones que realiza el creador de pases en el Panel de Control. Úsela para emitir tarjetas de fidelidad, cupones, entradas para eventos, tarjetas de embarque y tarjetas de tienda, y para enviar actualizaciones en tiempo real a los pases ya instalados en los dispositivos de sus usuarios.

<Aside type="note" title="Requisito previo: certificado PassKit">
Antes de poder crear pases para una aplicación, se debe configurar un certificado de firma de iOS PassKit para esa aplicación. El certificado se gestiona en el Panel de Control de Pushwoosh. Sin él, las solicitudes de `create` y `update` fallan. Consulte [Configuración de pases de Apple Wallet para iOS](/es/developer/first-steps/connect-messaging-services/ios-configuration/ios-wallet-pass-configuration/).
</Aside>

## URL base

```
https://apple-passkit.svc-nue.pushwoosh.com
```

Todos los endpoints se sirven a través de HTTPS. Las solicitudes y respuestas utilizan `application/json` a menos que se indique lo contrario.

## Autenticación

Cada solicitud debe incluir un encabezado `Authorization` con su [token de acceso a la API de Pushwoosh](/es/developer/api-reference/api-access-token/):

```
Authorization: Token <api-token>
```

La cuenta propietaria del token debe ser la propietaria de la aplicación a la que hace referencia `applicationCode`. Una solicitud para una aplicación que pertenece a otra cuenta devuelve `403 Forbidden`.

## Convenciones

*   **Nomenclatura de campos:** Los campos JSON utilizan `lowerCamelCase` (por ejemplo, `passTypeIdentifier`, `serialNumber`, `backgroundColor`).
*   **Campos no rellenados:** las respuestas incluyen todos los campos, incluso cuando están vacíos o tienen valor cero.
*   **Datos binarios:** los campos de `bytes` como `pkpassData` y los `data` de imagen son cadenas codificadas en Base64 en JSON.
*   **Números de serie:** el `serialNumber` siempre es asignado por el servidor cuando se crea un pase. Cualquier valor que envíe al crear será ignorado; este identifica el pase para todas las operaciones posteriores.

### Respuestas de error

La API asigna códigos de estado internos a códigos de estado HTTP:

| Estado HTTP | Significado |
| :--- | :--- |
| `400 Bad Request` | Argumento no válido: falta un campo obligatorio o está mal formado. |
| `401 Unauthorized` | Encabezado `Authorization` ausente o no válido. |
| `403 Forbidden` | La aplicación no pertenece a la cuenta del solicitante. |
| `404 Not Found` | No se encontró el pase, la plantilla o la aplicación. |
| `503 Service Unavailable` | El servicio está al máximo de su capacidad o no está disponible temporalmente. |

## Endpoints

| Método | Ruta | Descripción |
| :--- | :--- | :--- |
| `POST` | `/api/pass/validate` | Validar una configuración de pase |
| `POST` | `/api/pass/create` | Crear un nuevo `.pkpass` |
| `POST` | `/api/pass/update/{serialNumber}` | Actualizar un pase existente y notificar a los dispositivos |
| `GET` | `/api/passes` | Listar todos los pases para una aplicación |
| `GET` | `/api/pass/{applicationCode}/{serialNumber}` | Obtener un único pase |
| `GET` | `/api/pass/{applicationCode}/{serialNumber}/download` | Descargar el `.pkpass` de un pase existente |
| `DELETE` | `/api/pass/{applicationCode}/{serialNumber}` | Eliminar un pase |
| `GET` | `/api/pass/{serialNumber}/registrations` | Listar dispositivos registrados para un pase |
| `GET` | `/api/config` | Obtener la configuración de PassKit de la aplicación |
| `GET` | `/api/templates` | Listar plantillas de pases disponibles |
| `GET` | `/api/templates/{filename}` | Obtener una única plantilla |

## Crear un pase

Genera, firma y almacena un nuevo pase, y luego devuelve su número de serie asignado por el servidor.

`POST` `/api/pass/create`

<Aside type="tip">
Para obtener el archivo `.pkpass` en sí, llame a [Descargar un pase](#download-a-pass) (o cree un [enlace de instalación / código QR](#share-a-pass-as-a-qr-code)) con el número de serie devuelto.
</Aside>

### Cuerpo de la solicitud

| Parámetro | Tipo | Requerido | Descripción |
| :--- | :--- | :--- | :--- |
| `pass` | objeto | Sí | El [objeto de pase](#pass-object) que describe el pase. |
| `images` | array de objetos | No | [Imágenes del pase](#pass-image-object) (icono, logo, etc.). `icon` y `logo` son necesarios para un pase válido. |
| `userId` | string | Sí | El User ID de Pushwoosh al que se emite el pase. |
| `applicationCode` | string | Sí | El [código de aplicación de Pushwoosh](/es/developer/api-reference/api-identifiers/#application-code). |

<Aside type="note">
Al crear, si se omiten `teamIdentifier`, `passTypeIdentifier` u `organizationName`, tomarán por defecto los valores del certificado configurado de la aplicación. `formatVersion` toma por defecto el valor `1`. El `serialNumber` se asigna en el lado del servidor.
</Aside>

##### Ejemplo de solicitud

```json
{
  "applicationCode": "XXXXX-XXXXX",
  "userId": "user-123",
  "pass": {
    "description": "Acme loyalty card",
    "logoText": "Acme",
    "backgroundColor": "rgb(60, 65, 76)",
    "foregroundColor": "rgb(255, 255, 255)",
    "labelColor": "rgb(255, 255, 255)",
    "storeCard": {
      "primaryFields": [
        { "key": "balance", "label": "BALANCE", "value": "1200 pts" }
      ],
      "secondaryFields": [
        { "key": "member", "label": "MEMBER", "value": "Jane Doe" }
      ]
    },
    "barcodes": [
      {
        "format": "PKBarcodeFormatQR",
        "message": "1234567890",
        "messageEncoding": "iso-8859-1"
      }
    ]
  },
  "images": [
    { "imageType": "icon", "data": "<base64>", "contentType": "image/png" },
    { "imageType": "logo", "data": "<base64>", "contentType": "image/png" }
  ]
}
```

### Respuesta

| Campo | Tipo | Descripción |
| :--- | :--- | :--- |
| `serialNumber` | string | Identidad única asignada por el servidor del pase creado. Úselo para obtener el pase ([Obtener un pase](#get-a-pass)) o descargar el `.pkpass` ([Descargar un pase](#download-a-pass)). |
| `message` | string | Mensaje de resultado. |

##### Ejemplo de respuesta

```json
{
  "serialNumber": "a1b2c3d4-1234-5678-9abc-def012345678",
  "message": "Pass created successfully"
}
```

## Validar un pase

Comprueba la configuración de un pase con las especificaciones de Apple sin crear un archivo. Es útil antes de llamar a crear.

`POST` `/api/pass/validate`

### Cuerpo de la solicitud

| Parámetro | Tipo | Requerido | Descripción |
| :--- | :--- | :--- | :--- |
| `pass` | objeto | Sí | El [objeto de pase](#pass-object) a validar. |

### Respuesta

| Campo | Tipo | Descripción |
| :--- | :--- | :--- |
| `valid` | boolean | Indica si el pase supera la validación. |
| `errors` | array de strings | Problemas bloqueantes que deben ser corregidos. |
| `warnings` | array de strings | Advertencias no bloqueantes. |

## Actualizar un pase

Regenera el pase con nuevo contenido, lo vuelve a firmar, incrementa su etiqueta de actualización y envía una **notificación push silenciosa** a cada dispositivo que registró el pase. iOS luego recupera e instala la versión actualizada en segundo plano.

`POST` `/api/pass/update/{serialNumber}`

### Parámetros de ruta

| Parámetro | Tipo | Descripción |
| :--- | :--- | :--- |
| `serialNumber` | string | El número de serie devuelto cuando se creó el pase. |

### Cuerpo de la solicitud

| Parámetro | Tipo | Requerido | Descripción |
| :--- | :--- | :--- | :--- |
| `updates` | objeto | Sí | El [objeto de pase](#pass-object) completo con el nuevo contenido. |
| `applicationCode` | string | Sí | El código de aplicación de Pushwoosh. |

El `serialNumber` (de la ruta) y el token de autenticación del pase son conservados por el servidor independientemente de lo que envíe.

### Respuesta

| Campo | Tipo | Descripción |
| :--- | :--- | :--- |
| `success` | boolean | Indica si la actualización tuvo éxito. |
| `updateTag` | integer | Nueva etiqueta de actualización (una marca de tiempo de Unix). |
| `message` | string | Mensaje de resultado. |

## Listar pases

Devuelve una lista paginada y ordenada de los pases almacenados para una aplicación.

`GET` `/api/passes?applicationCode=XXXXX-XXXXX&page=0&perPage=20`

### Parámetros de consulta

| Parámetro | Tipo | Requerido | Descripción |
| :--- | :--- | :--- | :--- |
| `applicationCode` | string | Sí | El código de aplicación de Pushwoosh. |
| `orderBy` | string | No | Campo de ordenación: `UPDATED` (por defecto) o `CREATED`. |
| `orderDirection` | string | No | Dirección de ordenación: `DESC` (por defecto, los más nuevos primero) o `ASC`. |
| `page` | integer | No | Índice de página basado en cero. Por defecto es `0`. |
| `perPage` | integer | No | Tamaño de la página. `0` u omitido utiliza el valor por defecto del servidor. |

### Respuesta

| Campo | Tipo | Descripción |
| :--- | :--- | :--- |
| `passes` | array de objetos | La página actual de [registros de pases](#pass-record-object). |
| `page` | integer | El índice de página devuelto. |
| `perPage` | integer | El tamaño de página utilizado para esta respuesta. |
| `total` | integer | Número total de pases para la aplicación en todas las páginas. |

##### Ejemplo de respuesta

```json
{
  "passes": [ /* pass records */ ],
  "page": 0,
  "perPage": 20,
  "total": 137
}
```

## Obtener un pase

Devuelve un único pase almacenado, incluyendo su objeto de pase completo.

`GET` `/api/pass/{applicationCode}/{serialNumber}`

### Parámetros de ruta

| Parámetro | Tipo | Descripción |
| :--- | :--- | :--- |
| `applicationCode` | string | El código de aplicación de Pushwoosh. |
| `serialNumber` | string | El número de serie del pase. |

### Respuesta

Devuelve `{ "pass": { ... } }`, un único [registro de pase](#pass-record-object).

## Descargar un pase

Devuelve el archivo `.pkpass` almacenado de un pase existente.

`GET` `/api/pass/{applicationCode}/{serialNumber}/download`

### Respuesta

| Campo | Tipo | Descripción |
| :--- | :--- | :--- |
| `pkpassData` | string (Base64) | El archivo `.pkpass`. |
| `filename` | string | Nombre de archivo sugerido. |

## Eliminar un pase

Elimina un registro de pase y su archivo `.pkpass` almacenado.

`DELETE` `/api/pass/{applicationCode}/{serialNumber}`

### Respuesta

| Campo | Tipo | Descripción |
| :--- | :--- | :--- |
| `success` | boolean | Indica si el pase fue eliminado. |
| `message` | string | Mensaje de resultado. |

## Obtener registros de pases

Lista los dispositivos que han añadido el pase y están registrados para recibir actualizaciones.

`GET` `/api/pass/{serialNumber}/registrations?applicationCode=XXXXX-XXXXX`

### Respuesta

Devuelve `{ "registrations": [ ... ] }`, donde cada elemento tiene:

| Campo | Tipo | Descripción |
| :--- | :--- | :--- |
| `deviceLibraryIdentifier` | string | Identificador de la biblioteca de dispositivos de Apple. |
| `pushToken` | string | El token push del pase para el dispositivo. |

## Obtener configuración

Devuelve la configuración de PassKit resuelta para una aplicación a partir de su certificado.

`GET` `/api/config?applicationCode=XXXXX-XXXXX`

### Respuesta

| Campo | Tipo | Descripción |
| :--- | :--- | :--- |
| `teamIdentifier` | string | ID de equipo de Apple del certificado. |
| `passTypeIdentifier` | string | ID de tipo de pase del certificado. |
| `organizationName` | string | Nombre de la organización del certificado. |
| `hasCertificate` | boolean | Indica si hay un certificado configurado. |
| `webServiceUrl` | string | URL base del servicio web del pase. Los clientes construyen un enlace de instalación añadiendo `/v1/passes/{passType}/{serial}?token={authToken}`. |

## Plantillas

Liste las plantillas de pases disponibles, o recupere una como un [objeto de pase](#pass-object) que puede usar como punto de partida.

`GET` `/api/templates` — devuelve `{ "templates": [ { "filename", "name", "description", "style" } ] }`.

`GET` `/api/templates/{filename}` — devuelve `{ "template": { ...objeto de pase... } }`.

## Compartir un pase como un código QR

Para permitir que los usuarios añadan un pase escaneando un código QR (o tocando un enlace), codifique la **URL de instalación** del pase en un código QR. La URL se construye a partir de los valores que ya obtiene de la API:

```
{webServiceUrl}/v1/passes/{passTypeIdentifier}/{serialNumber}?token={authenticationToken}
```

| Parte de la URL | Dónde obtenerlo |
| :--- | :--- |
| `webServiceUrl` | [`GET /api/config`](#get-configuration) → `webServiceUrl` |
| `passTypeIdentifier` | [registro de pase](#pass-record-object) → `pass.passTypeIdentifier` (de listar/obtener) |
| `serialNumber` | [registro de pase](#pass-record-object) → `serialNumber` |
| `authenticationToken` | [registro de pase](#pass-record-object) → `pass.authenticationToken` |

Ejemplo:

```
https://apple-passkit.svc-nue.pushwoosh.com/v1/passes/pass.com.acme.loyalty/a1b2c3d4-1234-5678-9abc-def012345678?token=AbC123XyZ
```

Renderice esta URL como un código QR con cualquier biblioteca de QR. Cuando un usuario lo escanea, su dispositivo abre el enlace, descarga el último `.pkpass` y Wallet le pide que lo añada, lo que también registra el dispositivo para recibir actualizaciones.

## Referencia de objetos

### Objeto de pase

| Campo | Tipo | Descripción |
| :--- | :--- | :--- |
| `formatVersion` | integer | Versión del formato del pase. Por defecto es `1`. |
| `passTypeIdentifier` | string | ID de tipo de pase de Apple (`pass.com.yourcompany.passtype`). Toma el valor por defecto del certificado. |
| `serialNumber` | string | Asignado por el servidor al crear; identifica el pase. |
| `teamIdentifier` | string | ID de equipo de Apple. Toma el valor por defecto del certificado. |
| `organizationName` | string | Organización que se muestra en el pase. Toma el valor por defecto del certificado. |
| `description` | string | Descripción legible por humanos (requerida por Apple). |
| `boardingPass` / `coupon` / `eventTicket` / `storeCard` / `generic` | objeto | El estilo del pase. **Exactamente uno** debe estar configurado. Consulte [grupos de campos](#field-group-object). |
| `backgroundColor` | string | Color de fondo, `rgb(r, g, b)`. |
| `foregroundColor` | string | Color de primer plano (texto), `rgb(r, g, b)`. |
| `labelColor` | string | Color de la etiqueta del campo, `rgb(r, g, b)`. |
| `logoText` | string | Texto que se muestra junto al logo. |
| `suppressStripShine` | boolean | Desactivar el efecto de brillo en la imagen de la tira. |
| `barcodes` | array | [Códigos de barras](#barcode-object) que se muestran en el pase. |
| `locations` | array | [Ubicaciones](#location-object) que hacen que el pase sea relevante. |
| `beacons` | array | [Beacons](#beacon-object) que hacen que el pase sea relevante. |
| `relevantDate` | string | Fecha ISO 8601 en la que el pase se vuelve relevante. |
| `maxDistance` | integer | Distancia máxima (metros) para la relevancia de la ubicación. |
| `expirationDate` | string | Fecha de caducidad ISO 8601. |
| `voided` | boolean | Marca el pase como nulo. |
| `groupingIdentifier` | string | Agrupa pases relacionados (entradas de eventos/tarjetas de embarque). |
| `userInfo` | objeto (mapa) | Datos de la aplicación de clave/valor arbitrarios. |

<Aside type="note">
`authenticationToken` y `webServiceUrl` son gestionados por el servicio y no necesitan ser configurados por los clientes de la API.
</Aside>

### Objeto de grupo de campos

Cada estilo de pase (`boardingPass`, `coupon`, `eventTicket`, `storeCard`, `generic`) agrupa [campos](#field-object) en áreas:

| Campo | Tipo | Descripción |
| :--- | :--- | :--- |
| `headerFields` | array | Se muestra en el encabezado del pase (visible cuando está apilado en Wallet). |
| `primaryFields` | array | Campos más prominentes. |
| `secondaryFields` | array | Debajo de los campos primarios. |
| `auxiliaryFields` | array | Campos adicionales debajo de los secundarios. |
| `backFields` | array | Se muestra en el reverso del pase. |

`boardingPass` tiene adicionalmente `transitType` (`PKTransitTypeAir`, `PKTransitTypeTrain`, `PKTransitTypeBus`, `PKTransitTypeBoat`, o `PKTransitTypeGeneric`).

### Objeto de campo

| Campo | Tipo | Descripción |
| :--- | :--- | :--- |
| `key` | string | Clave de campo única dentro del pase. |
| `label` | string | Etiqueta del campo. |
| `value` | string | Valor del campo (texto o número como cadena). |
| `changeMessage` | string | Mensaje que se muestra cuando el valor cambia (use `%@` como marcador de posición). |
| `textAlignment` | string | Valor de `PKTextAlignment`. |
| `dateStyle` / `timeStyle` | string | `PKDateStyle` para el formato de fecha/hora. |
| `isRelative` | boolean | Mostrar la fecha relativa a ahora. |
| `numberStyle` | string | `PKNumberStyle` para el formato de número. |
| `currencyCode` | string | Código de moneda ISO 4217. |
| `dataDetectorTypes` | array de strings | Detectores de datos para aplicar al valor. |

### Objeto de código de barras

| Campo | Tipo | Descripción |
| :--- | :--- | :--- |
| `format` | string | `PKBarcodeFormatQR`, `PKBarcodeFormatPDF417`, `PKBarcodeFormatAztec`, o `PKBarcodeFormatCode128`. |
| `message` | string | Datos codificados en el código de barras. |
| `messageEncoding` | string | Codificación de texto, típicamente `iso-8859-1`. |
| `altText` | string | Texto que se muestra debajo del código de barras. |

### Objeto de ubicación

| Campo | Tipo | Descripción |
| :--- | :--- | :--- |
| `latitude` | number | Latitud. |
| `longitude` | number | Longitud. |
| `altitude` | number | Altitud en metros. |
| `relevantText` | string | Texto que se muestra en la pantalla de bloqueo cerca de esta ubicación. |

### Objeto de beacon

| Campo | Tipo | Descripción |
| :--- | :--- | :--- |
| `proximityUuid` | string | UUID de proximidad de iBeacon. |
| `major` | integer | Valor principal (major). |
| `minor` | integer | Valor secundario (minor). |
| `relevantText` | string | Texto que se muestra en la pantalla de bloqueo cerca de este beacon. |

### Objeto de imagen del pase

| Campo | Tipo | Descripción |
| :--- | :--- | :--- |
| `imageType` | string | Uno de `icon`, `logo`, `strip`, `background`, `footer`, `thumbnail`. `icon` y `logo` son obligatorios. |
| `data` | string (Base64) | Bytes de la imagen. |
| `contentType` | string | Tipo MIME, por ejemplo `image/png`. |

### Objeto de registro de pase

Devuelto por los endpoints de listar/obtener.

| Campo | Tipo | Descripción |
| :--- | :--- | :--- |
| `serialNumber` | string | Número de serie del pase. |
| `passTypeIdentifier` | string | ID de tipo de pase. |
| `organizationName` | string | Nombre de la organización. |
| `description` | string | Descripción del pase. |
| `createdAt` | string | Marca de tiempo de creación (RFC 3339). |
| `updatedAt` | string | Marca de tiempo de la última actualización (RFC 3339). |
| `updateTag` | integer | Etiqueta de actualización actual. |
| `pass` | objeto | El [objeto de pase](#pass-object) completo, para editar. |
| `userId` | string | El User ID de Pushwoosh al que se emitió el pase. |