GiGOアプリにおけるApple Pay決済導入の実装
はじめに
こんにちは、モバイル開発部の増子です。
私が担当しているGiGOアプリでは、クレジットカードやPayPayでの決済に対応していましたが、新たにApple Payを追加しました。
実装自体はシンプルでしたが、実際にリリースするまでにはドキュメントだけでは分かりにくい部分や、いくつかの問題に遭遇しました。
なお、GiGOアプリは、全国のGiGOグループのお店(アミューズメント施設)でプレイした履歴に応じておトクなサービスを受けられる、GiGOグループのお店公式アプリです。
本記事では、GiGOアプリにおけるApple Pay導入で得た知見を共有します。
Apple Pay決済とは
決済方式
iOSアプリの決済には「アプリ内課金(In-App Purchase)」と「外部決済」があります。
アプリ内課金はデジタルコンテンツ向け、外部決済は物理的な商品・サービス向けです。
なお、2025年12月に施行された スマートフォンソフトウェア競争促進法(スマホ法) により、アプリ内課金における外部決済への誘導が可能になるなど、決済を取り巻く環境は変化しています。
GiGOアプリでは、GiGOリンク でのクレジット購入や回数券の購入など、物理的なサービスへの決済のため外部決済を採用しています。今回、その決済手段としてApple Payを追加しました。
Apple Payのメリット
Apple Payを導入するメリットは、以下の点です。
ユーザー体験の向上
- Face ID / Touch IDで素早く認証できる
- カード情報の入力が不要
- Walletに登録済みのカードをそのまま使える
セキュリティ
- 実際のカード番号はアプリやサーバーに渡らない
- デバイス固有のトークンを使用
- 毎回の決済でユニークなセキュリティコードが生成される
コンバージョン向上
- 決済フローが短縮される
- カード情報入力の離脱を防げる
決済の仕組み
Apple Pay決済の基本的な流れは以下の通りです。
1. アプリがPKPaymentRequestを作成
2. PKPaymentAuthorizationViewControllerを表示
3. ユーザーがFace ID / Touch IDで認証
4. Apple Payがトークン化されたペイメントデータを返却
5. アプリがトークンをサーバーに送信
6. サーバーが決済代行サービスを通じて決済処理
7. 結果をApple Pay UIに通知
重要なのは、アプリやサーバーに渡されるのは「トークン化されたデータ」であり、実際のカード番号ではないという点です。これにより、セキュリティリスクを大幅に軽減できます。
アプリ側の実装内容
ここからは実際の実装内容を説明します。
PassKitの基本設定
Apple Pay決済を実装するには、PassKitフレームワークを使用します。
Merchant IDの取得・設定
まず、Apple Developer Portal でMerchant IDを作成します。
- Apple Developer Portal にログイン
- 「Certificates, Identifiers & Profiles」を選択
- 「Identifiers」から「Merchant IDs」を選択
- 新しいMerchant IDを作成
作成したMerchant IDは、Xcodeプロジェクトの「Signing & Capabilities」から「Apple Pay」を追加し、設定します。
対応カードブランドの選定
Apple Payでは複数のカードブランドに対応できます。
private static let supportedNetworks: [PKPaymentNetwork] = [
.visa,
.masterCard,
.JCB,
.amex
]
どのブランドに対応するかは、決済代行サービスの対応状況も確認して決定してください。
なお、対応可能なブランドの一覧は PKPaymentNetwork を参照してください。
PKPaymentRequestの作成
決済リクエストを作成する際は、以下のパラメータを設定します。
private func createPaymentRequest(amount: Decimal) -> PKPaymentRequest {
let request = PKPaymentRequest()
// 決済サマリー(ユーザーに表示される内容)
request.paymentSummaryItems = [
PKPaymentSummaryItem(
label: "GiGO", // 表示名
amount: NSDecimalNumber(decimal: amount)
)
]
// Merchant ID
request.merchantIdentifier = "merchant.com.example.app"
// 対応カードブランド
request.supportedNetworks = [.visa, .masterCard, .JCB, .amex]
// 決済機能(3Dセキュア対応)
request.merchantCapabilities = [.capability3DS]
// 国コード・通貨コード
request.countryCode = "JP"
request.currencyCode = "JPY"
// 配送関連(不要な場合は空に)
request.shippingType = .storePickup
request.requiredShippingContactFields = []
return request
}
paymentSummaryItems の label には、決済画面に表示されるサービス名を設定します。ユーザーが何に対して支払いを行うのか分かりやすい名称にしましょう。
決済フローの実装
PKPaymentAuthorizationViewControllerの表示
決済画面を表示するには、PKPaymentAuthorizationViewController を使用します。
func startPayment(amount: Int) {
let request = createPaymentRequest(amount: Decimal(amount))
guard let viewController = PKPaymentAuthorizationViewController(paymentRequest: request) else {
// 初期化失敗
return
}
viewController.delegate = self
// 決済画面を表示
present(viewController, animated: true)
}

Apple Pay決済画面
デリゲートでのトークン取得
決済が認証されると、デリゲートメソッドが呼ばれます。ここでトークンを取得し、サーバーに送信します。
extension ViewController: PKPaymentAuthorizationViewControllerDelegate {
func paymentAuthorizationViewController(
_ controller: PKPaymentAuthorizationViewController,
didAuthorizePayment payment: PKPayment,
handler completion: @escaping (PKPaymentAuthorizationResult) -> Void
) {
// トークンをBase64エンコード
let token = payment.token.paymentData.base64EncodedString()
Task {
do {
// サーバーに送信して決済処理
try await sendTokenToServer(token)
// 成功をApple Pay UIに通知
completion(PKPaymentAuthorizationResult(status: .success, errors: nil))
} catch {
// 失敗をApple Pay UIに通知
completion(PKPaymentAuthorizationResult(status: .failure, errors: nil))
}
}
}
func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) {
// 画面を閉じる
controller.dismiss(animated: true)
}
}
ここでのポイントは、サーバーAPIの結果に応じてApple Pay UIに成功/失敗を通知することです。これにより、ユーザーには決済結果が正しくフィードバックされます。

決済成功時の画面
利用可能性チェック
Apple Payが利用可能かどうかは、事前にチェックできます。
static func isApplePayAvailable() -> Bool {
// 指定したカードブランドで決済可能かチェック
PKPaymentAuthorizationViewController.canMakePayments(
usingNetworks: [.visa, .masterCard, .JCB, .amex]
)
}
このメソッドは以下の内容をチェックします。
- デバイスがApple Payに対応しているか
- Walletに対応するカードが登録されているか
利用不可の場合は、Apple Payボタンを非表示にしたり、Walletアプリへの誘導を表示したりするとよいでしょう。

GiGOアプリの支払い方法選択画面
ブランドガイドライン
Apple Payを導入する際は、Appleのブランドガイドラインに従う必要があります。
Human Interface Guidelinesの要点
ロゴの使用
Apple Payのロゴやマークを使用する際は、Appleが提供する公式アセットを使用してください。自作のロゴは使用できません。
文言の制約
「Apple Pay」という名称を使用する際のルールがあります。
- 「Apple Pay」は常に正しいスペルで表記する
- 「ApplePay」「apple pay」などの表記は不可
- Apple Payを「支払い方法の一つ」として説明する際は、他の決済方法と同列に扱う
詳細は Apple Pay Marketing Guidelines を参照してください。
開発時に遭遇した課題と対処法
シミュレータでのテスト
開発時にiOSシミュレータでテストする際には注意点があります。
実機でないとトークンが取得できない
iOSシミュレータではApple Payの決済フローをテストできますが、実際のペイメントトークンは取得できません。シミュレータで取得できるトークンはダミーデータであり、決済代行サービスでは処理できません。
対処法
開発・テスト時は以下のアプローチを取りました。
- UIフローのテスト - シミュレータで決済画面の表示・操作をテスト
- 決済処理のテスト - 実機でSandbox環境を使用してテスト
- 単体テスト - トークン送信以降の処理はモックを使用してテスト
#if DEBUG && targetEnvironment(simulator)
// シミュレータの場合はテスト用トークンを使用
let token = "test_token_for_development"
#else
let token = payment.token.paymentData.base64EncodedString()
#endif
Sandboxテスト
実機でApple Pay決済をテストする場合は、AppleのSandbox環境を使用します。
テスト環境のセットアップ
- App Store ConnectでSandboxテスターアカウントを作成
- テスト用デバイスでSandboxアカウントにサインイン
- Walletアプリでテスト用カードを追加
テストカード番号
テストカード番号は Apple公式ドキュメント を参照してください。
注意点
- Sandboxではテスト用カードを使用するため、実際の課金は発生しない
- テストデバイスの地域がApple Payをサポートしている国に設定されている必要がある
- プロダクション環境とSandbox環境では異なる鍵が使用される
Apple Payの追加/削除
Apple Payに登録されているカードの追加・削除に関する注意点です。
アプリ内でカードの追加・削除ができない
Apple Payに登録されているカードの追加・削除は、アプリ内から直接行うことができません。これはセキュリティ上の理由からAppleが制限しています。
対処法
GiGOアプリでは、ヘルプ記事やAppleサポートページへ誘導する形で対応しました。
- 追加時 → Apple Payの使い方を説明するヘルプ記事へ誘導
- 削除時 → Appleサポートページへ誘導
フォアグラウンド復帰時の状態更新
Walletアプリとの遷移時に気をつけるべき点があります。
Wallet設定変更後に画面が更新されない
ユーザーがWalletアプリでカードを追加・削除した後、アプリに戻ってきても画面が更新されない問題がありました。
対処法
UIScene.willEnterForegroundNotification を監視し、フォアグラウンド復帰時に状態を再チェックします。
.onReceive(NotificationCenter.default.publisher(for: UIScene.willEnterForegroundNotification)) { _ in
// Apple Pay登録状態が変わった場合、画面を更新
if previousAvailability != isApplePayAvailable() {
Task {
await reloadPaymentMethods()
}
}
}
バックグラウンド移行時に現在の状態を保存しておき、フォアグラウンド復帰時に比較することで、必要な場合のみ更新処理を実行します。
App Store審査でのリジェクト
実装が完了してApp Storeに申請したところ、リジェクトが発生しました。
Apple Pay統合が確認できない
Apple Pay機能を含むアプリを申請した際、以下の理由でリジェクトされました。
Guideline 2.1 - Information Needed
PassKit frameworkを含んでいるが、アプリ内でApple Pay統合を確認できなかった
審査担当者がApple Payの決済画面にたどり着けなかったことが原因でした。
対処法
App Reviewチームに対して、以下の情報を提供しました。
- Apple Payの決済画面までの詳細な操作手順
- 実際の操作を録画した動画
これにより、翌日には審査を通過できました。
証明書の更新
証明書の有効期限が切れると決済が処理されなくなるので注意が必要です。
Apple Pay Payment Processing Certificate
Apple Payを本番環境で使用するには、Apple Developer Portal で「Apple Pay Payment Processing Certificate」を作成する必要があります。
この証明書には以下の特徴があります。
- 有効期限は2年
- 期限切れになると決済が処理できなくなる
- 更新時はCSR(Certificate Signing Request)の再生成が必要
更新手順
- CSR(Certificate Signing Request)を生成
- Apple Developer Portal にログイン
- 「Certificates, Identifiers & Profiles」→ 該当のMerchant IDを選択
- 「Apple Pay Payment Processing Certificate」の「Create Certificate」をクリック
- CSRをアップロード
- 新しい証明書をダウンロード
- テスト環境で動作確認
- 本番環境に適用
注意点
- 証明書更新後も、古い証明書で処理中のトランザクションは完了できる
- 新しい証明書は即座に有効になる
- 更新作業自体でサービスが停止することはない
- 秘密鍵とPKCS#12(.p12)ファイルのパスワードは安全な場所に保管しておく必要がある
# 導入してみた所感
Apple Pay決済の導入は、実装自体はシンプルですが、以下の点で注意が必要でした。
- シミュレータでの制限 - 実機テストが必須
- Walletアプリとの連携 - カード管理はアプリ外で行う設計が必要
- 証明書管理 - 定期的な更新作業が発生
一方で、ユーザー体験の向上は明確に感じられました。カード情報を入力する手間がなく、Face IDで素早く決済できるため、決済フローがスムーズになりました。
導入後はユーザーから喜びの声をいただき、リリース初月から約1割の決済でApple Payが利用されています。
おわりに
Apple Payは、カード情報を入力する手間もなく、Face IDだけでサクッと決済できます。ゲームの待ち時間も短縮できるので、ぜひGiGOアプリで試してみてください。
Discussion