Update to latest version

The Google Pay API introduced new Android client libraries in August 2018. These new libraries support the construction of an IsReadyToPayRequest or PaymentDataRequest from a JSON object that is serialized as a string. This guide explains how to update Android code that uses a Builder object to the equivalent JSON-formatted string that's passed to the fromJson() method of IsReadyToPayRequest and PaymentDataRequest.

Payment methods

In the previous version of the Google Pay API, the Builder object we used only supported cards as a form of payment for IsReadyToPayRequest or PaymentDataRequest. In the latest version of the Google Pay API, the CARD payment method is only one of multiple possible payment methods for IsReadyToPayRequest or PaymentDataRequest.

Constants are no longer used. The Builder object that was used in the previous version referenced integer constants. The new, JSON-formatted string sets equivalent string values in the allowedAuthMethods property array of CardParameters. In order to update your code, identify your case, and follow the instructions below:

  1. If your app supported PAYMENT_METHOD_CARD:
    • Add "PAN_ONLY" to the allowedAuthMethods array.
  2. If your app supported PAYMENT_METHOD_TOKENIZED_CARD:
    • Add "CRYPTOGRAM_3DS" to the allowedAuthMethods array.

Apps were previously assigned a default set of allowed card networks if you didn't specify them. Apps are now required to provide a list of allowed card networks.

Builder

IsReadyToPayRequest.newBuilder()
    .addAllowedPaymentMethod(
        WalletConstants.PAYMENT_METHOD_CARD)
    .addAllowedPaymentMethod(
        WalletConstants.PAYMENT_METHOD_TOKENIZED_CARD);
PaymentDataRequest.newBuilder()
    .addAllowedPaymentMethod(
        WalletConstants.PAYMENT_METHOD_CARD)
    .addAllowedPaymentMethod(
        WalletConstants.PAYMENT_METHOD_TOKENIZED_CARD);

fromJson

{
  "apiVersion": 2,
  "apiVersionMinor": 0,
  "allowedPaymentMethods": [
    {
      "type": "CARD",
      "parameters": {
        "allowedAuthMethods": [
          "PAN_ONLY",
          "CRYPTOGRAM_3DS"
        ],
        "allowedCardNetworks": [
          "AMEX",
          "DISCOVER",
          "MASTERCARD",
          "VISA"
        ]
      }
    }
  ]
}

Card payment data tokenization

The Google Pay API returns encrypted card data that's referenced by your specified gateway or decrypted on your servers. Information previously provided to a PaymentMethodTokenizationParameters builder should be defined in the PaymentMethodTokenizationSpecification of a CARD payment method.

Builder

PaymentMethodTokenizationParameters.newBuilder()
    .setPaymentMethodTokenizationType(
        WalletConstants.PAYMENT_GATEWAY)
    .addParameter(
        "gateway",
        "example")
    .addParameter(
        "gatewayMerchantId",
        "exampleGatewayMerchantId")

fromJson

{
  "allowedPaymentMethods": [{
    "type": "CARD",
    "tokenizationSpecification": {
      "type": "PAYMENT_GATEWAY",
      "parameters": {
        "gateway": "example",
        "gatewayMerchantId": "exampleGatewayMerchantId"
      }
    }
  }]
}

Billing address

You have the option to require a billing address or phone number to associate with a CARD payment method. If you decide to require a billing address or phone number, you must specify the configuration of the required response in the BillingAddressParameters JSON object.

Builder

PaymentDataRequest.newBuilder()
    .setPhoneNumberRequired(true)
    .setCardRequirements(
        CardRequirements.newBuilder()
            .setBillingAddressRequired(true)
            .setBillingAddressFormat(
                WalletConstants.BILLING_ADDRESS_FORMAT_FULL));

fromJson

{
  "allowedPaymentMethods": [{
    "type": "CARD",
    "parameters": {
      "billingAddressRequired": true,
      "billingAddressParameters": {
        "format": "FULL",
        "phoneNumberRequired": true
      }
    }
  }]
}

Shipping address

You have the option to require your user to provide a shipping address, they can use a stored shipping address or enter a new one. The shipping address is a top-level property in the PaymentDataRequest JSON object. The shipping address countries you allow were previously added to a ShippingAddressRequirements builder, and should now be specified in the ShippingAddressParameters JSON object.

Builder

PaymentDataRequest.newBuilder()
    .setPhoneNumberRequired(true)
    .setShippingAddressRequired(true)
    .setShippingAddressRequirements(
        ShippingAddressRequirements.newBuilder()
            .addAllowedCountryCode("US")
            .addAllowedCountryCode("CA"))

fromJson

{
  "shippingAddressRequired": true,
  "shippingAddressParameters": {
    "allowedCountryCodes": [
      "US",
      "CA"
    ],
    "phoneNumberRequired": true
  }
}

PaymentData response

A response is a PaymentDataRequest object that contains a JSON-formatted response that is available to the toJson() class method. In order to receive this response, create a PaymentDataRequest object with the fromJson() class method and pass it to the loadPaymentData method of a PaymentsClient. A PaymentData instance is extracted from an Intent. A JSON-formatted string can be parsed into JSON name-value pairs by JSONObject or other JSON-aware libraries.

Previous Getters

PaymentData paymentData =
    PaymentData.getFromIntent(data);

Current JSON

PaymentData paymentData =
    PaymentData.getFromIntent(data);
String json = paymentData.toJson();
if (json != null) {
  JSONObject paymentDataJson =
      new JSONObject(json);
  JSONObject paymentMethodData =
      paymentDataJson.get("paymentMethodData");
}

Summary text for the selected payment method is available in the description property. See the CardInfo JSON object reference for additional properties that are available when the CARD type is returned.

Previous Getters

paymentData
    .getCardInfo()
    .getCardDescription();

Current JSON

paymentMethodData.get("description");

Information about a selected payment method and its tokenization is placed inside the paymentMethodData property.

Previous Getters

paymentData
    .getPaymentMethodToken()
    .getToken();

Current JSON

paymentMethodData
    .get("tokenizationData")
    .get("token");

Encrypted message response

Apps that specify a DIRECT payment method tokenization type and accept Android device tokens (previously WalletConstants.PAYMENT_METHOD_TOKENIZED_CARD ) must update the way they handle the decrypted encryptedMessage property on their servers. Both PAN_ONLY and CRYPTOGRAM_3DS types of authenticated cards appear as a paymentMethod of CARD, with additional information about the authentication method and fields specific to the authentication method provided in paymentMethodDetails.

As a result, if your server isn't updated, it can't forward Android device tokens to your gateway or processor. This is because it won't be able to distinguish between multiple types of card authentication in the response. Cards are a paymentMethod of CARD with additional information about the selected card's authentication method in paymentMethodDetails.authMethod. The tokens are authenticated with a 3-D Secure cryptogram and optional electronic commerce indicator (ECI).

ECI

{
  "paymentMethod": "TOKENIZED_CARD",
  "paymentMethodDetails": {
    "authMethod": "3DS",
    "dpan": "1111222233334444",
    "expirationMonth": 10,
    "expirationYear": 2020,
    "3dsCryptogram": "AAAAAA...",
    "3dsEciIndicator": "eci indicator"
  }
}

3-D Secure cryptogram

{
  "paymentMethod": "CARD",
  "paymentMethodDetails": {
    "authMethod": "CRYPTOGRAM_3DS",
    "pan": "1111222233334444",
    "expirationMonth": 10,
    "expirationYear": 2020,
    "cryptogram": "AAAAAA...",
    "eciIndicator": "eci indicator"
  }
}