Google ウォレットのパスの開発フロー

Google Wallet API には、ギフトカード、搭乗券、イベント チケットなど、特定のユースケース向けに最適化された事前定義された一連のパスタイプが用意されています。また、特定のパスタイプを利用できないユースケースを対象とした汎用パスタイプもあります。

この記事では、Google Wallet API を使用してパスを作成して発行するために必要な基本的な手順について説明します。以下で説明する手順の一部を実行する方法は複数ありますが、大まかには、同じ基本的な開発フローに従ってすべてのパスタイプが作成されます。

パスの作成手順について詳しくは、ウェブ、メール、SMS または Android アプリのガイドをご覧ください。

目的

パスクラスは、テンプレートと同様に、複数のパスに共通する一連のプロパティを定義します。たとえば、イベントのチケットを発行する場合、パスクラスはすべてのチケットに共通するフィールド(イベント名、日付、時刻など)を定義します。

発行するすべてのパスは、パスクラスを参照する必要があります。また、作成するすべてのパスクラスに一意の ID を割り当てる必要があります。この ID は、パスの作成時にその ID を参照するために使用されます。

仕組み

パスクラスは JSON 形式で定義され、Google Wallet REST API、Android SDK、Google ウォレット ビジネス コンソールで作成できます。

パスクラスの例を表示

{
  "id": "ISSUER_ID.EVENT_CLASS_ID",
  "issuerName": "[TEST ONLY] Heraldic Event",
  "localizedIssuerName": {
    "defaultValue": {
      "language": "en-US",
      "value": "[TEST ONLY] Heraldic Event"
    }
  },
  "logo": {
    "sourceUri": {
      "uri": "https://images.unsplash.com/photo-1475721027785-f74eccf877e2?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=660&h=660"
    },
    "contentDescription": {
      "defaultValue": {
        "language": "en-US",
        "value": "LOGO_IMAGE_DESCRIPTION"
      }
    }
  },
  "eventName": {
    "defaultValue": {
      "language": "en-US",
      "value": "Google Live"
    }
  },
  "venue": {
    "name": {
      "defaultValue": {
        "language": "en-US",
        "value": "Shoreline Amphitheater"
      }
    },
    "address": {
      "defaultValue": {
        "language": "en-US",
        "value": "ADDRESS_OF_THE_VENUE"
      }
    }
  },
  "dateTime": {
    "start": "2023-04-12T11:30"
  },
  "reviewStatus": "UNDER_REVIEW",
  "hexBackgroundColor": "#264750",
  "heroImage": {
    "sourceUri": {
      "uri": "https://images.unsplash.com/photo-1501281668745-f7f57925c3b4?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1032&h=336"
    },
    "contentDescription": {
      "defaultValue": {
        "language": "en-US",
        "value": "HERO_IMAGE_DESCRIPTION"
      }
    }
  }
}
    

目的

パス オブジェクトは、特定のユーザーに発行される一意のパスのプロパティを定義します。たとえば、イベント チケットのパス オブジェクトでは、座席番号や QR コードなど、特定のチケットに固有のフィールドを定義します。

パス オブジェクトが作成されると、Google Wallet API は新しいパスを保存し、そのパスを発行元のアカウントに関連付けます。この格納されるパスは、パス オブジェクトの一意のプロパティと、関連するパスクラスのテンプレート プロパティを組み合わせたものです。

また、各パス オブジェクトに一意の ID を割り当てる必要があります。この ID は、パスの発行時にオブジェクトを参照するために使用されます。

仕組み

パス オブジェクトは定義された JSON 形式で、Google Wallet REST API または Android SDK で作成できます。

パス オブジェクトの例を表示

{
  "id": "ISSUER_ID.OBJECT_ID",
  "classId": "ISSUER_ID.EVENT_CLASS_ID",
  "state": "ACTIVE",
  "seatInfo": {
    "seat": {
      "defaultValue": {
        "language": "en-us",
        "value": "5"
      }
    },
    "row": {
      "defaultValue": {
        "language": "en-us",
        "value": "G"
      }
    },
    "section": {
      "defaultValue": {
        "language": "en-us",
        "value": "40"
      }
    },
    "gate": {
      "defaultValue": {
        "language": "en-us",
        "value": "3A"
      }
    }
  },
  "barcode": {
    "type": "QR_CODE",
    "value": "BARCODE_VALUE",
    "alternateText": ""
  }
}
    

目的

ユーザーにパスを発行するには、パスクラスとパス オブジェクトを JSON Web Token(JWT)でエンコードする必要があります。JWT 形式は、2 者間のクレームを表すための一般的なオープン スタンダードです。Google Wallet API でパスを発行する場合、JWT を使用して、発行元のアカウントに関連付けられた特定のパスに対するアクセス権をユーザーが持っているというクレームが送信されます。

JWT が Google Wallet API に送信されると、エンコードされたデータを使用して特定のパスが識別され、ユーザーに発行されます。パスがすでに発行されている場合、Google Wallet API はこのデータを使用してパスが重複であると識別できるため、ユーザーの Google ウォレットに複数回追加されることはありません。

仕組み

JWT は、JWT 仕様に基づく JSON 形式で定義されます。Google Wallet API を使用してパスを発行する JWT を定義するには、発行するパスに関する情報を JWT の payload プロパティに指定します。

JWT の例を表示

{
  "iss": "issuer@example.com",
  "aud": "google",
  "typ": "savetowallet",
  "iat": 1696877738,
  "origins": [
    "www.example.com"
  ],
  "payload": {
    "eventTicketObjects": [
      {
        "id": "ISSUER_ID.LOYALTY_OBJECT_SUFFIX"
      }
    ]
  }
}
    

目的

パスを発行するために Google Wallet API に送信される JWT はすべて、Google ウォレット ビジネス コンソールで事前に指定した認証情報で署名する必要があります。署名することで、認証情報を使用して JWT が暗号化され、パスの安全性が保たれます。また、エンコードされたパスの詳細が有効で、発行者アカウントに関連付けられていることを Google Wallet API が認証できます。

仕組み

Google ウォレット クライアント ライブラリと Android SDK には、JWT に署名するための便利なメソッドが用意されています。また、複雑なコード署名を処理できるオープンソース ライブラリも数多く提供されています。

Google Wallet REST API を使用してパスを発行する場合、JWT は Google Cloud サービス アカウント キーで署名されます。Google ウォレット Android SDK を使用している場合は、SDK が自動的にアプリ署名証明書の SHA-1 フィンガープリントを使用して JWT の署名を処理します。

認証情報を保護するため、JWT の署名は、必ずデベロッパーのサーバー上で行うか、アプリで Google ウォレット Android SDK を使用して行う必要があります。

コード署名のサンプルを表示

Java

  // Create the JWT as a HashMap object
  HashMap claims = new HashMap();
  claims.put("iss", ((ServiceAccountCredentials) credentials).getClientEmail());
  claims.put("aud", "google");
  claims.put("origins", Arrays.asList("www.example.com"));
  claims.put("typ", "savetowallet");

  // Create the Google Wallet payload and add to the JWT
  HashMap payload = new HashMap();
  payload.put("eventTicketObjects", Arrays.asList(newObject));
  claims.put("payload", payload);

  // Google Cloud service account credentials are used to sign the JWT
  Algorithm algorithm =
      Algorithm.RSA256(
          null, (RSAPrivateKey) ((ServiceAccountCredentials) credentials).getPrivateKey());
  String token = JWT.create().withPayload(claims).sign(algorithm);
        

Node.JS

  // Create the JWT claims
  let claims = {
    iss: this.credentials.client_email,
    aud: 'google',
    origins: ['www.example.com'],
    typ: 'savetowallet',
    payload: {
      eventTicketObjects: [newObject]
    },
  };

  // The service account credentials are used to sign the JWT
  let token = jwt.sign(claims, this.credentials.private_key, { algorithm: 'RS256' });
        

Python

  # Create the JWT claims
  claims = {
      'iss': self.credentials.service_account_email,
      'aud': 'google',
      'origins': ['www.example.com'],
      'typ': 'savetowallet',
      'payload': {
          # The listed classes and objects will be created
          'eventTicketObjects': [new_object]
      }
  }

  # The service account credentials are used to sign the JWT
  signer = crypt.RSASigner.from_service_account_file(self.key_file_path)
  token = jwt.encode(signer, claims).decode('utf-8')
        

目的

署名付き JWT を作成したら、Google ウォレット ユーザーにパスを発行できます。これを行うには、ユーザーに [Google ウォレットに追加] 画面を表示するか、クリックします。ユーザーがボタンまたはハイパーリンクをクリックすると、署名付き JWT が Google Wallet API に送信され、保存した認証情報を使用して復号されます。JWT 署名が認証されると、Google ウォレットに保存するためにパスがユーザーに発行されます。

仕組み

[Google ウォレットに追加] を作成するにはボタンを生成するためのメソッドを提供する Google ウォレット Android SDK を使用してください。ウェブ、メール、テキスト メッセージなど、他のすべてのプラットフォームでは、https://pay.google.com/gp/v/save/<signed_jwt> の形式でハイパーリンクを作成します。可能であれば、このリンクを [Google ウォレットに追加] としてユーザーに配信することをおすすめします。] ボタンを離します。

[Google ウォレットに追加] の使用方法の詳細Google Wallet API のブランド ガイドラインをご覧ください。

コード例を表示

  https://pay.google.com/gp/v/save/<signed_jwt>
        

Android SDK

  private lateinit var walletClient: PayClient
  private val addToGoogleWalletRequestCode = 1000
  private lateinit var addToGoogleWalletButton: View

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    walletClient = Pay.getClient(this)
    addToGoogleWalletButton.setOnClickListener {
      walletClient.savePasses(newObjectJson, this, addToGoogleWalletRequestCode)
    }
  }
        

発行されたパスをユーザーが保存すると、保存した他のパスとともに Google ウォレット アプリに表示されます。

JWT でパス オブジェクトとパスクラスを作成する

パスクラスとパス オブジェクトは、Google Wallet REST API または Android SDK を使用して事前に作成できます。作成されたパスは、ID を参照してパスを発行するために使用されます。

または、「ジャストインタイム」でパスクラスとパス オブジェクトを作成することもできます。ユーザーにパスを発行するために使用される JWT に JSON を直接埋め込むことができます。このメソッドでは、「Google ウォレットに追加」を使用して署名付き JWT が送信されると、Google Wallet API によってパスクラスとパス オブジェクトが作成されます。クリックします。

たとえば、payload.eventTicketClasses プロパティと payload.eventTicketObjects プロパティを使用して新しいパスクラスとパス オブジェクトが定義された JWT を次に示します。これらのプロパティは配列であるため、1 つ以上のパスクラスまたはパス オブジェクトを受け入れることができます。JWT で、既存のパスクラスを ID で参照する新しいパス オブジェクトだけを指定することもできます。

JWT の例を表示

  {
    "iss": "issuer@example.com",
    "aud": "google",
    "typ": "savetowallet",
    "iat": 1696877738,
    "origins": [
      "www.example.com"
    ],
    "payload": {
      "eventTicketClasses": [{
        "id": "ISSUER_ID.EVENT_CLASS_ID",
        "issuerName": "[TEST ONLY] Heraldic Event",
        "localizedIssuerName": {
          "defaultValue": {
            "language": "en-US",
            "value": "[TEST ONLY] Heraldic Event"
          }
        },
        "logo": {
          "sourceUri": {
            "uri": "https://images.unsplash.com/photo-1475721027785-f74eccf877e2?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=660&h=660"
          },
          "contentDescription": {
            "defaultValue": {
              "language": "en-US",
              "value": "LOGO_IMAGE_DESCRIPTION"
            }
          }
        },
        "eventName": {
          "defaultValue": {
            "language": "en-US",
            "value": "Google Live"
          }
        },
        "venue": {
          "name": {
            "defaultValue": {
              "language": "en-US",
              "value": "Shoreline Amphitheater"
            }
          },
          "address": {
            "defaultValue": {
              "language": "en-US",
              "value": "ADDRESS_OF_THE_VENUE"
            }
          }
        },
        "dateTime": {
          "start": "2023-04-12T11:30"
        },
        "reviewStatus": "UNDER_REVIEW",
        "hexBackgroundColor": "#264750",
        "heroImage": {
          "sourceUri": {
            "uri": "https://images.unsplash.com/photo-1501281668745-f7f57925c3b4?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1032&h=336"
          },
          "contentDescription": {
            "defaultValue": {
              "language": "en-US",
              "value": "HERO_IMAGE_DESCRIPTION"
            }
          }
        }
      }],
      "eventTicketObjects": [{
        "id": "ISSUER_ID.OBJECT_ID",
        "classId": "ISSUER_ID.EVENT_CLASS_ID",
        "state": "ACTIVE",
        "seatInfo": {
          "seat": {
            "defaultValue": {
              "language": "en-us",
              "value": "5"
            }
          },
          "row": {
            "defaultValue": {
              "language": "en-us",
              "value": "G"
            }
          },
          "section": {
            "defaultValue": {
              "language": "en-us",
              "value": "40"
            }
          },
          "gate": {
            "defaultValue": {
              "language": "en-us",
              "value": "3A"
            }
          }
        },
        "barcode": {
          "type": "QR_CODE",
          "value": "BARCODE_VALUE",
          "alternateText": ""
        }
      }]
    }
  }