# Apple Wallet PassKit API

PassKit Designer API를 사용하면 [Apple Wallet 패스](/ko/product/messaging-channels/apple-wallet-passes/)를 프로그래밍 방식으로 생성, 업데이트, 다운로드 및 관리할 수 있습니다. Control Panel의 패스 빌더가 수행하는 것과 동일한 작업을 지원합니다. 이를 사용하여 멤버십 카드, 쿠폰, 이벤트 티켓, 탑승권, 스토어 카드를 발급하고, 사용자의 기기에 이미 설치된 패스에 실시간 업데이트를 푸시할 수 있습니다.

<Aside type="note" title="전제 조건: PassKit 인증서">
애플리케이션용 패스를 생성하기 전에 해당 애플리케이션에 iOS PassKit 서명 인증서가 구성되어 있어야 합니다. 인증서는 Pushwoosh Control Panel에서 관리됩니다. 인증서가 없으면 `create` 및 `update` 요청이 실패합니다. [iOS용 Apple Wallet 패스 구성](/ko/developer/first-steps/connect-messaging-services/ios-configuration/ios-wallet-pass-configuration/)을 참조하십시오.
</Aside>

## 기본 URL

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

모든 엔드포인트는 HTTPS를 통해 제공됩니다. 별도로 명시되지 않는 한 요청 및 응답은 `application/json`을 사용합니다.

## 인증

모든 요청에는 [Pushwoosh API 액세스 토큰](/ko/developer/api-reference/api-access-token/)이 포함된 `Authorization` 헤더가 있어야 합니다:

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

토큰을 소유한 계정은 `applicationCode`로 참조되는 애플리케이션을 소유해야 합니다. 다른 계정에 속한 애플리케이션에 대한 요청은 `403 Forbidden`을 반환합니다.

## 규칙

*   **필드 이름 지정:** JSON 필드는 `lowerCamelCase`를 사용합니다 (예: `passTypeIdentifier`, `serialNumber`, `backgroundColor`).
*   **채워지지 않은 필드:** 응답에는 비어 있거나 0 값인 경우에도 모든 필드가 포함됩니다.
*   **바이너리 데이터:** `pkpassData` 및 이미지 `data`와 같은 `bytes` 필드는 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)를 호출하거나 [설치 링크 / QR 코드](#share-a-pass-as-a-qr-code)를 만드십시오.
</Aside>


### 요청 본문

| 매개변수 | 유형 | 필수 | 설명 |
| :---- | :---- | :---- | :---- |
| `pass` | 객체 | 예 | 패스를 설명하는 [패스 객체](#pass-object). |
| `images` | 객체 배열 | 아니요 | [패스 이미지](#pass-image-object) (아이콘, 로고 등). 유효한 패스를 위해서는 `icon`과 `logo`가 필요합니다. |
| `userId` | 문자열 | 예 | 패스가 발급되는 Pushwoosh User ID. |
| `applicationCode` | 문자열 | 예 | [Pushwoosh 애플리케이션 코드](/ko/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` | 문자열 | 생성된 패스의 서버 할당 고유 ID. 이를 사용하여 패스를 가져오거나([패스 조회](#get-a-pass)) `.pkpass`를 다운로드([패스 다운로드](#download-a-pass))합니다. |
| `message` | 문자열 | 결과 메시지. |

##### 응답 예시

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

## 패스 유효성 검사

파일을 생성하지 않고 Apple의 사양에 대해 패스 구성을 확인합니다. create를 호출하기 전에 유용합니다.

`POST` `/api/pass/validate`

### 요청 본문

| 매개변수 | 유형 | 필수 | 설명 |
| :---- | :---- | :---- | :---- |
| `pass` | 객체 | 예 | 유효성을 검사할 [패스 객체](#pass-object). |

### 응답

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `valid` | 불리언 | 패스가 유효성 검사를 통과했는지 여부. |
| `errors` | 문자열 배열 | 수정해야 하는 차단 문제. |
| `warnings` | 문자열 배열 | 차단되지 않는 권고 사항. |



## 패스 업데이트

새로운 내용으로 패스를 다시 생성하고, 다시 서명하고, 업데이트 태그를 증가시킨 다음, 패스를 등록한 모든 기기에 **자동 푸시 알림**을 보냅니다. 그러면 iOS가 백그라운드에서 업데이트된 버전을 가져와 설치합니다.

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

### 경로 매개변수

| 매개변수 | 유형 | 설명 |
| :---- | :---- | :---- |
| `serialNumber` | 문자열 | 패스가 생성될 때 반환된 일련 번호. |

### 요청 본문

| 매개변수 | 유형 | 필수 | 설명 |
| :---- | :---- | :---- | :---- |
| `updates` | 객체 | 예 | 새로운 내용이 포함된 전체 [패스 객체](#pass-object). |
| `applicationCode` | 문자열 | 예 | Pushwoosh 애플리케이션 코드. |

`serialNumber`(경로에서)와 패스의 인증 토큰은 사용자가 보내는 내용과 관계없이 서버에 의해 보존됩니다.

### 응답

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `success` | 불리언 | 업데이트 성공 여부. |
| `updateTag` | 정수 | 새 업데이트 태그 (Unix 타임스탬프). |
| `message` | 문자열 | 결과 메시지. |



## 패스 목록 조회

애플리케이션에 저장된 패스의 페이지네이션되고 정렬된 목록을 반환합니다.

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

### 쿼리 매개변수

| 매개변수 | 유형 | 필수 | 설명 |
| :---- | :---- | :---- | :---- |
| `applicationCode` | 문자열 | 예 | Pushwoosh 애플리케이션 코드. |
| `orderBy` | 문자열 | 아니요 | 정렬 필드: `UPDATED`(기본값) 또는 `CREATED`. |
| `orderDirection` | 문자열 | 아니요 | 정렬 방향: `DESC`(기본값, 최신순) 또는 `ASC`. |
| `page` | 정수 | 아니요 | 0부터 시작하는 페이지 인덱스. 기본값은 `0`입니다. |
| `perPage` | 정수 | 아니요 | 페이지 크기. `0` 또는 생략 시 서버 기본값을 사용합니다. |

### 응답

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `passes` | 객체 배열 | 현재 페이지의 [패스 레코드](#pass-record-object). |
| `page` | 정수 | 반환된 페이지 인덱스. |
| `perPage` | 정수 | 이 응답에 사용된 페이지 크기. |
| `total` | 정수 | 모든 페이지에 걸쳐 애플리케이션의 총 패스 수. |

##### 응답 예시

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


## 패스 조회

전체 패스 객체를 포함하여 저장된 단일 패스를 반환합니다.

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

### 경로 매개변수

| 매개변수 | 유형 | 설명 |
| :---- | :---- | :---- |
| `applicationCode` | 문자열 | Pushwoosh 애플리케이션 코드. |
| `serialNumber` | 문자열 | 패스 일련 번호. |

### 응답

단일 [패스 레코드](#pass-record-object)인 `{ "pass": { ... } }`를 반환합니다.


## 패스 다운로드

기존 패스의 저장된 `.pkpass` 파일을 반환합니다.

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

### 응답

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `pkpassData` | 문자열 (Base64) | `.pkpass` 파일. |
| `filename` | 문자열 | 제안된 파일 이름. |


## 패스 삭제

패스 레코드와 저장된 `.pkpass` 파일을 제거합니다.

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

### 응답

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `success` | 불리언 | 패스가 삭제되었는지 여부. |
| `message` | 문자열 | 결과 메시지. |



## 패스 등록 조회

패스를 추가하고 업데이트에 등록된 기기 목록을 조회합니다.

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

### 응답

`{ "registrations": [ ... ] }`를 반환하며, 각 항목에는 다음이 포함됩니다:

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `deviceLibraryIdentifier` | 문자열 | Apple 기기 라이브러리 식별자. |
| `pushToken` | 문자열 | 기기의 패스 푸시 토큰. |



## 구성 조회

애플리케이션의 인증서에서 확인된 PassKit 구성을 반환합니다.

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

### 응답

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `teamIdentifier` | 문자열 | 인증서의 Apple Team ID. |
| `passTypeIdentifier` | 문자열 | 인증서의 Pass Type ID. |
| `organizationName` | 문자열 | 인증서의 조직 이름. |
| `hasCertificate` | 불리언 | 인증서가 구성되었는지 여부. |
| `webServiceUrl` | 문자열 | 패스 웹 서비스의 기본 URL. 클라이언트는 `/v1/passes/{passType}/{serial}?token={authToken}`을 추가하여 설치 링크를 만듭니다. |



## 템플릿

사용 가능한 패스 템플릿을 나열하거나, 시작점으로 사용할 수 있는 [패스 객체](#pass-object)로 하나를 가져옵니다.

`GET` `/api/templates` — `{ "templates": [ { "filename", "name", "description", "style" } ] }`를 반환합니다.

`GET` `/api/templates/{filename}` — `{ "template": { ...pass object... } }`를 반환합니다.



## QR 코드로 패스 공유

사용자가 QR 코드를 스캔하거나 링크를 탭하여 패스를 추가할 수 있도록 하려면 패스 **설치 URL**을 QR 코드로 인코딩하십시오. 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을 QR 코드로 렌더링하십시오. 사용자가 스캔하면 기기에서 링크가 열리고 최신 `.pkpass`가 다운로드되며 Wallet에서 추가하라는 메시지가 표시됩니다. 이 과정에서 기기가 업데이트에 등록됩니다.



## 객체 참조

### 패스 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `formatVersion` | 정수 | 패스 형식 버전. 기본값은 `1`입니다. |
| `passTypeIdentifier` | 문자열 | Apple Pass Type ID (`pass.com.yourcompany.passtype`). 인증서에서 기본값을 가져옵니다. |
| `serialNumber` | 문자열 | 생성 시 서버에서 할당되며 패스를 식별합니다. |
| `teamIdentifier` | 문자열 | Apple Team ID. 인증서에서 기본값을 가져옵니다. |
| `organizationName` | 문자열 | 패스에 표시되는 조직. 인증서에서 기본값을 가져옵니다. |
| `description` | 문자열 | 사람이 읽을 수 있는 설명 (Apple에서 요구). |
| `boardingPass` / `coupon` / `eventTicket` / `storeCard` / `generic` | 객체 | 패스 스타일. **정확히 하나**만 설정해야 합니다. [필드 그룹 객체](#field-group-object)를 참조하십시오. |
| `backgroundColor` | 문자열 | 배경색, `rgb(r, g, b)`. |
| `foregroundColor` | 문자열 | 전경(텍스트)색, `rgb(r, g, b)`. |
| `labelColor` | 문자열 | 필드 레이블 색, `rgb(r, g, b)`. |
| `logoText` | 문자열 | 로고 옆에 표시되는 텍스트. |
| `suppressStripShine` | 불리언 | 스트립 이미지의 광택 효과를 비활성화합니다. |
| `barcodes` | 배열 | 패스에 표시되는 [바코드](#barcode-object). |
| `locations` | 배열 | 패스를 관련성 있게 만드는 [위치](#location-object). |
| `beacons` | 배열 | 패스를 관련성 있게 만드는 [비콘](#beacon-object). |
| `relevantDate` | 문자열 | 패스가 관련성을 갖게 되는 ISO 8601 날짜. |
| `maxDistance` | 정수 | 위치 관련성을 위한 최대 거리(미터). |
| `expirationDate` | 문자열 | ISO 8601 만료 날짜. |
| `voided` | 불리언 | 패스를 무효로 표시합니다. |
| `groupingIdentifier` | 문자열 | 관련 패스(이벤트 티켓/탑승권)를 그룹화합니다. |
| `userInfo` | 객체 (맵) | 임의의 키/값 앱 데이터. |

<Aside type="note">
`authenticationToken`과 `webServiceUrl`은 서비스에서 관리하며 API 클라이언트가 설정할 필요가 없습니다.
</Aside>

### 필드 그룹 객체

각 패스 스타일(`boardingPass`, `coupon`, `eventTicket`, `storeCard`, `generic`)은 [필드](#field-object)를 영역으로 그룹화합니다:

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `headerFields` | 배열 | 패스 헤더에 표시됩니다 (Wallet에서 스택될 때 보임). |
| `primaryFields` | 배열 | 가장 눈에 띄는 필드. |
| `secondaryFields` | 배열 | 기본 필드 아래. |
| `auxiliaryFields` | 배열 | 보조 필드 아래의 추가 필드. |
| `backFields` | 배열 | 패스 뒷면에 표시됩니다. |

`boardingPass`에는 추가로 `transitType`(`PKTransitTypeAir`, `PKTransitTypeTrain`, `PKTransitTypeBus`, `PKTransitTypeBoat` 또는 `PKTransitTypeGeneric`)이 있습니다.

### 필드 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `key` | 문자열 | 패스 내에서 고유한 필드 키. |
| `label` | 문자열 | 필드 레이블. |
| `value` | 문자열 | 필드 값 (텍스트 또는 숫자를 문자열로). |
| `changeMessage` | 문자열 | 값이 변경될 때 표시되는 메시지 (`%@`를 자리 표시자로 사용). |
| `textAlignment` | 문자열 | `PKTextAlignment` 값. |
| `dateStyle` / `timeStyle` | 문자열 | 날짜/시간 서식 지정을 위한 `PKDateStyle`. |
| `isRelative` | 불리언 | 현재를 기준으로 날짜를 표시합니다. |
| `numberStyle` | 문자열 | 숫자 서식 지정을 위한 `PKNumberStyle`. |
| `currencyCode` | 문자열 | ISO 4217 통화 코드. |
| `dataDetectorTypes` | 문자열 배열 | 값에 적용할 데이터 감지기. |

### 바코드 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `format` | 문자열 | `PKBarcodeFormatQR`, `PKBarcodeFormatPDF417`, `PKBarcodeFormatAztec` 또는 `PKBarcodeFormatCode128`. |
| `message` | 문자열 | 바코드에 인코딩된 데이터. |
| `messageEncoding` | 문자열 | 텍스트 인코딩, 일반적으로 `iso-8859-1`. |
| `altText` | 문자열 | 바코드 아래에 표시되는 텍스트. |

### 위치 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `latitude` | 숫자 | 위도. |
| `longitude` | 숫자 | 경도. |
| `altitude` | 숫자 | 고도(미터). |
| `relevantText` | 문자열 | 이 위치 근처의 잠금 화면에 표시되는 텍스트. |

### 비콘 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `proximityUuid` | 문자열 | iBeacon 근접 UUID. |
| `major` | 정수 | Major 값. |
| `minor` | 정수 | Minor 값. |
| `relevantText` | 문자열 | 이 비콘 근처의 잠금 화면에 표시되는 텍스트. |

### 패스 이미지 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `imageType` | 문자열 | `icon`, `logo`, `strip`, `background`, `footer`, `thumbnail` 중 하나. `icon`과 `logo`는 필수입니다. |
| `data` | 문자열 (Base64) | 이미지 바이트. |
| `contentType` | 문자열 | MIME 유형, 예: `image/png`. |

### 패스 레코드 객체

list/get 엔드포인트에서 반환됩니다.

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `serialNumber` | 문자열 | 패스 일련 번호. |
| `passTypeIdentifier` | 문자열 | Pass Type ID. |
| `organizationName` | 문자열 | 조직 이름. |
| `description` | 문자열 | 패스 설명. |
| `createdAt` | 문자열 | 생성 타임스탬프 (RFC 3339). |
| `updatedAt` | 문자열 | 마지막 업데이트 타임스탬프 (RFC 3339). |
| `updateTag` | 정수 | 현재 업데이트 태그. |
| `pass` | 객체 | 편집을 위한 전체 [패스 객체](#pass-object). |
| `userId` | 문자열 | 패스가 발급된 Pushwoosh User ID. |