# Apple Wallet PassKit API

PassKit Designer API 允许您以编程方式创建、更新、下载和管理 [Apple Wallet 通票](/zh/product/messaging-channels/apple-wallet-passes/)。它支持与控制面板中的通票构建器相同的操作。使用它来发行会员卡、优惠券、活动门票、登机牌和商店卡，并向已安装在用户设备上的通票推送实时更新。

<Aside type="note" title="前提条件：PassKit 证书">
在为应用程序创建通票之前，必须为该应用程序配置 iOS PassKit 签名证书。该证书在 Pushwoosh 控制面板中管理。没有它，`create` 和 `update` 请求将失败。请参阅 [iOS 的 Apple Wallet 通票配置](/zh/developer/first-steps/connect-messaging-services/ios-configuration/ios-wallet-pass-configuration/)。
</Aside>

## 基 URL

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

所有端点都通过 HTTPS 提供服务。除非另有说明，否则请求和响应均使用 `application/json`。

## 身份验证

每个请求都必须包含一个 `Authorization` 标头，其中包含您的 [Pushwoosh API 访问令牌](/zh/developer/api-reference/api-access-token/)：

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

拥有令牌的账户必须拥有 `applicationCode` 引用的应用程序。对属于另一个账户的应用程序的请求将返回 `403 Forbidden`。

## 约定

*   **字段命名：** JSON 字段使用 `lowerCamelCase`（例如，`passTypeIdentifier`、`serialNumber`、`backgroundColor`）。
*   **未填充字段：** 响应包含所有字段，即使它们为空或值为零。
*   **二进制数据：** `bytes` 字段（如 `pkpassData` 和图像 `data`）在 JSON 中是 Base64 编码的字符串。
*   **序列号：** `serialNumber` 总是在创建通票时由服务器分配。您在创建时发送的任何值都将被忽略；它用于标识通票以进行后续所有操作。

### 错误响应

API 将内部状态码映射到 HTTP 状态码：

| HTTP 状态 | 含义 |
| :---- | :---- |
| `400 Bad Request` | 无效参数——缺少必需字段或字段格式不正确。 |
| `401 Unauthorized` | 缺少或无效的 `Authorization` 标头。 |
| `403 Forbidden` | 该应用程序不属于调用者的账户。 |
| `404 Not Found` | 未找到通票、模板或应用程序。 |
| `503 Service Unavailable` | 服务已满负荷或暂时不可用。 |

## 端点

| 方法 | 路径 | 描述 |
| :---- | :---- | :---- |
| `POST` | `/api/pass/validate` | 验证通票配置 |
| `POST` | `/api/pass/create` | 创建一个新的 `.pkpass` |
| `POST` | `/api/pass/update/{serialNumber}` | 更新现有通票并通知设备 |
| `GET` | `/api/passes` | 列出应用程序的所有通票 |
| `GET` | `/api/pass/{applicationCode}/{serialNumber}` | 获取单个通票 |
| `GET` | `/api/pass/{applicationCode}/{serialNumber}/download` | 下载现有通票的 `.pkpass` |
| `DELETE` | `/api/pass/{applicationCode}/{serialNumber}` | 删除通票 |
| `GET` | `/api/pass/{serialNumber}/registrations` | 列出为通票注册的设备 |
| `GET` | `/api/config` | 获取应用程序的 PassKit 配置 |
| `GET` | `/api/templates` | 列出可用的通票模板 |
| `GET` | `/api/templates/{filename}` | 获取单个模板 |


## 创建通票

生成、签名并存储一个新的通票，然后返回其服务器分配的序列号。

`POST` `/api/pass/create`

<Aside type="tip">
要获取 `.pkpass` 文件本身，请使用返回的序列号调用[下载通票](#download-a-pass)（或构建[安装链接/二维码](#share-a-pass-as-a-qr-code)）。
</Aside>


### 请求正文

| 参数 | 类型 | 必需 | 描述 |
| :---- | :---- | :---- | :---- |
| `pass` | object | 是 | 描述通票的[通票对象](#pass-object)。 |
| `images` | array of objects | 否 | [通票图片](#pass-image-object)（图标、标志等）。`icon` 和 `logo` 是有效通票的必需项。 |
| `userId` | string | 是 | 通票发行给的 Pushwoosh User ID。 |
| `applicationCode` | string | 是 | [Pushwoosh 应用程序代码](/zh/developer/api-reference/api-identifiers/#application-code)。 |

<Aside type="note">
创建时，如果省略 `teamIdentifier`、`passTypeIdentifier` 或 `organizationName`，它们将默认为应用程序配置证书中的值。`formatVersion` 默认为 `1`。`serialNumber` 在服务器端分配。
</Aside>

##### 请求示例

```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" }
  ]
}
```

### 响应

| 字段 | 类型 | 描述 |
| :---- | :---- | :---- |
| `serialNumber` | string | 服务器分配的已创建通票的唯一标识。使用它来获取通票（[获取通票](#get-a-pass)）或下载 `.pkpass`（[下载通票](#download-a-pass)）。 |
| `message` | string | 结果消息。 |

##### 响应示例

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

## 验证通票

根据 Apple 的规范检查通票配置，而无需创建文件。在调用 create 之前很有用。

`POST` `/api/pass/validate`

### 请求正文

| 参数 | 类型 | 必需 | 描述 |
| :---- | :---- | :---- | :---- |
| `pass` | object | 是 | 要验证的[通票对象](#pass-object)。 |

### 响应

| 字段 | 类型 | 描述 |
| :---- | :---- | :---- |
| `valid` | boolean | 通票是否通过验证。 |
| `errors` | array of strings | 必须修复的阻塞性问题。 |
| `warnings` | array of strings | 非阻塞性建议。 |



## 更新通票

用新内容重新生成通票，重新签名，增加其更新标签，并向注册了该通票的每个设备发送**静默推送通知**。然后，iOS 会在后台获取并安装更新后的版本。

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

### 路径参数

| 参数 | 类型 | 描述 |
| :---- | :---- | :---- |
| `serialNumber` | string | 创建通票时返回的序列号。 |

### 请求正文

| 参数 | 类型 | 必需 | 描述 |
| :---- | :---- | :---- | :---- |
| `updates` | object | 是 | 包含新内容的完整[通票对象](#pass-object)。 |
| `applicationCode` | string | 是 | Pushwoosh 应用程序代码。 |

无论您发送什么，服务器都会保留 `serialNumber`（来自路径）和通票的身份验证令牌。

### 响应

| 字段 | 类型 | 描述 |
| :---- | :---- | :---- |
| `success` | boolean | 更新是否成功。 |
| `updateTag` | integer | 新的更新标签（一个 Unix 时间戳）。 |
| `message` | string | 结果消息。 |



## 列出通票

返回为应用程序存储的通票的分页、排序列表。

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

### 查询参数

| 参数 | 类型 | 必需 | 描述 |
| :---- | :---- | :---- | :---- |
| `applicationCode` | string | 是 | Pushwoosh 应用程序代码。 |
| `orderBy` | string | 否 | 排序字段：`UPDATED`（默认）或 `CREATED`。 |
| `orderDirection` | string | 否 | 排序方向：`DESC`（默认，最新在前）或 `ASC`。 |
| `page` | integer | 否 | 从零开始的页面索引。默认为 `0`。 |
| `perPage` | integer | 否 | 页面大小。`0` 或省略将使用服务器默认值。 |

### 响应

| 字段 | 类型 | 描述 |
| :---- | :---- | :---- |
| `passes` | array of objects | 当前页的[通票记录](#pass-record-object)。 |
| `page` | integer | 返回的页面索引。 |
| `perPage` | integer | 此响应使用的页面大小。 |
| `total` | integer | 应用程序在所有页面上的通票总数。 |

##### 响应示例

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


## 获取通票

返回单个存储的通票，包括其完整的通票对象。

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

### 路径参数

| 参数 | 类型 | 描述 |
| :---- | :---- | :---- |
| `applicationCode` | string | Pushwoosh 应用程序代码。 |
| `serialNumber` | string | 通票序列号。 |

### 响应

返回 `{ "pass": { ... } }`，一个[通票记录](#pass-record-object)。


## 下载通票

返回现有通票的已存储 `.pkpass` 文件。

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

### 响应

| 字段 | 类型 | 描述 |
| :---- | :---- | :---- |
| `pkpassData` | string (Base64) | `.pkpass` 文件。 |
| `filename` | string | 建议的文件名。 |


## 删除通票

删除通票记录及其存储的 `.pkpass` 文件。

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

### 响应

| 字段 | 类型 | 描述 |
| :---- | :---- | :---- |
| `success` | boolean | 通票是否已删除。 |
| `message` | string | 结果消息。 |



## 获取通票注册信息

列出已添加该通票并注册更新的设备。

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

### 响应

返回 `{ "registrations": [ ... ] }`，其中每个项目包含：

| 字段 | 类型 | 描述 |
| :---- | :---- | :---- |
| `deviceLibraryIdentifier` | string | Apple 设备库标识符。 |
| `pushToken` | string | 设备的通票推送令牌。 |



## 获取配置

返回从应用程序证书中解析出的 PassKit 配置。

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

### 响应

| 字段 | 类型 | 描述 |
| :---- | :---- | :---- |
| `teamIdentifier` | string | 来自证书的 Apple Team ID。 |
| `passTypeIdentifier` | string | 来自证书的 Pass Type ID。 |
| `organizationName` | string | 来自证书的组织名称。 |
| `hasCertificate` | boolean | 是否已配置证书。 |
| `webServiceUrl` | string | 通票 Web 服务的基 URL。客户端通过附加 `/v1/passes/{passType}/{serial}?token={authToken}` 来构建安装链接。 |



## 模板

列出可用的通票模板，或获取一个作为您可以使用的起点的[通票对象](#pass-object)。

`GET` `/api/templates` — 返回 `{ "templates": [ { "filename", "name", "description", "style" } ] }`。

`GET` `/api/templates/{filename}` — 返回 `{ "template": { ...通票对象... } }`。



## 以二维码形式分享通票

要让用户通过扫描二维码（或点击链接）添加通票，请将通票**安装 URL** 编码为二维码。该 URL 是根据您已从 API 获取的值构建的：

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

| URL 部分 | 从何处获取 |
| :---- | :---- |
| `webServiceUrl` | [`GET /api/config`](#get-configuration) → `webServiceUrl` |
| `passTypeIdentifier` | [通票记录](#pass-record-object) → `pass.passTypeIdentifier`（来自 list/get） |
| `serialNumber` | [通票记录](#pass-record-object) → `serialNumber` |
| `authenticationToken` | [通票记录](#pass-record-object) → `pass.authenticationToken` |

示例：

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

使用任何 QR 库将此 URL 渲染为二维码。当用户扫描它时，他们的设备会打开链接，下载最新的 `.pkpass`，并且 Wallet 会提示他们添加它——这也会为设备注册更新。



## 对象参考

### 通票对象

| 字段 | 类型 | 描述 |
| :---- | :---- | :---- |
| `formatVersion` | integer | 通票格式版本。默认为 `1`。 |
| `passTypeIdentifier` | string | Apple Pass Type ID (`pass.com.yourcompany.passtype`)。默认为证书中的值。 |
| `serialNumber` | string | 在创建时由服务器分配；用于标识通票。 |
| `teamIdentifier` | string | Apple Team ID。默认为证书中的值。 |
| `organizationName` | string | 通票上显示的组织。默认为证书中的值。 |
| `description` | string | 人类可读的描述（Apple 要求）。 |
| `boardingPass` / `coupon` / `eventTicket` / `storeCard` / `generic` | object | 通票样式。必须且只能设置一个。请参阅[字段组](#field-group-object)。 |
| `backgroundColor` | string | 背景颜色，`rgb(r, g, b)`。 |
| `foregroundColor` | string | 前景色（文本）颜色，`rgb(r, g, b)`。 |
| `labelColor` | string | 字段标签颜色，`rgb(r, g, b)`。 |
| `logoText` | string | 显示在标志旁边的文本。 |
| `suppressStripShine` | boolean | 禁用条带图像上的光泽效果。 |
| `barcodes` | array | 通票上显示的[条形码](#barcode-object)。 |
| `locations` | array | 使通票具有相关性的[位置](#location-object)。 |
| `beacons` | array | 使通票具有相关性的[信标](#beacon-object)。 |
| `relevantDate` | string | 通票变为相关时的 ISO 8601 日期。 |
| `maxDistance` | integer | 位置相关性的最大距离（米）。 |
| `expirationDate` | string | ISO 8601 过期日期。 |
| `voided` | boolean | 将通票标记为无效。 |
| `groupingIdentifier` | string | 对相关通票（活动门票/登机牌）进行分组。 |
| `userInfo` | object (map) | 任意键/值应用数据。 |

<Aside type="note">
`authenticationToken` 和 `webServiceUrl` 由服务管理，API 客户端无需设置。
</Aside>

### 字段组对象

每种通票样式（`boardingPass`、`coupon`、`eventTicket`、`storeCard`、`generic`）都将[字段](#field-object)分组到不同区域：

| 字段 | 类型 | 描述 |
| :---- | :---- | :---- |
| `headerFields` | array | 显示在通票标题中（在 Wallet 中堆叠时可见）。 |
| `primaryFields` | array | 最突出的字段。 |
| `secondaryFields` | array | 在主字段下方。 |
| `auxiliaryFields` | array | 在次要字段下方的附加字段。 |
| `backFields` | array | 显示在通票背面。 |

`boardingPass` 额外具有 `transitType`（`PKTransitTypeAir`、`PKTransitTypeTrain`、`PKTransitTypeBus`、`PKTransitTypeBoat` 或 `PKTransitTypeGeneric`）。

### 字段对象

| 字段 | 类型 | 描述 |
| :---- | :---- | :---- |
| `key` | string | 通票内的唯一字段键。 |
| `label` | string | 字段标签。 |
| `value` | string | 字段值（文本或数字，以字符串形式表示）。 |
| `changeMessage` | string | 值更改时显示的消息（使用 `%@` 作为占位符）。 |
| `textAlignment` | string | `PKTextAlignment` 值。 |
| `dateStyle` / `timeStyle` | string | 用于日期/时间格式化的 `PKDateStyle`。 |
| `isRelative` | boolean | 显示相对于现在的日期。 |
| `numberStyle` | string | 用于数字格式化的 `PKNumberStyle`。 |
| `currencyCode` | string | ISO 4217 货币代码。 |
| `dataDetectorTypes` | array of strings | 应用于该值的数据检测器。 |

### 条形码对象

| 字段 | 类型 | 描述 |
| :---- | :---- | :---- |
| `format` | string | `PKBarcodeFormatQR`、`PKBarcodeFormatPDF417`、`PKBarcodeFormatAztec` 或 `PKBarcodeFormatCode128`。 |
| `message` | string | 在条形码中编码的数据。 |
| `messageEncoding` | string | 文本编码，通常为 `iso-8859-1`。 |
| `altText` | string | 显示在条形码下方的文本。 |

### 位置对象

| 字段 | 类型 | 描述 |
| :---- | :---- | :---- |
| `latitude` | number | 纬度。 |
| `longitude` | number | 经度。 |
| `altitude` | number | 海拔高度（米）。 |
| `relevantText` | string | 在此位置附近锁屏上显示的文本。 |

### 信标对象

| 字段 | 类型 | 描述 |
| :---- | :---- | :---- |
| `proximityUuid` | string | iBeacon 邻近 UUID。 |
| `major` | integer | Major 值。 |
| `minor` | integer | Minor 值。 |
| `relevantText` | string | 在此信标附近锁屏上显示的文本。 |

### 通票图片对象

| 字段 | 类型 | 描述 |
| :---- | :---- | :---- |
| `imageType` | string | `icon`、`logo`、`strip`、`background`、`footer`、`thumbnail` 之一。`icon` 和 `logo` 是必需的。 |
| `data` | string (Base64) | 图片字节。 |
| `contentType` | string | MIME 类型，例如 `image/png`。 |

### 通票记录对象

由 list/get 端点返回。

| 字段 | 类型 | 描述 |
| :---- | :---- | :---- |
| `serialNumber` | string | 通票序列号。 |
| `passTypeIdentifier` | string | Pass Type ID。 |
| `organizationName` | string | 组织名称。 |
| `description` | string | 通票描述。 |
| `createdAt` | string | 创建时间戳 (RFC 3339)。 |
| `updatedAt` | string | 最后更新时间戳 (RFC 3339)。 |
| `updateTag` | integer | 当前更新标签。 |
| `pass` | object | 完整的[通票对象](#pass-object)，用于编辑。 |
| `userId` | string | 通票发行给的 Pushwoosh User ID。 |