LASSIC Media らしくメディア
アプリのウォレット連携(パス)実装の進め方
LASSIC IT事業部|元請(プライムベンダー)としてシステム保守・運用を受託
この記事のポイント
- アプリのウォレット連携とは、会員証・クーポン・チケット・ポイントカードなどの「パス」をApple WalletやGoogle Walletへ追加・更新する仕組みで、決済のApple Pay/Google Payとは別論点です。
- Apple Walletは.pkpassファイルをPass Type ID証明書で署名する方式、Google Walletはパスクラス/パスオブジェクトをJWTで発行する方式と、発行の仕組みが異なります。
- パスの更新方式もApple(APNsによるプッシュ通知)とGoogle(REST APIでの直接更新)で異なり、外注時はこの更新設計まで確認範囲に含める必要があります。
目次
アプリのウォレット連携(パス)とは — 決済とは別のパス配布の仕組み
アプリのウォレット連携とは、会員証・クーポン・チケット・搭乗券・ポイントカードといった「パス」を、iPhoneのApple WalletやAndroidのGoogle Walletに追加・配信・更新する仕組みを指します。パスはユーザーの端末上で常に最新の状態を保つよう設計されており、企業側がバックエンドから情報を更新すると、端末側のパス表示にも反映される仕組みが用意されています。
ここで重要なのは、Apple Pay・Google Payという「決済」の仕組みとは別のサービスだという点です。Apple Payはクレジットカード等の決済情報を扱う支払いサービスであるのに対し、Apple Walletのパス機能は搭乗券・チケット・クーポン・ストアカード(ロイヤリティカード、割引カード、ポイントカード、ギフトカードなど)を管理する仕組みであり、Apple公式もWalletアプリの中で両者を明確に区別して説明しています*3。Googleについても同様に、店頭・非接触決済を扱うGoogle Payと、ロイヤリティプログラムやチケット、証明書などの非決済の証憑を扱うGoogle Walletのパスは別物です*3。この2つを混同して要件定義を進めると、決済実装(別稿で解説)とパス実装のどちらの話をしているのか発注先とかみ合わなくなるため、まず論点を切り分けることが起点になります。
パスの発行元は企業(イシュアー)で、Apple・Googleのプラットフォームはあくまでパスを表示・保管・更新通知する基盤という位置づけです。会員証やクーポンをアプリ内に留めるのではなく、端末標準のウォレットアプリに追加してもらうことで、ロック画面やウォレットアプリからワンタップで提示できるようになり、来店時の利用率向上や紙のポイントカード運用からの脱却を狙う施策として使われます。
ただし、Apple WalletとGoogle Walletでは、パスの構成ファイル・署名方式・更新方式のいずれも仕組みが異なります。両OSに対応させる場合は、共通のパス発行ロジックを一本化できるわけではなく、それぞれの仕様に合わせた実装が個別に必要になる点を押さえておく必要があります。
Apple Wallet — .pkpassの構成とPass Type ID証明書による署名
Apple Walletに追加するパスは、拡張子.pkpassの単一ファイルとして配布されます。.pkpassの実体はZIPアーカイブで、その中に複数のファイルが格納された構成です*1。
pass.json・画像・manifest.json・signatureの4要素
.pkpassの中心となるのがpass.jsonで、パスの種別・表示内容・有効期限などを定義する設定ファイルです*1。pass.jsonにはformatVersion(フォーマットバージョン)、passTypeIdentifier(pass.から始まる逆引きDNS形式の識別子)、teamIdentifier(Appleが発行するチームID)などのキーに加え、パスのスタイルを決めるキー(搭乗券・交通機関向けのboardingPass、イベント入場券向けのeventTicket、店舗のロイヤリティカードや割引カード・ポイントカード・ギフトカード向けのstoreCardなど)のいずれか1つを指定します*2。
pass.jsonに加えて、アイコンやロゴなどの画像ファイル一式、そしてmanifest.jsonが同梱されます。manifest.jsonには、pass.json自体と各画像ファイルのハッシュ値が記録されており、パス内のファイルが改ざんされていないかを検証するための台帳の役割を持ちます*1。すべてのファイルはUTF-8エンコーディングで、画像はPNG形式であることが求められます*1。
Pass Type ID証明書によるsignatureの生成
manifest.jsonに対してAppleが発行するPass Type ID証明書を用いて署名を行い、その結果をsignatureというファイルとしてパスに同梱します*1。この証明書はApple Developerアカウントで取得するもので、パスの種別(passTypeIdentifier)ごとに紐づく形で発行されます。署名済みのpass.json・画像・manifest.json・signatureの4点セットをZIPで固め、拡張子を.pkpassに変更したものが、実際に配布される1枚のパスファイルです。この署名によって、パスの発行元が正当な証明書の保有者であることと、内容が改ざんされていないことの両方を端末側が検証できる仕組みになっています*1。
証明書の管理はAppleの開発者アカウント権限に紐づくため、外注先が実装する場合も、証明書の発行・更新・失効の管理主体をどちらが担うかを事前に取り決めておく必要があります。証明書には有効期限があり、失効すると新規パスの発行や既存パスの更新が行えなくなるため、更新運用を含めた管理体制の設計が欠かせません。
Google Wallet — パスクラス/オブジェクトとJWTによる発行
Google Walletでは、Appleのような単一ファイル配布ではなく、パスクラス(Class)とパスオブジェクト(Object)という2階層のデータモデルでパスを管理します。パスクラスはパスの共通テンプレート(デザインやレイアウトなど、同一種別のパスに共通する定義)を表し、パスオブジェクトはユーザー1人ひとりに発行される個別のパスの実体です。ユーザーに発行するパスは、このパスクラスとパスオブジェクトを組み合わせて作成する仕組みになっています*4。
汎用パス・ロイヤリティ・イベントチケット・ギフトカードなどのパスタイプ
Google Walletには用途別の複数のパスタイプが用意されています。ロイヤリティカード(特典やポイント履歴の管理)、ギフトカード、オファー(クーポン施策)、イベントチケット(バーコード・QRコード・NFCによる入場)、搭乗券・交通系パスに加え、既存の定型タイプに当てはまらない固有のパス体験を作れる汎用パス(Generic Pass)が用意されています*5。会員証やクーポンなど、自社の要件に近いパスタイプを選定するところが最初の設計判断になります。
「Add to Google Wallet」はJWTで発行する
Web・メール・SMSなどブラウザ経由でパスをウォレットに追加してもらう場合、JSON Web Token(JWT)を使って実装します。事前に作成したパスクラスとパスオブジェクトの情報をJWTのペイロードに含め、Google Cloudのサービスアカウントの秘密鍵で署名を行います*4。署名済みのJWTは「https://pay.google.com/gp/v/save/」に続けて付与する形でリンク化し、このリンクをボタンやメールに埋め込むことで、タップ時にGoogle Walletへの追加画面が起動する仕組みです*4。なお、JWTの長さが1,800文字を超えるとブラウザ側で切り詰められて動作しないおそれがあるため、この上限を超えない長さに収める設計が推奨されています*4。この「Add to Google Wallet」の操作は、ユーザーがGoogleアカウントにログインした状態でのみ実行できる仕様です*4。
Apple Walletが証明書による署名済みファイルを直接配布するのに対し、Google Walletはサーバー側で管理するクラス/オブジェクトのデータをJWTという形で参照させる方式である点が、設計上の大きな違いです。Google側はAndroid SDKを使った実装も選択肢として提供しており、Web以外の配布経路ではSDK経由の実装が案内されています*4。
パスの更新(Apple=APNs / Google=REST API)の仕組み
パスは一度追加して終わりではなく、ポイント残高の増減や搭乗ゲートの変更、クーポンの有効期限延長など、発行後に内容を更新する運用が前提です。この更新の仕組みが、Apple WalletとGoogle Walletで根本的に異なります。
Apple Walletの更新はAPNsによるプッシュ通知が起点
Apple Walletのパス更新には、自社で用意するWebサービスとApple Push Notification service(APNs)を組み合わせた仕組みが使われます。ユーザーがパスを端末に追加すると、端末は自社のWebサービスに対してPOSTリクエストを送り、デバイス識別子・APNs向けのpushToken・パス種別・シリアル番号を登録します*6。パスの内容を更新したいときは、自社サーバーからAPNs経由で該当デバイスに空のペイロードを持つプッシュ通知を送信し、通知を受け取った端末側がWebサービスのGETエンドポイント(/v1/passes/{パス種別}/{シリアル番号})に更新後の.pkpassを取りに行く、という流れです*6。ユーザーがパスを削除した場合は、DELETEエンドポイントで登録解除の通知を受け取ります*6。つまりApple側は「更新があったことだけをプッシュで知らせ、実際のデータは自社サーバーから取得させる」設計であり、登録・配信・失効までを扱うWebサービスの実装が更新機能の前提になります。
Google Walletの更新はREST APIで直接反映
Google Walletでは、自社サーバーからREST APIのpatchメソッドやupdateメソッドを呼び出し、パスクラスやパスオブジェクトの内容を直接書き換えます*7。パスクラスを更新すると、そのクラスを参照している全ユーザーのパスに変更が反映され、パスオブジェクトを更新すると、その1件を保有するユーザーのみに変更が反映される仕組みです*7。Google公式のドキュメントでは、クラスの変更を保存すると該当するパスの保有者に対して自動的に更新が反映される旨が説明されています*7。Apple Walletのように自社でプッシュ通知用のWebサービスを構築する必要がなく、REST APIの呼び出しだけで更新が完結する点が実装上の大きな違いです。
この違いは工数見積もりに直結します。Apple Wallet対応では、パス発行だけでなく「登録受付・プッシュ送信・失効管理」を担うWebサービス一式の設計・運用が必要になるのに対し、Google Wallet対応ではAPIキー(サービスアカウント)の管理とREST呼び出しの実装が中心になります。両OSに対応する場合、更新まわりの設計・運用コストがOSごとに異なる前提で計画を立てる必要があります。
ユースケース別の設計(会員証・クーポン・チケット・ポイント)
パスの用途によって、選ぶパススタイル・パスタイプと更新頻度の設計が変わります。代表的なユースケースごとの考え方を整理します。
会員証・ポイントカードは残高更新の頻度が設計の核
会員証やポイントカードは、AppleではstoreCard、GoogleではLoyaltyのパスタイプに相当します*2 *5。来店やオンライン購入のたびにポイント残高を更新する運用が一般的なため、Apple側はAPNsのプッシュ配信基盤、Google側はREST APIの呼び出し頻度に耐えるバックエンド設計が必要です。ポイント加算のタイミングと、パス表示への反映タイミングにずれが生じないよう、決済・購買システムとの連携設計を合わせて検討する必要があります。
クーポンは有効期限管理と失効後の扱いが論点
クーポンはAppleではcoupon、Googleではオファーのパスタイプに相当します。クーポンは有効期限を過ぎた際の表示(淡色での非活性化や自動非表示など)をどう扱うかが設計上の論点になります。期限切れのクーポンがいつまでもウォレットに残り続けると、ユーザー体験を損ねるだけでなく、次のキャンペーン告知が埋もれる原因にもなります。有効期限到来時に自動更新をかけて表示を切り替える運用まで含めて設計しておくことが望ましいでしょう。
チケット・搭乗券はゲート変更や座席変更への即時反映が要件になりやすい
イベントチケットや搭乗券は、AppleではeventTicket・boardingPass、Googleではイベントチケット・搭乗券のパスタイプに相当します*2 *5。開催直前の会場変更やゲート変更、座席変更など、ユーザーが当日その場で確認する情報を扱うため、更新の即時性が特に重要になるユースケースです。Apple側はAPNsのプッシュが安定して届く設計、Google側はREST更新のタイミングを運営システムのイベントと連動させる設計が求められます。バーコード・QRコード・NFCのいずれで入場検証を行うかも、会場側のリーダー設備と合わせて事前に確認しておく必要があります*5。
いずれのユースケースでも共通するのは、「パスを追加してもらうこと」自体はゴールではなく、その後の更新運用を継続できるかどうかが施策の効果を左右するという点です。企画段階で、追加後にどの情報をどの頻度で更新するのかを具体化しておくことが、要件定義の精度を高めます。
外注時に確認すべき実装範囲と引き継ぎの論点
ウォレット連携をアプリ開発会社に外注する場合、パスの発行だけを実装して終わりにすると、更新運用の段階でつまずくケースが起こり得ます。発注前に確認しておきたい論点を整理します。
内製に必要なもの
ウォレット連携を内製で行うには、Apple側では証明書の管理とWebサービス(登録受付・APNs送信・失効管理)の実装、Google側ではサービスアカウントの管理とREST API呼び出しの実装という、OSごとに異なる技術要素を両方担える体制が必要です。特にApple側は、パスの発行だけでなく更新通知を受け止めるサーバーサイドの常時運用が前提になるため、単発のパス作成スクリプトだけでは更新機能が成立しません。社内にサーバーサイドの継続運用体制がない場合、内製よりも運用込みで任せられる発注先を検討する価値があります。
発注先への確認
提案書に「Apple WalletとGoogle Walletに対応します」とだけ書かれている場合、パスの新規発行だけでなく、更新の仕組み(Apple側のWebサービス設計、Google側のREST API実装)まで見積もりに含まれているかを確認する必要があります。証明書やサービスアカウントの発行・更新・失効を誰が管理するのか、パスタイプの選定根拠(storeCardかgenericか、ロイヤリティかオファーかなど)、有効期限切れのパスをどう扱うかといった論点を具体的に質問し、回答の解像度を見ることが実装力を見極める手がかりになります。
契約明記
開発会社との契約が終了した後、別の会社や自社に運用を引き継ぐ可能性がある場合は、Pass Type ID証明書やGoogle Cloudサービスアカウントの発行・管理権限の所在、pass.json・パスクラス定義のソースコード、更新用Webサービスの実装一式を納品物に含めるよう契約段階で明記しておく必要があります。証明書やサービスアカウントの管理主体が発注先のまま契約が終了すると、更新機能そのものが継続できなくなるおそれがあるため、権限移管の手順まで契約に盛り込んでおくことが望ましいでしょう。
ウォレット連携は一度実装して終わりではなく、証明書の更新やOS側の仕様変更に合わせて継続的にメンテナンスが必要な機能です。発注時にはこの運用フェーズまで含めた体制を確認しておくことが、長期的な安定運用につながります。
| 観点 | Apple Wallet | Google Wallet |
|---|---|---|
| 発行方式 | .pkpass(pass.json・画像・manifest.json・signatureを含むZIP)を配布 | パスクラス/パスオブジェクトを作成し、JWTで「Add to Google Wallet」リンクを発行 |
| 署名/証明書 | Pass Type ID証明書でmanifest.jsonに署名 | Google Cloudサービスアカウントの秘密鍵でJWTに署名 |
| 更新方式 | 自社Webサービス+APNsのプッシュ通知を起点に端末が更新後の.pkpassを取得 | REST API(patch/update)でクラス/オブジェクトを直接更新、保有者へ自動反映 |
| 主なパスタイプ | boardingPass・coupon・eventTicket・storeCard・generic | ロイヤリティ・ギフトカード・オファー・イベントチケット・搭乗券/交通系・汎用パス |
| 決済機能との関係 | Apple Payとは別サービス(Walletアプリ内で区別) | Google Payとは別サービス(決済カードとパスは別管理) |
まとめ:ウォレット連携を機能させる3つの判断軸
本稿では、Apple WalletとGoogle Walletへのパス(会員証・クーポン・チケット・ポイントカード)実装について、決済との違いから発行・署名・更新の仕組みまでの勘所を整理しました。要点を3つに集約すると次の通りです。第一に、ウォレット連携はApple Pay/Google Payの決済実装とは別の論点であり、要件定義の入り口で両者を切り分けておく必要があります。第二に、Apple Walletは.pkpassとPass Type ID証明書による署名、Google Walletはパスクラス/オブジェクトとJWTによる発行という、まったく異なる仕組みで動いているため、両OS対応を前提にするなら実装工数もOSごとに見積もる姿勢が欠かせません。第三に、更新方式もApple側はAPNsを起点とする自社Webサービスの継続運用、Google側はREST API呼び出しという違いがあり、外注する場合は発行だけでなく更新運用まで見積もりと引き継ぎ資料の範囲に含める確認が、長期的な安定運用を左右します。
よくある質問
ウォレット連携はApple Pay・Google Payの決済実装と同じですか。
別のサービスです*3。Apple Pay・Google Payはクレジットカード等の決済情報を扱う支払いサービスであるのに対し、Apple Wallet・Google Walletのパス機能は会員証・クーポン・チケット・搭乗券などの非決済の証憑を管理する仕組みです。決済実装を検討している場合は別稿(決済連携)を、パスの追加・配信・更新を検討している場合は本稿の内容を参照してください。
Apple WalletとGoogle Walletの両方に対応する場合、実装は共通化できますか。
パスの構成ファイル・署名方式・更新方式がOSごとに異なるため、共通のロジックを一本化することは難しく、それぞれの仕様に合わせた個別実装が必要です*1 *4。Appleは.pkpassとPass Type ID証明書、Googleはパスクラス/オブジェクトとJWTという異なる仕組みで動作するため、両OS対応を計画する際は工数もOSごとに見積もっておくことが望ましいでしょう。
パスの内容を更新すると、ユーザーの端末には自動で反映されますか。
仕組みが異なります。Apple Walletは、自社のWebサービスからApple Push Notification service(APNs)経由で更新通知を送り、通知を受け取った端末側が更新後の.pkpassを取得しに行く方式です*6。Google Walletは、REST APIでパスクラスやパスオブジェクトを更新すると、該当する保有者のパスに自動的に反映される方式です*7。いずれの場合も、更新の仕組みをどちらが実装・運用するかを事前に取り決めておく必要があります。
会員証・クーポン・チケットなど、どのパスタイプを選べばよいですか。
用途に応じた標準的なパスタイプが用意されています。会員証やポイントカードはAppleのstoreCard、Googleのロイヤリティに相当し、クーポンはAppleのcoupon、Googleのオファーに相当します*2 *5。イベントチケットや搭乗券もそれぞれ専用のパスタイプが用意されているため、既存のタイプに当てはまる場合はそちらを優先し、当てはまらない固有の体験が必要な場合に汎用パス(Generic)を検討する順序が基本です。
外注する場合、パスの発行だけでなく何を確認すべきですか。
パスの新規発行だけでなく、更新の仕組み(Apple側のWebサービス設計、Google側のREST API実装)まで見積もりに含まれているかを確認する必要があります。加えて、Pass Type ID証明書やGoogle Cloudサービスアカウントの管理主体、契約終了後の権限移管手順、pass.jsonやパスクラス定義のソースコードの引き継ぎ範囲を契約段階で明記しておくことが、長期的な運用の継続性を左右します。
著者:テレリモ総研編集部 鈴木 亮佑
ご不明な点はお問い合わせフォームからもご連絡いただけます。
- *1 出典:Apple「Building a Pass」(Wallet Passes documentation)https://developer.apple.com/documentation/walletpasses/building-a-pass
- *2 出典:Apple「Wallet Passes」(Apple Developer Documentation)https://developer.apple.com/documentation/walletpasses
- *3 出典:Apple「Wallet」(Apple Developer)https://developer.apple.com/wallet/
- *4 出典:Google「Add to Google Wallet」(Generic pass, Google Wallet API)https://developers.google.com/wallet/generic/web
- *5 出典:Google「Google Wallet API」(Google for Developers)https://developers.google.com/wallet
- *6 出典:Apple「Adding a Web Service to Update Passes」(Wallet Passes documentation)https://developer.apple.com/documentation/walletpasses/adding-a-web-service-to-update-passes
- *7 出典:Google「Update Passes Classes and Passes Objects」(Generic pass, Google Wallet API)https://developers.google.com/wallet/generic/use-cases/updates