# Google Wallet API

Google Wallet API를 사용하면 프로그래밍 방식으로 [Google Wallet 패스](/ko/product/messaging-channels/google-wallet-passes/)를 생성, 업데이트, 나열 및 관리할 수 있습니다. 제어판의 [패스 빌더](/ko/product/messaging-channels/google-wallet-passes/pass-builder/)가 수행하는 것과 동일한 작업을 지원합니다.

이 API를 사용하여 멤버십 카드, 쿠폰, 기프트 카드, 이벤트 티켓, 항공 탑승권, 대중교통 티켓 및 일반 패스를 발급하고, 사용자의 기기에 이미 저장된 패스에 실시간 업데이트를 푸시할 수 있습니다.

<Aside type="note" title="전제 조건: Google Wallet 구성">
애플리케이션에 대한 패스를 생성하기 전에, Pushwoosh 제어판에서 해당 애플리케이션에 대해 Google Wallet **발급자 ID**와 **서비스 계정 키**가 구성되어 있어야 합니다. 이것들이 없으면 `create` 및 `update` 요청이 실패합니다. [Android용 Google Wallet 패스 구성](/ko/developer/first-steps/connect-messaging-services/android-configuration/android-google-wallet-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`를 사용합니다 (예: `serialNumber`, `hexBackgroundColor`, `logoUrl`).
*   **채워지지 않은 필드:** 응답에는 비어 있거나 값이 0인 경우에도 모든 필드가 포함됩니다.
*   **ID:** `serialNumber`는 패스가 생성될 때 항상 서버에서 할당됩니다. 생성 시 보내는 모든 값은 무시됩니다. 전체 Google Wallet 객체 ID는 `{issuerId}.{serialNumber}`입니다.
*   **이미지:** `logoUrl` 및 `heroImageUrl`은 Google이 가져오는 이미지에 대한 공개 HTTPS URL이며, 업로드된 파일이 아닙니다.
*   **패스 스타일:** 패스에는 `generic`, `offer`, `loyalty`, `eventTicket`, `giftCard`, `flight` 또는 `transit` 중 정확히 하나의 스타일 객체가 설정되어야 합니다. 스타일은 생성 후 변경할 수 없습니다.

### 오류 응답

| HTTP 상태 | 의미 |
| :---- | :---- |
| `400 Bad Request` | 잘못된 인수—필수 필드가 누락되었거나 형식이 잘못되었습니다. |
| `401 Unauthorized` | `Authorization` 헤더가 누락되었거나 유효하지 않습니다. |
| `403 Forbidden` | 애플리케이션이 호출자의 계정에 속하지 않습니다. |
| `404 Not Found` | 패스, 템플릿 또는 애플리케이션을 찾을 수 없습니다. |
| `503 Service Unavailable` | 서비스 용량이 초과되었거나 일시적으로 사용할 수 없습니다. |

## 엔드포인트

| 메서드 | 경로 | 설명 |
| :---- | :---- | :---- |
| `POST` | `/api/google/pass/validate` | 패스 구성 유효성 검사 |
| `POST` | `/api/google/pass/create` | 새 패스 객체를 생성하고 저장 링크 받기 |
| `POST` | `/api/google/pass/update/{serialNumber}` | 기존 패스 업데이트; Google이 변경 사항 전달 |
| `GET` | `/api/google/pass/{applicationCode}/{serialNumber}/save-link` | "Google Wallet에 추가" 저장 링크 받기 |
| `GET` | `/api/google/pass/{applicationCode}/{serialNumber}` | 단일 패스 받기 |
| `GET` | `/api/google/passes` | 애플리케이션의 모든 패스 나열 |
| `POST` | `/api/google/pass/{applicationCode}/{serialNumber}/state` | 패스 활성화 또는 비활성화 |
| `DELETE` | `/api/google/pass/{applicationCode}/{serialNumber}` | 패스 삭제 |
| `GET` | `/api/google/config` | 애플리케이션의 Google Wallet 구성 받기 |
| `GET` | `/api/google/templates` | 사용 가능한 패스 템플릿 나열 |
| `GET` | `/api/google/templates/{filename}` | 단일 템플릿 받기 |

## 패스 생성

Google Wallet에서 패스 클래스와 객체를 생성한 다음, 서버에서 할당한 일련번호, 전체 객체 ID 및 "Google Wallet에 추가" 저장 링크를 반환합니다.

`POST` `/api/google/pass/create`

### 요청 본문

| 매개변수 | 유형 | 필수 | 설명 |
| :---- | :---- | :---- | :---- |
| `pass` | object | 예 | 패스를 설명하는 [패스 객체](#pass-object). 정확히 하나의 스타일이 설정되어야 합니다. |
| `userId` | string | 예 | 패스가 발급되는 [Pushwoosh User ID](/ko/developer/api-reference/api-identifiers/#user-id). |
| `applicationCode` | string | 예 | [Pushwoosh 애플리케이션 코드](/ko/developer/api-reference/api-identifiers/#application-code). |

##### 요청 예시

```json
{
  "applicationCode": "XXXXX-XXXXX",
  "userId": "user-123",
  "pass": {
    "hexBackgroundColor": "#3c414c",
    "logoUrl": "https://cdn.acme.com/logo.png",
    "loyalty": {
      "programName": "Acme Rewards",
      "accountName": "Jane Doe",
      "accountId": "1234567890",
      "pointsLabel": "Points",
      "pointsBalance": "1200",
      "rewardsTier": "Gold"
    },
    "barcode": {
      "format": "QR_CODE",
      "value": "1234567890"
    }
  }
}
```

### 응답

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `serialNumber` | string | 생성된 패스의 서버 할당 고유 ID. |
| `objectId` | string | 전체 Google Wallet 객체 ID: `{issuerId}.{serialNumber}`. |
| `saveLink` | string | "Google Wallet에 추가" 링크: `https://pay.google.com/gp/v/save/{jwt}`. |
| `message` | string | 결과 메시지. |

##### 응답 예시

```json
{
  "serialNumber": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
  "objectId": "XXXXXXXXXXXXXXX.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
  "saveLink": "https://pay.google.com/gp/v/save/{jwt}",
  "message": "Pass created successfully"
}
```

## 패스 유효성 검사

패스를 생성하지 않고 Google의 요구 사항에 대해 패스 구성을 확인합니다. 생성 호출 전에 유용합니다.

`POST` `/api/google/pass/validate`

### 요청 본문

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

### 응답

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

## 패스 업데이트

새로운 내용으로 패스 객체를 패치합니다. 그러면 Google은 패스를 저장한 모든 기기에 업데이트된 버전을 전달합니다. 선택적으로 업데이트와 함께 Android 알림을 보냅니다.

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

### 경로 매개변수

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

### 요청 본문

| 매개변수 | 유형 | 필수 | 설명 |
| :---- | :---- | :---- | :---- |
| `updates` | object | 예 | 새로운 내용이 포함된 [패스 객체](#pass-object). 스타일은 변경할 수 없습니다. |
| `applicationCode` | string | 예 | [Pushwoosh 애플리케이션 코드](/ko/developer/api-reference/api-identifiers/#application-code). |
| `notifyMessage` | string | 아니요 | 비어 있지 않은 경우, 패스를 저장한 모든 사람에게 이 텍스트가 포함된 Android 알림을 푸시합니다. 비어 있으면 자동 업데이트를 의미합니다. |
| `notifyOnUpdate` | boolean | 아니요 | 필드 업데이트 알림을 요청합니다. `loyalty`, `eventTicket`, `flight` 패스만 실제로 알림을 보내고, 다른 스타일은 플래그를 수락하지만 알림을 보내지 않습니다. 알림은 관련 시작 시간 3시간 이내에만 발생하며, Google은 24시간당 패스당 3개의 알림으로 제한합니다. |

<Aside type="note" title="업데이트 시 알림을 보내는 두 가지 방법">
`notifyMessage`는 패스를 저장한 모든 사람에게 사용자 지정 Android 알림을 보내며 모든 패스 스타일에 대해 작동합니다. `notifyOnUpdate`는 Google에 자체 필드 업데이트 알림을 보내도록 요청하며, 이는 `loyalty`, `eventTicket`, `flight` 패스에 대해서만 발생합니다.
</Aside>

### 응답

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `success` | boolean | 업데이트 성공 여부. |
| `message` | string | 결과 메시지. |

## 저장 링크 받기

이미 생성된 패스에 대한 "Google Wallet에 추가" 저장 링크를 반환합니다. 패스 객체는 이미 존재해야 합니다([패스 생성](#create-a-pass)을 통해 생성됨).

`GET` `/api/google/pass/{applicationCode}/{serialNumber}/save-link`

### 응답

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `saveLink` | string | `https://pay.google.com/gp/v/save/{jwt}`. |

<Aside type="tip" title="링크를 공유하거나 QR 코드로 렌더링하세요">
`saveLink`를 "Google Wallet에 추가" 버튼 뒤에 두거나, QR 라이브러리를 사용하여 QR 코드로 렌더링하세요. 사용자가 링크를 열면 Google은 패스를 저장하라는 메시지를 표시하고 업데이트를 위해 기기를 등록합니다.
</Aside>

## 패스 받기

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

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

### 응답

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

## 패스 목록

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

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

### 쿼리 매개변수

| 매개변수 | 유형 | 필수 | 설명 |
| :---- | :---- | :---- | :---- |
| `applicationCode` | string | 예 | [Pushwoosh 애플리케이션 코드](/ko/developer/api-reference/api-identifiers/#application-code). |
| `orderBy` | string | 아니요 | 정렬 필드: `UPDATED`(기본값) 또는 `CREATED`. |
| `orderDirection` | string | 아니요 | 정렬 방향: `DESC`(기본값, 최신순) 또는 `ASC`. |
| `page` | integer | 아니요 | 0부터 시작하는 페이지 인덱스. 기본값은 `0`입니다. |
| `perPage` | integer | 아니요 | 페이지 크기. `0`이거나 생략하면 서버 기본값을 사용합니다. |

### 응답

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

## 패스 상태 설정

패스를 활성화하거나 비활성화합니다. 비활성화된(비활성) 패스는 사용자의 Google Wallet의 **만료된 패스** 섹션으로 이동합니다. 레코드는 다시 활성화할 수 있도록 유지됩니다.

`POST` `/api/google/pass/{applicationCode}/{serialNumber}/state`

### 요청 본문

| 매개변수 | 유형 | 필수 | 설명 |
| :---- | :---- | :---- | :---- |
| `active` | boolean | 예 | `true`는 패스를 `ACTIVE`로 설정하고, `false`는 비활성화합니다(`INACTIVE`). |

### 응답

성공 시 빈 객체 `{}`를 반환합니다.

## 패스 삭제

Google에서 패스를 비활성화하고 Pushwoosh에 저장된 레코드를 제거합니다.

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

<Aside type="caution" title="저장된 패스는 강제로 제거할 수 없습니다">
Google은 사용자의 기기에 이미 저장된 패스를 제거하는 것을 허용하지 않습니다. 삭제는 패스를 비활성화하고( **만료된 패스**로 이동) Pushwoosh 레코드를 삭제합니다.
</Aside>

### 응답

성공 시 빈 객체 `{}`를 반환합니다.

## 구성 받기

애플리케이션의 Google Wallet 구성 상태를 반환합니다.

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

### 응답

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `hasServiceAccount` | boolean | 서비스 계정 키가 구성되었는지 여부. |
| `issuerId` | string | 구성된 [Google Pay 및 Wallet 콘솔 발급자 ID](/ko/developer/first-steps/connect-messaging-services/android-configuration/android-google-wallet-configuration/#create-the-issuer-account). |
| `serviceAccountEmail` | string | 구성된 [서비스 계정](/ko/developer/first-steps/connect-messaging-services/android-configuration/android-google-wallet-configuration/#create-the-service-account-key)의 `client_email`. |

## 템플릿

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

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

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

## 객체 참조

### 패스 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `serialNumber` | string | 생성 시 서버에서 할당되며, 패스를 식별합니다. |
| `generic` / `offer` / `loyalty` / `eventTicket` / `giftCard` / `flight` / `transit` | object | 패스 스타일. **정확히 하나**만 설정해야 합니다. 아래의 스타일 객체를 참조하세요. |
| `hexBackgroundColor` | string | 카드 배경색, `#rrggbb`. |
| `logoUrl` | string | 로고 이미지의 공개 HTTPS URL. 멤버십 및 대중교통에 필요합니다. |
| `heroImageUrl` | string | 넓은 배너 이미지의 공개 HTTPS URL. |
| `barcode` | object | 패스에 표시되는 [바코드](#barcode-object). |
| `textModules` | array | 상세 보기에 표시되는 [텍스트 모듈](#text-module-object). |
| `links` | array | 상세 보기에 표시되는 [링크 모듈](#link-module-object). |
| `expirationTime` | string | Google이 패스를 자동으로 만료시키는 ISO 8601 시간. 비어 있으면 만료되지 않음. |
| `appLink` | object | [앱 링크](#app-link-object): 패스 전면의 CTA 버튼. |
| `locations` | array | 지오펜스 알림을 트리거하는 [위치](#location-object) (최대 10개). |
| `holdersPolicy` | string | 패스를 저장할 수 있는 사람: `ONE_USER_ALL_DEVICES`(기본값), `ONE_USER_ONE_DEVICE` 또는 `MULTIPLE_HOLDERS`. |

### 일반 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `cardTitle` | string | 필수. 카드 상단의 발급자/프로그램 이름. |
| `header` | string | 필수. 카드의 주 제목. |
| `subheader` | string | 보조 제목. |
| `cardFields` | array | 전면에 고정된 최대 6개의 [텍스트 모듈](#text-module-object) (최대 3행 2열). |

### 쿠폰 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `title` | string | 필수. 예: `모든 상품 20% 할인`. |
| `provider` | string | 필수. 판매자 이름. |
| `details` | string | 쿠폰 상세 정보. |
| `finePrint` | string | 이용 약관. |
| `redemptionChannel` | string | `ONLINE`, `INSTORE`, `BOTH`(기본값) 또는 `TEMPORARY_PRICE_REDUCTION`. |
| `issuerName` | string | Google의 "발급자" 표면에 표시되며, 기본값은 `provider`입니다. |

### 멤버십 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `programName` | string | 필수. 패스에 `logoUrl`이 필요합니다. |
| `accountName` | string | 카드에 표시되는 회원 이름. |
| `accountId` | string | 카드에 표시되는 회원 ID. |
| `pointsLabel` | string | 예: `포인트`. 잔액과 함께만 표시됩니다. |
| `pointsBalance` | string | 포인트 잔액. |
| `rewardsTier` | string | 예: `골드`. |
| `rewardsTierLabel` | string | 등급 옆의 라벨. 기본값은 `등급`입니다. |
| `issuerName` | string | 기본값은 `programName`입니다. |

### 이벤트 티켓 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `eventName` | string | 필수. |
| `venueName` / `venueAddress` | string | 장소 상세 정보. |
| `startDateTime` / `endDateTime` | string | 오프셋이 있는 ISO 8601 (예: `2026-07-01T19:30:00+02:00`). |
| `ticketHolderName` / `ticketNumber` / `ticketType` | string | 소지자 및 티켓 상세 정보. |
| `section` / `row` / `seat` / `gate` | string | 좌석 상세 정보. |
| `issuerName` | string | 기본값은 `eventName`입니다. |

### 기프트 카드 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `merchantName` | string | 필수. |
| `cardNumber` | string | 필수. |
| `pin` | string | 카드 PIN. |
| `balance` | string | 십진수 금액, 예: `25.00`. `balanceCurrency`가 필요합니다. |
| `balanceCurrency` | string | ISO 4217 통화 코드, 예: `USD`. |
| `issuerName` | string | 기본값은 `merchantName`입니다. |

### 항공편 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `carrierIataCode` | string | 필수. 2자리 IATA 코드, 예: `LX`. |
| `airlineName` | string | 항공사 표시 이름. |
| `flightNumber` | string | 필수. 숫자만, 예: `113`. |
| `originAirportCode` / `destinationAirportCode` | string | 필수. 3자리 IATA 코드. |
| `originTerminal` / `originGate` / `destinationTerminal` | string | 터미널 및 게이트 상세 정보. |
| `departureDateTime` | string | 필수. 출발 공항 **현지** 시간, 오프셋 **없는** ISO 8601 (예: `2026-09-01T06:30:00`). |
| `boardingTime` / `arrivalDateTime` | string | 동일한 현지 형식. `arrivalDateTime`은 도착지 현지 시간입니다. |
| `passengerName` | string | 필수. |
| `confirmationCode` / `seatNumber` / `seatClass` / `boardingGroup` | string | 승객 상세 정보. |
| `issuerName` | string | 기본값은 `airlineName`, 그 다음은 항공사 코드입니다. |

### 대중교통 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `transitType` | string | 필수. `BUS`, `RAIL`, `TRAM`, `FERRY` 또는 `OTHER`. |
| `transitOperatorName` | string | 필수. 패스에 `logoUrl`이 필요합니다. |
| `passengerName` | string | 필수. |
| `ticketNumber` | string | 티켓 번호. |
| `tripType` | string | `ONE_WAY`(기본값) 또는 `ROUND_TRIP`. |
| `legs` | array | 여행 순서대로 하나 이상의 [대중교통 구간](#transit-leg-object). |
| `issuerName` | string | 기본값은 `transitOperatorName`입니다. |

### 대중교통 구간 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `originName` / `destinationName` | string | 필수. |
| `departureDateTime` / `arrivalDateTime` | string | ISO 8601; 오프셋은 선택 사항(생략 시 현지 시간). |
| `platform` / `coach` / `seat` | string | 탑승 상세 정보. |
| `fareName` | string | 예: `Anytime Single`. |

### 바코드 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `format` | string | `QR_CODE`, `PDF_417`, `AZTEC`, `CODE_128`, `EAN_13` 및 기타 Google Wallet 바코드 유형. |
| `value` | string | 바코드에 인코딩된 데이터. |
| `altText` | string | 바코드 아래에 표시되는 텍스트. |

### 텍스트 모듈 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `id` | string | 모듈의 식별자. |
| `header` | string | 모듈 제목. |
| `body` | string | 모듈 텍스트. |

### 링크 모듈 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `uri` | string | 외부 링크 URL. |
| `description` | string | 상세 보기에 표시되는 링크 라벨. |

### 앱 링크 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `uri` | string | 웹 URL 또는 딥링크 대상 URI. |
| `androidPackageName` | string | 선택 사항. 설정 시 Android 앱을 엽니다. |
| `description` | string | 대상 URI의 내부 설명(보이는 버튼 라벨 아님). 기본값은 URI입니다. |

### 위치 객체

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `latitude` | number | `-90.0`에서 `+90.0`까지. |
| `longitude` | number | `-180.0`에서 `+180.0`까지. |

### 패스 레코드 객체

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

| 필드 | 유형 | 설명 |
| :---- | :---- | :---- |
| `serialNumber` | string | 패스 일련번호. |
| `objectId` | string | 전체 Google Wallet 객체 ID `{issuerId}.{serialNumber}`. |
| `cardTitle` | string | 패스의 표시 제목/헤더. |
| `header` | string | 보조 표시 제목. |
| `userId` | string | 패스가 발급된 [Pushwoosh User ID](/ko/developer/api-reference/api-identifiers/#user-id). |
| `createdAt` / `updatedAt` | string | 생성 및 마지막 업데이트 타임스탬프. |
| `state` | string | `ACTIVE` 또는 `INACTIVE`. |
| `style` | string | `generic`, `offer`, `loyalty`, `eventTicket`, `giftCard`, `flight` 또는 `transit`. |
| `pass` | object | 편집을 위한 전체 [패스 객체](#pass-object). |