Fluxo de desenvolvimento do cartão da Carteira do Google

A API Google Wallet oferece um conjunto predefinido de tipos de cartão otimizados para casos de uso específicos, como vales-presente, cartões de embarque, ingressos de eventos e muito mais. Há também um tipo de cartão genérico destinado aos casos de uso em que um tipo específico de cartão não está disponível.

Neste artigo, apresentamos as etapas básicas necessárias para criar e emitir um cartão usando a API Google Wallet. Há várias maneiras de realizar algumas das etapas detalhadas abaixo, mas, em geral, todos os tipos de cartão são criados seguindo o mesmo fluxo de desenvolvimento básico.

Para ver um tutorial detalhado sobre como criar um cartão, consulte os guias para Web, e-mail e SMS ou apps Android.

Para que serve

Uma classe de cartões define um conjunto de propriedades comuns em vários cartões, semelhante a um modelo. Por exemplo, se você estivesse emitindo ingressos de um evento, a classe de cartões definiria campos que são iguais em todos os ingressos, como o nome, a data e a hora do evento.

Todos os cartões emitidos precisam referenciar uma classe de cartão. Também é necessário atribuir um ID exclusivo a cada classe de cartão criada, que será usado como referência na criação de cartões.

Como isso acontece

Uma classe de cartões é definida no formato JSON e pode ser criada com a API REST da Carteira do Google, o SDK do Android ou no Console Business da Carteira do Google.

Mostrar exemplo de classe de cartões

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

Para que serve

Um objeto de cartões define as propriedades de um cartão exclusivo que será emitido para um usuário específico. Por exemplo, o objeto de cartões de um ingresso de evento define campos exclusivos de um ingresso específico, como o número do assento ou um QR code desse ingresso.

Quando um objeto de cartão é criado, a API Google Wallet armazena um novo cartão e o associa à sua conta de emissor. Esse cartão armazenado é uma combinação das propriedades exclusivas do objeto de cartões e das propriedades do modelo da classe de cartões associada.

Você também precisa atribuir a cada objeto de cartão um ID exclusivo, que será usado como referência ao emitir um cartão.

Como isso acontece

Um objeto de cartões é definido no formato JSON e pode ser criado com a API REST da Carteira do Google ou o SDK do Android.

Mostrar exemplo de objeto de cartões

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

Para que serve

Para emitir um cartão para um usuário, uma classe de cartões e um objeto de cartões precisam ser codificados em um JSON Web Token (JWT). O formato JWT é um padrão comum e aberto para representar declarações entre duas partes. No caso de emissão de cartões com a API Google Wallet, os JWTs são usados para enviar uma declaração de que um usuário tem o direito de acessar um cartão específico associado à sua conta de emissor.

Quando um JWT é enviado à API Google Wallet, os dados codificados são usados para identificar um cartão específico e emiti-lo ao usuário. Se o cartão já foi emitido, esses dados também permitem que a API Google Wallet identifique que o cartão é uma cópia, para que ele não seja adicionado à Carteira do Google do usuário mais de uma vez.

Como isso acontece

Os JWTs são definidos no formato JSON com base na especificação JWT. Para definir um JWT para emitir um cartão com a API Google Wallet, forneça as informações sobre o cartão que você quer emitir na propriedade payload do JWT.

Mostrar exemplo de JWT

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

Para que serve

Todos os JWTs enviados à API Google Wallet para emitir um cartão precisam ser assinados com as credenciais que você forneceu anteriormente no Console Business da Carteira do Google. A assinatura usa suas credenciais para criptografar o JWT. Assim, seus cartões permanecem seguros e a API Google Wallet pode autenticar se os detalhes do cartão codificados são válidos e associados à sua conta de emissor.

Como isso acontece

As bibliotecas de cliente da Carteira do Google e o SDK do Android oferecem métodos convenientes para assinar seus JWTs. Há também várias bibliotecas de código aberto disponíveis que lidam com a complexidade da assinatura de código para você escolher.

Para quem usa a API REST da Carteira do Google para emitir cartões, o JWT é assinado com uma chave de conta de serviço do Google Cloud. Para quem usa o SDK para Android da Carteira do Google, o SDK processa automaticamente a assinatura do JWT com a impressão digital SHA-1 do seu certificado de assinatura de apps.

Para proteger suas credenciais, os JWTs devem ser assinados apenas no seu servidor ou usando o SDK do Android da Carteira do Google no seu app.

Mostrar exemplo de assinatura de código

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

Para que serve

Depois de criar um JWT assinado, você vai poder emitir seu cartão para um usuário da Carteira do Google. Para fazer isso, apresente ao usuário um botão ou um link "Adicionar à Carteira do Google". Quando um usuário clica no botão ou no hiperlink, o JWT assinado é enviado para a API Google Wallet, que a descriptografa usando suas credenciais salvas. Depois que a assinatura JWT for autenticada, o cartão será emitido para que o usuário salve na Carteira do Google.

Como isso acontece

Para criar um botão "Adicionar à Carteira do Google" em um app Android, use o SDK da Carteira do Google para Android, que oferece métodos para gerar o botão. Para todas as outras plataformas, incluindo Web, e-mail e mensagens de texto, crie um hiperlink no formato https://pay.google.com/gp/v/save/<signed_jwt>. Sempre que possível, o melhor é entregar esse link ao usuário como um botão "Adicionar à Carteira do Google".

Para mais informações sobre como usar o botão "Adicionar à Carteira do Google", consulte as Diretrizes da promoção de marca da API Google Wallet.

Mostrar exemplo de código

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

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

Depois que o usuário salvar o cartão emitido, ele vai aparecer no app Carteira do Google com todos os outros cartões salvos.

Como criar objetos e classes de cartões no JWT

As classes e os objetos de cartões podem ser criados com antecedência usando a API REST da Carteira do Google ou o SDK do Android. Depois de criados, eles são usados para emitir cartões referenciando seu ID.

Como alternativa, também é possível criar classes e objetos de cartões no momento certo, incorporando o JSON diretamente no JWT usado para emitir o cartão para um usuário. Nesse método, as classes e os objetos de cartão são criados pela API Google Wallet quando o JWT assinado é enviado usando um botão ou link "Adicionar à Carteira do Google".

Por exemplo, o exemplo a seguir mostra um JWT com uma nova classe de cartões e um objeto de cartões definidos usando as propriedades payload.eventTicketClasses e payload.eventTicketObjects. Essas propriedades são matrizes. Portanto, elas podem aceitar uma ou mais classes ou objetos de cartões. Também é possível especificar apenas um novo objeto de cartões no JWT que se refere a uma classe de cartões atual pelo ID.

Mostrar exemplo de 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": ""
        }
      }]
    }
  }