Order with Google projects allow for sandbox and production payments. As you test your Order with Google project in the Quick Test or Sandbox environments, use Sandbox as your Payment Mode. While you test your data feed, you can switch between sandbox and production payments. When you enable the sandbox payment mode, the customer's provided payment method can't be charged for any completed transactions.
Configuration
To test your payment configuration so that actual charges aren't applied, you need to enable sandbox payments. To do so, follow these steps:
- On the Partner Portal, navigate to Configuration > Features.
- On the Account features card, find the Payment Mode radio button.
- Select the Sandbox option and click Save changes.
When the Sandbox payment mode is selected, Order with Google will configure the Google Pay API to use the test environment. Your PSP will not charge any payments when using the Sandbox payment mode. Additionally, the isInSandbox
field will be in set to true
in the CheckoutRequestMessage and SubmitOrderRequestMessage.
Checkout Response Message
The CheckoutResponseMessage
sent by your Food Ordering web service contains
PaymentOptions
. When you
set up your checkout,
you provide a placeholder payment options using an example payment gateway.
- Be sure to update the
CheckoutResponseMessage
sent by your web service with the appropriate tokenization configuration.
Payment option examples
The following are example JSON PaymentOptions
objects from a
CheckoutResponseMessage
for various payment gateways using sandbox keys:
JSON
"paymentOptions": { "googleProvidedOptions": { "facilitationSpecification": "{\"apiVersion\":2,\"apiVersionMinor\":0,\"merchantInfo\":{\"merchantName\":\"merchantName\"},\"allowedPaymentMethods\":[{\"type\":\"CARD\",\"parameters\":{\"allowedAuthMethods\":[\"PAN_ONLY\"],\"allowedCardNetworks\":[\"VISA\",\"MASTERCARD\"],\"billingAddressRequired\":true,\"cvcRequired\":true},\"tokenizationSpecification\":{\"type\":\"PAYMENT_GATEWAY\",\"parameters\":{\"gatewayMerchantId\":\"YOUR_MERCHANT_ID\",\"gateway\":\"cybersource\"}}}],\"transactionInfo\":{\"currencyCode\":\"USD\",\"totalPriceStatus\":\"ESTIMATED\",\"totalPrice\":\"31.85\"}} " } }
JSON
"paymentOptions": { "googleProvidedOptions": { "facilitationSpecification": "{\"apiVersion\":2,\"apiVersionMinor\":0,\"merchantInfo\":{\"merchantName\":\"merchantName\"},\"allowedPaymentMethods\":[{\"type\":\"CARD\",\"parameters\":{\"allowedAuthMethods\":[\"PAN_ONLY\"],\"allowedCardNetworks\":[\"VISA\",\"MASTERCARD\"],\"billingAddressRequired\":true,\"cvcRequired\":true},\"tokenizationSpecification\":{\"type\":\"PAYMENT_GATEWAY\",\"parameters\":{\"gateway\":\"braintree\",\"braintree:apiVersion\":\"v1\",\"braintree:sdkVersion\":\"1.4.0\",\"braintree:merchantId\":\"YOUR_MERCHANT_ID\",\"braintree:clientKey\":\"YOUR_BRAINTREE_SANDVOX_OR_PRODUCTION_KEY\"}}}],\"transactionInfo\":{\"currencyCode\":\"USD\",\"totalPriceStatus\":\"ESTIMATED\",\"totalPrice\":\"31.85\"}} " } }
JSON
"paymentOptions": { "googleProvidedOptions": { "facilitationSpecification": "{\"apiVersion\":2,\"apiVersionMinor\":0,\"merchantInfo\":{\"merchantName\":\"merchantName\"},\"allowedPaymentMethods\":[{\"type\":\"CARD\",\"parameters\":{\"allowedAuthMethods\":[\"PAN_ONLY\"],\"allowedCardNetworks\":[\"VISA\",\"MASTERCARD\"],\"billingAddressRequired\":true,\"cvcRequired\":true},\"tokenizationSpecification\":{\"type\":\"PAYMENT_GATEWAY\",\"parameters\":{\"gateway\":\"stripe\",\"stripe:version\":\"2018-10-31\",\"stripe:publishableKey\":\"YOUR_PRODUCTION_OR_SANDBOX_STRIPE_KEY\"}}}],\"transactionInfo\":{\"currencyCode\":\"USD\",\"totalPriceStatus\":\"ESTIMATED\",\"totalPrice\":\"31.85\"}} " } }
Flag sandbox transactions
When the transaction sandbox setting is enabled, the isInSandbox
field is set
to true
for incoming requests to your web service endpoint
(CheckoutRequestMessage
and SubmitOrderRequestMessage
).
Do the following when the isInSandbox
field is set to true
:
- Use sandbox keys instead of production keys in the tokenization configuration for your payment gateway. Most payment processors provide API keys for both sandbox and production.
- Don't trigger any communication with the web service provider, usually a restaurant, as they don't have to be informed of any sandbox transactions.
Test credit cards aren't supported, even when the transaction sandbox is enabled. You must use a real credit card when you make a transaction. However, when a sandbox token is used, your payment processor doesn't process the transaction.
Process payments
When a customer submits their order, Order with Google sends the SubmitOrderRequestMessage to your
web service endpoint. The Google Pay token is included as a base-64 encoded string in the SubmitOrderRequestMessage
instrumentToken field. To process the customer's payment, do one of the following depending on your payment gateway:
Payment gateway | |
---|---|
Stripe or Braintree | Decode the base-64 encoded token string and send the appropriate data contained in the decoded token payload to your payment gateway to process the payment. |
All other PSPs | Send the complete base-64 encoded token string to your payment gateway api to process the payment. The Google Pay payment method token structure contains encrypted fields that your payment gateway can decrypt to process the payment. |
Decoded payload example
The following examples show decoded payloads returned in the instrumentToken
field for various payment gateways:
JSON
This JSON example represents a decoded payment token when using
Braintree. Extract the value of the nonce
field
and send the value to Braintree to process the payment.
{ "androidPayCards": [{ "type": "AndroidPayCard", "nonce": "aeeb8297-4242...", "description": "AndroidPay", "consumed": false, "details": { "cardType": "Visa", "lastTwo": "29" } }] }
If Google Pay is not enabled in the Braintree control panel, the
instrumentToken
field decodes to the following error:
{ "error": { "message": "Record not found" }, "fieldErrors": [] }
JSON
This JSON example represents a decoded payment token when using Stripe.
Extract the value of the id
field and send it to Stripe to
process the payment.
{ "id": "tok_abcdefg1234...", "object": "token", "card": { "id": "card_abcde...", "object": "card", "address_city": null, "address_country": null, "address_line1": null, "address_line1_check": null, "address_line2": null, "address_state": null, "address_zip": null, "address_zip_check": null, "brand": "Visa", "country": "US", "cvc_check": null, "dynamic_last4": "1234", "exp_month": 1, "exp_year": 2019, "funding": "credit", "last4": "1234", "metadata": {}, "name": null, "tokenization_method": "android_pay" }, "client_ip": "74.125.177.36", "created": 1500483670, "livemode": false, "type": "card", "used": false }
JSON
This JSON example represents a decoded payment token when using Square.
{ "signature": "MEYCIQCMAsWCrY2GfHM/gMAKiK3QCKJJOIkjZeTQGzcdWgvrhwIhAJ3mXwe+wmU9z+Apv1rTDsCVQBzayvWzT4ywxytrSPla", "protocolVersion": "ECv1", "signedMessage": "{\"encryptedMessage\":\"WkYz21EYxojwTqWh6A3oYXtmctu1PlqF+tNYPA4cq017nqj16Ge7kaVR7MI1XG1OrCmcMwP20u5Zb5E28XYan8UI8M4L120orvE9XU1ivZuO4Myq2O3ue8v0lY1MDx8Mnk+5mkAv1kLmzJc91gEQ2leIwrPuMDYqsQUHzTR3Jikh5/v+iWRkyQPKKxgj5c6Erdu/pkg1xV6fQJcHNdq9Jw11zl95x6eQurxw2Uy8v811azGr+noKJbw0uye72MkhmzMS5QKOzwGT9nBfO+zPLYSEewsdOcPbNZF94zk/KU9nxom/gQ+eYEMIZvOj9lO4gQqDqR6DyWyStk7MjeXQTvXWZBI1JpqvOrlTHL0Ct18RpbfOio7hAtafzb0NnqEKlsun+SSpJmvI7U6n6Cnu1JUMUGfT/Jsi6RJ3N6pRw2BubeR1925Xl3jXQnlz5io6X1YRlAcnshZyf6CjBpKES32aTf1m1IHRhZ2Jj6i/g7Y\\u003d\",\"ephemeralPublicKey\":\"BDQA0Cf//BHPcnB0R/GRrWa2g7T1QF97eOhAYy7l45M+kJnsoeL9OaUQV/KIMLvcgbmKkZIm2FQeL7ftd6S4q4c\\u003d\",\"tag\":\"DHtVyXNo+PDr7Thi/EjBBbsr2k7y1SwGIn0D9mmPTJc\\u003d\"}" }
To process the payment using the token, return the base-64 encoded token string with your request to Square's payment api in the source_id
field prefixed by gpay:
{ "idempotency_key": "ID", "source_id": "gpay:GOOGLE_PAY_BASE64_ENCODED_TOKEN", "amount_money": { "amount": 50, "currency": "USD" }, "location_id": "LOCATION_ID", "billing_address": { "postal_code": "11111" } }
The following is a Node.js example that decodes the base-64 encoded
instrumentToken
from Braintree:
Node.js
function decodeToken(instrumentToken) { let decodedString = new Buffer(instrumentToken, 'base64').toString('ascii') if (decodedString.androidPayCards) { return decodedString.androidPayCards[0].nonce; } }