Flux de développement de cartes Google Wallet

L'API Google Wallet fournit un ensemble prédéfini de types de cartes optimisées pour des cas d'utilisation spécifiques, tels que les cartes cadeaux, les cartes d'embarquement, les billets pour des événements, etc. Il existe également un type de carte générique destiné aux cas d'utilisation où un type de carte spécifique n'est pas disponible.

Cet article a pour but de vous aider à vous familiariser avec la procédure de base nécessaire pour créer et émettre une carte à l'aide de l'API Google Wallet. Il existe plusieurs façons d'effectuer certaines des étapes décrites ci-dessous, mais de manière générale, tous les types de cartes sont créés en suivant le même flux de développement de base.

Pour découvrir en détail comment créer une carte, consultez les guides pour le Web, les e-mails et les SMS, ou les applications Android.

À quoi ça sert ?

Une classe Cartes définit un ensemble de propriétés communes à plusieurs cartes, comme dans un modèle. Par exemple, si vous émettez des billets pour un événement, la classe Cartes définit des champs identiques pour tous les billets, tels que le nom, la date et l'heure de l'événement.

Chaque carte que vous émettez doit référencer une classe de carte. Vous devez également attribuer un ID unique à chaque classe de carte que vous créez, qui permet de le référencer lors de la création de cartes.

Procédure

Une classe Cartes est définie au format JSON et peut être créée avec l'API REST Google Wallet, le SDK Android ou dans la Business Console de Google Wallet.

Afficher un exemple de classe de carte

{
  "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"
      }
    }
  }
}
    

À quoi ça sert ?

Un objet Cartes définit les propriétés d'une carte unique qui sera délivrée à un utilisateur spécifique. Par exemple, l'objet Cartes d'un billet pour un événement définit des champs spécifiques à chaque billet, comme le numéro de siège ou le code QR de ce billet.

Lorsqu'un objet Cartes est créé, l'API Google Wallet stocke une nouvelle carte et l'associe à votre compte d'émetteur. Cette carte stockée est une combinaison des propriétés uniques de l'objet Cartes et des propriétés de modèle de la classe Cartes associée.

Vous devez également attribuer à chaque objet Cartes un identifiant unique qui permet de le référencer lors de l'émission d'une carte.

Procédure

Un objet Cartes est au format JSON défini et peut être créé avec l'API REST Google Wallet ou le SDK Android.

Afficher un exemple d'objet Cartes

{
  "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": ""
  }
}
    

À quoi ça sert ?

Pour émettre une carte à un utilisateur, une classe Cartes et un objet Cartes doivent être encodés dans un jeton Web JSON (JWT). Le format JWT est une norme ouverte et commune permettant de représenter les revendications entre deux parties. Dans le cas de l'émission de cartes avec l'API Google Wallet, les jetons JWT sont utilisés pour envoyer une demande indiquant qu'un utilisateur a le droit d'accéder à une carte spécifique associée à votre compte d'émetteur.

Lorsqu'un jeton JWT est envoyé à l'API Google Wallet, les données encodées sont utilisées pour identifier une carte spécifique et l'envoyer à l'utilisateur. Si la carte a déjà été émise, ces données permettent également à l'API Google Wallet d'identifier que la carte est un doublon afin qu'elle ne soit pas ajoutée plusieurs fois au Google Wallet de l'utilisateur.

Procédure

Les jetons JWT sont définis au format JSON selon la spécification JWT. Pour définir un jeton JWT permettant d'émettre une carte avec l'API Google Wallet, vous devez fournir les informations sur la carte que vous souhaitez émettre dans la propriété payload du jeton JWT.

Afficher l'exemple de jeton JWT

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

À quoi ça sert ?

Tous les jetons JWT envoyés à l'API Google Wallet pour émettre une carte doivent être signés avec les identifiants que vous avez déjà fournis dans la Business Console de Google Wallet. La signature utilise vos identifiants pour chiffrer le JWT afin de sécuriser vos cartes, et pour permettre à l'API Google Wallet d'authentifier que les informations de la carte qui y sont encodées sont valides et associées à votre compte d'émetteur.

Procédure

Les bibliothèques clientes Google Wallet et le SDK Android proposent des méthodes pratiques pour signer vos jetons JWT. Il existe également de nombreuses bibliothèques Open Source qui gèrent la complexité de la signature du code.

Pour ceux qui utilisent l'API REST Google Wallet pour émettre des cartes, le JWT est signé avec une clé de compte de service Google Cloud. Si vous utilisez le SDK Google Wallet pour Android, le SDK gère automatiquement la signature du jeton JWT avec l'empreinte SHA-1 de votre certificat de signature d'application.

Pour protéger vos identifiants, les jetons JWT ne doivent être signés que sur votre serveur ou à l'aide du SDK Android de Google Wallet dans votre application.

Afficher un exemple de signature de code

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')
        

À quoi ça sert ?

Une fois que vous avez créé un jeton JWT signé, vous pouvez envoyer votre carte à un utilisateur Google Wallet. Pour ce faire, l'utilisateur peut cliquer sur le bouton ou le lien "Ajouter à Google Wallet". Lorsqu'un utilisateur clique sur le bouton ou le lien hypertexte, le jeton JWT signé est envoyé à l'API Google Wallet, qui le déchiffre à l'aide des identifiants enregistrés. Une fois la signature JWT authentifiée, la carte est délivrée à l'utilisateur pour qu'il l'enregistre dans Google Wallet.

Procédure

Pour créer un bouton "Ajouter à Google Wallet" pour une application Android, utilisez le SDK Google Wallet pour Android, qui fournit des méthodes permettant de le générer. Pour toutes les autres plates-formes, y compris le Web, les e-mails et les SMS, créez un lien hypertexte au format https://pay.google.com/gp/v/save/<signed_jwt>. Dans la mesure du possible, il est préférable de fournir ce lien à l'utilisateur sous la forme d'un bouton "Ajouter à Google Wallet".

Pour en savoir plus sur l'utilisation du bouton "Ajouter à Google Wallet", consultez les Consignes relatives à la marque de l'API Google Wallet.

Afficher l'exemple de code

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

SDK Android

  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)
    }
  }
        

Une fois que l'utilisateur a enregistré la carte émise, elle apparaît dans l'application Google Wallet avec toutes les autres cartes enregistrées.

Créer des objets et des classes de cartes dans le jeton JWT

Les classes et les objets de cartes peuvent être créés à l'avance à l'aide de l'API REST Google Wallet ou du SDK Android. Une fois créées, elles sont ensuite utilisées pour émettre des cartes en référençant leur ID.

Vous pouvez également créer des classes et des objets de cartes "juste à temps" en intégrant leur JSON directement dans le JWT qui est utilisé pour émettre la carte à un utilisateur. Avec cette méthode, les classes et les objets des cartes sont créés par l'API Google Wallet lorsque le jeton JWT signé est envoyé à l'aide d'un bouton ou d'un lien "Ajouter à Google Wallet".

Par exemple, voici un JWT avec une nouvelle classe de carte et un objet Cartes définis à l'aide des propriétés payload.eventTicketClasses et payload.eventTicketObjects. Notez que ces propriétés sont des tableaux et qu'elles peuvent donc accepter un ou plusieurs objets Cartes ou classes de cartes. Vous pouvez également spécifier simplement un nouvel objet Cartes dans le JWT qui référence une classe Cartes existante par son ID.

Afficher l'exemple de jeton 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": ""
        }
      }]
    }
  }