Build physical transactions with merchant-managed payments (Dialogflow)

This guide will walk you through the process of developing an Actions project that incorporates transactions for physical goods using payment methods managed by your site.

Transaction flow

When your Actions project handles physical transactions using merchant-managed payments, it uses the following flow:

  1. Gather information (optional)- Depending on the nature of your transaction, you may want to gather the following information from the user at the start of the conversation:
    1. Validate transaction requirements- Use the transactions requirements helper at the start of the conversation to make sure the user's payment information is properly configured and available before the user builds their cart.
    2. Request a delivery address- If your transaction requires a delivery address, request fulfillment of the delivery address helper intent to gather one from the user.
  2. Build the order- Walk the user through a "cart assembly" where they pick which items they want to purchase.
  3. Perform Account Linking- In order for the user to use a payment method they've saved with your service, use Account Linking to associate their Google account with their account on your service.
  4. Propose the order- Once the cart is complete, propose the order to the user so they can confirm it's correct. If the order is confirmed, you'll receive a response with order details and a payment token.
  5. Finalize the order and send a receipt- With the order confirmed, update your inventory tracking or other fulfillment services then send a receipt to the user.
  6. Send order updates- Over the course of the order fulfillment's lifespan, give the user order updates by sending PATCH requests to the Orders API.

Restrictions and review guidelines

Keep in mind that additional policies apply to Actions with transactions. It can take us up to six weeks to review Actions with transactions, so factor that time in when planning your release schedule. To ease the review process, make sure you comply with the policies and guidelines for transactions before submitting your Action for review.

You can only deploy Actions that sell physical goods in the following countries:

Australia
Brazil
Canada
Indonesia
Japan
Mexico
Qatar
Russia
Singapore
Switzerland
Thailand
Turkey
United Kingdom
United States

Build your project

For extensive examples of transactional conversations, view our transactions samples in Node.js and Java .

Project setup

When creating your Action, you must specify that you want to perform transactions in the Actions console . Also, if you're using the Node.JS client library, set up your fulfillment to use the latest version of the Orders API.

To set up your project and fulfillment, do the following:

  1. Create a new project or import an existing project.
  2. Navigate to Deploy > Directory information.
  3. Under Additional information > Transactions> check the box that says "Do your Actions use the Transactions API to perform transactions of physical goods?".

  4. If you're using the Node.JS client library to build your Action's fulfillment, open your fulfillment code and update your app delcaration to set the ordersv3 flag to true . The following code snippet shows an example app declaration for Orders version 3.

Node.js

 const 
  
 { 
 dialogflow 
 } 
  
 = 
  
 require 
 ( 
 'actions-on-google' 
 ); 
 let 
  
 app 
  
 = 
  
 dialogflow 
 ({ 
  
 clientId 
 , 
  
 // If using account linking 
  
 debug 
 : 
  
 true 
 , 
  
 ordersv3 
 : 
  
 true 
 , 
 }); 
  

Node.js

 const 
  
 { 
 actionssdk 
 } 
  
 = 
  
 require 
 ( 
 'actions-on-google' 
 ); 
 let 
  
 app 
  
 = 
  
 actionssdk 
 ({ 
  
 clientId 
 , 
  
 // If using account linking 
  
 debug 
 : 
  
 true 
 , 
  
 ordersv3 
 : 
  
 true 
 , 
 }); 
  

When using your own payment method to charge the user, we recommend linking their Google account with an account they have with your own service to retrieve, present, and charge payment methods stored there.

We provide OAuth 2.0 account linking to satisfy this requirement. We highly recommend enabling the OAuth 2.0 Assertion flow as it enables a very streamlined user experience.

We provide the actions.intent.SIGN_IN intent which allows you to request that a user link accounts mid-conversation. You must enable account linking in the Actions Console to use the actions.intent.SIGN_IN intent.

You should use this intent if you are unable to find an accessToken in the User object in the webhook request. This means that the user has not yet linked their account.

After requesting the actions.intent.SIGN_IN intent, you will receive an Argument containing a SignInStatus with a value of either "OK" , "CANCELLED" , or "ERROR" . If the status is "OK" you should be able to find an accessToken in the User object.

Fulfillment

1. Gather information (optional)

1a. Validate transaction requirements (optional)

User experience

Trigger the actions.intent.TRANSACTION_REQUIREMENTS_CHECK intent to quickly check whether or not users will be able to perform a transaction. This step will ensure users can proceed and give them an opportunity to fix any settings preventing them from fulfilling a transaction.

For example, when invoked, your Action might ask, "would you like to order shoes, or check your account balance?" If the user says "order shoes", you should request this intent right away, which will ensure they can proceed and give them an opportunity to fix any settings preventing them from continuing with the transaction.

Requesting the transactions requirements check intent will result in one of the following outcomes:

  • If the requirements are met, the intent will be sent back to your fulfillment with a success condition and you can proceed with building the user's order.
  • If one or more of the requirements cannot be met, the intent will be sent back to your fulfillment with a failure condition. In this case, you should pivot the conversation away from the transactional experience, or end the conversation.
    • If any errors resulting in the failure state can be fixed by the user, they will be prompted to resolve those issues on their device. If the conversation is taking place on an voice-only surface, a handoff will be initiated to the user's phone.
Fulfillment

To ensure that a user meets transaction requirements, request fulfillment of the actions.intent.TRANSACTION_REQUIREMENTS_CHECK intent with a TransactionRequirementsCheckSpec object.

Check requirements

You can check to see if a user satisfies transactions requirements by using the client library:

Node.js

 conv 
 . 
 ask 
 ( 
 new 
  
 TransactionRequirements 
 ()); 
  

Node.js

 conv 
 . 
 ask 
 ( 
 new 
  
 TransactionRequirements 
 ()); 
  

Java

 return 
  
 getResponseBuilder 
 ( 
 request 
 ) 
  
 . 
 add 
 ( 
 new 
  
 TransactionRequirements 
 ()) 
  
 . 
 build 
 (); 
  

Java

 return 
  
 getResponseBuilder 
 ( 
 request 
 ) 
  
 . 
 add 
 ( 
 new 
  
 TransactionRequirements 
 ()) 
  
 . 
 build 
 (); 
  

JSON

 { 
  
 "payload" 
 : 
  
 { 
  
 "google" 
 : 
  
 { 
  
 "expectUserResponse" 
 : 
  
 true 
 , 
  
 "systemIntent" 
 : 
  
 { 
  
 "intent" 
 : 
  
 "actions.intent.TRANSACTION_REQUIREMENTS_CHECK" 
 , 
  
 "data" 
 : 
  
 { 
  
 "@type" 
 : 
  
 "type.googleapis.com/google.actions.transactions.v3.TransactionRequirementsCheckSpec" 
  
 } 
  
 } 
  
 } 
  
 } 
  
 } 
  

JSON

 { 
  
 "expectUserResponse" 
 : 
  
 true 
 , 
  
 "expectedInputs" 
 : 
  
 [ 
  
 { 
  
 "possibleIntents" 
 : 
  
 [ 
  
 { 
  
 "intent" 
 : 
  
 "actions.intent.TEXT" 
  
 } 
  
 ], 
  
 "inputPrompt" 
 : 
  
 { 
  
 "richInitialPrompt" 
 : 
  
 { 
  
 "items" 
 : 
  
 [ 
  
 { 
  
 "simpleResponse" 
 : 
  
 { 
  
 "textToSpeech" 
 : 
  
 "Looks like you're good to go! Next I'll need your delivery address.Try saying \"get delivery address\"." 
  
 } 
  
 } 
  
 ], 
  
 "suggestions" 
 : 
  
 [ 
  
 { 
  
 "title" 
 : 
  
 "get delivery address" 
  
 } 
  
 ] 
  
 } 
  
 } 
  
 } 
  
 ], 
  
 "conversationToken" 
 : 
  
 "{\"data\":{\"paymentType\":\"merchant_payment\"}}" 
 } 
  
Receive the result of a requirements check

After the Assistant fulfills the intent, it sends your fulfillment a request with the actions.intent.TRANSACTION_REQUIREMENTS_CHECK intent with the result of the check. To properly handle this request, declare a Dialogflow intent that's triggered by the actions_intent_TRANSACTION_REQUIREMENTS_CHECK event. When triggered, handle it in your fulfillment using the client library:

Node.js

 app 
 . 
 intent 
 ( 
 'Transaction Check Complete' 
 , 
  
 ( 
 conv 
 ) 
  
 = 
>  
 { 
  
 const 
  
 arg 
  
 = 
  
 conv 
 . 
 arguments 
 . 
 get 
 ( 
 'TRANSACTION_REQUIREMENTS_CHECK_RESULT' 
 ); 
  
 if 
  
 ( 
 arg 
 && 
 arg 
 . 
 resultType 
  
 === 
  
 'CAN_TRANSACT' 
 ) 
  
 { 
  
 // Normally take the user through cart building flow 
  
 conv 
 . 
 ask 
 ( 
 `Looks like you're good to go! ` 
  
 + 
  
 `Next I'll need your delivery address.` 
  
 + 
  
 `Try saying "get delivery address".` 
 ); 
  
 conv 
 . 
 ask 
 ( 
 new 
  
 Suggestions 
 ( 
 'get delivery address' 
 )); 
  
 } 
  
 else 
  
 { 
  
 // Exit conversation 
  
 conv 
 . 
 close 
 ( 
 'Transaction failed.' 
 ); 
  
 } 
 }); 
  

Node.js

 app 
 . 
 intent 
 ( 
 'actions.intent.TRANSACTION_REQUIREMENTS_CHECK' 
 , 
  
 ( 
 conv 
 ) 
  
 = 
>  
 { 
  
 const 
  
 arg 
  
 = 
  
 conv 
 . 
 arguments 
 . 
 get 
 ( 
 'TRANSACTION_REQUIREMENTS_CHECK_RESULT' 
 ); 
  
 if 
  
 ( 
 arg 
 && 
 arg 
 . 
 resultType 
  
 === 
  
 'CAN_TRANSACT' 
 ) 
  
 { 
  
 // Normally take the user through cart building flow 
  
 conv 
 . 
 ask 
 ( 
 `Looks like you're good to go! ` 
  
 + 
  
 `Next I'll need your delivery address.` 
  
 + 
  
 `Try saying "get delivery address".` 
 ); 
  
 conv 
 . 
 ask 
 ( 
 new 
  
 Suggestions 
 ( 
 'get delivery address' 
 )); 
  
 } 
  
 else 
  
 { 
  
 // Exit conversation 
  
 conv 
 . 
 close 
 ( 
 'Transaction failed.' 
 ); 
  
 } 
 }); 
  

Java

 @ForIntent 
 ( 
 "Transaction Check Complete" 
 ) 
 public 
  
 ActionResponse 
  
 transactionCheckComplete 
 ( 
 ActionRequest 
  
 request 
 ) 
  
 { 
  
 LOGGER 
 . 
 info 
 ( 
 "Checking Transaction Requirements Result." 
 ); 
  
 // Check result of transaction requirements check 
  
 Argument 
  
 transactionCheckResult 
  
 = 
  
 request 
  
 . 
 getArgument 
 ( 
 "TRANSACTION_REQUIREMENTS_CHECK_RESULT" 
 ); 
  
 boolean 
  
 result 
  
 = 
  
 false 
 ; 
  
 if 
  
 ( 
 transactionCheckResult 
  
 != 
  
 null 
 ) 
  
 { 
  
 Map<String 
 , 
  
 Object 
>  
 map 
  
 = 
  
 transactionCheckResult 
 . 
 getExtension 
 (); 
  
 if 
  
 ( 
 map 
  
 != 
  
 null 
 ) 
  
 { 
  
 String 
  
 resultType 
  
 = 
  
 ( 
 String 
 ) 
  
 map 
 . 
 get 
 ( 
 "resultType" 
 ); 
  
 result 
  
 = 
  
 resultType 
  
 != 
  
 null 
 && 
 resultType 
 . 
 equals 
 ( 
 "CAN_TRANSACT" 
 ); 
  
 } 
  
 } 
  
 ResponseBuilder 
  
 responseBuilder 
  
 = 
  
 getResponseBuilder 
 ( 
 request 
 ); 
  
 if 
  
 ( 
 result 
 ) 
  
 { 
  
 // Normally take the user through cart building flow 
  
 responseBuilder 
  
 . 
 add 
 ( 
 "Looks like you're good to go! Next " 
  
 + 
  
 "I'll need your delivery address. Try saying " 
  
 + 
  
 "\"get delivery address\"." 
 ) 
  
 . 
 addSuggestions 
 ( 
 new 
  
 String 
 [] 
 { 
 "get delivery address" 
 }); 
  
 } 
  
 else 
  
 { 
  
 // Exit conversation 
  
 responseBuilder 
 . 
 add 
 ( 
 "Transaction failed." 
 ); 
  
 } 
  
 return 
  
 responseBuilder 
 . 
 build 
 (); 
 } 
  

Java

 @ForIntent 
 ( 
 "actions.intent.TRANSACTION_REQUIREMENTS_CHECK" 
 ) 
 public 
  
 ActionResponse 
  
 transactionCheckComplete 
 ( 
 ActionRequest 
  
 request 
 ) 
  
 { 
  
 LOGGER 
 . 
 info 
 ( 
 "Checking Transaction Requirements Result." 
 ); 
  
 // Check result of transaction requirements check 
  
 Argument 
  
 transactionCheckResult 
  
 = 
  
 request 
  
 . 
 getArgument 
 ( 
 "TRANSACTION_REQUIREMENTS_CHECK_RESULT" 
 ); 
  
 boolean 
  
 result 
  
 = 
  
 false 
 ; 
  
 if 
  
 ( 
 transactionCheckResult 
  
 != 
  
 null 
 ) 
  
 { 
  
 Map<String 
 , 
  
 Object 
>  
 map 
  
 = 
  
 transactionCheckResult 
 . 
 getExtension 
 (); 
  
 if 
  
 ( 
 map 
  
 != 
  
 null 
 ) 
  
 { 
  
 String 
  
 resultType 
  
 = 
  
 ( 
 String 
 ) 
  
 map 
 . 
 get 
 ( 
 "resultType" 
 ); 
  
 result 
  
 = 
  
 resultType 
  
 != 
  
 null 
 && 
 resultType 
 . 
 equals 
 ( 
 "CAN_TRANSACT" 
 ); 
  
 } 
  
 } 
  
 ResponseBuilder 
  
 responseBuilder 
  
 = 
  
 getResponseBuilder 
 ( 
 request 
 ); 
  
 if 
  
 ( 
 result 
 ) 
  
 { 
  
 // Normally take the user through cart building flow 
  
 responseBuilder 
  
 . 
 add 
 ( 
 "Looks like you're good to go! Next " 
  
 + 
  
 "I'll need your delivery address. Try saying " 
  
 + 
  
 "\"get delivery address\"." 
 ) 
  
 . 
 addSuggestions 
 ( 
 new 
  
 String 
 [] 
 { 
 "get delivery address" 
 }); 
  
 } 
  
 else 
  
 { 
  
 // Exit conversation 
  
 responseBuilder 
 . 
 add 
 ( 
 "Transaction failed." 
 ); 
  
 } 
  
 return 
  
 responseBuilder 
 . 
 build 
 (); 
 } 
  

JSON

 { 
  
 "responseId" 
 : 
  
 "db1a333c-2781-41e3-84b1-cc0cc37643d7-594de0a7" 
 , 
  
 "queryResult" 
 : 
  
 { 
  
 "queryText" 
 : 
  
 "actions_intent_TRANSACTION_REQUIREMENTS_CHECK" 
 , 
  
 "action" 
 : 
  
 "transaction.check.complete" 
 , 
  
 "parameters" 
 : 
  
 {}, 
  
 "allRequiredParamsPresent" 
 : 
  
 true 
 , 
  
 "fulfillmentText" 
 : 
  
 "Failed to get transaction check results" 
 , 
  
 "fulfillmentMessages" 
 : 
  
 [ 
  
 { 
  
 "text" 
 : 
  
 { 
  
 "text" 
 : 
  
 [ 
  
 "Failed to get transaction check results" 
  
 ] 
  
 } 
  
 } 
  
 ], 
  
 "outputContexts" 
 : 
  
 [ 
  
 { 
  
 "name" 
 : 
  
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_media_response_audio" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_audio_output" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_account_linking" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_screen_output" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_web_browser" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/google_assistant_input_type_keyboard" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/merchant_payment" 
 , 
  
 "lifespanCount" 
 : 
  
 1 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_intent_transaction_requirements_check" 
 , 
  
 "parameters" 
 : 
  
 { 
  
 "TRANSACTION_REQUIREMENTS_CHECK_RESULT" 
 : 
  
 { 
  
 "@type" 
 : 
  
 "type.googleapis.com/google.actions.transactions.v3.TransactionRequirementsCheckResult" 
 , 
  
 "resultType" 
 : 
  
 "CAN_TRANSACT" 
  
 }, 
  
 "text" 
 : 
  
 "" 
  
 } 
  
 } 
  
 ], 
  
 "intent" 
 : 
  
 { 
  
 "name" 
 : 
  
 "projects/df-transactions/agent/intents/fd16d86b-60db-4d19-a683-5b52a22f4795" 
 , 
  
 "displayName" 
 : 
  
 "Transaction Check Complete" 
  
 }, 
  
 "intentDetectionConfidence" 
 : 
  
 1 
 , 
  
 "languageCode" 
 : 
  
 "en" 
  
 }, 
  
 "originalDetectIntentRequest" 
 : 
  
 { 
  
 "source" 
 : 
  
 "google" 
 , 
  
 "version" 
 : 
  
 "2" 
 , 
  
 "payload" 
 : 
  
 { 
  
 "user" 
 : 
  
 { 
  
 "locale" 
 : 
  
 "en-US" 
 , 
  
 "lastSeen" 
 : 
  
 "2019-09-23T19:49:32Z" 
 , 
  
 "userVerificationStatus" 
 : 
  
 "VERIFIED" 
  
 }, 
  
 "conversation" 
 : 
  
 { 
  
 "conversationId" 
 : 
  
 "ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy" 
 , 
  
 "type" 
 : 
  
 "ACTIVE" 
 , 
  
 "conversationToken" 
 : 
  
 "[ 
 \" 
 merchant_payment 
 \" 
 ]" 
  
 }, 
  
 "inputs" 
 : 
  
 [ 
  
 { 
  
 "intent" 
 : 
  
 "actions.intent.TRANSACTION_REQUIREMENTS_CHECK" 
 , 
  
 "rawInputs" 
 : 
  
 [ 
  
 { 
  
 "inputType" 
 : 
  
 "KEYBOARD" 
  
 } 
  
 ], 
  
 "arguments" 
 : 
  
 [ 
  
 { 
  
 "name" 
 : 
  
 "TRANSACTION_REQUIREMENTS_CHECK_RESULT" 
 , 
  
 "extension" 
 : 
  
 { 
  
 "@type" 
 : 
  
 "type.googleapis.com/google.actions.transactions.v3.TransactionRequirementsCheckResult" 
 , 
  
 "resultType" 
 : 
  
 "CAN_TRANSACT" 
  
 } 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "text" 
  
 } 
  
 ] 
  
 } 
  
 ], 
  
 "surface" 
 : 
  
 { 
  
 "capabilities" 
 : 
  
 [ 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.MEDIA_RESPONSE_AUDIO" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.AUDIO_OUTPUT" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.ACCOUNT_LINKING" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.SCREEN_OUTPUT" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.WEB_BROWSER" 
  
 } 
  
 ] 
  
 }, 
  
 "availableSurfaces" 
 : 
  
 [ 
  
 { 
  
 "capabilities" 
 : 
  
 [ 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.WEB_BROWSER" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.AUDIO_OUTPUT" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.SCREEN_OUTPUT" 
  
 } 
  
 ] 
  
 } 
  
 ] 
  
 } 
  
 }, 
  
 "session" 
 : 
  
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy" 
  
 } 
  

JSON

 { 
  
 "user" 
 : 
  
 { 
  
 "locale" 
 : 
  
 "en-US" 
 , 
  
 "lastSeen" 
 : 
  
 "2019-11-11T23:56:03Z" 
 , 
  
 "userVerificationStatus" 
 : 
  
 "VERIFIED" 
  
 }, 
  
 "conversation" 
 : 
  
 { 
  
 "conversationId" 
 : 
  
 "ABwppHGFwStZlYaQ9YT8rg9t_idVsxZrku1pUDrEbGSJmSUMatVdPwPEEQSCe1IwIBoN4sS4Weyn9pmgetEgbsWgw3JSvQmw" 
 , 
  
 "type" 
 : 
  
 "ACTIVE" 
 , 
  
 "conversationToken" 
 : 
  
 "{\"data\":{\"paymentType\":\"merchant_payment\"}}" 
  
 }, 
  
 "inputs" 
 : 
  
 [ 
  
 { 
  
 "intent" 
 : 
  
 "actions.intent.TRANSACTION_REQUIREMENTS_CHECK" 
 , 
  
 "rawInputs" 
 : 
  
 [ 
  
 {} 
  
 ], 
  
 "arguments" 
 : 
  
 [ 
  
 { 
  
 "name" 
 : 
  
 "TRANSACTION_REQUIREMENTS_CHECK_RESULT" 
 , 
  
 "extension" 
 : 
  
 { 
  
 "@type" 
 : 
  
 "type.googleapis.com/google.actions.transactions.v3.TransactionRequirementsCheckResult" 
 , 
  
 "resultType" 
 : 
  
 "CAN_TRANSACT" 
  
 } 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "text" 
  
 } 
  
 ] 
  
 } 
  
 ], 
  
 "surface" 
 : 
  
 { 
  
 "capabilities" 
 : 
  
 [ 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.AUDIO_OUTPUT" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.ACCOUNT_LINKING" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.SCREEN_OUTPUT" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.MEDIA_RESPONSE_AUDIO" 
  
 } 
  
 ] 
  
 }, 
  
 "availableSurfaces" 
 : 
  
 [ 
  
 { 
  
 "capabilities" 
 : 
  
 [ 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.SCREEN_OUTPUT" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.AUDIO_OUTPUT" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.WEB_BROWSER" 
  
 } 
  
 ] 
  
 } 
  
 ] 
 } 
  

1b. Request a delivery address (optional)

If your transaction requires a user's delivery address, you can request fulfillment of the actions.intent.DELIVERY_ADDRESS intent. This might be useful for determining the total price, delivery/pickup location, or for ensuring the user is within your service region.

When requesting this intent to be fulfilled, you pass in a reason option that allows you to preface the Assistant's request to obtain an address with a string. For example, if you specify "to know where to send the order", the Assistant might ask the user:

"To know where to send the order, I'll need to get your delivery address"

User experience

On surfaces with a screen, the user will choose which address they want to use for the transaction. If they haven't previously given an address, they'll be able to enter a new address.

On voice-only surfaces, the Assistant will ask the user for permission to share their default address for the transaction. If they haven't previously given an address, the conversation will be handed off to a phone for entry.

Request the address

Node.js

 app 
 . 
 intent 
 ( 
 'Delivery Address' 
 , 
  
 ( 
 conv 
 ) 
  
 = 
>  
 { 
  
 conv 
 . 
 ask 
 ( 
 new 
  
 DeliveryAddress 
 ({ 
  
 addressOptions 
 : 
  
 { 
  
 reason 
 : 
  
 'To know where to send the order' 
 , 
  
 }, 
  
 })); 
 }); 
  

Node.js

 conv 
 . 
 ask 
 ( 
 new 
  
 DeliveryAddress 
 ({ 
  
 addressOptions 
 : 
  
 { 
  
 reason 
 : 
  
 'To know where to send the order' 
 , 
  
 }, 
 })); 
  

Java

 @ForIntent 
 ( 
 "Delivery Address" 
 ) 
 public 
  
 ActionResponse 
  
 deliveryAddress 
 ( 
 ActionRequest 
  
 request 
 ) 
  
 { 
  
 DeliveryAddressValueSpecAddressOptions 
  
 addressOptions 
  
 = 
  
 new 
  
 DeliveryAddressValueSpecAddressOptions 
 () 
  
 . 
 setReason 
 ( 
 "To know where to send the order" 
 ); 
  
 return 
  
 getResponseBuilder 
 ( 
 request 
 ) 
  
 . 
 add 
 ( 
 new 
  
 DeliveryAddress 
 () 
  
 . 
 setAddressOptions 
 ( 
 addressOptions 
 )) 
  
 . 
 build 
 (); 
 } 
  

Java

 DeliveryAddressValueSpecAddressOptions 
  
 addressOptions 
  
 = 
  
 new 
  
 DeliveryAddressValueSpecAddressOptions 
 () 
  
 . 
 setReason 
 ( 
 "To know where to send the order" 
 ); 
 return 
  
 getResponseBuilder 
 ( 
 request 
 ) 
  
 . 
 add 
 ( 
 new 
  
 DeliveryAddress 
 () 
  
 . 
 setAddressOptions 
 ( 
 addressOptions 
 )) 
  
 . 
 build 
 (); 
  

JSON

 { 
  
 "payload" 
 : 
  
 { 
  
 "google" 
 : 
  
 { 
  
 "expectUserResponse" 
 : 
  
 true 
 , 
  
 "systemIntent" 
 : 
  
 { 
  
 "intent" 
 : 
  
 "actions.intent.DELIVERY_ADDRESS" 
 , 
  
 "data" 
 : 
  
 { 
  
 "@type" 
 : 
  
 "type.googleapis.com/google.actions.v2.DeliveryAddressValueSpec" 
 , 
  
 "addressOptions" 
 : 
  
 { 
  
 "reason" 
 : 
  
 "To know where to send the order" 
  
 } 
  
 } 
  
 } 
  
 } 
  
 } 
  
 } 
  

JSON

 { 
  
 "expectUserResponse" 
 : 
  
 true 
 , 
  
 "expectedInputs" 
 : 
  
 [ 
  
 { 
  
 "possibleIntents" 
 : 
  
 [ 
  
 { 
  
 "intent" 
 : 
  
 "actions.intent.DELIVERY_ADDRESS" 
 , 
  
 "inputValueData" 
 : 
  
 { 
  
 "@type" 
 : 
  
 "type.googleapis.com/google.actions.v2.DeliveryAddressValueSpec" 
 , 
  
 "addressOptions" 
 : 
  
 { 
  
 "reason" 
 : 
  
 "To know where to send the order" 
  
 } 
  
 } 
  
 } 
  
 ] 
  
 } 
  
 ], 
  
 "conversationToken" 
 : 
  
 "{\"data\":{\"paymentType\":\"merchant_payment\"}}" 
 } 
  
Receive the address

After the Assistant fulfills the intent, it sends your fulfillment a request with the actions.intent.DELIVERY_ADDRESS intent.

To properly handle this request, declare a Dialogflow intent that's triggered by the actions_intent_DELIVERY_ADDRESS event. When triggered, handle it in your fulfillment using the client library:

Node.js

 app 
 . 
 intent 
 ( 
 'Delivery Address Complete' 
 , 
  
 ( 
 conv 
 ) 
  
 = 
>  
 { 
  
 const 
  
 arg 
  
 = 
  
 conv 
 . 
 arguments 
 . 
 get 
 ( 
 'DELIVERY_ADDRESS_VALUE' 
 ); 
  
 if 
  
 ( 
 arg 
 && 
 arg 
 . 
 userDecision 
  
 === 
 'ACCEPTED' 
 ) 
  
 { 
  
 conv 
 . 
 data 
 . 
 location 
  
 = 
  
 arg 
 . 
 location 
 ; 
  
 conv 
 . 
 ask 
 ( 
 'Great, got your address! Now say "confirm transaction".' 
 ); 
  
 conv 
 . 
 ask 
 ( 
 new 
  
 Suggestions 
 ( 
 'confirm transaction' 
 )); 
  
 } 
  
 else 
  
 { 
  
 conv 
 . 
 close 
 ( 
 'Transaction failed.' 
 ); 
  
 } 
 }); 
  

Node.js

 app 
 . 
 intent 
 ( 
 'actions.intent.DELIVERY_ADDRESS' 
 , 
  
 ( 
 conv 
 ) 
  
 = 
>  
 { 
  
 const 
  
 arg 
  
 = 
  
 conv 
 . 
 arguments 
 . 
 get 
 ( 
 'DELIVERY_ADDRESS_VALUE' 
 ); 
  
 if 
  
 ( 
 arg 
 && 
 arg 
 . 
 userDecision 
  
 === 
 'ACCEPTED' 
 ) 
  
 { 
  
 conv 
 . 
 data 
 . 
 location 
  
 = 
  
 arg 
 . 
 location 
 ; 
  
 conv 
 . 
 ask 
 ( 
 'Great, got your address! Now say "confirm transaction".' 
 ); 
  
 conv 
 . 
 ask 
 ( 
 new 
  
 Suggestions 
 ( 
 'confirm transaction' 
 )); 
  
 } 
  
 else 
  
 { 
  
 conv 
 . 
 close 
 ( 
 'Transaction failed.' 
 ); 
  
 } 
 }); 
  

Java

 @ForIntent 
 ( 
 "Delivery Address Complete" 
 ) 
 public 
  
 ActionResponse 
  
 deliveryAddressComplete 
 ( 
 ActionRequest 
  
 request 
 ) 
  
 { 
  
 Argument 
  
 deliveryAddressValue 
  
 = 
  
 request 
 . 
 getArgument 
 ( 
 "DELIVERY_ADDRESS_VALUE" 
 ); 
  
 Location 
  
 deliveryAddress 
  
 = 
  
 null 
 ; 
  
 if 
  
 ( 
 deliveryAddressValue 
  
 != 
  
 null 
 ) 
  
 { 
  
 Map<String 
 , 
  
 Object 
>  
 map 
  
 = 
  
 deliveryAddressValue 
 . 
 getExtension 
 (); 
  
 if 
  
 ( 
 map 
  
 != 
  
 null 
 ) 
  
 { 
  
 String 
  
 userDecision 
  
 = 
  
 ( 
 String 
 ) 
  
 map 
 . 
 get 
 ( 
 "userDecision" 
 ); 
  
 Location 
  
 location 
  
 = 
  
 ( 
 Location 
 ) 
  
 map 
 . 
 get 
 ( 
 "location" 
 ); 
  
 deliveryAddress 
  
 = 
  
 userDecision 
  
 != 
  
 null 
 && 
 userDecision 
 . 
 equals 
 ( 
 "ACCEPTED" 
 ) 
  
 ? 
  
 location 
  
 : 
  
 null 
 ; 
  
 } 
  
 } 
  
 ResponseBuilder 
  
 responseBuilder 
  
 = 
  
 getResponseBuilder 
 ( 
 request 
 ); 
  
 if 
  
 ( 
 deliveryAddress 
  
 != 
  
 null 
 ) 
  
 { 
  
 // Cache delivery address in conversation data for later use 
  
 Map<String 
 , 
  
 Object 
>  
 conversationData 
  
 = 
  
 request 
 . 
 getConversationData 
 (); 
  
 conversationData 
 . 
 put 
 ( 
 "location" 
 , 
  
 GSON_BUILDER 
 . 
 create 
 (). 
 toJson 
 ( 
 deliveryAddress 
 , 
  
 Location 
 . 
 class 
 )); 
  
 responseBuilder 
  
 . 
 add 
 ( 
 "Great, got your address! Now say \"confirm transaction\"." 
 ) 
  
 . 
 addSuggestions 
 ( 
 new 
  
 String 
 [] 
  
 { 
  
 "confirm transaction" 
  
 }); 
  
 } 
  
 else 
  
 { 
  
 responseBuilder 
 . 
 add 
 ( 
 "Transaction failed." 
 ). 
 endConversation 
 (); 
  
 } 
  
 return 
  
 responseBuilder 
 . 
 build 
 (); 
 } 
  

Java

 @ForIntent 
 ( 
 "actions.intent.DELIVERY_ADDRESS" 
 ) 
 public 
  
 ActionResponse 
  
 deliveryAddressComplete 
 ( 
 ActionRequest 
  
 request 
 ) 
  
 { 
  
 Argument 
  
 deliveryAddressValue 
  
 = 
  
 request 
 . 
 getArgument 
 ( 
 "DELIVERY_ADDRESS_VALUE" 
 ); 
  
 Location 
  
 deliveryAddress 
  
 = 
  
 null 
 ; 
  
 if 
  
 ( 
 deliveryAddressValue 
  
 != 
  
 null 
 ) 
  
 { 
  
 Map<String 
 , 
  
 Object 
>  
 map 
  
 = 
  
 deliveryAddressValue 
 . 
 getExtension 
 (); 
  
 if 
  
 ( 
 map 
  
 != 
  
 null 
 ) 
  
 { 
  
 String 
  
 userDecision 
  
 = 
  
 ( 
 String 
 ) 
  
 map 
 . 
 get 
 ( 
 "userDecision" 
 ); 
  
 Location 
  
 location 
  
 = 
  
 ( 
 Location 
 ) 
  
 map 
 . 
 get 
 ( 
 "location" 
 ); 
  
 deliveryAddress 
  
 = 
  
 userDecision 
  
 != 
  
 null 
 && 
 userDecision 
 . 
 equals 
 ( 
 "ACCEPTED" 
 ) 
  
 ? 
  
 location 
  
 : 
  
 null 
 ; 
  
 } 
  
 } 
  
 ResponseBuilder 
  
 responseBuilder 
  
 = 
  
 getResponseBuilder 
 ( 
 request 
 ); 
  
 if 
  
 ( 
 deliveryAddress 
  
 != 
  
 null 
 ) 
  
 { 
  
 // Cache delivery address in conversation data for later use 
  
 Map<String 
 , 
  
 Object 
>  
 conversationData 
  
 = 
  
 request 
 . 
 getConversationData 
 (); 
  
 conversationData 
 . 
 put 
 ( 
 "location" 
 , 
  
 GSON_BUILDER 
 . 
 create 
 (). 
 toJson 
 ( 
 deliveryAddress 
 , 
  
 Location 
 . 
 class 
 )); 
  
 responseBuilder 
  
 . 
 add 
 ( 
 "Great, got your address! Now say \"confirm transaction\"." 
 ) 
  
 . 
 addSuggestions 
 ( 
 new 
  
 String 
 [] 
  
 { 
  
 "confirm transaction" 
  
 }); 
  
 } 
  
 else 
  
 { 
  
 responseBuilder 
 . 
 add 
 ( 
 "Transaction failed." 
 ). 
 endConversation 
 (); 
  
 } 
  
 return 
  
 responseBuilder 
 . 
 build 
 (); 
 } 
  

JSON

 { 
  
 "responseId" 
 : 
  
 "58b0c305-b437-47ac-8593-4fb0122a19e6-594de0a7" 
 , 
  
 "queryResult" 
 : 
  
 { 
  
 "queryText" 
 : 
  
 "actions_intent_DELIVERY_ADDRESS" 
 , 
  
 "parameters" 
 : 
  
 {}, 
  
 "allRequiredParamsPresent" 
 : 
  
 true 
 , 
  
 "fulfillmentMessages" 
 : 
  
 [ 
  
 { 
  
 "text" 
 : 
  
 { 
  
 "text" 
 : 
  
 [ 
  
 "" 
  
 ] 
  
 } 
  
 } 
  
 ], 
  
 "outputContexts" 
 : 
  
 [ 
  
 { 
  
 "name" 
 : 
  
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_media_response_audio" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_audio_output" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_account_linking" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_screen_output" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_web_browser" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_intent_delivery_address" 
 , 
  
 "parameters" 
 : 
  
 { 
  
 "DELIVERY_ADDRESS_VALUE" 
 : 
  
 { 
  
 "@type" 
 : 
  
 "type.googleapis.com/google.actions.v2.DeliveryAddressValue" 
 , 
  
 "userDecision" 
 : 
  
 "ACCEPTED" 
 , 
  
 "location" 
 : 
  
 { 
  
 "coordinates" 
 : 
  
 { 
  
 "latitude" 
 : 
  
 37.432524 
 , 
  
 "longitude" 
 : 
  
 - 
 122.098545 
  
 }, 
  
 "zipCode" 
 : 
  
 "94043-1351" 
 , 
  
 "city" 
 : 
  
 "MOUNTAIN VIEW" 
 , 
  
 "postalAddress" 
 : 
  
 { 
  
 "regionCode" 
 : 
  
 "US" 
 , 
  
 "postalCode" 
 : 
  
 "94043-1351" 
 , 
  
 "administrativeArea" 
 : 
  
 "CA" 
 , 
  
 "locality" 
 : 
  
 "MOUNTAIN VIEW" 
 , 
  
 "addressLines" 
 : 
  
 [ 
  
 "1600 AMPHITHEATRE PKWY" 
  
 ], 
  
 "recipients" 
 : 
  
 [ 
  
 "John Doe" 
  
 ] 
  
 }, 
  
 "phoneNumber" 
 : 
  
 "+1 123-456-7890" 
  
 } 
  
 }, 
  
 "text" 
 : 
  
 "1600 AMPHITHEATRE PKWY" 
  
 } 
  
 } 
  
 ], 
  
 "intent" 
 : 
  
 { 
  
 "name" 
 : 
  
 "projects/df-transactions/agent/intents/0be5d130-1760-4355-85e9-4dc01da8bf3c" 
 , 
  
 "displayName" 
 : 
  
 "Delivery Address Complete" 
  
 }, 
  
 "intentDetectionConfidence" 
 : 
  
 1 
 , 
  
 "languageCode" 
 : 
  
 "en" 
  
 }, 
  
 "originalDetectIntentRequest" 
 : 
  
 { 
  
 "source" 
 : 
  
 "google" 
 , 
  
 "version" 
 : 
  
 "2" 
 , 
  
 "payload" 
 : 
  
 { 
  
 "user" 
 : 
  
 { 
  
 "locale" 
 : 
  
 "en-US" 
 , 
  
 "lastSeen" 
 : 
  
 "2019-09-23T19:49:55Z" 
 , 
  
 "userVerificationStatus" 
 : 
  
 "VERIFIED" 
  
 }, 
  
 "conversation" 
 : 
  
 { 
  
 "conversationId" 
 : 
  
 "ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy" 
 , 
  
 "type" 
 : 
  
 "ACTIVE" 
 , 
  
 "conversationToken" 
 : 
  
 "[]" 
  
 }, 
  
 "inputs" 
 : 
  
 [ 
  
 { 
  
 "intent" 
 : 
  
 "actions.intent.DELIVERY_ADDRESS" 
 , 
  
 "rawInputs" 
 : 
  
 [ 
  
 { 
  
 "query" 
 : 
  
 "1600 AMPHITHEATRE PKWY" 
  
 } 
  
 ], 
  
 "arguments" 
 : 
  
 [ 
  
 { 
  
 "name" 
 : 
  
 "DELIVERY_ADDRESS_VALUE" 
 , 
  
 "extension" 
 : 
  
 { 
  
 "@type" 
 : 
  
 "type.googleapis.com/google.actions.v2.DeliveryAddressValue" 
 , 
  
 "userDecision" 
 : 
  
 "ACCEPTED" 
 , 
  
 "location" 
 : 
  
 { 
  
 "coordinates" 
 : 
  
 { 
  
 "latitude" 
 : 
  
 37.432524 
 , 
  
 "longitude" 
 : 
  
 - 
 122.098545 
  
 }, 
  
 "zipCode" 
 : 
  
 "94043-1351" 
 , 
  
 "city" 
 : 
  
 "MOUNTAIN VIEW" 
 , 
  
 "postalAddress" 
 : 
  
 { 
  
 "regionCode" 
 : 
  
 "US" 
 , 
  
 "postalCode" 
 : 
  
 "94043-1351" 
 , 
  
 "administrativeArea" 
 : 
  
 "CA" 
 , 
  
 "locality" 
 : 
  
 "MOUNTAIN VIEW" 
 , 
  
 "addressLines" 
 : 
  
 [ 
  
 "1600 AMPHITHEATRE PKWY" 
  
 ], 
  
 "recipients" 
 : 
  
 [ 
  
 "John Doe" 
  
 ] 
  
 }, 
  
 "phoneNumber" 
 : 
  
 "+1 123-456-7890" 
  
 } 
  
 } 
  
 } 
  
 ] 
  
 } 
  
 ], 
  
 "surface" 
 : 
  
 { 
  
 "capabilities" 
 : 
  
 [ 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.WEB_BROWSER" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.SCREEN_OUTPUT" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.ACCOUNT_LINKING" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.MEDIA_RESPONSE_AUDIO" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.AUDIO_OUTPUT" 
  
 } 
  
 ] 
  
 }, 
  
 "availableSurfaces" 
 : 
  
 [ 
  
 { 
  
 "capabilities" 
 : 
  
 [ 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.WEB_BROWSER" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.AUDIO_OUTPUT" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.SCREEN_OUTPUT" 
  
 } 
  
 ] 
  
 } 
  
 ] 
  
 } 
  
 }, 
  
 "session" 
 : 
  
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy" 
  
 } 
  

JSON

 { 
  
 "user" 
 : 
  
 { 
  
 "locale" 
 : 
  
 "en-US" 
 , 
  
 "lastSeen" 
 : 
  
 "2019-11-11T23:57:20Z" 
 , 
  
 "userVerificationStatus" 
 : 
  
 "VERIFIED" 
  
 }, 
  
 "conversation" 
 : 
  
 { 
  
 "conversationId" 
 : 
  
 "ABwppHGFwStZlYaQ9YT8rg9t_idVsxZrku1pUDrEbGSJmSUMatVdPwPEEQSCe1IwIBoN4sS4Weyn9pmgetEgbsWgw3JSvQmw" 
 , 
  
 "type" 
 : 
  
 "ACTIVE" 
 , 
  
 "conversationToken" 
 : 
  
 "{\"data\":{\"paymentType\":\"merchant_payment\"}}" 
  
 }, 
  
 "inputs" 
 : 
  
 [ 
  
 { 
  
 "intent" 
 : 
  
 "actions.intent.DELIVERY_ADDRESS" 
 , 
  
 "rawInputs" 
 : 
  
 [ 
  
 { 
  
 "inputType" 
 : 
  
 "VOICE" 
 , 
  
 "query" 
 : 
  
 "1600 AMPHITHEATRE PKWY" 
  
 } 
  
 ], 
  
 "arguments" 
 : 
  
 [ 
  
 { 
  
 "name" 
 : 
  
 "DELIVERY_ADDRESS_VALUE" 
 , 
  
 "extension" 
 : 
  
 { 
  
 "@type" 
 : 
  
 "type.googleapis.com/google.actions.v2.DeliveryAddressValue" 
 , 
  
 "userDecision" 
 : 
  
 "ACCEPTED" 
 , 
  
 "location" 
 : 
  
 { 
  
 "coordinates" 
 : 
  
 { 
  
 "latitude" 
 : 
  
 37.421578499999995 
 , 
  
 "longitude" 
 : 
  
 - 
 122.0837816 
  
 }, 
  
 "zipCode" 
 : 
  
 "94043-1351" 
 , 
  
 "city" 
 : 
  
 "MOUNTAIN VIEW" 
 , 
  
 "postalAddress" 
 : 
  
 { 
  
 "regionCode" 
 : 
  
 "US" 
 , 
  
 "postalCode" 
 : 
  
 "94043-1351" 
 , 
  
 "administrativeArea" 
 : 
  
 "CA" 
 , 
  
 "locality" 
 : 
  
 "MOUNTAIN VIEW" 
 , 
  
 "addressLines" 
 : 
  
 [ 
  
 "1600 AMPHITHEATRE PKWY" 
  
 ], 
  
 "recipients" 
 : 
  
 [ 
  
 "John Doe" 
  
 ] 
  
 }, 
  
 "phoneNumber" 
 : 
  
 "+1 123-456-7890" 
  
 } 
  
 } 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "text" 
 , 
  
 "rawText" 
 : 
  
 "1600 AMPHITHEATRE PKWY" 
 , 
  
 "textValue" 
 : 
  
 "1600 AMPHITHEATRE PKWY" 
  
 } 
  
 ] 
  
 } 
  
 ], 
  
 "surface" 
 : 
  
 { 
  
 "capabilities" 
 : 
  
 [ 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.SCREEN_OUTPUT" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.AUDIO_OUTPUT" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.MEDIA_RESPONSE_AUDIO" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.ACCOUNT_LINKING" 
  
 } 
  
 ] 
  
 }, 
  
 "availableSurfaces" 
 : 
  
 [ 
  
 { 
  
 "capabilities" 
 : 
  
 [ 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.AUDIO_OUTPUT" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.WEB_BROWSER" 
  
 }, 
  
 { 
  
 "name" 
 : 
  
 "actions.capability.SCREEN_OUTPUT" 
  
 } 
  
 ] 
  
 } 
  
 ] 
 } 
  

2. Build the order

User experience

Once you have the user information you need, you build a "cart assembly" experience that guides the user to build an order. Every Action will have a slightly different cart assembly flow as appropriate for their product or service.

The most basic cart assembly experience has a user pick items from a list to add to their order, though you can design the conversation to simplify the user experience. You could build a cart assembly experience that enables the user to re-order their most recent purchase via a simple yes or no question. You could also present the user a carousel or list card of the top "featured" or "recommended" items.

We recommend using rich responses to present the user's options visually, but also design the conversation such that the user can build their cart using only their voice. For some best practices and examples of high-quality cart assembly experiences, see the Transactions Design Guidelines .

Fulfillment

Throughout your conversation, you'll need to gather the items that a user wants to purchase and then construct an Order object.

At minimum, your Order must contain the following:

  • buyerInfo - Information about the user making the purchase.
  • transactionMerchant - Information about the merchant that facilitated the order.
  • contents - The actual contents of the order listed as lineItems .
  • priceAttributes - Pricing details about the order, including the total cost of the order with discounts and taxes.

Refer to the Order response documentation to construct your cart. Note that you may need to include different fields depending on the order.

The sample code below shows a complete order, including optional fields:

Node.js

 const 
  
 order 
  
 = 
  
 { 
  
 createTime 
 : 
  
 '2019-09-24T18:00:00.877Z' 
 , 
  
 lastUpdateTime 
 : 
  
 '2019-09-24T18:00:00.877Z' 
 , 
  
 merchantOrderId 
 : 
  
 orderId 
 , 
  
 // A unique ID String for the order 
  
 userVisibleOrderId 
 : 
  
 orderId 
 , 
  
 transactionMerchant 
 : 
  
 { 
  
 id 
 : 
  
 'http://www.example.com' 
 , 
  
 name 
 : 
  
 'Example Merchant' 
 , 
  
 }, 
  
 contents 
 : 
  
 { 
  
 lineItems 
 : 
  
 [ 
  
 { 
  
 id 
 : 
  
 'LINE_ITEM_ID' 
 , 
  
 name 
 : 
  
 'Pizza' 
 , 
  
 description 
 : 
  
 'A four cheese pizza.' 
 , 
  
 priceAttributes 
 : 
  
 [ 
  
 { 
  
 type 
 : 
  
 'REGULAR' 
 , 
  
 name 
 : 
  
 'Item Price' 
 , 
  
 state 
 : 
  
 'ACTUAL' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 8990000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 { 
  
 type 
 : 
  
 'TOTAL' 
 , 
  
 name 
 : 
  
 'Total Price' 
 , 
  
 state 
 : 
  
 'ACTUAL' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 9990000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 ], 
  
 notes 
 : 
  
 [ 
  
 'Extra cheese.' 
 , 
  
 ], 
  
 purchase 
 : 
  
 { 
  
 quantity 
 : 
  
 1 
 , 
  
 unitMeasure 
 : 
  
 { 
  
 measure 
 : 
  
 1 
 , 
  
 unit 
 : 
  
 'POUND' 
 , 
  
 }, 
  
 itemOptions 
 : 
  
 [ 
  
 { 
  
 id 
 : 
  
 'ITEM_OPTION_ID' 
 , 
  
 name 
 : 
  
 'Pepperoni' 
 , 
  
 prices 
 : 
  
 [ 
  
 { 
  
 type 
 : 
  
 'REGULAR' 
 , 
  
 state 
 : 
  
 'ACTUAL' 
 , 
  
 name 
 : 
  
 'Item Price' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 1000000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 { 
  
 type 
 : 
  
 'TOTAL' 
 , 
  
 name 
 : 
  
 'Total Price' 
 , 
  
 state 
 : 
  
 'ACTUAL' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 1000000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 ], 
  
 note 
 : 
  
 'Extra pepperoni' 
 , 
  
 quantity 
 : 
  
 1 
 , 
  
 subOptions 
 : 
  
 [], 
  
 }, 
  
 ], 
  
 }, 
  
 }, 
  
 ], 
  
 }, 
  
 buyerInfo 
 : 
  
 { 
  
 email 
 : 
  
 'janedoe@gmail.com' 
 , 
  
 firstName 
 : 
  
 'Jane' 
 , 
  
 lastName 
 : 
  
 'Doe' 
 , 
  
 displayName 
 : 
  
 'Jane Doe' 
 , 
  
 }, 
  
 priceAttributes 
 : 
  
 [ 
  
 { 
  
 type 
 : 
  
 'SUBTOTAL' 
 , 
  
 name 
 : 
  
 'Subtotal' 
 , 
  
 state 
 : 
  
 'ESTIMATE' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 9990000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 { 
  
 type 
 : 
  
 'DELIVERY' 
 , 
  
 name 
 : 
  
 'Delivery' 
 , 
  
 state 
 : 
  
 'ACTUAL' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 2000000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 { 
  
 type 
 : 
  
 'TAX' 
 , 
  
 name 
 : 
  
 'Tax' 
 , 
  
 state 
 : 
  
 'ESTIMATE' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 3780000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 { 
  
 type 
 : 
  
 'TOTAL' 
 , 
  
 name 
 : 
  
 'Total Price' 
 , 
  
 state 
 : 
  
 'ESTIMATE' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 15770000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 ], 
  
 followUpActions 
 : 
  
 [ 
  
 { 
  
 type 
 : 
  
 'VIEW_DETAILS' 
 , 
  
 title 
 : 
  
 'View details' 
 , 
  
 openUrlAction 
 : 
  
 { 
  
 url 
 : 
  
 'http://example.com' 
 , 
  
 }, 
  
 }, 
  
 { 
  
 type 
 : 
  
 'CALL' 
 , 
  
 title 
 : 
  
 'Call us' 
 , 
  
 openUrlAction 
 : 
  
 { 
  
 url 
 : 
  
 'tel:+16501112222' 
 , 
  
 }, 
  
 }, 
  
 { 
  
 type 
 : 
  
 'EMAIL' 
 , 
  
 title 
 : 
  
 'Email us' 
 , 
  
 openUrlAction 
 : 
  
 { 
  
 url 
 : 
  
 'mailto:person@example.com' 
 , 
  
 }, 
  
 }, 
  
 ], 
  
 termsOfServiceUrl 
 : 
  
 'http://www.example.com' 
 , 
  
 note 
 : 
  
 'Sale event' 
 , 
  
 promotions 
 : 
  
 [ 
  
 { 
  
 coupon 
 : 
  
 'COUPON_CODE' 
 , 
  
 }, 
  
 ], 
  
 purchase 
 : 
  
 { 
  
 status 
 : 
  
 'CREATED' 
 , 
  
 userVisibleStatusLabel 
 : 
  
 'CREATED' 
 , 
  
 type 
 : 
  
 'FOOD' 
 , 
  
 returnsInfo 
 : 
  
 { 
  
 isReturnable 
 : 
  
 false 
 , 
  
 daysToReturn 
 : 
  
 1 
 , 
  
 policyUrl 
 : 
  
 'http://www.example.com' 
 , 
  
 }, 
  
 fulfillmentInfo 
 : 
  
 { 
  
 id 
 : 
  
 'FULFILLMENT_SERVICE_ID' 
 , 
  
 fulfillmentType 
 : 
  
 'DELIVERY' 
 , 
  
 expectedFulfillmentTime 
 : 
  
 { 
  
 timeIso8601 
 : 
  
 '2019-09-25T18:00:00.877Z' 
 , 
  
 }, 
  
 location 
 : 
  
 location 
 , 
  
 price 
 : 
  
 { 
  
 type 
 : 
  
 'REGULAR' 
 , 
  
 name 
 : 
  
 'Delivery Price' 
 , 
  
 state 
 : 
  
 'ACTUAL' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 2000000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 fulfillmentContact 
 : 
  
 { 
  
 email 
 : 
  
 'johnjohnson@gmail.com' 
 , 
  
 firstName 
 : 
  
 'John' 
 , 
  
 lastName 
 : 
  
 'Johnson' 
 , 
  
 displayName 
 : 
  
 'John Johnson' 
 , 
  
 }, 
  
 }, 
  
 purchaseLocationType 
 : 
  
 'ONLINE_PURCHASE' 
 , 
  
 }, 
 }; 
  

Node.js

 const 
  
 order 
  
 = 
  
 { 
  
 createTime 
 : 
  
 '2019-09-24T18:00:00.877Z' 
 , 
  
 lastUpdateTime 
 : 
  
 '2019-09-24T18:00:00.877Z' 
 , 
  
 merchantOrderId 
 : 
  
 orderId 
 , 
  
 // A unique ID String for the order 
  
 userVisibleOrderId 
 : 
  
 orderId 
 , 
  
 transactionMerchant 
 : 
  
 { 
  
 id 
 : 
  
 'http://www.example.com' 
 , 
  
 name 
 : 
  
 'Example Merchant' 
 , 
  
 }, 
  
 contents 
 : 
  
 { 
  
 lineItems 
 : 
  
 [ 
  
 { 
  
 id 
 : 
  
 'LINE_ITEM_ID' 
 , 
  
 name 
 : 
  
 'Pizza' 
 , 
  
 description 
 : 
  
 'A four cheese pizza.' 
 , 
  
 priceAttributes 
 : 
  
 [ 
  
 { 
  
 type 
 : 
  
 'REGULAR' 
 , 
  
 name 
 : 
  
 'Item Price' 
 , 
  
 state 
 : 
  
 'ACTUAL' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 8990000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 { 
  
 type 
 : 
  
 'TOTAL' 
 , 
  
 name 
 : 
  
 'Total Price' 
 , 
  
 state 
 : 
  
 'ACTUAL' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 9990000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 ], 
  
 notes 
 : 
  
 [ 
  
 'Extra cheese.' 
 , 
  
 ], 
  
 purchase 
 : 
  
 { 
  
 quantity 
 : 
  
 1 
 , 
  
 unitMeasure 
 : 
  
 { 
  
 measure 
 : 
  
 1 
 , 
  
 unit 
 : 
  
 'POUND' 
 , 
  
 }, 
  
 itemOptions 
 : 
  
 [ 
  
 { 
  
 id 
 : 
  
 'ITEM_OPTION_ID' 
 , 
  
 name 
 : 
  
 'Pepperoni' 
 , 
  
 prices 
 : 
  
 [ 
  
 { 
  
 type 
 : 
  
 'REGULAR' 
 , 
  
 state 
 : 
  
 'ACTUAL' 
 , 
  
 name 
 : 
  
 'Item Price' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 1000000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 { 
  
 type 
 : 
  
 'TOTAL' 
 , 
  
 name 
 : 
  
 'Total Price' 
 , 
  
 state 
 : 
  
 'ACTUAL' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 1000000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 ], 
  
 note 
 : 
  
 'Extra pepperoni' 
 , 
  
 quantity 
 : 
  
 1 
 , 
  
 subOptions 
 : 
  
 [], 
  
 }, 
  
 ], 
  
 }, 
  
 }, 
  
 ], 
  
 }, 
  
 buyerInfo 
 : 
  
 { 
  
 email 
 : 
  
 'janedoe@gmail.com' 
 , 
  
 firstName 
 : 
  
 'Jane' 
 , 
  
 lastName 
 : 
  
 'Doe' 
 , 
  
 displayName 
 : 
  
 'Jane Doe' 
 , 
  
 }, 
  
 priceAttributes 
 : 
  
 [ 
  
 { 
  
 type 
 : 
  
 'SUBTOTAL' 
 , 
  
 name 
 : 
  
 'Subtotal' 
 , 
  
 state 
 : 
  
 'ESTIMATE' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 9990000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 { 
  
 type 
 : 
  
 'DELIVERY' 
 , 
  
 name 
 : 
  
 'Delivery' 
 , 
  
 state 
 : 
  
 'ACTUAL' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 2000000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 { 
  
 type 
 : 
  
 'TAX' 
 , 
  
 name 
 : 
  
 'Tax' 
 , 
  
 state 
 : 
  
 'ESTIMATE' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 3780000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 { 
  
 type 
 : 
  
 'TOTAL' 
 , 
  
 name 
 : 
  
 'Total Price' 
 , 
  
 state 
 : 
  
 'ESTIMATE' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 15770000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 ], 
  
 followUpActions 
 : 
  
 [ 
  
 { 
  
 type 
 : 
  
 'VIEW_DETAILS' 
 , 
  
 title 
 : 
  
 'View details' 
 , 
  
 openUrlAction 
 : 
  
 { 
  
 url 
 : 
  
 'http://example.com' 
 , 
  
 }, 
  
 }, 
  
 { 
  
 type 
 : 
  
 'CALL' 
 , 
  
 title 
 : 
  
 'Call us' 
 , 
  
 openUrlAction 
 : 
  
 { 
  
 url 
 : 
  
 'tel:+16501112222' 
 , 
  
 }, 
  
 }, 
  
 { 
  
 type 
 : 
  
 'EMAIL' 
 , 
  
 title 
 : 
  
 'Email us' 
 , 
  
 openUrlAction 
 : 
  
 { 
  
 url 
 : 
  
 'mailto:person@example.com' 
 , 
  
 }, 
  
 }, 
  
 ], 
  
 termsOfServiceUrl 
 : 
  
 'http://www.example.com' 
 , 
  
 note 
 : 
  
 'Sale event' 
 , 
  
 promotions 
 : 
  
 [ 
  
 { 
  
 coupon 
 : 
  
 'COUPON_CODE' 
 , 
  
 }, 
  
 ], 
  
 purchase 
 : 
  
 { 
  
 status 
 : 
  
 'CREATED' 
 , 
  
 userVisibleStatusLabel 
 : 
  
 'CREATED' 
 , 
  
 type 
 : 
  
 'FOOD' 
 , 
  
 returnsInfo 
 : 
  
 { 
  
 isReturnable 
 : 
  
 false 
 , 
  
 daysToReturn 
 : 
  
 1 
 , 
  
 policyUrl 
 : 
  
 'http://www.example.com' 
 , 
  
 }, 
  
 fulfillmentInfo 
 : 
  
 { 
  
 id 
 : 
  
 'FULFILLMENT_SERVICE_ID' 
 , 
  
 fulfillmentType 
 : 
  
 'DELIVERY' 
 , 
  
 expectedFulfillmentTime 
 : 
  
 { 
  
 timeIso8601 
 : 
  
 '2019-09-25T18:00:00.877Z' 
 , 
  
 }, 
  
 location 
 : 
  
 location 
 , 
  
 price 
 : 
  
 { 
  
 type 
 : 
  
 'REGULAR' 
 , 
  
 name 
 : 
  
 'Delivery Price' 
 , 
  
 state 
 : 
  
 'ACTUAL' 
 , 
  
 amount 
 : 
  
 { 
  
 currencyCode 
 : 
  
 'USD' 
 , 
  
 amountInMicros 
 : 
  
 2000000 
 , 
  
 }, 
  
 taxIncluded 
 : 
  
 true 
 , 
  
 }, 
  
 fulfillmentContact 
 : 
  
 { 
  
 email 
 : 
  
 'johnjohnson@gmail.com' 
 , 
  
 firstName 
 : 
  
 'John' 
 , 
  
 lastName 
 : 
  
 'Johnson' 
 , 
  
 displayName 
 : 
  
 'John Johnson' 
 , 
  
 }, 
  
 }, 
  
 purchaseLocationType 
 : 
  
 'ONLINE_PURCHASE' 
 , 
  
 }, 
 }; 
  

Java

 // Transaction Merchant 
 MerchantV3 
  
 transactionMerchant 
  
 = 
  
 new 
  
 MerchantV3 
 () 
  
 . 
 setId 
 ( 
 "http://www.example.com" 
 ) 
  
 . 
 setName 
 ( 
 "Example Merchant" 
 ); 
 // Line Item 
 PriceAttribute 
  
 itemPrice 
  
 = 
  
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "REGULAR" 
 ) 
  
 . 
 setName 
 ( 
 "Item Price" 
 ) 
  
 . 
 setState 
 ( 
 "ACTUAL" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 8990000L 
 ) 
  
 ) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 ); 
 PriceAttribute 
  
 totalItemPrice 
  
 = 
  
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "TOTAL" 
 ) 
  
 . 
 setName 
 ( 
 "Total Price" 
 ) 
  
 . 
 setState 
 ( 
 "ACTUAL" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 9990000L 
 ) 
  
 ) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 ); 
 // Purchase Item Extension 
 PurchaseItemExtension 
  
 purchaseItemExtension 
  
 = 
  
 new 
  
 PurchaseItemExtension 
 () 
  
 . 
 setQuantity 
 ( 
 1 
 ) 
  
 . 
 setUnitMeasure 
 ( 
 new 
  
 MerchantUnitMeasure 
 () 
  
 . 
 setMeasure 
 ( 
 1.0 
 ) 
  
 . 
 setUnit 
 ( 
 "POUND" 
 )) 
  
 . 
 setItemOptions 
 ( 
 Arrays 
 . 
 asList 
 ( 
 new 
  
 PurchaseItemExtensionItemOption 
 () 
  
 . 
 setId 
 ( 
 "ITEM_OPTION_ID" 
 ) 
  
 . 
 setName 
 ( 
 "Pepperoni" 
 ) 
  
 . 
 setPrices 
 ( 
 Arrays 
 . 
 asList 
 ( 
  
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "REGULAR" 
 ) 
  
 . 
 setState 
 ( 
 "ACTUAL" 
 ) 
  
 . 
 setName 
 ( 
 "Item Price" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 1000000L 
 )) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 ), 
  
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "TOTAL" 
 ) 
  
 . 
 setState 
 ( 
 "ACTUAL" 
 ) 
  
 . 
 setName 
 ( 
 "Total Price" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 1000000L 
 )) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 ) 
  
 )) 
  
 . 
 setNote 
 ( 
 "Extra pepperoni" 
 ) 
  
 . 
 setQuantity 
 ( 
 1 
 ))); 
 LineItemV3 
  
 lineItem 
  
 = 
  
 new 
  
 LineItemV3 
 () 
  
 . 
 setId 
 ( 
 "LINE_ITEM_ID" 
 ) 
  
 . 
 setName 
 ( 
 "Pizza" 
 ) 
  
 . 
 setDescription 
 ( 
 "A four cheese pizza." 
 ) 
  
 . 
 setPriceAttributes 
 ( 
 Arrays 
 . 
 asList 
 ( 
 itemPrice 
 , 
  
 totalItemPrice 
 )) 
  
 . 
 setNotes 
 ( 
 Collections 
 . 
 singletonList 
 ( 
 "Extra cheese." 
 )) 
  
 . 
 setPurchase 
 ( 
 purchaseItemExtension 
 ); 
 // Order Contents 
 OrderContents 
  
 contents 
  
 = 
  
 new 
  
 OrderContents 
 () 
  
 . 
 setLineItems 
 ( 
 Collections 
 . 
 singletonList 
 ( 
 lineItem 
 )); 
 // User Info 
 UserInfo 
  
 buyerInfo 
  
 = 
  
 new 
  
 UserInfo 
 () 
  
 . 
 setEmail 
 ( 
 "janedoe@gmail.com" 
 ) 
  
 . 
 setFirstName 
 ( 
 "Jane" 
 ) 
  
 . 
 setLastName 
 ( 
 "Doe" 
 ) 
  
 . 
 setDisplayName 
 ( 
 "Jane Doe" 
 ); 
 // Price Attributes 
 PriceAttribute 
  
 subTotal 
  
 = 
  
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "SUBTOTAL" 
 ) 
  
 . 
 setName 
 ( 
 "Subtotal" 
 ) 
  
 . 
 setState 
 ( 
 "ESTIMATE" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 9990000L 
 ) 
  
 ) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 ); 
 PriceAttribute 
  
 deliveryFee 
  
 = 
  
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "DELIVERY" 
 ) 
  
 . 
 setName 
 ( 
 "Delivery" 
 ) 
  
 . 
 setState 
 ( 
 "ACTUAL" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 2000000L 
 ) 
  
 ) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 ); 
 PriceAttribute 
  
 tax 
  
 = 
  
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "TAX" 
 ) 
  
 . 
 setName 
 ( 
 "Tax" 
 ) 
  
 . 
 setState 
 ( 
 "ESTIMATE" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 3780000L 
 ) 
  
 ) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 ); 
 PriceAttribute 
  
 totalPrice 
  
 = 
  
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "TOTAL" 
 ) 
  
 . 
 setName 
 ( 
 "Total Price" 
 ) 
  
 . 
 setState 
 ( 
 "ESTIMATE" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 15770000L 
 ) 
  
 ) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 ); 
 // Follow up actions 
 Action 
  
 viewDetails 
  
 = 
  
 new 
  
 Action 
 () 
  
 . 
 setType 
 ( 
 "VIEW_DETAILS" 
 ) 
  
 . 
 setTitle 
 ( 
 "View details" 
 ) 
  
 . 
 setOpenUrlAction 
 ( 
 new 
  
 OpenUrlAction 
 () 
  
 . 
 setUrl 
 ( 
 "https://example.com" 
 )); 
 Action 
  
 call 
  
 = 
  
 new 
  
 Action 
 () 
  
 . 
 setType 
 ( 
 "CALL" 
 ) 
  
 . 
 setTitle 
 ( 
 "Call us" 
 ) 
  
 . 
 setOpenUrlAction 
 ( 
 new 
  
 OpenUrlAction 
 () 
  
 . 
 setUrl 
 ( 
 "tel:+16501112222" 
 )); 
 Action 
  
 email 
  
 = 
  
 new 
  
 Action 
 () 
  
 . 
 setType 
 ( 
 "EMAIL" 
 ) 
  
 . 
 setTitle 
 ( 
 "Email us" 
 ) 
  
 . 
 setOpenUrlAction 
 ( 
 new 
  
 OpenUrlAction 
 () 
  
 . 
 setUrl 
 ( 
 "mailto:person@example.com" 
 )); 
 // Terms of service and order note 
 String 
  
 termsOfServiceUrl 
  
 = 
  
 "http://example.com" 
 ; 
 String 
  
 orderNote 
  
 = 
  
 "Sale event" 
 ; 
 // Promotions 
 PromotionV3 
  
 promotion 
  
 = 
  
 new 
  
 PromotionV3 
 () 
  
 . 
 setCoupon 
 ( 
 "COUPON_CODE" 
 ); 
 // Purchase Order Extension 
 Location 
  
 location 
  
 = 
  
 GSON_BUILDER 
 . 
 create 
 (). 
 fromJson 
 ( 
  
 ( 
 String 
 ) 
  
 conversationData 
 . 
 get 
 ( 
 "location" 
 ), 
  
 Location 
 . 
 class 
 ); 
 PurchaseOrderExtension 
  
 purchaseOrderExtension 
  
 = 
  
 new 
  
 PurchaseOrderExtension 
 () 
  
 . 
 setStatus 
 ( 
 "CREATED" 
 ) 
  
 . 
 setUserVisibleStatusLabel 
 ( 
 "CREATED" 
 ) 
  
 . 
 setType 
 ( 
 "FOOD" 
 ) 
  
 . 
 setReturnsInfo 
 ( 
 new 
  
 PurchaseReturnsInfo 
 () 
  
 . 
 setIsReturnable 
 ( 
 false 
 ) 
  
 . 
 setDaysToReturn 
 ( 
 1 
 ) 
  
 . 
 setPolicyUrl 
 ( 
 "https://example.com" 
 )) 
  
 . 
 setFulfillmentInfo 
 ( 
 new 
  
 PurchaseFulfillmentInfo 
 () 
  
 . 
 setId 
 ( 
 "FULFILLMENT_SERVICE_ID" 
 ) 
  
 . 
 setFulfillmentType 
 ( 
 "DELIVERY" 
 ) 
  
 . 
 setExpectedFulfillmentTime 
 ( 
 new 
  
 TimeV3 
 () 
  
 . 
 setTimeIso8601 
 ( 
 "2019-09-25T18:00:00.877Z" 
 )) 
  
 . 
 setLocation 
 ( 
 location 
 ) 
  
 . 
 setPrice 
 ( 
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "REGULAR" 
 ) 
  
 . 
 setName 
 ( 
 "Delivery price" 
 ) 
  
 . 
 setState 
 ( 
 "ACTUAL" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 2000000L 
 )) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 )) 
  
 . 
 setFulfillmentContact 
 ( 
 new 
  
 UserInfo 
 () 
  
 . 
 setEmail 
 ( 
 "johnjohnson@gmail.com" 
 ) 
  
 . 
 setFirstName 
 ( 
 "John" 
 ) 
  
 . 
 setLastName 
 ( 
 "Johnson" 
 ) 
  
 . 
 setDisplayName 
 ( 
 "John Johnson" 
 ))) 
  
 . 
 setPurchaseLocationType 
 ( 
 "ONLINE_PURCHASE" 
 ); 
 OrderV3 
  
 order 
  
 = 
  
 new 
  
 OrderV3 
 () 
  
 . 
 setCreateTime 
 ( 
 "2019-09-24T18:00:00.877Z" 
 ) 
  
 . 
 setLastUpdateTime 
 ( 
 "2019-09-24T18:00:00.877Z" 
 ) 
  
 . 
 setMerchantOrderId 
 ( 
 orderId 
 ) 
  
 . 
 setUserVisibleOrderId 
 ( 
 orderId 
 ) 
  
 . 
 setTransactionMerchant 
 ( 
 transactionMerchant 
 ) 
  
 . 
 setContents 
 ( 
 contents 
 ) 
  
 . 
 setBuyerInfo 
 ( 
 buyerInfo 
 ) 
  
 . 
 setPriceAttributes 
 ( 
 Arrays 
 . 
 asList 
 ( 
  
 subTotal 
 , 
  
 deliveryFee 
 , 
  
 tax 
 , 
  
 totalPrice 
  
 )) 
  
 . 
 setFollowUpActions 
 ( 
 Arrays 
 . 
 asList 
 ( 
  
 viewDetails 
 , 
  
 call 
 , 
  
 email 
  
 )) 
  
 . 
 setTermsOfServiceUrl 
 ( 
 termsOfServiceUrl 
 ) 
  
 . 
 setNote 
 ( 
 orderNote 
 ) 
  
 . 
 setPromotions 
 ( 
 Collections 
 . 
 singletonList 
 ( 
 promotion 
 )) 
  
 . 
 setPurchase 
 ( 
 purchaseOrderExtension 
 ); 
  

Java

 // Transaction Merchant 
 MerchantV3 
  
 transactionMerchant 
  
 = 
  
 new 
  
 MerchantV3 
 () 
  
 . 
 setId 
 ( 
 "http://www.example.com" 
 ) 
  
 . 
 setName 
 ( 
 "Example Merchant" 
 ); 
 // Line Item 
 PriceAttribute 
  
 itemPrice 
  
 = 
  
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "REGULAR" 
 ) 
  
 . 
 setName 
 ( 
 "Item Price" 
 ) 
  
 . 
 setState 
 ( 
 "ACTUAL" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 8990000L 
 ) 
  
 ) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 ); 
 PriceAttribute 
  
 totalItemPrice 
  
 = 
  
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "TOTAL" 
 ) 
  
 . 
 setName 
 ( 
 "Total Price" 
 ) 
  
 . 
 setState 
 ( 
 "ACTUAL" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 9990000L 
 ) 
  
 ) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 ); 
 // Purchase Item Extension 
 PurchaseItemExtension 
  
 purchaseItemExtension 
  
 = 
  
 new 
  
 PurchaseItemExtension 
 () 
  
 . 
 setUnitMeasure 
 ( 
 new 
  
 MerchantUnitMeasure 
 () 
  
 . 
 setMeasure 
 ( 
 1.0 
 ) 
  
 . 
 setUnit 
 ( 
 "POUND" 
 )) 
  
 . 
 setItemOptions 
 ( 
 Arrays 
 . 
 asList 
 ( 
 new 
  
 PurchaseItemExtensionItemOption 
 () 
  
 . 
 setId 
 ( 
 "ITEM_OPTION_ID" 
 ) 
  
 . 
 setName 
 ( 
 "Pepperoni" 
 ) 
  
 . 
 setPrices 
 ( 
 Arrays 
 . 
 asList 
 ( 
  
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "REGULAR" 
 ) 
  
 . 
 setState 
 ( 
 "ACTUAL" 
 ) 
  
 . 
 setName 
 ( 
 "Item Price" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 1000000L 
 )) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 ), 
  
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "TOTAL" 
 ) 
  
 . 
 setState 
 ( 
 "ACTUAL" 
 ) 
  
 . 
 setName 
 ( 
 "Total Price" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 1000000L 
 )) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 ) 
  
 )) 
  
 . 
 setNote 
 ( 
 "Extra pepperoni" 
 ))); 
 LineItemV3 
  
 lineItem 
  
 = 
  
 new 
  
 LineItemV3 
 () 
  
 . 
 setId 
 ( 
 "LINE_ITEM_ID" 
 ) 
  
 . 
 setName 
 ( 
 "Pizza" 
 ) 
  
 . 
 setDescription 
 ( 
 "A four cheese pizza." 
 ) 
  
 . 
 setPriceAttributes 
 ( 
 Arrays 
 . 
 asList 
 ( 
 itemPrice 
 , 
  
 totalItemPrice 
 )) 
  
 . 
 setNotes 
 ( 
 Collections 
 . 
 singletonList 
 ( 
 "Extra cheese." 
 )) 
  
 . 
 setPurchase 
 ( 
 purchaseItemExtension 
 ); 
 // Order Contents 
 OrderContents 
  
 contents 
  
 = 
  
 new 
  
 OrderContents 
 () 
  
 . 
 setLineItems 
 ( 
 Collections 
 . 
 singletonList 
 ( 
 lineItem 
 )); 
 // User Info 
 UserInfo 
  
 buyerInfo 
  
 = 
  
 new 
  
 UserInfo 
 () 
  
 . 
 setEmail 
 ( 
 "janedoe@gmail.com" 
 ) 
  
 . 
 setFirstName 
 ( 
 "Jane" 
 ) 
  
 . 
 setLastName 
 ( 
 "Doe" 
 ) 
  
 . 
 setDisplayName 
 ( 
 "Jane Doe" 
 ); 
 // Price Attributes 
 PriceAttribute 
  
 subTotal 
  
 = 
  
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "SUBTOTAL" 
 ) 
  
 . 
 setName 
 ( 
 "Subtotal" 
 ) 
  
 . 
 setState 
 ( 
 "ESTIMATE" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 9990000L 
 ) 
  
 ) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 ); 
 PriceAttribute 
  
 deliveryFee 
  
 = 
  
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "DELIVERY" 
 ) 
  
 . 
 setName 
 ( 
 "Delivery" 
 ) 
  
 . 
 setState 
 ( 
 "ACTUAL" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 2000000L 
 ) 
  
 ) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 ); 
 PriceAttribute 
  
 tax 
  
 = 
  
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "TAX" 
 ) 
  
 . 
 setName 
 ( 
 "Tax" 
 ) 
  
 . 
 setState 
 ( 
 "ESTIMATE" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 3780000L 
 ) 
  
 ) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 ); 
 PriceAttribute 
  
 totalPrice 
  
 = 
  
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "TOTAL" 
 ) 
  
 . 
 setName 
 ( 
 "Total Price" 
 ) 
  
 . 
 setState 
 ( 
 "ESTIMATE" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 15770000L 
 ) 
  
 ) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 ); 
 // Follow up actions 
 Action 
  
 viewDetails 
  
 = 
  
 new 
  
 Action 
 () 
  
 . 
 setType 
 ( 
 "VIEW_DETAILS" 
 ) 
  
 . 
 setTitle 
 ( 
 "View details" 
 ) 
  
 . 
 setOpenUrlAction 
 ( 
 new 
  
 OpenUrlAction 
 () 
  
 . 
 setUrl 
 ( 
 "https://example.com" 
 )); 
 Action 
  
 call 
  
 = 
  
 new 
  
 Action 
 () 
  
 . 
 setType 
 ( 
 "CALL" 
 ) 
  
 . 
 setTitle 
 ( 
 "Call us" 
 ) 
  
 . 
 setOpenUrlAction 
 ( 
 new 
  
 OpenUrlAction 
 () 
  
 . 
 setUrl 
 ( 
 "tel:+16501112222" 
 )); 
 Action 
  
 email 
  
 = 
  
 new 
  
 Action 
 () 
  
 . 
 setType 
 ( 
 "EMAIL" 
 ) 
  
 . 
 setTitle 
 ( 
 "Email us" 
 ) 
  
 . 
 setOpenUrlAction 
 ( 
 new 
  
 OpenUrlAction 
 () 
  
 . 
 setUrl 
 ( 
 "mailto:person@example.com" 
 )); 
 // Terms of service and order note 
 String 
  
 termsOfServiceUrl 
  
 = 
  
 "http://example.com" 
 ; 
 String 
  
 orderNote 
  
 = 
  
 "Sale event" 
 ; 
 // Promotions 
 PromotionV3 
  
 promotion 
  
 = 
  
 new 
  
 PromotionV3 
 () 
  
 . 
 setCoupon 
 ( 
 "COUPON_CODE" 
 ); 
 // Purchase Order Extension 
 Location 
  
 location 
  
 = 
  
 GSON_BUILDER 
 . 
 create 
 (). 
 fromJson 
 ( 
  
 ( 
 String 
 ) 
  
 conversationData 
 . 
 get 
 ( 
 "location" 
 ), 
  
 Location 
 . 
 class 
 ); 
 PurchaseOrderExtension 
  
 purchaseOrderExtension 
  
 = 
  
 new 
  
 PurchaseOrderExtension 
 () 
  
 . 
 setStatus 
 ( 
 "CREATED" 
 ) 
  
 . 
 setUserVisibleStatusLabel 
 ( 
 "CREATED" 
 ) 
  
 . 
 setType 
 ( 
 "FOOD" 
 ) 
  
 . 
 setReturnsInfo 
 ( 
 new 
  
 PurchaseReturnsInfo 
 () 
  
 . 
 setIsReturnable 
 ( 
 false 
 ) 
  
 . 
 setDaysToReturn 
 ( 
 1 
 ) 
  
 . 
 setPolicyUrl 
 ( 
 "https://example.com" 
 )) 
  
 . 
 setFulfillmentInfo 
 ( 
 new 
  
 PurchaseFulfillmentInfo 
 () 
  
 . 
 setId 
 ( 
 "FULFILLMENT_SERVICE_ID" 
 ) 
  
 . 
 setFulfillmentType 
 ( 
 "DELIVERY" 
 ) 
  
 . 
 setExpectedFulfillmentTime 
 ( 
 new 
  
 TimeV3 
 () 
  
 . 
 setTimeIso8601 
 ( 
 "2019-09-25T18:00:00.877Z" 
 )) 
  
 . 
 setLocation 
 ( 
 location 
 ) 
  
 . 
 setPrice 
 ( 
 new 
  
 PriceAttribute 
 () 
  
 . 
 setType 
 ( 
 "REGULAR" 
 ) 
  
 . 
 setName 
 ( 
 "Delivery price" 
 ) 
  
 . 
 setState 
 ( 
 "ACTUAL" 
 ) 
  
 . 
 setAmount 
 ( 
 new 
  
 MoneyV3 
 () 
  
 . 
 setCurrencyCode 
 ( 
 "USD" 
 ) 
  
 . 
 setAmountInMicros 
 ( 
 2000000L 
 )) 
  
 . 
 setTaxIncluded 
 ( 
 true 
 )) 
  
 . 
 setFulfillmentContact 
 ( 
 new 
  
 UserInfo 
 () 
  
 . 
 setEmail 
 ( 
 "johnjohnson@gmail.com" 
 ) 
  
 . 
 setFirstName 
 ( 
 "John" 
 ) 
  
 . 
 setLastName 
 ( 
 "Johnson" 
 ) 
  
 . 
 setDisplayName 
 ( 
 "John Johnson" 
 ))) 
  
 . 
 setPurchaseLocationType 
 ( 
 "ONLINE_PURCHASE" 
 ); 
 OrderV3 
  
 order 
  
 = 
  
 new 
  
 OrderV3 
 () 
  
 . 
 setCreateTime 
 ( 
 "2019-09-24T18:00:00.877Z" 
 ) 
  
 . 
 setLastUpdateTime 
 ( 
 "2019-09-24T18:00:00.877Z" 
 ) 
  
 . 
 setMerchantOrderId 
 ( 
 orderId 
 ) 
  
 . 
 setUserVisibleOrderId 
 ( 
 orderId 
 ) 
  
 . 
 setTransactionMerchant 
 ( 
 transactionMerchant 
 ) 
  
 . 
 setContents 
 ( 
 contents 
 ) 
  
 . 
 setBuyerInfo 
 ( 
 buyerInfo 
 ) 
  
 . 
 setPriceAttributes 
 ( 
 Arrays 
 . 
 asList 
 ( 
  
 subTotal 
 , 
  
 deliveryFee 
 , 
  
 tax 
 , 
  
 totalPrice 
  
 )) 
  
 . 
 setFollowUpActions 
 ( 
 Arrays 
 . 
 asList 
 ( 
  
 viewDetails 
 , 
  
 call 
 , 
  
 email 
  
 )) 
  
 . 
 setTermsOfServiceUrl 
 ( 
 termsOfServiceUrl 
 ) 
  
 . 
 setNote 
 ( 
 orderNote 
 ) 
  
 . 
 setPromotions 
 ( 
 Collections 
 . 
 singletonList 
 ( 
 promotion 
 )) 
  
 . 
 setPurchase 
 ( 
 purchaseOrderExtension 
 ); 
  

When using your own payment method to charge the user, we recommend linking their Google account with an account they have with your own service to retrieve, present, and charge payment methods stored there.

We provide OAuth 2.0 account linking to satisfy this requirement. We highly recommend enabling the OAuth 2.0 Assertion flow as it enables a very streamlined user experience.

We provide the actions.intent.SIGN_IN intent which allows you to request that a user link accounts mid-conversation. You must enable account linking in the Actions Console to use the actions.intent.SIGN_IN intent.

You should use this intent if you are unable to find an accessToken in the User object in the webhook request. This means that the user has not yet linked their account.

After requesting the actions.intent.SIGN_IN intent, you will receive an Argument containing a SignInStatus with a value of either "OK" , "CANCELLED" , or "ERROR" . If the status is "OK" you should be able to find an accessToken in the User object.

Fulfillment

4. Propose the order

Once you've built an order, you must present it to the user to confirm or reject. Request the actions.intent.TRANSACTION_DECISION intent and provide the order that you built with the user's stored payment information.

User Experience

When you request the actions.intent.TRANSACTION_DECISION intent, the Assistant initiates a built-in experience in which the Order you passed is rendered directly onto a "cart preview card". The user can say "place order", decline the transaction, change a payment option like the credit card or address, or request to change the order's contents.

The user may also request changes to the order at this point. In this case, you should make sure your fulfillment can handle order change requests after finishing the cart assembly experience.

Fulfillment

When you request the actions.intent.TRANSACTION_DECISION intent, you'll create a TransactionDecision that contains the Order as well as orderOptions and paymentParameters . Your paymentParameters object includes a merchantPaymentOption with fields that describe the user's payment method.

The following code shows an example TransactionsDecision for an order, paid using a Visa credit card:

Node.js

 conv 
 . 
 ask 
 ( 
 new 
  
 TransactionDecision 
 ({ 
  
 orderOptions 
 : 
  
 { 
  
 userInfoOptions 
 : 
  
 { 
  
 userInfoProperties 
 : 
  
 [ 
  
 'EMAIL' 
 , 
  
 ], 
  
 }, 
  
 }, 
  
 paymentParameters 
 : 
  
 { 
  
 merchantPaymentOption 
 : 
  
 { 
  
 defaultMerchantPaymentMethodId 
 : 
  
 '12345678' 
 , 
  
 managePaymentMethodUrl 
 : 
  
 'https://example.com/managePayment' 
 , 
  
 merchantPaymentMethod 
 : 
  
 [ 
  
 { 
  
 paymentMethodDisplayInfo 
 : 
  
 { 
  
 paymentMethodDisplayName 
 : 
  
 'VISA **** 1234' 
 , 
  
 paymentType 
 : 
  
 'PAYMENT_CARD' 
 , 
  
 }, 
  
 paymentMethodGroup 
 : 
  
 'Payment method group' 
 , 
  
 paymentMethodId 
 : 
  
 '12345678' 
 , 
  
 paymentMethodStatus 
 : 
  
 { 
  
 status 
 : 
  
 'STATUS_OK' 
 , 
  
 statusMessage 
 : 
  
 'Status message' 
 , 
  
 }, 
  
 }, 
  
 ], 
  
 }, 
  
 }, 
  
 presentationOptions 
 : 
  
 { 
  
 actionDisplayName 
 : 
  
 'PLACE_ORDER' 
 , 
  
 }, 
  
 order 
 : 
  
 order 
 , 
 })); 
  

Node.js

 conv 
 . 
 ask 
 ( 
 new 
  
 TransactionDecision 
 ({ 
  
 orderOptions 
 : 
  
 { 
  
 userInfoOptions 
 : 
  
 { 
  
 userInfoProperties 
 : 
  
 [ 
  
 'EMAIL' 
 , 
  
 ], 
  
 }, 
  
 }, 
  
 paymentParameters 
 : 
  
 { 
  
 merchantPaymentOption 
 : 
  
 { 
  
 defaultMerchantPaymentMethodId 
 : 
  
 '12345678' 
 , 
  
 managePaymentMethodUrl 
 : 
  
 'https://example.com/managePayment' 
 , 
  
 merchantPaymentMethod 
 : 
  
 [ 
  
 { 
  
 paymentMethodDisplayInfo 
 : 
  
 { 
  
 paymentMethodDisplayName 
 : 
  
 'VISA **** 1234' 
 , 
  
 paymentType 
 : 
  
 'PAYMENT_CARD' 
 , 
  
 }, 
  
 paymentMethodGroup 
 : 
  
 'Payment method group' 
 , 
  
 paymentMethodId 
 : 
  
 '12345678' 
 , 
  
 paymentMethodStatus 
 : 
  
 { 
  
 status 
 : 
  
 'STATUS_OK' 
 , 
  
 statusMessage 
 : 
  
 'Status message' 
 , 
  
 }, 
  
 }, 
  
 ], 
  
 }, 
  
 }, 
  
 presentationOptions 
 : 
  
 { 
  
 actionDisplayName 
 : 
  
 'PLACE_ORDER' 
 , 
  
 }, 
  
 order 
 : 
  
 order 
 , 
 })); 
  

Java

 // Create order options 
 OrderOptionsV3 
  
 orderOptions 
  
 = 
  
 new 
  
 OrderOptionsV3 
 () 
  
 . 
 setUserInfoOptions 
 ( 
 new 
  
 UserInfoOptions 
 () 
  
 . 
 setUserInfoProperties 
 ( 
 Collections 
 . 
 singletonList 
 ( 
 "EMAIL" 
 ))); 
 // Create presentation options 
 PresentationOptionsV3 
  
 presentationOptions 
  
 = 
  
 new 
  
 PresentationOptionsV3 
 () 
  
 . 
 setActionDisplayName 
 ( 
 "PLACE_ORDER" 
 ); 
 // Create payment parameters 
 MerchantPaymentMethod 
  
 merchantPaymentMethod 
  
 = 
  
 new 
  
 MerchantPaymentMethod 
 () 
  
 . 
 setPaymentMethodDisplayInfo 
 ( 
 new 
  
 PaymentMethodDisplayInfo 
 () 
  
 . 
 setPaymentMethodDisplayName 
 ( 
 "VISA **** 1234" 
 ) 
  
 . 
 setPaymentType 
 ( 
 "PAYMENT_CARD" 
 )) 
  
 . 
 setPaymentMethodGroup 
 ( 
 "Payment method group" 
 ) 
  
 . 
 setPaymentMethodId 
 ( 
 "12345678" 
 ) 
  
 . 
 setPaymentMethodStatus 
 ( 
 new 
  
 PaymentMethodStatus 
 () 
  
 . 
 setStatus 
 ( 
 "STATUS_OK" 
 ) 
  
 . 
 setStatusMessage 
 ( 
 "Status message" 
 )); 
 MerchantPaymentOption 
  
 merchantPaymentOption 
  
 = 
  
 new 
  
 MerchantPaymentOption 
 () 
  
 . 
 setDefaultMerchantPaymentMethodId 
 ( 
 "12345678" 
 ) 
  
 . 
 setManagePaymentMethodUrl 
 ( 
 "https://example.com/managePayment" 
 ) 
  
 . 
 setMerchantPaymentMethod 
 ( 
 Collections 
 . 
 singletonList 
 ( 
 merchantPaymentMethod 
 )); 
 paymentParameters 
 . 
 setMerchantPaymentOption 
 ( 
 merchantPaymentOption 
 ); 
 return 
  
 getResponseBuilder 
 ( 
 request 
 ) 
  
 . 
 add 
 ( 
 new 
  
 TransactionDecision 
 () 
  
 . 
 setOrder 
 ( 
 order 
 ) 
  
 . 
 setOrderOptions 
 ( 
 orderOptions 
 ) 
  
 . 
 setPresentationOptions 
 ( 
 presentationOptions 
 ) 
  
 . 
 setPaymentParameters 
 ( 
 paymentParameters 
 ) 
  
 ) 
  
 . 
 build 
 (); 
  

Java

 // Create order options 
 OrderOptionsV3 
  
 orderOptions 
  
 = 
  
 new 
  
 OrderOptionsV3 
 () 
  
 . 
 setUserInfoOptions 
 ( 
 new 
  
 UserInfoOptions 
 () 
  
 . 
 setUserInfoProperties 
 ( 
 Collections 
 . 
 singletonList 
 ( 
 "EMAIL" 
 ))); 
 // Create presentation options 
 PresentationOptionsV3 
  
 presentationOptions 
  
 = 
  
 new 
  
 PresentationOptionsV3 
 () 
  
 . 
 setActionDisplayName 
 ( 
 "PLACE_ORDER" 
 ); 
 // Create payment parameters 
 MerchantPaymentMethod 
  
 merchantPaymentMethod 
  
 = 
  
 new 
  
 MerchantPaymentMethod 
 () 
  
 . 
 setPaymentMethodDisplayInfo 
 ( 
 new 
  
 PaymentMethodDisplayInfo 
 () 
  
 . 
 setPaymentMethodDisplayName 
 ( 
 "VISA **** 1234" 
 ) 
  
 . 
 setPaymentType 
 ( 
 "PAYMENT_CARD" 
 )) 
  
 . 
 setPaymentMethodGroup 
 ( 
 "Payment method group" 
 ) 
  
 . 
 setPaymentMethodId 
 ( 
 "12345678" 
 ) 
  
 . 
 setPaymentMethodStatus 
 ( 
 new 
  
 PaymentMethodStatus 
 () 
  
 . 
 setStatus 
 ( 
 "STATUS_OK" 
 ) 
  
 . 
 setStatusMessage 
 ( 
 "Status message" 
 )); 
 MerchantPaymentOption 
  
 merchantPaymentOption 
  
 = 
  
 new 
  
 MerchantPaymentOption 
 () 
  
 . 
 setDefaultMerchantPaymentMethodId 
 ( 
 "12345678" 
 ) 
  
 . 
 setManagePaymentMethodUrl 
 ( 
 "https://example.com/managePayment" 
 ) 
  
 . 
 setMerchantPaymentMethod 
 ( 
 Collections 
 . 
 singletonList 
 ( 
 merchantPaymentMethod 
 )); 
 paymentParameters 
 . 
 setMerchantPaymentOption 
 ( 
 merchantPaymentOption 
 ); 
 return 
  
 getResponseBuilder 
 ( 
 request 
 ) 
  
 . 
 add 
 ( 
 new 
  
 TransactionDecision 
 () 
  
 . 
 setOrder 
 ( 
 order 
 ) 
  
 . 
 setOrderOptions 
 ( 
 orderOptions 
 ) 
  
 . 
 setPresentationOptions 
 ( 
 presentationOptions 
 ) 
  
 . 
 setPaymentParameters 
 ( 
 paymentParameters 
 ) 
  
 ) 
  
 . 
 build 
 (); 
  

JSON

 { 
 "payload" 
 : 
 { 
 "google" 
 : 
 { 
 "expectUserResponse" 
 : 
 true 
 , 
 "richResponse" 
 : 
 { 
 "items" 
 : 
 [ 
 { 
 "simpleResponse" 
 : 
 { 
 "textToSpeech" 
 : 
 "Transaction Decision Placeholder." 
 } 
 } 
 ] 
 }, 
 "systemIntent" 
 : 
 { 
 "intent" 
 : 
 "actions.intent.TRANSACTION_DECISION" 
 , 
 "data" 
 : 
 { 
 "@type" 
 : 
 "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec" 
 , 
 "orderOptions" 
 : 
 { 
 "userInfoOptions" 
 : 
 { 
 "userInfoProperties" 
 : 
 [ 
 "EMAIL" 
 ] 
 } 
 }, 
 "paymentParameters" 
 : 
 { 
 "merchantPaymentOption" 
 : 
 { 
 "defaultMerchantPaymentMethodId" 
 : 
 "12345678" 
 , 
 "managePaymentMethodUrl" 
 : 
 "https://example.com/managePayment" 
 , 
 "merchantPaymentMethod" 
 : 
 [ 
 { 
 "paymentMethodDisplayInfo" 
 : 
 { 
 "paymentMethodDisplayName" 
 : 
 "VISA **** 1234" 
 , 
 "paymentType" 
 : 
 "PAYMENT_CARD" 
 }, 
 "paymentMethodGroup" 
 : 
 "Payment method group" 
 , 
 "paymentMethodId" 
 : 
 "12345678" 
 , 
 "paymentMethodStatus" 
 : 
 { 
 "status" 
 : 
 "STATUS_OK" 
 , 
 "statusMessage" 
 : 
 "Status message" 
 } 
 } 
 ] 
 } 
 }, 
 "presentationOptions" 
 : 
 { 
 "actionDisplayName" 
 : 
 "PLACE_ORDER" 
 }, 
 "order" 
 : 
 { 
 "createTime" 
 : 
 "2019-09-24T18:00:00.877Z" 
 , 
 "lastUpdateTime" 
 : 
 "2019-09-24T18:00:00.877Z" 
 , 
 "merchantOrderId" 
 : 
 "ORDER_ID" 
 , 
 "userVisibleOrderId" 
 : 
 "ORDER_ID" 
 , 
 "transactionMerchant" 
 : 
 { 
 "id" 
 : 
 "http://www.example.com" 
 , 
 "name" 
 : 
 "Example Merchant" 
 }, 
 "contents" 
 : 
 { 
 "lineItems" 
 : 
 [ 
 { 
 "id" 
 : 
 "LINE_ITEM_ID" 
 , 
 "name" 
 : 
 "Pizza" 
 , 
 "description" 
 : 
 "A four cheese pizza." 
 , 
 "priceAttributes" 
 : 
 [ 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Item Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 8990000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 9990000 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "notes" 
 : 
 [ 
 "Extra cheese." 
 ], 
 "purchase" 
 : 
 { 
 "quantity" 
 : 
 1 
 , 
 "unitMeasure" 
 : 
 { 
 "measure" 
 : 
 1 
 , 
 "unit" 
 : 
 "POUND" 
 }, 
 "itemOptions" 
 : 
 [ 
 { 
 "id" 
 : 
 "ITEM_OPTION_ID" 
 , 
 "name" 
 : 
 "Pepperoni" 
 , 
 "prices" 
 : 
 [ 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "name" 
 : 
 "Item Price" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 1000000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 1000000 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "note" 
 : 
 "Extra pepperoni" 
 , 
 "quantity" 
 : 
 1 
 , 
 "subOptions" 
 : 
 [] 
 } 
 ] 
 } 
 } 
 ] 
 }, 
 "buyerInfo" 
 : 
 { 
 "email" 
 : 
 "janedoe@gmail.com" 
 , 
 "firstName" 
 : 
 "Jane" 
 , 
 "lastName" 
 : 
 "Doe" 
 , 
 "displayName" 
 : 
 "Jane Doe" 
 }, 
 "priceAttributes" 
 : 
 [ 
 { 
 "type" 
 : 
 "SUBTOTAL" 
 , 
 "name" 
 : 
 "Subtotal" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 9990000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "DELIVERY" 
 , 
 "name" 
 : 
 "Delivery" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 2000000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TAX" 
 , 
 "name" 
 : 
 "Tax" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 3780000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 15770000 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "followUpActions" 
 : 
 [ 
 { 
 "type" 
 : 
 "VIEW_DETAILS" 
 , 
 "title" 
 : 
 "View details" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "http://example.com" 
 } 
 }, 
 { 
 "type" 
 : 
 "CALL" 
 , 
 "title" 
 : 
 "Call us" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "tel:+16501112222" 
 } 
 }, 
 { 
 "type" 
 : 
 "EMAIL" 
 , 
 "title" 
 : 
 "Email us" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "mailto:person@example.com" 
 } 
 } 
 ], 
 "termsOfServiceUrl" 
 : 
 "http://www.example.com" 
 , 
 "note" 
 : 
 "Sale event" 
 , 
 "promotions" 
 : 
 [ 
 { 
 "coupon" 
 : 
 "COUPON_CODE" 
 } 
 ], 
 "purchase" 
 : 
 { 
 "status" 
 : 
 "CREATED" 
 , 
 "userVisibleStatusLabel" 
 : 
 "CREATED" 
 , 
 "type" 
 : 
 "FOOD" 
 , 
 "returnsInfo" 
 : 
 { 
 "isReturnable" 
 : 
 false 
 , 
 "daysToReturn" 
 : 
 1 
 , 
 "policyUrl" 
 : 
 "http://www.example.com" 
 }, 
 "fulfillmentInfo" 
 : 
 { 
 "id" 
 : 
 "FULFILLMENT_SERVICE_ID" 
 , 
 "fulfillmentType" 
 : 
 "DELIVERY" 
 , 
 "expectedFulfillmentTime" 
 : 
 { 
 "timeIso8601" 
 : 
 "2019-09-25T18:00:00.877Z" 
 }, 
 "location" 
 : 
 { 
 "city" 
 : 
 "MOUNTAIN VIEW" 
 , 
 "coordinates" 
 : 
 { 
 "latitude" 
 : 
 37.432524 
 , 
 "longitude" 
 : 
 - 
 122.098545 
 }, 
 "phoneNumber" 
 : 
 "+1 123-456-7890" 
 , 
 "postalAddress" 
 : 
 { 
 "addressLines" 
 : 
 [ 
 "1600 AMPHITHEATRE PKWY" 
 ], 
 "administrativeArea" 
 : 
 "CA" 
 , 
 "locality" 
 : 
 "MOUNTAIN VIEW" 
 , 
 "postalCode" 
 : 
 "94043-1351" 
 , 
 "recipients" 
 : 
 [ 
 "John Doe" 
 ], 
 "regionCode" 
 : 
 "US" 
 }, 
 "zipCode" 
 : 
 "94043-1351" 
 }, 
 "price" 
 : 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Delivery Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 2000000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 "fulfillmentContact" 
 : 
 { 
 "email" 
 : 
 "johnjohnson@gmail.com" 
 , 
 "firstName" 
 : 
 "John" 
 , 
 "lastName" 
 : 
 "Johnson" 
 , 
 "displayName" 
 : 
 "John Johnson" 
 } 
 }, 
 "purchaseLocationType" 
 : 
 "ONLINE_PURCHASE" 
 } 
 } 
 } 
 } 
 } 
 }, 
 "outputContexts" 
 : 
 [ 
 { 
 "name" 
 : 
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/_actions_on_google" 
 , 
 "lifespanCount" 
 : 
 99 
 , 
 "parameters" 
 : 
 { 
 "data" 
 : 
 "{\"location\":{\"coordinates\":{\"latitude\":37.432524,\"longitude\":-122.098545},\"zipCode\":\"94043-1351\",\"city\":\"MOUNTAIN VIEW\",\"postalAddress\":{\"regionCode\":\"US\",\"postalCode\":\"94043-1351\",\"administrativeArea\":\"CA\",\"locality\":\"MOUNTAIN VIEW\",\"addressLines\":[\"1600 AMPHITHEATRE PKWY\"],\"recipients\":[\"John Doe\"]},\"phoneNumber\":\"+1 123-456-7890\"},\"latestOrderId\":\"ORDER_ID\"}" 
 } 
 } 
 ] 
 } 
  

JSON

 { 
 "expectUserResponse" 
 : 
 true 
 , 
 "expectedInputs" 
 : 
 [ 
 { 
 "possibleIntents" 
 : 
 [ 
 { 
 "intent" 
 : 
 "actions.intent.TRANSACTION_DECISION" 
 , 
 "inputValueData" 
 : 
 { 
 "@type" 
 : 
 "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec" 
 , 
 "orderOptions" 
 : 
 { 
 "userInfoOptions" 
 : 
 { 
 "userInfoProperties" 
 : 
 [ 
 "EMAIL" 
 ] 
 } 
 }, 
 "paymentParameters" 
 : 
 { 
 "merchantPaymentOption" 
 : 
 { 
 "defaultMerchantPaymentMethodId" 
 : 
 "12345678" 
 , 
 "managePaymentMethodUrl" 
 : 
 "https://example.com/managePayment" 
 , 
 "merchantPaymentMethod" 
 : 
 [ 
 { 
 "paymentMethodDisplayInfo" 
 : 
 { 
 "paymentMethodDisplayName" 
 : 
 "VISA **** 1234" 
 , 
 "paymentType" 
 : 
 "PAYMENT_CARD" 
 }, 
 "paymentMethodGroup" 
 : 
 "Payment method group" 
 , 
 "paymentMethodId" 
 : 
 "12345678" 
 , 
 "paymentMethodStatus" 
 : 
 { 
 "status" 
 : 
 "STATUS_OK" 
 , 
 "statusMessage" 
 : 
 "Status message" 
 } 
 } 
 ] 
 } 
 }, 
 "presentationOptions" 
 : 
 { 
 "actionDisplayName" 
 : 
 "PLACE_ORDER" 
 }, 
 "order" 
 : 
 { 
 "createTime" 
 : 
 "2019-09-24T18:00:00.877Z" 
 , 
 "lastUpdateTime" 
 : 
 "2019-09-24T18:00:00.877Z" 
 , 
 "merchantOrderId" 
 : 
 "ORDER_ID" 
 , 
 "userVisibleOrderId" 
 : 
 "ORDER_ID" 
 , 
 "transactionMerchant" 
 : 
 { 
 "id" 
 : 
 "http://www.example.com" 
 , 
 "name" 
 : 
 "Example Merchant" 
 }, 
 "contents" 
 : 
 { 
 "lineItems" 
 : 
 [ 
 { 
 "id" 
 : 
 "LINE_ITEM_ID" 
 , 
 "name" 
 : 
 "Pizza" 
 , 
 "description" 
 : 
 "A four cheese pizza." 
 , 
 "priceAttributes" 
 : 
 [ 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Item Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 8990000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 9990000 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "notes" 
 : 
 [ 
 "Extra cheese." 
 ], 
 "purchase" 
 : 
 { 
 "quantity" 
 : 
 1 
 , 
 "unitMeasure" 
 : 
 { 
 "measure" 
 : 
 1 
 , 
 "unit" 
 : 
 "POUND" 
 }, 
 "itemOptions" 
 : 
 [ 
 { 
 "id" 
 : 
 "ITEM_OPTION_ID" 
 , 
 "name" 
 : 
 "Pepperoni" 
 , 
 "prices" 
 : 
 [ 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "name" 
 : 
 "Item Price" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 1000000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 1000000 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "note" 
 : 
 "Extra pepperoni" 
 , 
 "quantity" 
 : 
 1 
 , 
 "subOptions" 
 : 
 [] 
 } 
 ] 
 } 
 } 
 ] 
 }, 
 "buyerInfo" 
 : 
 { 
 "email" 
 : 
 "janedoe@gmail.com" 
 , 
 "firstName" 
 : 
 "Jane" 
 , 
 "lastName" 
 : 
 "Doe" 
 , 
 "displayName" 
 : 
 "Jane Doe" 
 }, 
 "priceAttributes" 
 : 
 [ 
 { 
 "type" 
 : 
 "SUBTOTAL" 
 , 
 "name" 
 : 
 "Subtotal" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 9990000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "DELIVERY" 
 , 
 "name" 
 : 
 "Delivery" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 2000000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TAX" 
 , 
 "name" 
 : 
 "Tax" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 3780000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 15770000 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "followUpActions" 
 : 
 [ 
 { 
 "type" 
 : 
 "VIEW_DETAILS" 
 , 
 "title" 
 : 
 "View details" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "http://example.com" 
 } 
 }, 
 { 
 "type" 
 : 
 "CALL" 
 , 
 "title" 
 : 
 "Call us" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "tel:+16501112222" 
 } 
 }, 
 { 
 "type" 
 : 
 "EMAIL" 
 , 
 "title" 
 : 
 "Email us" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "mailto:person@example.com" 
 } 
 } 
 ], 
 "termsOfServiceUrl" 
 : 
 "http://www.example.com" 
 , 
 "note" 
 : 
 "Sale event" 
 , 
 "promotions" 
 : 
 [ 
 { 
 "coupon" 
 : 
 "COUPON_CODE" 
 } 
 ], 
 "purchase" 
 : 
 { 
 "status" 
 : 
 "CREATED" 
 , 
 "userVisibleStatusLabel" 
 : 
 "CREATED" 
 , 
 "type" 
 : 
 "FOOD" 
 , 
 "returnsInfo" 
 : 
 { 
 "isReturnable" 
 : 
 false 
 , 
 "daysToReturn" 
 : 
 1 
 , 
 "policyUrl" 
 : 
 "http://www.example.com" 
 }, 
 "fulfillmentInfo" 
 : 
 { 
 "id" 
 : 
 "FULFILLMENT_SERVICE_ID" 
 , 
 "fulfillmentType" 
 : 
 "DELIVERY" 
 , 
 "expectedFulfillmentTime" 
 : 
 { 
 "timeIso8601" 
 : 
 "2019-09-25T18:00:00.877Z" 
 }, 
 "location" 
 : 
 { 
 "coordinates" 
 : 
 { 
 "latitude" 
 : 
 37.421578499999995 
 , 
 "longitude" 
 : 
 - 
 122.0837816 
 }, 
 "zipCode" 
 : 
 "94043-1351" 
 , 
 "city" 
 : 
 "MOUNTAIN VIEW" 
 , 
 "postalAddress" 
 : 
 { 
 "regionCode" 
 : 
 "US" 
 , 
 "postalCode" 
 : 
 "94043-1351" 
 , 
 "administrativeArea" 
 : 
 "CA" 
 , 
 "locality" 
 : 
 "MOUNTAIN VIEW" 
 , 
 "addressLines" 
 : 
 [ 
 "1600 AMPHITHEATRE PKWY" 
 ], 
 "recipients" 
 : 
 [ 
 "John Doe" 
 ] 
 }, 
 "phoneNumber" 
 : 
 "+1 123-456-7890" 
 }, 
 "price" 
 : 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Delivery Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 2000000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 "fulfillmentContact" 
 : 
 { 
 "email" 
 : 
 "johnjohnson@gmail.com" 
 , 
 "firstName" 
 : 
 "John" 
 , 
 "lastName" 
 : 
 "Johnson" 
 , 
 "displayName" 
 : 
 "John Johnson" 
 } 
 }, 
 "purchaseLocationType" 
 : 
 "ONLINE_PURCHASE" 
 } 
 } 
 } 
 } 
 ], 
 "inputPrompt" 
 : 
 { 
 "richInitialPrompt" 
 : 
 { 
 "items" 
 : 
 [ 
 { 
 "simpleResponse" 
 : 
 { 
 "textToSpeech" 
 : 
 "Transaction Decision Placeholder." 
 } 
 } 
 ] 
 } 
 } 
 } 
 ], 
 "conversationToken" 
 : 
 "{\"data\":{\"paymentType\":\"merchant_payment\",\"location\":{\"coordinates\":{\"latitude\":37.421578499999995,\"longitude\":-122.0837816},\"zipCode\":\"94043-1351\",\"city\":\"MOUNTAIN VIEW\",\"postalAddress\":{\"regionCode\":\"US\",\"postalCode\":\"94043-1351\",\"administrativeArea\":\"CA\",\"locality\":\"MOUNTAIN VIEW\",\"addressLines\":[\"1600 AMPHITHEATRE PKWY\"],\"recipients\":[\"John Doe\"]},\"phoneNumber\":\"+1 123-456-7890\"},\"latestOrderId\":\"ORDER_ID\"}}" 
 } 
  

Handle the user's decision

After the Assistant fulfills the intent, it sends your fulfillment a request with the actions_intent_TRANSACTION_DECISION intent with the user's answer to the transaction decision. You will receive an Argument containing a TransactionDecisionValue. This value will contain the following:

  • transactionDecision - The user's decision regarding the proposed order. The possible values are ORDER_ACCEPTED , ORDER_REJECTED , DELIVERY_ADDRESS_UPDATED , CART_CHANGE_REQUESTED , and USER_CANNOT_TRANSACT .
  • deliveryAddress - An updated delivery address, in the event that the user changed their delivery address. In this case, the value of transactionDecision will be DELIVERY_ADDRESS_UPDATED .

To properly handle this request, declare a Dialogflow intent that's triggered by the actions_intent_TRANSACTION_DECISION event. When triggered, handle it in your fulfillment:

Node.js

 const 
  
 arg 
  
 = 
  
 conv 
 . 
 arguments 
 . 
 get 
 ( 
 'TRANSACTION_DECISION_VALUE' 
 ); 
 if 
  
 ( 
 arg 
 && 
 arg 
 . 
 transactionDecision 
  
 === 
  
 'ORDER_ACCEPTED' 
 ) 
  
 { 
  
 console 
 . 
 log 
 ( 
 'Order accepted.' 
 ); 
  
 const 
  
 order 
  
 = 
  
 arg 
 . 
 order 
 ; 
 } 
  

Node.js

 const 
  
 arg 
  
 = 
  
 conv 
 . 
 arguments 
 . 
 get 
 ( 
 'TRANSACTION_DECISION_VALUE' 
 ); 
 if 
  
 ( 
 arg 
 && 
 arg 
 . 
 transactionDecision 
  
 === 
  
 'ORDER_ACCEPTED' 
 ) 
  
 { 
  
 console 
 . 
 log 
 ( 
 'Order accepted.' 
 ); 
  
 const 
  
 order 
  
 = 
  
 arg 
 . 
 order 
 ; 
 } 
  

Java

 // Check transaction decision value 
 Argument 
  
 transactionDecisionValue 
  
 = 
  
 request 
  
 . 
 getArgument 
 ( 
 "TRANSACTION_DECISION_VALUE" 
 ); 
 Map<String 
 , 
  
 Object 
>  
 extension 
  
 = 
  
 null 
 ; 
 if 
  
 ( 
 transactionDecisionValue 
  
 != 
  
 null 
 ) 
  
 { 
  
 extension 
  
 = 
  
 transactionDecisionValue 
 . 
 getExtension 
 (); 
 } 
 String 
  
 transactionDecision 
  
 = 
  
 null 
 ; 
 if 
  
 ( 
 extension 
  
 != 
  
 null 
 ) 
  
 { 
  
 transactionDecision 
  
 = 
  
 ( 
 String 
 ) 
  
 extension 
 . 
 get 
 ( 
 "transactionDecision" 
 ); 
 } 
 ResponseBuilder 
  
 responseBuilder 
  
 = 
  
 getResponseBuilder 
 ( 
 request 
 ); 
 if 
  
 (( 
 transactionDecision 
  
 != 
  
 null 
 && 
 transactionDecision 
 . 
 equals 
 ( 
 "ORDER_ACCEPTED" 
 ))) 
  
 { 
  
 OrderV3 
  
 order 
  
 = 
  
 (( 
 OrderV3 
 ) 
  
 extension 
 . 
 get 
 ( 
 "order" 
 )); 
 } 
  

Java

 // Check transaction decision value 
 Argument 
  
 transactionDecisionValue 
  
 = 
  
 request 
  
 . 
 getArgument 
 ( 
 "TRANSACTION_DECISION_VALUE" 
 ); 
 Map<String 
 , 
  
 Object 
>  
 extension 
  
 = 
  
 null 
 ; 
 if 
  
 ( 
 transactionDecisionValue 
  
 != 
  
 null 
 ) 
  
 { 
  
 extension 
  
 = 
  
 transactionDecisionValue 
 . 
 getExtension 
 (); 
 } 
 String 
  
 transactionDecision 
  
 = 
  
 null 
 ; 
 if 
  
 ( 
 extension 
  
 != 
  
 null 
 ) 
  
 { 
  
 transactionDecision 
  
 = 
  
 ( 
 String 
 ) 
  
 extension 
 . 
 get 
 ( 
 "transactionDecision" 
 ); 
 } 
 ResponseBuilder 
  
 responseBuilder 
  
 = 
  
 getResponseBuilder 
 ( 
 request 
 ); 
 if 
  
 (( 
 transactionDecision 
  
 != 
  
 null 
 && 
 transactionDecision 
 . 
 equals 
 ( 
 "ORDER_ACCEPTED" 
 ))) 
  
 { 
  
 OrderV3 
  
 order 
  
 = 
  
 (( 
 OrderV3 
 ) 
  
 extension 
 . 
 get 
 ( 
 "order" 
 )); 
 } 
  

JSON

 { 
 "responseId" 
 : 
 "aba44717-4236-4602-af55-e5ae1fc2d97a-594de0a7" 
 , 
 "queryResult" 
 : 
 { 
 "queryText" 
 : 
 "actions_intent_TRANSACTION_DECISION" 
 , 
 "action" 
 : 
 "transaction.decision.complete" 
 , 
 "parameters" 
 : 
 {}, 
 "allRequiredParamsPresent" 
 : 
 true 
 , 
 "fulfillmentText" 
 : 
 "Failed to get transaction decision" 
 , 
 "fulfillmentMessages" 
 : 
 [ 
 { 
 "text" 
 : 
 { 
 "text" 
 : 
 [ 
 "Failed to get transaction decision" 
 ] 
 } 
 } 
 ], 
 "outputContexts" 
 : 
 [ 
 { 
 "name" 
 : 
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_media_response_audio" 
 }, 
 { 
 "name" 
 : 
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_audio_output" 
 }, 
 { 
 "name" 
 : 
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_account_linking" 
 }, 
 { 
 "name" 
 : 
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_screen_output" 
 }, 
 { 
 "name" 
 : 
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_web_browser" 
 }, 
 { 
 "name" 
 : 
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/google_assistant_input_type_voice" 
 }, 
 { 
 "name" 
 : 
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/_actions_on_google" 
 , 
 "lifespanCount" 
 : 
 97 
 , 
 "parameters" 
 : 
 { 
 "data" 
 : 
 "{\"location\":{\"coordinates\":{\"latitude\":37.432524,\"longitude\":-122.098545},\"zipCode\":\"94043-1351\",\"city\":\"MOUNTAIN VIEW\",\"postalAddress\":{\"regionCode\":\"US\",\"postalCode\":\"94043-1351\",\"administrativeArea\":\"CA\",\"locality\":\"MOUNTAIN VIEW\",\"addressLines\":[\"1600 AMPHITHEATRE PKWY\"],\"recipients\":[\"John Doe\"]},\"phoneNumber\":\"+1 123-456-7890\"}}" 
 } 
 }, 
 { 
 "name" 
 : 
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_intent_transaction_decision" 
 , 
 "parameters" 
 : 
 { 
 "TRANSACTION_DECISION_VALUE" 
 : 
 { 
 "@type" 
 : 
 "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValue" 
 , 
 "transactionDecision" 
 : 
 "ORDER_ACCEPTED" 
 , 
 "order" 
 : 
 { 
 "createTime" 
 : 
 "2019-09-24T18:00:00.877Z" 
 , 
 "lastUpdateTime" 
 : 
 "2019-09-24T18:00:00.877Z" 
 , 
 "merchantOrderId" 
 : 
 "ORDER_ID" 
 , 
 "userVisibleOrderId" 
 : 
 "ORDER_ID" 
 , 
 "transactionMerchant" 
 : 
 { 
 "id" 
 : 
 "http://www.example.com" 
 , 
 "name" 
 : 
 "Example Merchant" 
 }, 
 "contents" 
 : 
 { 
 "lineItems" 
 : 
 [ 
 { 
 "id" 
 : 
 "LINE_ITEM_ID" 
 , 
 "name" 
 : 
 "Pizza" 
 , 
 "description" 
 : 
 "A four cheese pizza." 
 , 
 "priceAttributes" 
 : 
 [ 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Line Item Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 8990000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 9990000 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "notes" 
 : 
 [ 
 "Extra cheese." 
 ], 
 "purchase" 
 : 
 { 
 "quantity" 
 : 
 1 
 , 
 "unitMeasure" 
 : 
 { 
 "measure" 
 : 
 1 
 , 
 "unit" 
 : 
 "POUND" 
 }, 
 "itemOptions" 
 : 
 [ 
 { 
 "id" 
 : 
 "ITEM_OPTION_ID" 
 , 
 "name" 
 : 
 "Pepperoni" 
 , 
 "prices" 
 : 
 [ 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "name" 
 : 
 "Item Price" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 1000000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 1000000 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "note" 
 : 
 "Extra pepperoni" 
 , 
 "quantity" 
 : 
 1 
 , 
 "subOptions" 
 : 
 [] 
 } 
 ] 
 } 
 } 
 ] 
 }, 
 "buyerInfo" 
 : 
 { 
 "email" 
 : 
 "janedoe@gmail.com" 
 , 
 "firstName" 
 : 
 "Jane" 
 , 
 "lastName" 
 : 
 "Doe" 
 , 
 "displayName" 
 : 
 "Jane Doe" 
 }, 
 "priceAttributes" 
 : 
 [ 
 { 
 "type" 
 : 
 "SUBTOTAL" 
 , 
 "name" 
 : 
 "Subtotal" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 9990000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "DELIVERY" 
 , 
 "name" 
 : 
 "Delivery" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 2000000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TAX" 
 , 
 "name" 
 : 
 "Tax" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 3780000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 15770000 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "followUpActions" 
 : 
 [ 
 { 
 "type" 
 : 
 "VIEW_DETAILS" 
 , 
 "title" 
 : 
 "View details" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "http://example.com" 
 } 
 }, 
 { 
 "type" 
 : 
 "CALL" 
 , 
 "title" 
 : 
 "Call us" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "tel:+16501112222" 
 } 
 }, 
 { 
 "type" 
 : 
 "EMAIL" 
 , 
 "title" 
 : 
 "Email us" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "mailto:person@example.com" 
 } 
 } 
 ], 
 "termsOfServiceUrl" 
 : 
 "www.example.com" 
 , 
 "note" 
 : 
 "Sale event" 
 , 
 "promotions" 
 : 
 [ 
 { 
 "coupon" 
 : 
 "COUPON_CODE" 
 } 
 ], 
 "purchase" 
 : 
 { 
 "status" 
 : 
 "CREATED" 
 , 
 "userVisibleStatusLabel" 
 : 
 "CREATED" 
 , 
 "type" 
 : 
 "FOOD" 
 , 
 "returnsInfo" 
 : 
 { 
 "isReturnable" 
 : 
 false 
 , 
 "daysToReturn" 
 : 
 1 
 , 
 "policyUrl" 
 : 
 "http://www.example.com" 
 }, 
 "fulfillmentInfo" 
 : 
 { 
 "id" 
 : 
 "FULFILLMENT_SERVICE_ID" 
 , 
 "fulfillmentType" 
 : 
 "DELIVERY" 
 , 
 "expectedFulfillmentTime" 
 : 
 { 
 "timeIso8601" 
 : 
 "2019-09-25T18:00:00.877Z" 
 }, 
 "location" 
 : 
 {}, 
 "price" 
 : 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Delivery Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 2000000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 "fulfillmentContact" 
 : 
 { 
 "email" 
 : 
 "johnjohnson@gmail.com" 
 , 
 "firstName" 
 : 
 "John" 
 , 
 "lastName" 
 : 
 "Johnson" 
 , 
 "displayName" 
 : 
 "John Johnson" 
 } 
 }, 
 "purchaseLocationType" 
 : 
 "ONLINE_PURCHASE" 
 } 
 } 
 }, 
 "text" 
 : 
 "" 
 } 
 } 
 ], 
 "intent" 
 : 
 { 
 "name" 
 : 
 "projects/df-transactions/agent/intents/fd16d86b-60db-4d19-a683-5b52a22f4795" 
 , 
 "displayName" 
 : 
 "Transaction Decision Complete" 
 }, 
 "intentDetectionConfidence" 
 : 
 1 
 , 
 "languageCode" 
 : 
 "en" 
 }, 
 "originalDetectIntentRequest" 
 : 
 { 
 "source" 
 : 
 "google" 
 , 
 "version" 
 : 
 "2" 
 , 
 "payload" 
 : 
 { 
 "user" 
 : 
 { 
 "locale" 
 : 
 "en-US" 
 , 
 "lastSeen" 
 : 
 "2019-09-23T19:49:32Z" 
 , 
 "userVerificationStatus" 
 : 
 "VERIFIED" 
 }, 
 "conversation" 
 : 
 { 
 "conversationId" 
 : 
 "ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy" 
 , 
 "type" 
 : 
 "ACTIVE" 
 , 
 "conversationToken" 
 : 
 "[\"merchant_payment\"]" 
 }, 
 "inputs" 
 : 
 [ 
 { 
 "intent" 
 : 
 "actions.intent.TRANSACTION_DECISION" 
 , 
 "rawInputs" 
 : 
 [ 
 { 
 "inputType" 
 : 
 "KEYBOARD" 
 } 
 ], 
 "arguments" 
 : 
 [ 
 { 
 "name" 
 : 
 "TRANSACTION_DECISION_VALUE" 
 , 
 "extension" 
 : 
 { 
 "@type" 
 : 
 "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValue" 
 , 
 "transactionDecision" 
 : 
 "ORDER_ACCEPTED" 
 , 
 "order" 
 : 
 { 
 "createTime" 
 : 
 "2019-09-24T18:00:00.877Z" 
 , 
 "lastUpdateTime" 
 : 
 "2019-09-24T19:00:00.877Z" 
 , 
 "merchantOrderId" 
 : 
 "ORDER_ID" 
 , 
 "userVisibleOrderId" 
 : 
 "ORDER_ID" 
 , 
 "transactionMerchant" 
 : 
 { 
 "id" 
 : 
 "http://www.example.com" 
 , 
 "name" 
 : 
 "Example Merchant" 
 }, 
 "contents" 
 : 
 { 
 "lineItems" 
 : 
 [ 
 { 
 "id" 
 : 
 "LINE_ITEM_ID" 
 , 
 "name" 
 : 
 "Pizza" 
 , 
 "description" 
 : 
 "A four cheese pizza." 
 , 
 "priceAttributes" 
 : 
 [ 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Line Item Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 8990000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 9990000 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "notes" 
 : 
 [ 
 "Extra cheese." 
 ], 
 "purchase" 
 : 
 { 
 "quantity" 
 : 
 1 
 , 
 "unitMeasure" 
 : 
 { 
 "measure" 
 : 
 1 
 , 
 "unit" 
 : 
 "POUND" 
 }, 
 "itemOptions" 
 : 
 [ 
 { 
 "id" 
 : 
 "ITEM_OPTION_ID" 
 , 
 "name" 
 : 
 "Pepperoni" 
 , 
 "prices" 
 : 
 [ 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "name" 
 : 
 "Item Price" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 1000000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 1000000 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "note" 
 : 
 "Extra pepperoni" 
 , 
 "quantity" 
 : 
 1 
 , 
 "subOptions" 
 : 
 [] 
 } 
 ] 
 } 
 } 
 ] 
 }, 
 "buyerInfo" 
 : 
 { 
 "email" 
 : 
 "janedoe@gmail.com" 
 , 
 "firstName" 
 : 
 "Jane" 
 , 
 "lastName" 
 : 
 "Doe" 
 , 
 "displayName" 
 : 
 "Jane Doe" 
 }, 
 "priceAttributes" 
 : 
 [ 
 { 
 "type" 
 : 
 "SUBTOTAL" 
 , 
 "name" 
 : 
 "Subtotal" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 9990000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "DELIVERY" 
 , 
 "name" 
 : 
 "Delivery" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 2000000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TAX" 
 , 
 "name" 
 : 
 "Tax" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 3780000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 15770000 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "followUpActions" 
 : 
 [ 
 { 
 "type" 
 : 
 "VIEW_DETAILS" 
 , 
 "title" 
 : 
 "View details" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "http://example.com" 
 } 
 }, 
 { 
 "type" 
 : 
 "CALL" 
 , 
 "title" 
 : 
 "Call us" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "tel:+16501112222" 
 } 
 }, 
 { 
 "type" 
 : 
 "EMAIL" 
 , 
 "title" 
 : 
 "Email us" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "mailto:person@example.com" 
 } 
 } 
 ], 
 "termsOfServiceUrl" 
 : 
 "www.example.com" 
 , 
 "note" 
 : 
 "Sale event" 
 , 
 "promotions" 
 : 
 [ 
 { 
 "coupon" 
 : 
 "COUPON_CODE" 
 } 
 ], 
 "purchase" 
 : 
 { 
 "status" 
 : 
 "CREATED" 
 , 
 "userVisibleStatusLabel" 
 : 
 "CREATED" 
 , 
 "type" 
 : 
 "FOOD" 
 , 
 "returnsInfo" 
 : 
 { 
 "isReturnable" 
 : 
 false 
 , 
 "daysToReturn" 
 : 
 1 
 , 
 "policyUrl" 
 : 
 "http://www.example.com" 
 }, 
 "fulfillmentInfo" 
 : 
 { 
 "id" 
 : 
 "FULFILLMENT_SERVICE_ID" 
 , 
 "fulfillmentType" 
 : 
 "DELIVERY" 
 , 
 "expectedFulfillmentTime" 
 : 
 { 
 "timeIso8601" 
 : 
 "2019-09-25T18:00:00.877Z" 
 }, 
 "location" 
 : 
 {}, 
 "price" 
 : 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Delivery Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 2000000 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 "fulfillmentContact" 
 : 
 { 
 "email" 
 : 
 "johnjohnson@gmail.com" 
 , 
 "firstName" 
 : 
 "John" 
 , 
 "lastName" 
 : 
 "Johnson" 
 , 
 "displayName" 
 : 
 "John Johnson" 
 } 
 }, 
 "purchaseLocationType" 
 : 
 "ONLINE_PURCHASE" 
 } 
 } 
 } 
 }, 
 { 
 "name" 
 : 
 "text" 
 } 
 ] 
 } 
 ], 
 "surface" 
 : 
 { 
 "capabilities" 
 : 
 [ 
 { 
 "name" 
 : 
 "actions.capability.MEDIA_RESPONSE_AUDIO" 
 }, 
 { 
 "name" 
 : 
 "actions.capability.AUDIO_OUTPUT" 
 }, 
 { 
 "name" 
 : 
 "actions.capability.ACCOUNT_LINKING" 
 }, 
 { 
 "name" 
 : 
 "actions.capability.SCREEN_OUTPUT" 
 }, 
 { 
 "name" 
 : 
 "actions.capability.WEB_BROWSER" 
 } 
 ] 
 }, 
 "availableSurfaces" 
 : 
 [ 
 { 
 "capabilities" 
 : 
 [ 
 { 
 "name" 
 : 
 "actions.capability.WEB_BROWSER" 
 }, 
 { 
 "name" 
 : 
 "actions.capability.AUDIO_OUTPUT" 
 }, 
 { 
 "name" 
 : 
 "actions.capability.SCREEN_OUTPUT" 
 } 
 ] 
 } 
 ] 
 } 
 }, 
 "session" 
 : 
 "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy" 
 } 
  

JSON

 { 
 "user" 
 : 
 { 
 "locale" 
 : 
 "en-US" 
 , 
 "lastSeen" 
 : 
 "2019-11-11T23:57:31Z" 
 , 
 "userVerificationStatus" 
 : 
 "VERIFIED" 
 }, 
 "conversation" 
 : 
 { 
 "conversationId" 
 : 
 "ABwppHGFwStZlYaQ9YT8rg9t_idVsxZrku1pUDrEbGSJmSUMatVdPwPEEQSCe1IwIBoN4sS4Weyn9pmgetEgbsWgw3JSvQmw" 
 , 
 "type" 
 : 
 "ACTIVE" 
 , 
 "conversationToken" 
 : 
 "{\"data\":{\"paymentType\":\"merchant_payment\",\"location\":{\"coordinates\":{\"latitude\":37.421578499999995,\"longitude\":-122.0837816},\"zipCode\":\"94043-1351\",\"city\":\"MOUNTAIN VIEW\",\"postalAddress\":{\"regionCode\":\"US\",\"postalCode\":\"94043-1351\",\"administrativeArea\":\"CA\",\"locality\":\"MOUNTAIN VIEW\",\"addressLines\":[\"1600 AMPHITHEATRE PKWY\"],\"recipients\":[\"John Doe\"]},\"phoneNumber\":\"+1 123-456-7890\"},\"latestOrderId\":\"ORDER_ID\"}}" 
 }, 
 "inputs" 
 : 
 [ 
 { 
 "intent" 
 : 
 "actions.intent.TRANSACTION_DECISION" 
 , 
 "rawInputs" 
 : 
 [ 
 {} 
 ], 
 "arguments" 
 : 
 [ 
 { 
 "name" 
 : 
 "TRANSACTION_DECISION_VALUE" 
 , 
 "extension" 
 : 
 { 
 "@type" 
 : 
 "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValue" 
 , 
 "transactionDecision" 
 : 
 "ORDER_ACCEPTED" 
 , 
 "order" 
 : 
 { 
 "googleOrderId" 
 : 
 "05528125187071048269" 
 , 
 "merchantOrderId" 
 : 
 "ORDER_ID" 
 , 
 "userVisibleOrderId" 
 : 
 "ORDER_ID" 
 , 
 "buyerInfo" 
 : 
 { 
 "email" 
 : 
 "janedoe@example.com" 
 , 
 "firstName" 
 : 
 "Jane" 
 , 
 "lastName" 
 : 
 "Doe" 
 , 
 "displayName" 
 : 
 "Jane Doe" 
 }, 
 "createTime" 
 : 
 "2019-09-24T18:00:00.877Z" 
 , 
 "lastUpdateTime" 
 : 
 "2019-09-24T18:00:00.877Z" 
 , 
 "transactionMerchant" 
 : 
 { 
 "id" 
 : 
 "http://www.example.com" 
 , 
 "name" 
 : 
 "Example Merchant" 
 }, 
 "contents" 
 : 
 { 
 "lineItems" 
 : 
 [ 
 { 
 "id" 
 : 
 "LINE_ITEM_ID" 
 , 
 "name" 
 : 
 "Pizza" 
 , 
 "priceAttributes" 
 : 
 [ 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Item Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "8990000" 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "9990000" 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "description" 
 : 
 "A four cheese pizza." 
 , 
 "notes" 
 : 
 [ 
 "Extra cheese." 
 ], 
 "purchase" 
 : 
 { 
 "quantity" 
 : 
 1 
 , 
 "itemOptions" 
 : 
 [ 
 { 
 "id" 
 : 
 "ITEM_OPTION_ID" 
 , 
 "name" 
 : 
 "Pepperoni" 
 , 
 "prices" 
 : 
 [ 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Item Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "1000000" 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "1000000" 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "note" 
 : 
 "Extra pepperoni" 
 , 
 "quantity" 
 : 
 1 
 } 
 ], 
 "unitMeasure" 
 : 
 { 
 "measure" 
 : 
 1 
 , 
 "unit" 
 : 
 "POUND" 
 } 
 }, 
 "vertical" 
 : 
 { 
 "@type" 
 : 
 "type.googleapis.com/google.actions.orders.v3.verticals.purchase.PurchaseItemExtension" 
 , 
 "quantity" 
 : 
 1 
 , 
 "itemOptions" 
 : 
 [ 
 { 
 "id" 
 : 
 "ITEM_OPTION_ID" 
 , 
 "name" 
 : 
 "Pepperoni" 
 , 
 "prices" 
 : 
 [ 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Item Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "1000000" 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "1000000" 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "note" 
 : 
 "Extra pepperoni" 
 , 
 "quantity" 
 : 
 1 
 } 
 ], 
 "unitMeasure" 
 : 
 { 
 "measure" 
 : 
 1 
 , 
 "unit" 
 : 
 "POUND" 
 } 
 } 
 } 
 ] 
 }, 
 "priceAttributes" 
 : 
 [ 
 { 
 "type" 
 : 
 "SUBTOTAL" 
 , 
 "name" 
 : 
 "Subtotal" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "9990000" 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "DELIVERY" 
 , 
 "name" 
 : 
 "Delivery" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "2000000" 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TAX" 
 , 
 "name" 
 : 
 "Tax" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "3780000" 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "15770000" 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "followUpActions" 
 : 
 [ 
 { 
 "type" 
 : 
 "VIEW_DETAILS" 
 , 
 "title" 
 : 
 "View details" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "http://example.com" 
 } 
 }, 
 { 
 "type" 
 : 
 "CALL" 
 , 
 "title" 
 : 
 "Call us" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "tel:+16501112222" 
 } 
 }, 
 { 
 "type" 
 : 
 "EMAIL" 
 , 
 "title" 
 : 
 "Email us" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "mailto:person@example.com" 
 } 
 } 
 ], 
 "termsOfServiceUrl" 
 : 
 "http://www.example.com" 
 , 
 "note" 
 : 
 "Sale event" 
 , 
 "paymentData" 
 : 
 { 
 "paymentResult" 
 : 
 { 
 "merchantPaymentMethodId" 
 : 
 "12345678" 
 }, 
 "paymentInfo" 
 : 
 { 
 "paymentMethodDisplayInfo" 
 : 
 { 
 "paymentType" 
 : 
 "PAYMENT_CARD" 
 , 
 "paymentMethodDisplayName" 
 : 
 "VISA **** 1234" 
 }, 
 "paymentMethodProvenance" 
 : 
 "PAYMENT_METHOD_PROVENANCE_MERCHANT" 
 } 
 }, 
 "promotions" 
 : 
 [ 
 { 
 "coupon" 
 : 
 "COUPON_CODE" 
 } 
 ], 
 "purchase" 
 : 
 { 
 "status" 
 : 
 "CREATED" 
 , 
 "type" 
 : 
 "FOOD" 
 , 
 "returnsInfo" 
 : 
 { 
 "daysToReturn" 
 : 
 1 
 , 
 "policyUrl" 
 : 
 "http://www.example.com" 
 }, 
 "fulfillmentInfo" 
 : 
 { 
 "id" 
 : 
 "FULFILLMENT_SERVICE_ID" 
 , 
 "fulfillmentType" 
 : 
 "DELIVERY" 
 , 
 "expectedFulfillmentTime" 
 : 
 { 
 "timeIso8601" 
 : 
 "2019-09-25T18:00:00.877Z" 
 }, 
 "location" 
 : 
 { 
 "coordinates" 
 : 
 { 
 "latitude" 
 : 
 37.421578499999995 
 , 
 "longitude" 
 : 
 - 
 122.0837816 
 }, 
 "zipCode" 
 : 
 "94043-1351" 
 , 
 "city" 
 : 
 "MOUNTAIN VIEW" 
 , 
 "postalAddress" 
 : 
 { 
 "regionCode" 
 : 
 "US" 
 , 
 "postalCode" 
 : 
 "94043-1351" 
 , 
 "administrativeArea" 
 : 
 "CA" 
 , 
 "locality" 
 : 
 "MOUNTAIN VIEW" 
 , 
 "addressLines" 
 : 
 [ 
 "1600 AMPHITHEATRE PKWY" 
 ], 
 "recipients" 
 : 
 [ 
 "John Doe" 
 ] 
 }, 
 "phoneNumber" 
 : 
 "+1 123-456-7890" 
 }, 
 "price" 
 : 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Delivery Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "2000000" 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 "fulfillmentContact" 
 : 
 { 
 "email" 
 : 
 "johnjohnson@gmail.com" 
 , 
 "firstName" 
 : 
 "John" 
 , 
 "lastName" 
 : 
 "Johnson" 
 , 
 "displayName" 
 : 
 "John Johnson" 
 } 
 }, 
 "purchaseLocationType" 
 : 
 "ONLINE_PURCHASE" 
 , 
 "userVisibleStatusLabel" 
 : 
 "CREATED" 
 }, 
 "vertical" 
 : 
 { 
 "@type" 
 : 
 "type.googleapis.com/google.actions.orders.v3.verticals.purchase.PurchaseOrderExtension" 
 , 
 "status" 
 : 
 "CREATED" 
 , 
 "type" 
 : 
 "FOOD" 
 , 
 "returnsInfo" 
 : 
 { 
 "daysToReturn" 
 : 
 1 
 , 
 "policyUrl" 
 : 
 "http://www.example.com" 
 }, 
 "fulfillmentInfo" 
 : 
 { 
 "id" 
 : 
 "FULFILLMENT_SERVICE_ID" 
 , 
 "fulfillmentType" 
 : 
 "DELIVERY" 
 , 
 "expectedFulfillmentTime" 
 : 
 { 
 "timeIso8601" 
 : 
 "2019-09-25T18:00:00.877Z" 
 }, 
 "location" 
 : 
 { 
 "coordinates" 
 : 
 { 
 "latitude" 
 : 
 37.421578499999995 
 , 
 "longitude" 
 : 
 - 
 122.0837816 
 }, 
 "zipCode" 
 : 
 "94043-1351" 
 , 
 "city" 
 : 
 "MOUNTAIN VIEW" 
 , 
 "postalAddress" 
 : 
 { 
 "regionCode" 
 : 
 "US" 
 , 
 "postalCode" 
 : 
 "94043-1351" 
 , 
 "administrativeArea" 
 : 
 "CA" 
 , 
 "locality" 
 : 
 "MOUNTAIN VIEW" 
 , 
 "addressLines" 
 : 
 [ 
 "1600 AMPHITHEATRE PKWY" 
 ], 
 "recipients" 
 : 
 [ 
 "John Doe" 
 ] 
 }, 
 "phoneNumber" 
 : 
 "+1 123-456-7890" 
 }, 
 "price" 
 : 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Delivery Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "2000000" 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 "fulfillmentContact" 
 : 
 { 
 "email" 
 : 
 "johnjohnson@gmail.com" 
 , 
 "firstName" 
 : 
 "John" 
 , 
 "lastName" 
 : 
 "Johnson" 
 , 
 "displayName" 
 : 
 "John Johnson" 
 } 
 }, 
 "purchaseLocationType" 
 : 
 "ONLINE_PURCHASE" 
 , 
 "userVisibleStatusLabel" 
 : 
 "CREATED" 
 } 
 } 
 } 
 }, 
 { 
 "name" 
 : 
 "text" 
 } 
 ] 
 } 
 ], 
 "surface" 
 : 
 { 
 "capabilities" 
 : 
 [ 
 { 
 "name" 
 : 
 "actions.capability.AUDIO_OUTPUT" 
 }, 
 { 
 "name" 
 : 
 "actions.capability.MEDIA_RESPONSE_AUDIO" 
 }, 
 { 
 "name" 
 : 
 "actions.capability.ACCOUNT_LINKING" 
 }, 
 { 
 "name" 
 : 
 "actions.capability.SCREEN_OUTPUT" 
 } 
 ] 
 }, 
 "availableSurfaces" 
 : 
 [ 
 { 
 "capabilities" 
 : 
 [ 
 { 
 "name" 
 : 
 "actions.capability.SCREEN_OUTPUT" 
 }, 
 { 
 "name" 
 : 
 "actions.capability.WEB_BROWSER" 
 }, 
 { 
 "name" 
 : 
 "actions.capability.AUDIO_OUTPUT" 
 } 
 ] 
 } 
 ] 
 } 
  

5. Finalize the order and send a receipt

When the actions.intent.TRANSACTION_DECISION intent returns with a transactionDecision of ORDER_ACCEPTED , you must immediately perform whatever processing is required to "confirm" the order (like persisting it in your own database and charging the user).

You can end the conversation with this response, but you must include a simple response to keep the conversation moving. When you provide this initial orderUpdate , the user will see a "collapsed receipt card" along with the rest of your response. This card will mirror the receipt that the user finds in their Order History.

During order confirmation, your order object can include a userVisibleOrderId which is the ID that the user sees for the order. You can reuse your merchantOrderId for this field.

Part of the OrderUpdate object will need to contain a follow-up action object, which manifest as URL buttons at the bottom of the order details that the user can find in their Assistant Order History.

Fulfillment

Node.js

 // Set lastUpdateTime and update status of order 
 const 
  
 order 
  
 = 
  
 arg 
 . 
 order 
 ; 
 order 
 . 
 lastUpdateTime 
  
 = 
  
 '2019-09-24T19:00:00.877Z' 
 ; 
 order 
 . 
 purchase 
 . 
 status 
  
 = 
  
 'CONFIRMED' 
 ; 
 order 
 . 
 purchase 
 . 
 userVisibleStatusLabel 
  
 = 
  
 'Order confirmed' 
 ; 
 // Send synchronous order update 
 conv 
 . 
 ask 
 ( 
 `Transaction completed! Your order` 
 + 
  
 ` 
 ${ 
 conv 
 . 
 data 
 . 
 latestOrderId 
 } 
 is all set!` 
 ); 
 conv 
 . 
 ask 
 ( 
 new 
  
 Suggestions 
 ( 
 'send order update' 
 )); 
 conv 
 . 
 ask 
 ( 
 new 
  
 OrderUpdate 
 ({ 
  
 type 
 : 
  
 'SNAPSHOT' 
 , 
  
 reason 
 : 
  
 'Reason string' 
 , 
  
 order 
 : 
  
 order 
 , 
 })); 
  

Node.js

 // Set lastUpdateTime and update status of order 
 const 
  
 order 
  
 = 
  
 arg 
 . 
 order 
 ; 
 order 
 . 
 lastUpdateTime 
  
 = 
  
 '2019-09-24T19:00:00.877Z' 
 ; 
 order 
 . 
 purchase 
 . 
 status 
  
 = 
  
 'CONFIRMED' 
 ; 
 order 
 . 
 purchase 
 . 
 userVisibleStatusLabel 
  
 = 
  
 'Order confirmed' 
 ; 
 // Send synchronous order update 
 conv 
 . 
 ask 
 ( 
 `Transaction completed! Your order ` 
 + 
  
 ` 
 ${ 
 conv 
 . 
 data 
 . 
 latestOrderId 
 } 
 is all set!` 
 ); 
 conv 
 . 
 ask 
 ( 
 new 
  
 Suggestions 
 ( 
 'send order update' 
 )); 
 conv 
 . 
 ask 
 ( 
 new 
  
 OrderUpdate 
 ({ 
  
 type 
 : 
  
 'SNAPSHOT' 
 , 
  
 reason 
 : 
  
 'Reason string' 
 , 
  
 order 
 : 
  
 order 
 , 
 })); 
  

Java

 OrderV3 
  
 order 
  
 = 
  
 (( 
 OrderV3 
 ) 
  
 extension 
 . 
 get 
 ( 
 "order" 
 )); 
 order 
 . 
 setLastUpdateTime 
 ( 
 "2019-09-24T19:00:00.877Z" 
 ); 
 // Update order status 
 PurchaseOrderExtension 
  
 purchaseOrderExtension 
  
 = 
  
 order 
 . 
 getPurchase 
 (); 
 purchaseOrderExtension 
 . 
 setStatus 
 ( 
 "CONFIRMED" 
 ); 
 purchaseOrderExtension 
 . 
 setUserVisibleStatusLabel 
 ( 
 "Order confirmed" 
 ); 
 order 
 . 
 setPurchase 
 ( 
 purchaseOrderExtension 
 ); 
 // Order update 
 OrderUpdateV3 
  
 orderUpdate 
  
 = 
  
 new 
  
 OrderUpdateV3 
 () 
  
 . 
 setType 
 ( 
 "SNAPSHOT" 
 ) 
  
 . 
 setReason 
 ( 
 "Reason string" 
 ) 
  
 . 
 setOrder 
 ( 
 order 
 ); 
 Map<String 
 , 
  
 Object 
>  
 conversationData 
  
 = 
  
 request 
 . 
 getConversationData 
 (); 
 String 
  
 orderId 
  
 = 
  
 ( 
 String 
 ) 
  
 conversationData 
 . 
 get 
 ( 
 "latestOrderId" 
 ); 
 responseBuilder 
  
 . 
 add 
 ( 
 "Transaction completed! Your order " 
  
 + 
  
 orderId 
  
 + 
  
 " is all set!" 
 ) 
  
 . 
 addSuggestions 
 ( 
 new 
  
 String 
 [] 
  
 { 
 "send order update" 
 }) 
  
 . 
 add 
 ( 
 new 
  
 StructuredResponse 
 (). 
 setOrderUpdateV3 
 ( 
 orderUpdate 
 )); 
  

Java

 OrderV3 
  
 order 
  
 = 
  
 (( 
 OrderV3 
 ) 
  
 extension 
 . 
 get 
 ( 
 "order" 
 )); 
 order 
 . 
 setLastUpdateTime 
 ( 
 "2019-09-24T19:00:00.877Z" 
 ); 
 // Update order status 
 PurchaseOrderExtension 
  
 purchaseOrderExtension 
  
 = 
  
 order 
 . 
 getPurchase 
 (); 
 purchaseOrderExtension 
 . 
 setStatus 
 ( 
 "CONFIRMED" 
 ); 
 purchaseOrderExtension 
 . 
 setUserVisibleStatusLabel 
 ( 
 "Order confirmed" 
 ); 
 order 
 . 
 setPurchase 
 ( 
 purchaseOrderExtension 
 ); 
 // Order update 
 OrderUpdateV3 
  
 orderUpdate 
  
 = 
  
 new 
  
 OrderUpdateV3 
 () 
  
 . 
 setType 
 ( 
 "SNAPSHOT" 
 ) 
  
 . 
 setReason 
 ( 
 "Reason string" 
 ) 
  
 . 
 setOrder 
 ( 
 order 
 ); 
 Map<String 
 , 
  
 Object 
>  
 conversationData 
  
 = 
  
 request 
 . 
 getConversationData 
 (); 
 String 
  
 orderId 
  
 = 
  
 ( 
 String 
 ) 
  
 conversationData 
 . 
 get 
 ( 
 "latestOrderId" 
 ); 
 responseBuilder 
  
 . 
 add 
 ( 
 "Transaction completed! Your order " 
  
 + 
  
 orderId 
  
 + 
  
 " is all set!" 
 ) 
  
 . 
 addSuggestions 
 ( 
 new 
  
 String 
 [] 
  
 { 
 "send order update" 
 }) 
  
 . 
 add 
 ( 
 new 
  
 StructuredResponse 
 (). 
 setOrderUpdateV3 
 ( 
 orderUpdate 
 )); 
  

JSON

 { 
  
 "payload" 
 : 
  
 { 
  
 "google" 
 : 
  
 { 
  
 "expectUserResponse" 
 : 
  
 true 
 , 
  
 "richResponse" 
 : 
  
 { 
  
 "items" 
 : 
  
 [ 
  
 { 
  
 "simpleResponse" 
 : 
  
 { 
  
 "textToSpeech" 
 : 
  
 "Transaction completed! Your order undefined is all set!" 
  
 } 
  
 }, 
  
 { 
  
 "structuredResponse" 
 : 
  
 { 
  
 "orderUpdateV3" 
 : 
  
 { 
  
 "order" 
 : 
  
 { 
  
 "buyerInfo" 
 : 
  
 { 
  
 "displayName" 
 : 
  
 "Jane Doe" 
 , 
  
 "email" 
 : 
  
 "janedoe@gmail.com" 
 , 
  
 "firstName" 
 : 
  
 "Jane" 
 , 
  
 "lastName" 
 : 
  
 "Doe" 
  
 }, 
  
 "contents" 
 : 
  
 { 
  
 "lineItems" 
 : 
  
 [ 
  
 { 
  
 "description" 
 : 
  
 "A four cheese pizza." 
 , 
  
 "id" 
 : 
  
 "LINE_ITEM_ID" 
 , 
  
 "name" 
 : 
  
 "Pizza" 
 , 
  
 "notes" 
 : 
  
 [ 
  
 "Extra cheese." 
  
 ], 
  
 "priceAttributes" 
 : 
  
 [ 
  
 { 
  
 "amount" 
 : 
  
 { 
  
 "amountInMicros" 
 : 
  
 8990000 
 , 
  
 "currencyCode" 
 : 
  
 "USD" 
  
 }, 
  
 "name" 
 : 
  
 "Line Item Price" 
 , 
  
 "state" 
 : 
  
 "ACTUAL" 
 , 
  
 "taxIncluded" 
 : 
  
 true 
 , 
  
 "type" 
 : 
  
 "REGULAR" 
  
 }, 
  
 { 
  
 "amount" 
 : 
  
 { 
  
 "amountInMicros" 
 : 
  
 9990000 
 , 
  
 "currencyCode" 
 : 
  
 "USD" 
  
 }, 
  
 "name" 
 : 
  
 "Total Price" 
 , 
  
 "state" 
 : 
  
 "ACTUAL" 
 , 
  
 "taxIncluded" 
 : 
  
 true 
 , 
  
 "type" 
 : 
  
 "TOTAL" 
  
 } 
  
 ], 
  
 "purchase" 
 : 
  
 { 
  
 "itemOptions" 
 : 
  
 [ 
  
 { 
  
 "id" 
 : 
  
 "ITEM_OPTION_ID" 
 , 
  
 "name" 
 : 
  
 "Pepperoni" 
 , 
  
 "note" 
 : 
  
 "Extra pepperoni" 
 , 
  
 "prices" 
 : 
  
 [ 
  
 { 
  
 "amount" 
 : 
  
 { 
  
 "amountInMicros" 
 : 
  
 1000000 
 , 
  
 "currencyCode" 
 : 
  
 "USD" 
  
 }, 
  
 "name" 
 : 
  
 "Item Price" 
 , 
  
 "state" 
 : 
  
 "ACTUAL" 
 , 
  
 "taxIncluded" 
 : 
  
 true 
 , 
  
 "type" 
 : 
  
 "REGULAR" 
  
 }, 
  
 { 
  
 "amount" 
 : 
  
 { 
  
 "amountInMicros" 
 : 
  
 1000000 
 , 
  
 "currencyCode" 
 : 
  
 "USD" 
  
 }, 
  
 "name" 
 : 
  
 "Total Price" 
 , 
  
 "state" 
 : 
  
 "ACTUAL" 
 , 
  
 "taxIncluded" 
 : 
  
 true 
 , 
  
 "type" 
 : 
  
 "TOTAL" 
  
 } 
  
 ], 
  
 "quantity" 
 : 
  
 1 
 , 
  
 "subOptions" 
 : 
  
 [] 
  
 } 
  
 ], 
  
 "quantity" 
 : 
  
 1 
 , 
  
 "unitMeasure" 
 : 
  
 { 
  
 "measure" 
 : 
  
 1 
 , 
  
 "unit" 
 : 
  
 "POUND" 
  
 } 
  
 } 
  
 } 
  
 ] 
  
 }, 
  
 "createTime" 
 : 
  
 "2019-09-24T18:00:00.877Z" 
 , 
  
 "followUpActions" 
 : 
  
 [ 
  
 { 
  
 "openUrlAction" 
 : 
  
 { 
  
 "url" 
 : 
  
 "http://example.com" 
  
 }, 
  
 "title" 
 : 
  
 "View details" 
 , 
  
 "type" 
 : 
  
 "VIEW_DETAILS" 
  
 }, 
  
 { 
  
 "openUrlAction" 
 : 
  
 { 
  
 "url" 
 : 
  
 "tel:+16501112222" 
  
 }, 
  
 "title" 
 : 
  
 "Call us" 
 , 
  
 "type" 
 : 
  
 "CALL" 
  
 }, 
  
 { 
  
 "openUrlAction" 
 : 
  
 { 
  
 "url" 
 : 
  
 "mailto:person@example.com" 
  
 }, 
  
 "title" 
 : 
  
 "Email us" 
 , 
  
 "type" 
 : 
  
 "EMAIL" 
  
 } 
  
 ], 
  
 "lastUpdateTime" 
 : 
  
 "2019-09-24T19:00:00.877Z" 
 , 
  
 "merchantOrderId" 
 : 
  
 "ORDER_ID" 
 , 
  
 "note" 
 : 
  
 "Sale event" 
 , 
  
 "priceAttributes" 
 : 
  
 [ 
  
 { 
  
 "amount" 
 : 
  
 { 
  
 "amountInMicros" 
 : 
  
 9990000 
 , 
  
 "currencyCode" 
 : 
  
 "USD" 
  
 }, 
  
 "name" 
 : 
  
 "Subtotal" 
 , 
  
 "state" 
 : 
  
 "ESTIMATE" 
 , 
  
 "taxIncluded" 
 : 
  
 true 
 , 
  
 "type" 
 : 
  
 "SUBTOTAL" 
  
 }, 
  
 { 
  
 "amount" 
 : 
  
 { 
  
 "amountInMicros" 
 : 
  
 2000000 
 , 
  
 "currencyCode" 
 : 
  
 "USD" 
  
 }, 
  
 "name" 
 : 
  
 "Delivery" 
 , 
  
 "state" 
 : 
  
 "ACTUAL" 
 , 
  
 "taxIncluded" 
 : 
  
 true 
 , 
  
 "type" 
 : 
  
 "DELIVERY" 
  
 }, 
  
 { 
  
 "amount" 
 : 
  
 { 
  
 "amountInMicros" 
 : 
  
 3780000 
 , 
  
 "currencyCode" 
 : 
  
 "USD" 
  
 }, 
  
 "name" 
 : 
  
 "Tax" 
 , 
  
 "state" 
 : 
  
 "ESTIMATE" 
 , 
  
 "taxIncluded" 
 : 
  
 true 
 , 
  
 "type" 
 : 
  
 "TAX" 
  
 }, 
  
 { 
  
 "amount" 
 : 
  
 { 
  
 "amountInMicros" 
 : 
  
 15770000 
 , 
  
 "currencyCode" 
 : 
  
 "USD" 
  
 }, 
  
 "name" 
 : 
  
 "Total Price" 
 , 
  
 "state" 
 : 
  
 "ESTIMATE" 
 , 
  
 "taxIncluded" 
 : 
  
 true 
 , 
  
 "type" 
 : 
  
 "TOTAL" 
  
 } 
  
 ], 
  
 "promotions" 
 : 
  
 [ 
  
 { 
  
 "coupon" 
 : 
  
 "COUPON_CODE" 
  
 } 
  
 ], 
  
 "purchase" 
 : 
  
 { 
  
 "fulfillmentInfo" 
 : 
  
 { 
  
 "expectedFulfillmentTime" 
 : 
  
 { 
  
 "timeIso8601" 
 : 
  
 "2019-09-25T18:00:00.877Z" 
  
 }, 
  
 "fulfillmentContact" 
 : 
  
 { 
  
 "displayName" 
 : 
  
 "John Johnson" 
 , 
  
 "email" 
 : 
  
 "johnjohnson@gmail.com" 
 , 
  
 "firstName" 
 : 
  
 "John" 
 , 
  
 "lastName" 
 : 
  
 "Johnson" 
  
 }, 
  
 "fulfillmentType" 
 : 
  
 "DELIVERY" 
 , 
  
 "id" 
 : 
  
 "FULFILLMENT_SERVICE_ID" 
 , 
  
 "location" 
 : 
  
 {}, 
  
 "price" 
 : 
  
 { 
  
 "amount" 
 : 
  
 { 
  
 "amountInMicros" 
 : 
  
 2000000 
 , 
  
 "currencyCode" 
 : 
  
 "USD" 
  
 }, 
  
 "name" 
 : 
  
 "Delivery Price" 
 , 
  
 "state" 
 : 
  
 "ACTUAL" 
 , 
  
 "taxIncluded" 
 : 
  
 true 
 , 
  
 "type" 
 : 
  
 "REGULAR" 
  
 } 
  
 }, 
  
 "purchaseLocationType" 
 : 
  
 "ONLINE_PURCHASE" 
 , 
  
 "returnsInfo" 
 : 
  
 { 
  
 "daysToReturn" 
 : 
  
 1 
 , 
  
 "isReturnable" 
 : 
  
 false 
 , 
  
 "policyUrl" 
 : 
  
 "http://www.example.com" 
  
 }, 
  
 "status" 
 : 
  
 "CONFIRMED" 
 , 
  
 "type" 
 : 
  
 "FOOD" 
 , 
  
 "userVisibleStatusLabel" 
 : 
  
 "Order confirmed" 
  
 }, 
  
 "termsOfServiceUrl" 
 : 
  
 "www.example.com" 
 , 
  
 "transactionMerchant" 
 : 
  
 { 
  
 "id" 
 : 
  
 "http://www.example.com" 
 , 
  
 "name" 
 : 
  
 "Example Merchant" 
  
 }, 
  
 "userVisibleOrderId" 
 : 
  
 "ORDER_ID" 
  
 }, 
  
 "reason" 
 : 
  
 "Reason string" 
 , 
  
 "type" 
 : 
  
 "SNAPSHOT" 
  
 } 
  
 } 
  
 } 
  
 ], 
  
 "suggestions" 
 : 
  
 [ 
  
 { 
  
 "title" 
 : 
  
 "send order update" 
  
 } 
  
 ] 
  
 } 
  
 } 
  
 } 
 } 
  

JSON

 { 
 "expectUserResponse" 
 : 
 true 
 , 
 "expectedInputs" 
 : 
 [ 
 { 
 "possibleIntents" 
 : 
 [ 
 { 
 "intent" 
 : 
 "actions.intent.TEXT" 
 } 
 ], 
 "inputPrompt" 
 : 
 { 
 "richInitialPrompt" 
 : 
 { 
 "items" 
 : 
 [ 
 { 
 "simpleResponse" 
 : 
 { 
 "textToSpeech" 
 : 
 "Transaction completed! Your order ORDER_ID is all set!" 
 } 
 }, 
 { 
 "structuredResponse" 
 : 
 { 
 "orderUpdateV3" 
 : 
 { 
 "type" 
 : 
 "SNAPSHOT" 
 , 
 "reason" 
 : 
 "Reason string" 
 , 
 "order" 
 : 
 { 
 "googleOrderId" 
 : 
 "05528125187071048269" 
 , 
 "merchantOrderId" 
 : 
 "ORDER_ID" 
 , 
 "userVisibleOrderId" 
 : 
 "ORDER_ID" 
 , 
 "buyerInfo" 
 : 
 { 
 "email" 
 : 
 "janedoe@example.com" 
 , 
 "firstName" 
 : 
 "Jane" 
 , 
 "lastName" 
 : 
 "Doe" 
 , 
 "displayName" 
 : 
 "Jane Doe" 
 }, 
 "createTime" 
 : 
 "2019-09-24T18:00:00.877Z" 
 , 
 "lastUpdateTime" 
 : 
 "2019-09-24T19:00:00.877Z" 
 , 
 "transactionMerchant" 
 : 
 { 
 "id" 
 : 
 "http://www.example.com" 
 , 
 "name" 
 : 
 "Example Merchant" 
 }, 
 "contents" 
 : 
 { 
 "lineItems" 
 : 
 [ 
 { 
 "id" 
 : 
 "LINE_ITEM_ID" 
 , 
 "name" 
 : 
 "Pizza" 
 , 
 "priceAttributes" 
 : 
 [ 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Item Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "8990000" 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "9990000" 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "description" 
 : 
 "A four cheese pizza." 
 , 
 "notes" 
 : 
 [ 
 "Extra cheese." 
 ], 
 "purchase" 
 : 
 { 
 "quantity" 
 : 
 1 
 , 
 "itemOptions" 
 : 
 [ 
 { 
 "id" 
 : 
 "ITEM_OPTION_ID" 
 , 
 "name" 
 : 
 "Pepperoni" 
 , 
 "prices" 
 : 
 [ 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Item Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "1000000" 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "1000000" 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "note" 
 : 
 "Extra pepperoni" 
 , 
 "quantity" 
 : 
 1 
 } 
 ], 
 "unitMeasure" 
 : 
 { 
 "measure" 
 : 
 1 
 , 
 "unit" 
 : 
 "POUND" 
 } 
 }, 
 "vertical" 
 : 
 { 
 "@type" 
 : 
 "type.googleapis.com/google.actions.orders.v3.verticals.purchase.PurchaseItemExtension" 
 , 
 "quantity" 
 : 
 1 
 , 
 "itemOptions" 
 : 
 [ 
 { 
 "id" 
 : 
 "ITEM_OPTION_ID" 
 , 
 "name" 
 : 
 "Pepperoni" 
 , 
 "prices" 
 : 
 [ 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Item Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "1000000" 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "1000000" 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "note" 
 : 
 "Extra pepperoni" 
 , 
 "quantity" 
 : 
 1 
 } 
 ], 
 "unitMeasure" 
 : 
 { 
 "measure" 
 : 
 1 
 , 
 "unit" 
 : 
 "POUND" 
 } 
 } 
 } 
 ] 
 }, 
 "priceAttributes" 
 : 
 [ 
 { 
 "type" 
 : 
 "SUBTOTAL" 
 , 
 "name" 
 : 
 "Subtotal" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "9990000" 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "DELIVERY" 
 , 
 "name" 
 : 
 "Delivery" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "2000000" 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TAX" 
 , 
 "name" 
 : 
 "Tax" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "3780000" 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 { 
 "type" 
 : 
 "TOTAL" 
 , 
 "name" 
 : 
 "Total Price" 
 , 
 "state" 
 : 
 "ESTIMATE" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "15770000" 
 }, 
 "taxIncluded" 
 : 
 true 
 } 
 ], 
 "followUpActions" 
 : 
 [ 
 { 
 "type" 
 : 
 "VIEW_DETAILS" 
 , 
 "title" 
 : 
 "View details" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "http://example.com" 
 } 
 }, 
 { 
 "type" 
 : 
 "CALL" 
 , 
 "title" 
 : 
 "Call us" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "tel:+16501112222" 
 } 
 }, 
 { 
 "type" 
 : 
 "EMAIL" 
 , 
 "title" 
 : 
 "Email us" 
 , 
 "openUrlAction" 
 : 
 { 
 "url" 
 : 
 "mailto:person@example.com" 
 } 
 } 
 ], 
 "termsOfServiceUrl" 
 : 
 "http://www.example.com" 
 , 
 "note" 
 : 
 "Sale event" 
 , 
 "paymentData" 
 : 
 { 
 "paymentResult" 
 : 
 { 
 "merchantPaymentMethodId" 
 : 
 "12345678" 
 }, 
 "paymentInfo" 
 : 
 { 
 "paymentMethodDisplayInfo" 
 : 
 { 
 "paymentType" 
 : 
 "PAYMENT_CARD" 
 , 
 "paymentMethodDisplayName" 
 : 
 "VISA **** 1234" 
 }, 
 "paymentMethodProvenance" 
 : 
 "PAYMENT_METHOD_PROVENANCE_MERCHANT" 
 } 
 }, 
 "promotions" 
 : 
 [ 
 { 
 "coupon" 
 : 
 "COUPON_CODE" 
 } 
 ], 
 "purchase" 
 : 
 { 
 "status" 
 : 
 "CONFIRMED" 
 , 
 "type" 
 : 
 "FOOD" 
 , 
 "returnsInfo" 
 : 
 { 
 "daysToReturn" 
 : 
 1 
 , 
 "policyUrl" 
 : 
 "http://www.example.com" 
 }, 
 "fulfillmentInfo" 
 : 
 { 
 "id" 
 : 
 "FULFILLMENT_SERVICE_ID" 
 , 
 "fulfillmentType" 
 : 
 "DELIVERY" 
 , 
 "expectedFulfillmentTime" 
 : 
 { 
 "timeIso8601" 
 : 
 "2019-09-25T18:00:00.877Z" 
 }, 
 "location" 
 : 
 { 
 "coordinates" 
 : 
 { 
 "latitude" 
 : 
 37.421578499999995 
 , 
 "longitude" 
 : 
 - 
 122.0837816 
 }, 
 "zipCode" 
 : 
 "94043-1351" 
 , 
 "city" 
 : 
 "MOUNTAIN VIEW" 
 , 
 "postalAddress" 
 : 
 { 
 "regionCode" 
 : 
 "US" 
 , 
 "postalCode" 
 : 
 "94043-1351" 
 , 
 "administrativeArea" 
 : 
 "CA" 
 , 
 "locality" 
 : 
 "MOUNTAIN VIEW" 
 , 
 "addressLines" 
 : 
 [ 
 "1600 AMPHITHEATRE PKWY" 
 ], 
 "recipients" 
 : 
 [ 
 "John Doe" 
 ] 
 }, 
 "phoneNumber" 
 : 
 "+1 123-456-7890" 
 }, 
 "price" 
 : 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Delivery Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "2000000" 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 "fulfillmentContact" 
 : 
 { 
 "email" 
 : 
 "johnjohnson@gmail.com" 
 , 
 "firstName" 
 : 
 "John" 
 , 
 "lastName" 
 : 
 "Johnson" 
 , 
 "displayName" 
 : 
 "John Johnson" 
 } 
 }, 
 "purchaseLocationType" 
 : 
 "ONLINE_PURCHASE" 
 , 
 "userVisibleStatusLabel" 
 : 
 "Order confirmed" 
 }, 
 "vertical" 
 : 
 { 
 "@type" 
 : 
 "type.googleapis.com/google.actions.orders.v3.verticals.purchase.PurchaseOrderExtension" 
 , 
 "status" 
 : 
 "CREATED" 
 , 
 "type" 
 : 
 "FOOD" 
 , 
 "returnsInfo" 
 : 
 { 
 "daysToReturn" 
 : 
 1 
 , 
 "policyUrl" 
 : 
 "http://www.example.com" 
 }, 
 "fulfillmentInfo" 
 : 
 { 
 "id" 
 : 
 "FULFILLMENT_SERVICE_ID" 
 , 
 "fulfillmentType" 
 : 
 "DELIVERY" 
 , 
 "expectedFulfillmentTime" 
 : 
 { 
 "timeIso8601" 
 : 
 "2019-09-25T18:00:00.877Z" 
 }, 
 "location" 
 : 
 { 
 "coordinates" 
 : 
 { 
 "latitude" 
 : 
 37.421578499999995 
 , 
 "longitude" 
 : 
 - 
 122.0837816 
 }, 
 "zipCode" 
 : 
 "94043-1351" 
 , 
 "city" 
 : 
 "MOUNTAIN VIEW" 
 , 
 "postalAddress" 
 : 
 { 
 "regionCode" 
 : 
 "US" 
 , 
 "postalCode" 
 : 
 "94043-1351" 
 , 
 "administrativeArea" 
 : 
 "CA" 
 , 
 "locality" 
 : 
 "MOUNTAIN VIEW" 
 , 
 "addressLines" 
 : 
 [ 
 "1600 AMPHITHEATRE PKWY" 
 ], 
 "recipients" 
 : 
 [ 
 "John Doe" 
 ] 
 }, 
 "phoneNumber" 
 : 
 "+1 123-456-7890" 
 }, 
 "price" 
 : 
 { 
 "type" 
 : 
 "REGULAR" 
 , 
 "name" 
 : 
 "Delivery Price" 
 , 
 "state" 
 : 
 "ACTUAL" 
 , 
 "amount" 
 : 
 { 
 "currencyCode" 
 : 
 "USD" 
 , 
 "amountInMicros" 
 : 
 "2000000" 
 }, 
 "taxIncluded" 
 : 
 true 
 }, 
 "fulfillmentContact" 
 : 
 { 
 "email" 
 : 
 "johnjohnson@gmail.com" 
 , 
 "firstName" 
 : 
 "John" 
 , 
 "lastName" 
 : 
 "Johnson" 
 , 
 "displayName" 
 : 
 "John Johnson" 
 } 
 }, 
 "purchaseLocationType" 
 : 
 "ONLINE_PURCHASE" 
 , 
 "userVisibleStatusLabel" 
 : 
 "CREATED" 
 } 
 } 
 } 
 } 
 } 
 ], 
 "suggestions" 
 : 
 [ 
 { 
 "title" 
 : 
 "send order update" 
 } 
 ] 
 } 
 } 
 } 
 ], 
 "conversationToken" 
 : 
 "{\"data\":{\"paymentType\":\"merchant_payment\",\"location\":{\"coordinates\":{\"latitude\":37.421578499999995,\"longitude\":-122.0837816},\"zipCode\":\"94043-1351\",\"city\":\"MOUNTAIN VIEW\",\"postalAddress\":{\"regionCode\":\"US\",\"postalCode\":\"94043-1351\",\"administrativeArea\":\"CA\",\"locality\":\"MOUNTAIN VIEW\",\"addressLines\":[\"1600 AMPHITHEATRE PKWY\"],\"recipients\":[\"John Doe\"]},\"phoneNumber\":\"+1 123-456-7890\"},\"latestOrderId\":\"ORDER_ID\"}}" 
 } 
  

6. Send order updates

You'll need to keep the user informed about the order's status over the course of its lifetime. Send the user order updates by sending HTTP PATCH requests to the Orders API with the order status and details.

Set up asynchronous requests to the Orders API

Order update requests to the Orders API are authorized by an access token. To PATCH an order update to the Orders API, download a JSON service account key associated with your Actions Console project, then exchange the service account key for a bearer token that can be passed into the Authorization header of the HTTP request.

To retrieve your service account key, perform the following steps:

  1. In the Google Cloud console , go to Menu ☰ > APIs & Services > Credentials > Create credentials > Service account key.
  2. Under Service Account, select New Service Account.
  3. Set the service account to service-account .
  4. Set Roleto Project > Owner.
  5. Set key type to JSON.
  6. Select Create.
  7. A private JSON service account key will be downloaded to your local machine.

In your order updates code, you can exchange your service key for a bearer token using the Google APIs client library and the "https://www.googleapis.com/auth/actions.order.developer" scope. You can find installation steps and examples on the API client library GitHub page .

You can also reference order-update.js in our Node.js and Java samples for an example key exchange.

Send order updates

Once you've exchanged your service account key for an OAuth bearer token, you can send order updates as authorized PATCH requests to the Orders API.

Orders API URL: PATCH https://actions.googleapis.com/v3/orders/${orderId}

Provide the following headers in your request:

  • "Authorization: Bearer token" with the OAuth bearer token you exchanged your service account key for.
  • "Content-Type: application/json" .

The PATCH request should take a JSON body of the following format:

{ "orderUpdate": OrderUpdate }

The OrderUpdate object consists of the following top-level fields:

  • updateMask - The fields of the order that you're updating. To update the order status, set the value to purchase.status, purchase.userVisibleStatusLabel .
  • order - The contents of the update. If you're updating the contents of the order, set the value to the updated Order object. If you're updating the status of the order (for example, from "CONFIRMED" to "SHIPPED" ), the object contains the following fields:

    • merchantOrderId - The same ID you set in your Order object.
    • lastUpdateTime - The timestamp of this update.
    • purchase - An object containing the following:
      • status - The status of the order as a PurchaseStatus , such as " SHIPPED " or " DELIVERED ".
      • userVisibleStatusLabel - A user-facing label providing details on the order status, such as "Your order has been shipped and is on the way".
  • userNotification (optional) - A userNotification object that can display on the user's device when this update is sent. Note that including this object doesn't guarantee that a notification appears on the user's device.

The following sample code shows an example OrderUpdate that updates the status of the order to DELIVERED :

Node.js

 // Import the 'googleapis' module for authorizing the request. 
 const 
  
 { 
 google 
 } 
  
 = 
  
 require 
 ( 
 'googleapis' 
 ); 
 // Import the 'request-promise' module for sending an HTTP POST request. 
 const 
  
 request 
  
 = 
  
 require 
 ( 
 'request-promise' 
 ); 
 // Import the OrderUpdate class from the Actions on Google client library. 
 const 
  
 { 
 OrderUpdate 
 } 
  
 = 
  
 require 
 ( 
 'actions-on-google' 
 ); 
 // Import the service account key used to authorize the request. 
 // Replacing the string path with a path to your service account key. 
 // i.e. const serviceAccountKey = require('./service-account.json') 
 // Create a new JWT client for the Actions API using credentials 
 // from the service account key. 
 let 
  
 jwtClient 
  
 = 
  
 new 
  
 google 
 . 
 auth 
 . 
 JWT 
 ( 
  
 serviceAccountKey 
 . 
 client_email 
 , 
  
 null 
 , 
  
 serviceAccountKey 
 . 
 private_key 
 , 
  
 [ 
 'https://www.googleapis.com/auth/actions.order.developer' 
 ], 
  
 null 
 , 
 ); 
 // Authorize the client 
 let 
  
 tokens 
  
 = 
  
 await 
  
 jwtClient 
 . 
 authorize 
 (); 
 // Declare order update 
 const 
  
 orderUpdate 
  
 = 
  
 new 
  
 OrderUpdate 
 ({ 
  
 updateMask 
 : 
  
 [ 
  
 'lastUpdateTime' 
 , 
  
 'purchase.status' 
 , 
  
 'purchase.userVisibleStatusLabel' 
 , 
  
 ]. 
 join 
 ( 
 ',' 
 ), 
  
 order 
 : 
  
 { 
  
 merchantOrderId 
 : 
  
 orderId 
 , 
  
 // Specify the ID of the order to update 
  
 lastUpdateTime 
 : 
  
 new 
  
 Date 
 (). 
 toISOString 
 (), 
  
 purchase 
 : 
  
 { 
  
 status 
 : 
  
 'DELIVERED' 
 , 
  
 userVisibleStatusLabel 
 : 
  
 'Order delivered' 
 , 
  
 }, 
  
 }, 
  
 reason 
 : 
  
 'Order status updated to delivered.' 
 , 
 }); 
 // Set up the PATCH request header and body, 
 // including the authorized token and order update. 
 let 
  
 options 
  
 = 
  
 { 
  
 method 
 : 
  
 'PATCH' 
 , 
  
 uri 
 : 
  
 `https://actions.googleapis.com/v3/orders/ 
 ${ 
 orderId 
 } 
 ` 
 , 
  
 auth 
 : 
  
 { 
  
 bearer 
 : 
  
 tokens 
 . 
 access_token 
 , 
  
 }, 
  
 body 
 : 
  
 { 
  
 header 
 : 
  
 { 
  
 isInSandbox 
 : 
  
 true 
 , 
  
 }, 
  
 orderUpdate 
 , 
  
 }, 
  
 json 
 : 
  
 true 
 , 
 }; 
 // Send the PATCH request to the Orders API. 
 try 
  
 { 
  
 await 
  
 request 
 ( 
 options 
 ); 
  
 conv 
 . 
 close 
 ( 
 `The order has been updated.` 
 ); 
 } 
  
 catch 
  
 ( 
 e 
 ) 
  
 { 
  
 console 
 . 
 log 
 ( 
 `Error: 
 ${ 
 e 
 } 
 ` 
 ); 
  
 conv 
 . 
 close 
 ( 
 `There was an error sending an order update.` 
 ); 
 } 
  

Node.js

 // Import the 'googleapis' module for authorizing the request. 
 const 
  
 { 
 google 
 } 
  
 = 
  
 require 
 ( 
 'googleapis' 
 ); 
 // Import the 'request-promise' module for sending an HTTP POST request. 
 const 
  
 request 
  
 = 
  
 require 
 ( 
 'request-promise' 
 ); 
 // Import the OrderUpdate class from the Actions on Google client library. 
 const 
  
 { 
 OrderUpdate 
 } 
  
 = 
  
 require 
 ( 
 'actions-on-google' 
 ); 
 // Import the service account key used to authorize the request. 
 // Replacing the string path with a path to your service account key. 
 // i.e. const serviceAccountKey = require('./service-account.json') 
 // Create a new JWT client for the Actions API using credentials 
 // from the service account key. 
 let 
  
 jwtClient 
  
 = 
  
 new 
  
 google 
 . 
 auth 
 . 
 JWT 
 ( 
  
 serviceAccountKey 
 . 
 client_email 
 , 
  
 null 
 , 
  
 serviceAccountKey 
 . 
 private_key 
 , 
  
 [ 
 'https://www.googleapis.com/auth/actions.order.developer' 
 ], 
  
 null 
 , 
 ); 
 // Authorize the client 
 let 
  
 tokens 
  
 = 
  
 await 
  
 jwtClient 
 . 
 authorize 
 (); 
 // Declare order update 
 const 
  
 orderUpdate 
  
 = 
  
 new 
  
 OrderUpdate 
 ({ 
  
 updateMask 
 : 
  
 [ 
  
 'lastUpdateTime' 
 , 
  
 'purchase.status' 
 , 
  
 'purchase.userVisibleStatusLabel' 
 , 
  
 ]. 
 join 
 ( 
 ',' 
 ), 
  
 order 
 : 
  
 { 
  
 merchantOrderId 
 : 
  
 orderId 
 , 
  
 // Specify the ID of the order to update 
  
 lastUpdateTime 
 : 
  
 new 
  
 Date 
 (). 
 toISOString 
 (), 
  
 purchase 
 : 
  
 { 
  
 status 
 : 
  
 'DELIVERED' 
 , 
  
 userVisibleStatusLabel 
 : 
  
 'Order delivered' 
 , 
  
 }, 
  
 }, 
  
 reason 
 : 
  
 'Order status updated to delivered.' 
 , 
 }); 
 // Set up the PATCH request header and body, 
 // including the authorized token and order update. 
 let 
  
 options 
  
 = 
  
 { 
  
 method 
 : 
  
 'PATCH' 
 , 
  
 uri 
 : 
  
 `https://actions.googleapis.com/v3/orders/ 
 ${ 
 orderId 
 } 
 ` 
 , 
  
 auth 
 : 
  
 { 
  
 bearer 
 : 
  
 tokens 
 . 
 access_token 
 , 
  
 }, 
  
 body 
 : 
  
 { 
  
 header 
 : 
  
 { 
  
 isInSandbox 
 : 
  
 true 
 , 
  
 }, 
  
 orderUpdate 
 , 
  
 }, 
  
 json 
 : 
  
 true 
 , 
 }; 
 // Send the PATCH request to the Orders API. 
 try 
  
 { 
  
 await 
  
 request 
 ( 
 options 
 ); 
  
 conv 
 . 
 close 
 ( 
 `The order has been updated.` 
 ); 
 } 
  
 catch 
  
 ( 
 e 
 ) 
  
 { 
  
 console 
 . 
 log 
 ( 
 `Error: 
 ${ 
 e 
 } 
 ` 
 ); 
  
 conv 
 . 
 close 
 ( 
 `There was an error sending an order update.` 
 ); 
 } 
  

Java

 // Setup service account credentials 
 String 
  
 serviceAccountFile 
  
 = 
  
 MyActionsApp 
 . 
 class 
 . 
 getClassLoader 
 () 
  
 . 
 getResource 
 ( 
 SERVICE_ACCOUNT_KEY_FILE_NAME 
 ) 
  
 . 
 getFile 
 (); 
 InputStream 
  
 actionsApiServiceAccount 
  
 = 
  
 new 
  
 FileInputStream 
 ( 
  
 serviceAccountFile 
 ); 
 ServiceAccountCredentials 
  
 serviceAccountCredentials 
  
 = 
  
 ( 
 ServiceAccountCredentials 
 ) 
  
 ServiceAccountCredentials 
 . 
 fromStream 
 ( 
 actionsApiServiceAccount 
 ) 
  
 . 
 createScoped 
 ( 
 Collections 
 . 
 singleton 
 ( 
  
 "https://www.googleapis.com/auth/actions.order.developer" 
 )); 
 AccessToken 
  
 token 
  
 = 
  
 serviceAccountCredentials 
 . 
 refreshAccessToken 
 (); 
 // Setup request with headers 
 HttpPatch 
  
 patchRequest 
  
 = 
  
 new 
  
 HttpPatch 
 ( 
  
 "https://actions.googleapis.com/v3/orders/" 
  
 + 
  
 orderId 
 ); 
 patchRequest 
 . 
 setHeader 
 ( 
 "Content-type" 
 , 
  
 "application/json" 
 ); 
 patchRequest 
 . 
 setHeader 
 ( 
 "Authorization" 
 , 
  
 "Bearer " 
  
 + 
  
 token 
 . 
 getTokenValue 
 ()); 
 // Create order update 
 FieldMask 
  
 fieldMask 
  
 = 
  
 FieldMask 
 . 
 newBuilder 
 (). 
 addAllPaths 
 ( 
 Arrays 
 . 
 asList 
 ( 
  
 "lastUpdateTime" 
 , 
  
 "purchase.status" 
 , 
  
 "purchase.userVisibleStatusLabel" 
 )) 
  
 . 
 build 
 (); 
 OrderUpdateV3 
  
 orderUpdate 
  
 = 
  
 new 
  
 OrderUpdateV3 
 () 
  
 . 
 setOrder 
 ( 
 new 
  
 OrderV3 
 () 
  
 . 
 setMerchantOrderId 
 ( 
 orderId 
 ) 
  
 . 
 setLastUpdateTime 
 ( 
 Instant 
 . 
 now 
 (). 
 toString 
 ()) 
  
 . 
 setPurchase 
 ( 
 new 
  
 PurchaseOrderExtension 
 () 
  
 . 
 setStatus 
 ( 
 "DELIVERED" 
 ) 
  
 . 
 setUserVisibleStatusLabel 
 ( 
 "Order delivered." 
 ))) 
  
 . 
 setUpdateMask 
 ( 
 FieldMaskUtil 
 . 
 toString 
 ( 
 fieldMask 
 )) 
  
 . 
 setReason 
 ( 
 "Order status was updated to delivered." 
 ); 
 // Setup JSON body containing order update 
 JsonParser 
  
 parser 
  
 = 
  
 new 
  
 JsonParser 
 (); 
 JsonObject 
  
 orderUpdateJson 
  
 = 
  
 parser 
 . 
 parse 
 ( 
 new 
  
 Gson 
 (). 
 toJson 
 ( 
 orderUpdate 
 )). 
 getAsJsonObject 
 (); 
 JsonObject 
  
 body 
  
 = 
  
 new 
  
 JsonObject 
 (); 
 body 
 . 
 add 
 ( 
 "orderUpdate" 
 , 
  
 orderUpdateJson 
 ); 
 JsonObject 
  
 header 
  
 = 
  
 new 
  
 JsonObject 
 (); 
 header 
 . 
 addProperty 
 ( 
 "isInSandbox" 
 , 
  
 true 
 ); 
 body 
 . 
 add 
 ( 
 "header" 
 , 
  
 header 
 ); 
 StringEntity 
  
 entity 
  
 = 
  
 new 
  
 StringEntity 
 ( 
 body 
 . 
 toString 
 ()); 
 entity 
 . 
 setContentType 
 ( 
 ContentType 
 . 
 APPLICATION_JSON 
 . 
 getMimeType 
 ()); 
 patchRequest 
 . 
 setEntity 
 ( 
 entity 
 ); 
 // Make request 
 HttpClient 
  
 httpClient 
  
 = 
  
 HttpClientBuilder 
 . 
 create 
 (). 
 build 
 (); 
 HttpResponse 
  
 response 
  
 = 
  
 httpClient 
 . 
 execute 
 ( 
 patchRequest 
 ); 
 LOGGER 
 . 
 info 
 ( 
 response 
 . 
 getStatusLine 
 (). 
 getStatusCode 
 () 
  
 + 
  
 " " 
  
 + 
  
 response 
  
 . 
 getStatusLine 
 (). 
 getReasonPhrase 
 ()); 
 return 
  
 getResponseBuilder 
 ( 
 request 
 ) 
  
 . 
 add 
 ( 
 "The order has been updated." 
 ) 
  
 . 
 build 
 (); 
  

Java

 // Setup service account credentials 
 String 
  
 serviceAccountFile 
  
 = 
  
 MyActionsApp 
 . 
 class 
 . 
 getClassLoader 
 () 
  
 . 
 getResource 
 ( 
 SERVICE_ACCOUNT_KEY_FILE_NAME 
 ) 
  
 . 
 getFile 
 (); 
 InputStream 
  
 actionsApiServiceAccount 
  
 = 
  
 new 
  
 FileInputStream 
 ( 
  
 serviceAccountFile 
 ); 
 ServiceAccountCredentials 
  
 serviceAccountCredentials 
  
 = 
  
 ( 
 ServiceAccountCredentials 
 ) 
  
 ServiceAccountCredentials 
 . 
 fromStream 
 ( 
 actionsApiServiceAccount 
 ) 
  
 . 
 createScoped 
 ( 
 Collections 
 . 
 singleton 
 ( 
  
 "https://www.googleapis.com/auth/actions.order.developer" 
 )); 
 AccessToken 
  
 token 
  
 = 
  
 serviceAccountCredentials 
 . 
 refreshAccessToken 
 (); 
 // Setup request with headers 
 HttpPatch 
  
 patchRequest 
  
 = 
  
 new 
  
 HttpPatch 
 ( 
  
 "https://actions.googleapis.com/v3/orders/" 
  
 + 
  
 orderId 
 ); 
 patchRequest 
 . 
 setHeader 
 ( 
 "Content-type" 
 , 
  
 "application/json" 
 ); 
 patchRequest 
 . 
 setHeader 
 ( 
 "Authorization" 
 , 
  
 "Bearer " 
  
 + 
  
 token 
 . 
 getTokenValue 
 ()); 
 // Create order update 
 FieldMask 
  
 fieldMask 
  
 = 
  
 FieldMask 
 . 
 newBuilder 
 (). 
 addAllPaths 
 ( 
 Arrays 
 . 
 asList 
 ( 
  
 "lastUpdateTime" 
 , 
  
 "purchase.status" 
 , 
  
 "purchase.userVisibleStatusLabel" 
 )) 
  
 . 
 build 
 (); 
 OrderUpdateV3 
  
 orderUpdate 
  
 = 
  
 new 
  
 OrderUpdateV3 
 () 
  
 . 
 setOrder 
 ( 
 new 
  
 OrderV3 
 () 
  
 . 
 setMerchantOrderId 
 ( 
 orderId 
 ) 
  
 . 
 setLastUpdateTime 
 ( 
 Instant 
 . 
 now 
 (). 
 toString 
 ()) 
  
 . 
 setPurchase 
 ( 
 new 
  
 PurchaseOrderExtension 
 () 
  
 . 
 setStatus 
 ( 
 "DELIVERED" 
 ) 
  
 . 
 setUserVisibleStatusLabel 
 ( 
 "Order delivered." 
 ))) 
  
 . 
 setUpdateMask 
 ( 
 FieldMaskUtil 
 . 
 toString 
 ( 
 fieldMask 
 )) 
  
 . 
 setReason 
 ( 
 "Order status was updated to delivered." 
 ); 
 // Setup JSON body containing order update 
 JsonParser 
  
 parser 
  
 = 
  
 new 
  
 JsonParser 
 (); 
 JsonObject 
  
 orderUpdateJson 
  
 = 
  
 parser 
 . 
 parse 
 ( 
 new 
  
 Gson 
 (). 
 toJson 
 ( 
 orderUpdate 
 )). 
 getAsJsonObject 
 (); 
 JsonObject 
  
 body 
  
 = 
  
 new 
  
 JsonObject 
 (); 
 body 
 . 
 add 
 ( 
 "orderUpdate" 
 , 
  
 orderUpdateJson 
 ); 
 JsonObject 
  
 header 
  
 = 
  
 new 
  
 JsonObject 
 (); 
 header 
 . 
 addProperty 
 ( 
 "isInSandbox" 
 , 
  
 true 
 ); 
 body 
 . 
 add 
 ( 
 "header" 
 , 
  
 header 
 ); 
 StringEntity 
  
 entity 
  
 = 
  
 new 
  
 StringEntity 
 ( 
 body 
 . 
 toString 
 ()); 
 entity 
 . 
 setContentType 
 ( 
 ContentType 
 . 
 APPLICATION_JSON 
 . 
 getMimeType 
 ()); 
 patchRequest 
 . 
 setEntity 
 ( 
 entity 
 ); 
 // Make request 
 HttpClient 
  
 httpClient 
  
 = 
  
 HttpClientBuilder 
 . 
 create 
 (). 
 build 
 (); 
 HttpResponse 
  
 response 
  
 = 
  
 httpClient 
 . 
 execute 
 ( 
 patchRequest 
 ); 
 LOGGER 
 . 
 info 
 ( 
 response 
 . 
 getStatusLine 
 (). 
 getStatusCode 
 () 
  
 + 
  
 " " 
  
 + 
  
 response 
  
 . 
 getStatusLine 
 (). 
 getReasonPhrase 
 ()); 
 return 
  
 getResponseBuilder 
 ( 
 request 
 ) 
  
 . 
 add 
 ( 
 "The order has been updated." 
 ) 
  
 . 
 build 
 (); 
  
Set the purchase status

An order update's status must be descriptive of the current state of the order. In your update's order.purchase.status field, use one of the following values:

  • CREATED - Order is accepted by the user and "created" from the perspective of your Action but requires manual processing on your back-end.
  • CONFIRMED - Order is active and being processed for fulfillment.
  • IN_PREPARATION - Order is being prepared for shipment/delivery, such as food being cooked or an item being packaged.
  • READY_FOR_PICKUP - Order is available for pick-up by the recipient.
  • DELIVERED - Order has been delivered to the recipient
  • OUT_OF_STOCK - One or more items in the order is out-of-stock.
  • CHANGE_REQUESTED - User requested a change to the order, and the change is being processed.
  • RETURNED - Order has been returned by the user after delivery.
  • REJECTED - If you were unable to process, charge, or otherwise "activate" the order.
  • CANCELLED - Order was cancelled by the user.

You should send order updates for each status that is relevant to your transaction. For example, if your transaction requires manual processing to log the order after it's placed, send a CREATED order update until that additional processing is done. Not every order requires every status value.

Troubleshooting

If you run into any issues during testing, you should read our troubleshooting steps for transactions.

Design a Mobile Site
View Site in Mobile | Classic
Share by: