Opaque (i.e., encrypted) payment card sent via client-side push provisioning. It is deliberately named to be similar to the Opaque Payment Card that is already passed through client-side push provisioning to Token Service Providers for the purpose of tokenization.
is encrypted and signed in accordance with the OpenPGP specification defined in RFC 4880, and then a non-URL-safe Base64 encoding is applied to the encrypted bytes, in accordance with RFC 4648, section 4, with the encoded output being represented as a byte array.
Below is sample Java server code for generating a Google OPC, starting from a
String
that contains the underlying JSON representation. Here, the java.util.Base64 class is used to accomplish the Base64 encoding.
String googleOpcJson =
"{"
+ " \"protocolHeader\": {"
+ " \"version\": 1"
+ " },"
+ " \"validationContext\": {"
+ " \"serverSessionId\": \"GoogleSession123\""
+ " },"
+ " \"paymentCard\": {"
+ " \"accountNumber\": \"4321123412341234\","
+ " \"expiryMonth\": \"12\","
+ " \"expiryYear\": \"29\""
+ " }"
+ "}";
byte[] googleOpcSignedAndEncryptedBytes =
openPgpSignAndEncrypt(
googleOpcJson, issuerPrivateSigningKey,
googlePublicEncryptionKey);
// This Base64 encoded byte array is the final representation of the
// Google OPC that should be
// returned to the Android or Web client.
byte[] googleOpcBase64Bytes =
Base64.getEncoder()
.encode(googleOpcSignedAndEncryptedBytes);
REQUIRED: The version of the JSON API spec used to construct this Google Opaque Payment Card object. The current version will be provided by Google and will change at Google's discretion, but generally only for major (i.e., breaking) changes.
ValidationContext
Fields that allow Google to validate the push is valid in the given context, for example the expected destination. This information will be compared to other unsigned information for consistency.
JSON representation
{// Union field intended_destination can be only one of the following:"serverSessionId": string// End of list of possible types for union field intended_destination.}
Fields
Union field intended_destination. REQUIRED: The intended "destination" of the push, for validation purposes. Only one destination should be supplied. intended_destination can be only one of the following:
serverSessionId
string
A push provisioning session ID in the form of a UUID generated by a Google server. The destination user is implied by the session.
PaymentCard
Description of a payment card account (i.e., credit card, debit card, charge card).
REQUIRED: The account number itself (i.e., the FPAN).
expiryMonth
string
REQUIRED: Expiration month, formatted MM.
expiryYear
string
REQUIRED: Expiration year, formatted YY.
All rights reserved. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-03-05 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-03-05 UTC."],[[["\u003cp\u003eGoogleOpaquePaymentCard is an encrypted and signed representation of payment card details for client-side push provisioning.\u003c/p\u003e\n"],["\u003cp\u003eThe card details are encrypted using PGP and may be web-safe base64 encoded.\u003c/p\u003e\n"],["\u003cp\u003eThe structure includes protocol header, validation context (e.g., server session ID), and payment card information (account number, expiry).\u003c/p\u003e\n"],["\u003cp\u003eThe JSON representation of the card details before encryption contains fields for version, server session ID, account number, expiry month, and expiry year.\u003c/p\u003e\n"],["\u003cp\u003eGoogle uses the provided validation context to ensure the push provisioning is legitimate and intended for the correct destination.\u003c/p\u003e\n"]]],["The provided content outlines the structure and process for creating a Google Opaque Payment Card (OPC). Key actions include: defining the OPC's structure with `protocolHeader`, `validationContext`, and `paymentCard` fields, encrypting and signing the underlying JSON representation using OpenPGP, and applying Base64 encoding on the server side to ensure security. The `protocolHeader` contains the version, the `validationContext` ensures push validity, and `paymentCard` contains the card details like account number, expiry month, and expiry year. The Java example shows an OPC generation.\n"],null,["- [JSON representation](#SCHEMA_REPRESENTATION)\n- [ProtocolHeader](#ProtocolHeader)\n - [JSON representation](#ProtocolHeader.SCHEMA_REPRESENTATION)\n- [ValidationContext](#ValidationContext)\n - [JSON representation](#ValidationContext.SCHEMA_REPRESENTATION)\n- [PaymentCard](#PaymentCard)\n - [JSON representation](#PaymentCard.SCHEMA_REPRESENTATION)\n\nOpaque (i.e., encrypted) payment card sent via client-side push provisioning. It is deliberately named to be similar to the Opaque Payment Card that is already passed through client-side push provisioning to Token Service Providers for the purpose of tokenization.\n\nHere's an example of a clear text JSON request: \n\n\n {\n \"protocolHeader\": {\n \"version\": 1\n },\n \"validationContext\": {\n \"serverSessionId\": \"GoogleSession123\"\n },\n \"paymentCard\": {\n \"accountNumber\": \"4321123412341234\",\n \"expiryMonth\": \"12\",\n \"expiryYear\": \"29\"\n }\n }\n\n\u003cbr /\u003e\n\n| **Important:** The signing and encryption of the Google OPC must be done **on your server** to avoid exposing your PGP keys. We also strongly recommend applying the Base64 encoding on your server, so that the encoding logic can be shared between your Android and Web integrations.\n\nThe underlying JSON representation of the\n\n`GoogleOpaquePaymentCard`\n\nis encrypted and signed in accordance with the OpenPGP specification defined in [RFC 4880](https://datatracker.ietf.org/doc/html/rfc4880), and then a non-URL-safe Base64 encoding is applied to the encrypted bytes, in accordance with [RFC 4648, section 4](https://datatracker.ietf.org/doc/html/rfc4648#section-4), with the encoded output being represented as a byte array.\n\nBelow is sample Java server code for generating a Google OPC, starting from a\n\n`String`\n\nthat contains the underlying JSON representation. Here, the [java.util.Base64](https://docs.oracle.com/javase/9/docs/api/java/util/Base64.html) class is used to accomplish the Base64 encoding.\n\n\u003cbr /\u003e\n\n\n String googleOpcJson =\n \"{\"\n + \" \\\"protocolHeader\\\": {\"\n + \" \\\"version\\\": 1\"\n + \" },\"\n + \" \\\"validationContext\\\": {\"\n + \" \\\"serverSessionId\\\": \\\"GoogleSession123\\\"\"\n + \" },\"\n + \" \\\"paymentCard\\\": {\"\n + \" \\\"accountNumber\\\": \\\"4321123412341234\\\",\"\n + \" \\\"expiryMonth\\\": \\\"12\\\",\"\n + \" \\\"expiryYear\\\": \\\"29\\\"\"\n + \" }\"\n + \"}\";\n byte[] googleOpcSignedAndEncryptedBytes =\n openPgpSignAndEncrypt(\n googleOpcJson, issuerPrivateSigningKey,\n googlePublicEncryptionKey);\n // This Base64 encoded byte array is the final representation of the\n // Google OPC that should be\n // returned to the Android or Web client.\n byte[] googleOpcBase64Bytes =\n Base64.https://docs.oracle.com/javase/9/docs/api/java/util/Base64.html#getEncoder--()\n .https://docs.oracle.com/javase/9/docs/api/java/util/Base64.Encoder.html#encode-byte:A-(googleOpcSignedAndEncryptedBytes);\n\n| JSON representation |\n|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| ``` { \"protocolHeader\": { object (/pay/client-side-push-provisioning-v1/google-client-side-push-provisioning-api/GoogleOpaquePaymentCard#ProtocolHeader) }, \"validationContext\": { object (/pay/client-side-push-provisioning-v1/google-client-side-push-provisioning-api/GoogleOpaquePaymentCard#ValidationContext) }, \"paymentCard\": { object (/pay/client-side-push-provisioning-v1/google-client-side-push-provisioning-api/GoogleOpaquePaymentCard#PaymentCard) } } ``` |\n\n| Fields ||\n|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `protocolHeader` | `object (`[ProtocolHeader](/pay/client-side-push-provisioning-v1/google-client-side-push-provisioning-api/GoogleOpaquePaymentCard#ProtocolHeader)`)` **REQUIRED**: A header for this message. |\n| `validationContext` | `object (`[ValidationContext](/pay/client-side-push-provisioning-v1/google-client-side-push-provisioning-api/GoogleOpaquePaymentCard#ValidationContext)`)` **REQUIRED**: Context for the push that can be verified. |\n| `paymentCard` | `object (`[PaymentCard](/pay/client-side-push-provisioning-v1/google-client-side-push-provisioning-api/GoogleOpaquePaymentCard#PaymentCard)`)` **REQUIRED**: Payment card details. |\n\nProtocolHeader Header object that includes protocol layer fields.\n\n| JSON representation |\n|-------------------------------|\n| ``` { \"version\": string } ``` |\n\n| Fields ||\n|-----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `version` | `string (`[Int64Value](https://developers.google.com/discovery/v1/type-format)` format)` **REQUIRED**: The version of the JSON API spec used to construct this Google Opaque Payment Card object. The current version will be provided by Google and will change at Google's discretion, but generally only for major (i.e., breaking) changes. |\n\nValidationContext Fields that allow Google to validate the push is valid in the given context, for example the expected destination. This information will be compared to other unsigned information for consistency.\n\n| JSON representation |\n|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| ``` { // Union field `intended_destination` can be only one of the following: \"serverSessionId\": string // End of list of possible types for union field `intended_destination`. } ``` |\n\n| Fields ||\n|-------------------|---------------------------------------------------------------------------------------------------------------------------------------------|\n| Union field `intended_destination`. **REQUIRED** : The intended \"destination\" of the push, for validation purposes. Only one destination should be supplied. `intended_destination` can be only one of the following: ||\n| `serverSessionId` | `string` A push provisioning session ID in the form of a UUID generated by a Google server. The destination user is implied by the session. |\n\nPaymentCard Description of a payment card account (i.e., credit card, debit card, charge card).\n\n| JSON representation |\n|----------------------------------------------------------------------------------|\n| ``` { \"accountNumber\": string, \"expiryMonth\": string, \"expiryYear\": string } ``` |\n\n| Fields ||\n|-----------------|--------------------------------------------------------------------|\n| `accountNumber` | `string` **REQUIRED**: The account number itself (i.e., the FPAN). |\n| `expiryMonth` | `string` **REQUIRED** : Expiration month, formatted `MM`. |\n| `expiryYear` | `string` **REQUIRED** : Expiration year, formatted `YY`. |"]]