Google Pay

Google Pay is a digital wallet platform and online payment system that powers in-app, tap-to-pay, and website purchases. It enables users to make payments online from the Web and with Android phones, tablets and watches. Because Google Pay represents a significantly different workflow than that used with traditional payment methods, it’s important to first understand how it works before integrating with Spreedly.

Google Pay preparation

Implementing Google Pay with Spreedly

🚧

You must complete the Google Pay Preparation section and have Google Pay production credentials before proceeding with Spreedly.

Using Spreedly and Google Pay versus the Google Play billing system

For sales of physical goods and services, your app can accept Google Pay. Those payments are then processed through your gateway partner. However, in-app purchases of digital products and content must use the Google Play billing system. Those payments are processed by Google and are subject to their transaction fees.

For more information about which purchases must use the Google Play billing system, see Google Play’s developer terms.

Supported gateways

Currently, you can use Spreedly’s Google Pay support with the following gateways:

If you’d like to use Google Pay against a gateway that’s not listed here, drop us a line.

How Google Pay works with Spreedly

When a customer adds a credit or debit card to their Google Pay app, Google Pay requests a token, from the bank that issued that card, to represent the card being added. Once the token is issued, this card is now “tokenized,” meaning it has a unique identification number associated with it. Google Pay encrypts the newly tokenized card and it is ready to be used for payments. At the time of sale, Google Pay sends the customer’s tokenized card and a cryptogram, which acts as a one-time-use password used in the encryption process, to the merchant app along with basic transaction information. The next step, typically handled by the merchant app when using a traditional workflow without Spreedly, is to decrypt the payload from Google and send the payment token and related transaction information to a supporting processor. The token is sent to one of the few gateways that natively support Google Pay.

The overall transaction flow is very similar to the traditional Google Pay process. The only difference is that Spreedly receives the encrypted Google Pay payload from the merchant app and is responsible for decrypting the payment token and relaying the transaction information to a chosen gateway or receiver.

For the authentication method of the card transaction, authMethod in paymentMethodDetails, Spreedly supports both PAN_ONLY and CRYPTOGRAM_3DS (PayPal is not supported). PAN_ONLY gives support for payment methods that Google Pay deems are non-tokenized cards. CRYPTOGRAM_3DS gives support for payment methods that Google Pay deems are tokenized cards. Additional information regarding the google pay type is included in the Transactions section below.

When requesting the encrypted payload from Google, the merchant app needs to include the following values for the gateway and gatewayMerchantId fields:

{
  "type": "CARD",
  "parameters": {
    "allowedAuthMethods": [
      "PAN_ONLY",
      "CRYPTOGRAM_3DS"
    ],
    "allowedCardNetworks": [
      "AMEX",
      "DISCOVER",
      "JCB",
      "MASTERCARD",
      "VISA"
    ]
  },
  "tokenizationSpecification": {
    "type": "PAYMENT_GATEWAY",
    "parameters": {
      "gateway": "spreedly",
      "gatewayMerchantId": "SPREEDLY_ENVIRONMENT_KEY"
    }
  }
}
<allowedPaymentMethods>
  <type>CARD</type>
  <parameters>
    <allowedAuthMethods>
      <allowedAuthMethod>PAN_ONLY</allowedAuthMethod>
      <allowedAuthMethod>CRYPTOGRAM_3DS</allowedAuthMethod>
    </allowedAuthMethods>
    <allowedCardNetworks>
      <allowedCardNetwork>AMEX</allowedCardNetwork>
      <allowedCardNetwork>DISCOVER</allowedCardNetwork>
      <allowedCardNetwork>JCB</allowedCardNetwork>
      <allowedCardNetwork>MASTERCARD</allowedCardNetwork>
      <allowedCardNetwork>VISA</allowedCardNetwork>
    </allowedCardNetworks>
  </parameters>
  <tokenizationSpecification>
    <type>PAYMENT_GATEWAY</type>
    <parameters>
      <gateway>spreedly</gateway>
      <gatewayMerchantId>SPREEDLY_ENVIRONMENT_KEY</gatewayMerchantId>
    </parameters>
  </tokenizationSpecification>
</allowedPaymentMethods>

Google Pay on Android Devices

Google Pay on the Web

Implementing Google Pay on the Web is completely independent of using Spreedly iFrame. Spreedly iFrame does not interact with Google Pay on the Web nor does it need to. Google returns the payment data to you in an encrypted form, and then you pass the encrypted data to Spreedly.

Testing guidelines

Google Test Card Suite

Google provides a test card suite that allows developers to run tests without having to add a real card to their Google account. Access to the test suite requires email registration. Follow the guidelines in Google's developer docs to add your email to the Google group. Configure your payment sheet to Google's TEST environment and you will see a list of test cards that you can use to generate a test payload. Make sure you have used your Spreedly environment key for gatewayMerchantId (refer to the code snippet above for recommended Google Pay configuration). Use the generated payment token to initiate a test transaction at Spreedly. Do not pass test_card_number in the Spreedly call when using a test payload.

Real card with test_card_number

As part of progressive testing, you can verify real payload decryption in your Spreedly environment. Add a real card to your Google account. Configure your payment sheet to Google's PROD environment. Select the real card during checkout and generate a sample payment token. Use the token to initiate a test transaction at Spreedly. Make sure to pass test_card_number to override the real payload. Spreedly will successfully decrypt the payload, add a Google Pay payment method to your vault, and use the override value for the test transaction. This ensures real payment data is not sent to any test or sandbox gateways.

Real card micro transaction

Add a real card to your Google account. Configure your payment sheet to Google's PROD environment. Run a low value checkout (ex: $1.00) using the real card. Use the generated payment token to initiate a real transaction on a Spreedly production gateway. This provides high confidence that the integration is ready for business traffic.

Transactions

When a Google Pay transaction is initiated, a Payment Token (paymentMethodData.tokenizationData.token) containing a JSON-formatted string is sent to the merchant app. This paymentMethodData.tokenizationData.token is what Spreedly needs to process the transaction and looks something like this

{
  "signature": "MEYCIQDTe92wpG6OUgxJ/8Qnr36XzSgjGGCM7R3LwxjgwPYMTAIhAJDrjHG9wEm1BxVM6MMMB+jGTGpi3VScEMVbHIUsObFi",
  "protocolVersion": "ECv1",
  "signedMessage": "{\"encryptedMessage\":\"FY8w/U3IbdsZQovX8ufNGFDOePgc/genRiMjHyvuIBqLY4a6uPz7wI0ra31K6YbFJlAnCjFhTwSvDxAYXw6hlmI8sESO5eM1eZlzfP3+NoKV80OXKvOM/xI/qOQEqpEQEVXx6Bw2EpMMFW8yBaA8XPUNee3EJlUk+/f8lRdRcNmI65QKPLAzUnySo75HzBkSc5It/8/oXdYwR93/K6HRKGZuD+bIaxy3SUvC9ehQqhBoP+A34yQX1knfJ1qjBMhhVVcPZHi+Bg6LXA4ms/lfDdim6D1Epr6XQhc2h4RZ/dT+6Enn81s/8ym+jMMs8kqsW9ib8vkdTARv9AbUu7zeGPrKTCAxwc1n6joRR72dSnNCI9j9sxd9tkuC9wuRyDmjbWT+hRZgLc1v/xzzNImo3NxdKdaPzKBE3t9XQZY5fp3lZELaoXAuxAZYtZ7bX64Mz9c28wD8EM+krvfbmGMiBjIt8EfeH48/SjeaUKfDu+yQnjPJAKbDZPhKJ1jqlY/ChP0Om7spQacT86QUVK/DwfzukwvwwRJkWydNEac5fgfS2T6ToZ+PW4VHbxkDnY/h+B0uwdlNQIL2a3Ar5Q\\u003d\\u003d\",\"ephemeralPublicKey\":\"BGkK4bSvob+e7ZgaNV/4vSJYYa10OJzd3aUk9yPEP6iNBRcfHiD/NTvhKjN4P24l0tEzH3L8TrySl6AczPJpCkw\\u003d\",\"tag\":\"xGEhEfJESIyBSfq2fExWiZxNWelnm3m4i8P7cgsarqg\\u003d\"}"
}

Transacting with a Google Pay payment method is very similar to using a credit card. Depending on your gateway’s support, you can initiate an authorize or purchase, passing in the Google Pay paymentMethodData.tokenizationData.token string. You can also add a Google Pay payment method as a separate call from the actual transaction.

Purchase example:

curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.xml \
-u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
-H 'Content-Type: application/xml' \
-d '<transaction>
      <amount>1122</amount>
      <currency_code>USD</currency_code>
      <google_pay>
        <payment_data><![CDATA[{"signature":"MEUCIA6SGVRwhOyeYRkeDUUNwB/kGtyfQAlOsg7NZydT17u/AiEA48BhWGQEF1EbEU0J+m8eSK3rTfhok9QqpiFVbME+Ky0\u003d","protocolVersion":"ECv1","signedMessage":"{\"encryptedMessage\":\"3v4IcT/eovIDP2WF8iRUy4qWQnE9Cx0vQxIZ5f9i3Emv3Tzs1AzvB7cxXhxrjp9FVIzdOwsZAPAsm03gvoYq8Xdr70XvrVRd2MFwQhMC7IV/uEsthw4JsR8oCkbI5v/zqhu2B+JodFgavNliHcpKBgijy2D6bpx7jXEkM39M/L4oBObFxFrhVSLA1GjOV6A5gLAXNXt0ffkCYekihqAyJrWlk3sCBDCF5SUiAKEIOIZtzZLgusxjVp6ufZHOHm/53uhAi6JWSJ1E6G5aaYGtULYdwgURHtxN5OIzQPYlEGctaQd5tgfCsBFfGkYyN1GRNgclbaLzAfk/Jn7/6IVKuV0ol3xubTcnjGTZXwtTjiEyYDoz1yVqB9ViMmJa55L6nBtbbAkcNEgAi7dPnrbvBGEP7QWsNT9D71g8SWrlRTCYUAOyuamaQhofG4ul1IVjmltdAy2BHBWpqgJnR9kczydQyE7uDiqhSC1/0eG8GCGIqoi8XfOioGXfMyLZ1p2ZcNK9ECjzUrH/edrwgtShxgWuWMwQTM4DQlVTAA/R4DVs192YWZcc7jm5wLqZ0+XEaPuighJM1Ps1Egeccg\\u003d\\u003d\",\"ephemeralPublicKey\":\"BA2SvF9BdCX7Tl1wwRkyLzTfqhctobhZgSugC9Cz77XNUCBOBMfFyJQt506PUs89D6IJZZfOkZopy0shRF9Uph4\\u003d\",\"tag\":\"Uhin1BE7KAuuiam7eEQFimRUDd9Xn6tZc2fClTpfrXQ\\u003d\"}"}
]]></payment_data>
        <test_card_number>4111111111111111</test_card_number> <!-- Remove in production -->
      </google_pay>
    </transaction>'

The test_card_number parameter is available when you want to override the alias PAN contained in the payment data so it can be processed as a test transaction. You can use any test card number recognized by Spreedly here.

Please note that Google Pay transactions should not include attempt_3dsecure: true as a parameter. When Google Pay payment methods are tokenized, 3DS has already been performed as part of that flow. For more information on 3DS, please refer to our Spreedly 3DS Solutions guide.

The transaction response will include the google_pay_type field with a value of either TOKENIZED_CARD or NON_TOKENIZED_CARD. This value corresponds with how the payment method was treated during the transaction process, as either a network tokenized card or not, and is based on data received within the paymentMethodData.tokenizationData.token.

<transaction>
  <on_test_gateway type="boolean">true</on_test_gateway>
  <created_at type="dateTime">2018-09-27T11:03:41Z</created_at>
  <updated_at type="dateTime">2018-09-27T11:03:41Z</updated_at>
  <succeeded type="boolean">true</succeeded>
  <state>succeeded</state>
  <token>IKkSx9f72fVQ10H3AzcHFDADvIt</token>
  <transaction_type>Purchase</transaction_type>
  <order_id>AH2EjteGTgCbm_KqL7GsQKBb41AD1wjKBt5e5LfRv8XW6Hs-c1swAd5fXRYyJz8Apl4ypCkOEuLf9YNe0my25BwuwIFo6OSa2pLSD4aXT8TQywlTnCKPBShMId5iF2sT-DbsSNO66dcu</order_id>
  <ip nil="true"/>
  <description nil="true"/>
  <email nil="true"/>
  <merchant_name_descriptor nil="true"/>
  <merchant_location_descriptor nil="true"/>
  <gateway_specific_fields nil="true"/>
  <gateway_specific_response_fields>
  </gateway_specific_response_fields>
  <gateway_transaction_id>55</gateway_transaction_id>
  <gateway_latency_ms type="integer">0</gateway_latency_ms>
  <amount type="integer">1122</amount>
  <currency_code>USD</currency_code>
  <retain_on_success type="boolean">false</retain_on_success>
  <payment_method_added type="boolean">true</payment_method_added>
  <message key="messages.transaction_succeeded">Succeeded!</message>
  <gateway_token>IRMVoS9jurugLBkX8pM7YTmTj9F</gateway_token>
  <gateway_type>test</gateway_type>
  <shipping_address>
    <name></name>
    <address1 nil="true"/>
    <address2 nil="true"/>
    <city nil="true"/>
    <state nil="true"/>
    <zip nil="true"/>
    <country nil="true"/>
    <phone_number nil="true"/>
  </shipping_address>
  <response>
    <success type="boolean">true</success>
    <message>Successful purchase</message>
    <avs_code nil="true"/>
    <avs_message nil="true"/>
    <cvv_code nil="true"/>
    <cvv_message nil="true"/>
    <pending type="boolean">false</pending>
    <result_unknown type="boolean">false</result_unknown>
    <error_code nil="true"/>
    <error_detail nil="true"/>
    <cancelled type="boolean">false</cancelled>
    <fraud_review nil="true"/>
    <created_at type="dateTime">2018-09-27T11:03:41Z</created_at>
    <updated_at type="dateTime">2018-09-27T11:03:41Z</updated_at>
  </response>
  <api_urls>
  </api_urls>
  <payment_method>
    <token>IbI86ToYVmcFngoM9kYWlsG64Lm</token>
    <created_at type="dateTime">2018-09-27T11:03:41Z</created_at>
    <updated_at type="dateTime">2018-09-27T11:03:41Z</updated_at>
    <email nil="true"/>
    <data nil="true"/>
    <storage_state>cached</storage_state>
    <test type="boolean">true</test>
    <last_four_digits>1111</last_four_digits>
    <first_six_digits>411111</first_six_digits>
    <card_type>visa</card_type>
    <first_name nil="true"/>
    <last_name nil="true"/>
    <month type="integer">12</month>
    <year type="integer">2023</year>
    <full_name></full_name>
    <address1 nil="true"/>
    <address2 nil="true"/>
    <city nil="true"/>
    <state nil="true"/>
    <zip nil="true"/>
    <country nil="true"/>
    <phone_number nil="true"/>
    <company nil="true"/>
    <shipping_address1 nil="true"/>
    <shipping_address2 nil="true"/>
    <shipping_city nil="true"/>
    <shipping_state nil="true"/>
    <shipping_zip nil="true"/>
    <shipping_country nil="true"/>
    <shipping_phone_number nil="true"/>
    <payment_method_type>google_pay</payment_method_type>
    <google_pay_type>TOKENIZED_CARD</google_pay_type>
    <errors>
    </errors>
  </payment_method>
</transaction>

Recurring transactions

Recurring payments with Google Pay are unfortunately not supported at this time.