Quy trình phát triển thẻ và vé trong Google Wallet

Google Wallet API cung cấp một tập hợp các loại thẻ và vé được xác định trước được tối ưu hoá cho các trường hợp sử dụng cụ thể, chẳng hạn như thẻ quà tặng, thẻ lên máy bay, vé xem sự kiện, v.v. Ngoài ra, còn có một loại thẻ và vé chung dành cho các trường hợp sử dụng không có loại thẻ và vé cụ thể.

Bài viết này nhằm giúp bạn làm quen với các bước cơ bản cần thiết để tạo và cấp thẻ và vé bằng Google Wallet API. Có nhiều cách để thực hiện một số bước được nêu chi tiết bên dưới, nhưng ở cấp độ cao, tất cả loại thẻ và vé đều được tạo bằng cách tuân theo cùng một quy trình phát triển cơ bản.

Để biết hướng dẫn chi tiết về cách tạo thẻ và vé, hãy xem hướng dẫn về web, email và SMS hoặc ứng dụng Android.

Mục đích sử dụng

Lớp Thẻ và vé xác định một tập hợp thuộc tính phổ biến trên nhiều thẻ và vé, tương tự như một mẫu. Ví dụ: Nếu bạn bán vé cho một sự kiện, thì Lớp Thẻ và vé sẽ xác định các trường giống nhau cho tất cả các vé, chẳng hạn như tên sự kiện, ngày và giờ.

Mỗi thẻ và vé mà bạn cấp phải tham chiếu đến một lớp Thẻ và vé. Bạn cũng phải chỉ định một mã nhận dạng duy nhất cho mọi Lớp thẻ và vé mà bạn tạo. Lớp này dùng để tham chiếu đến lớp đó khi tạo thẻ và vé.

Cách thực hiện

Lớp Thẻ và vé được xác định ở định dạng JSON và có thể được tạo bằng API REST của Google Wallet, SDK Android hoặc trong Google Wallet Business Console.

Hiện lớp thẻ và vé mẫu

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

Mục đích sử dụng

Đối tượng thẻ và vé xác định các thuộc tính của một thẻ và vé duy nhất sẽ được cấp cho một người dùng cụ thể. Ví dụ: Đối tượng Thẻ và vé cho một vé xem sự kiện sẽ xác định các trường dành riêng cho một vé cụ thể, chẳng hạn như số ghế hoặc mã QR của vé đó.

Khi một Đối tượng thẻ và vé được tạo, Google Wallet API sẽ lưu trữ một thẻ và vé mới và liên kết thẻ/vé đó với tài khoản Tổ chức phát hành của bạn. Thẻ và vé được lưu trữ này là sự kết hợp các thuộc tính duy nhất của Đối tượng thẻ và vé và các thuộc tính mẫu của Lớp thẻ và vé được liên kết.

Bạn cũng phải gán một mã nhận dạng duy nhất cho mỗi Đối tượng thẻ và vé. Mã này dùng để tham chiếu đến đối tượng đó khi cấp thẻ và vé.

Cách thực hiện

Đối tượng Passes được xác định ở định dạng JSON và có thể được tạo bằng API REST của Google Wallet hoặc SDK Android.

Ví dụ về việc truyền đối tượng

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

Mục đích sử dụng

Để cấp thẻ và vé cho người dùng, Lớp thẻ và vé phải được mã hoá bằng Mã thông báo web JSON (JWT). Định dạng JWT là một tiêu chuẩn mở và phổ biến để trình bày các tuyên bố giữa hai bên. Trong trường hợp cấp thẻ và vé bằng API Google Wallet, JWT được dùng để gửi tuyên bố rằng người dùng có quyền truy cập vào thẻ và vé cụ thể được liên kết với tài khoản Công ty phát hành thẻ của bạn.

Khi một JWT được gửi tới API Google Wallet, dữ liệu đã mã hoá sẽ được dùng để xác định một thẻ và vé cụ thể và phát hành nó cho người dùng. Nếu thẻ và vé đã được cấp, dữ liệu này cũng cho phép API Google Wallet xác định rằng thẻ và vé là trùng lặp để thẻ và vé không được thêm vào Google Wallet của người dùng nhiều lần.

Cách thực hiện

JWT được xác định ở định dạng JSON dựa trên thông số kỹ thuật JWT. Để xác định JWT cho việc cấp thẻ và vé bằng Google Wallet API, bạn cần cung cấp thông tin về thẻ và vé mà bạn muốn phát hành trong thuộc tính payload của JWT.

Hiển thị JWT ví dụ

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

Mục đích sử dụng

Tất cả JWT được gửi tới API Google Wallet để cấp thẻ và vé đều phải được ký bằng thông tin xác thực mà bạn đã cung cấp trước đó trong Google Wallet Business Console. Việc ký sử dụng thông tin xác thực của bạn để mã hoá JWT nhằm đảm bảo thẻ và vé của bạn vẫn được bảo mật và cho phép Google Wallet API xác thực rằng thông tin chi tiết được mã hoá trong thẻ và vé đó là hợp lệ và được liên kết với tài khoản Tổ chức phát hành thẻ của bạn.

Cách thực hiện

Thư viện ứng dụng Google Wallet và SDK Android cung cấp các phương thức tiện lợi để ký JWT của bạn. Ngoài ra còn có nhiều thư viện nguồn mở giúp xử lý sự phức tạp của việc ký mã để bạn lựa chọn.

Đối với những người sử dụng API REST của Google Wallet để cấp thẻ và vé, JWT được ký bằng khoá của tài khoản dịch vụ Google Cloud. Đối với những người sử dụng SDK Android của Google Wallet, SDK sẽ tự động xử lý việc ký JWT bằng vân tay số SHA-1 của chứng chỉ ký ứng dụng của bạn.

Để bảo vệ thông tin đăng nhập, bạn chỉ nên ký JWT trên máy chủ hoặc sử dụng SDK Android của Google Wallet trong ứng dụng của mình.

Hiện ký mã mẫu

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

Mục đích sử dụng

Sau khi tạo JWT đã ký, bạn có thể cấp thẻ và vé cho người dùng Google Wallet! Việc này được thực hiện bằng cách hiển thị cho người dùng nút hoặc đường liên kết "Thêm vào Google Wallet". Khi người dùng nhấp vào nút hoặc siêu liên kết đó, JWT đã ký sẽ được gửi đến Google Wallet API, sau đó sẽ giải mã bằng thông tin xác thực đã lưu của bạn. Sau khi chữ ký JWT được xác thực, thẻ và vé sẽ được cấp cho người dùng để lưu vào Google Wallet.

Cách thực hiện

Để tạo nút "Thêm vào Google Wallet" cho ứng dụng Android, hãy sử dụng SDK Android của Google Wallet. SDK này cung cấp các phương thức tạo nút. Đối với tất cả các nền tảng khác, bao gồm cả web, email và tin nhắn văn bản, hãy tạo một siêu liên kết theo định dạng https://pay.google.com/gp/v/save/<signed_jwt>. Nếu có thể, tốt nhất là nên cung cấp đường liên kết này cho người dùng dưới dạng nút "Thêm vào Google Wallet".

Để biết thêm thông tin về cách sử dụng nút 'Thêm vào Google Wallet', hãy xem Nguyên tắc về thương hiệu của Google Wallet API

Hiện mã ví dụ

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

Sau khi người dùng lưu thẻ và vé đã phát hành, nó sẽ xuất hiện trong ứng dụng Google Wallet cùng với mọi thẻ và vé khác mà họ đã lưu.

Tạo các đối tượng truyền và lớp truyền trong JWT

Bạn có thể tạo trước các lớp và đối tượng thẻ và vé bằng API REST của Google Wallet hoặc SDK Android. Sau khi được tạo, chúng sẽ được dùng để cấp thẻ và vé bằng cách tham chiếu mã nhận dạng của chúng.

Ngoài ra, bạn cũng có thể tạo các Lớp thẻ và vé và Truyền đối tượng "đúng lúc" bằng cách nhúng trực tiếp JSON của các lớp đó vào JWT dùng để cấp thẻ và vé cho người dùng. Trong phương thức này, các lớp Thẻ và đối tượng của Thẻ và vé được tạo bởi API Google Wallet khi JWT đã ký được gửi bằng nút hoặc đường liên kết "Thêm vào Google Wallet".

Ví dụ: sau đây là một JWT có một Lớp và Đối tượng thẻ và vé mới được xác định bằng các thuộc tính payload.eventTicketClassespayload.eventTicketObjects. Lưu ý rằng các thuộc tính này là các mảng nên chúng có thể chấp nhận một hoặc nhiều Lớp truyền hoặc các đối tượng Truyền. Bạn cũng có thể chỉ định một Đối tượng thẻ và vé mới trong JWT tham chiếu đến một Lớp thẻ và vé hiện có theo mã nhận dạng của đối tượng đó.

Hiển thị JWT ví dụ

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