Set up sandbox payments

Food Ordering projects allow the option for sandbox and production payments. While testing your Food Ordering project using the Preview or Sandbox environment, use the transaction sandbox.

While testing your data feed, you can enable or disable the transaction sandbox. When enabled, the transaction sandbox prevents the customer's provided payment method from being charged for any completed transactions.

Configuration

In order to test your payment configuration without incurring actual charges, you need to enable sandbox payments.

To enable sandbox payments, follow these steps:

  1. In the Actions console, navigate to Develop > Data feeds.
  2. On the Test your app with feeds card, click Get started.
  3. Check the Use transaction sandbox option.

Checkout Response Message

The CheckoutResponseMessage sent by your Food Ordering web service contains PaymentOptions. When setting up your checkout, you provided placeholder payment options using an example payment gateway.

  • Update the CheckoutResponseMessage sent by your web service with the appropriate tokenization configuration.

Payment option examples

Below 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\"}} "
    }
}
    

Flagging 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).

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.
  • Do not trigger any communication with the web service provider (usually a restaurant), as they should not be informed of any sandbox transactions.

Processing payment

When a customer submits their order, the SubmitOrderRequestMessage to your web service endpoint includes a base-64 encoded token string in the instrumentToken field of GoogleProvidedPaymentInstrument.

To process the customer's payment, do the following:

  1. Decode the base-64 encoded token string.
  2. Send the appropriate data contained in the decoded token payload to your payment gateway to process the payment.

Decoded payload example

Below are examples of decoded payloads of the token 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
}
    

Below 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;
  }
}