העברת עסקאות במוצרים פיזיים לגרסה 3 (Dialogflow)

ב-7 באוגוסט 2019 הוצאנו משימוש את Orders v2 API והוחלף ב-Orders גרסה 3. אם יצרתם פעולה שמטפלת בעסקאות פיזיות לפני התאריך הזה, תוכלו להיעזר במדריך הזה כדי לעדכן את הפעולה כך שתשתמש ב-Orders v3.

שינויים ב-API

גרסה 3 של Orders API כוללת את השינויים העיקריים הבאים מגרסה 2:

  • מבנה הבקשה – מבנה ההזמנה בגרסה 3 מכיל את כל פרטי ההזמנה, ולא רק את תוכן העגלה.
  • Orders (עדכוני הזמנות) – הגרסה 3 Orders API מטפלת בעדכוני הזמנות בנוסף לטיפול במיקומי ההזמנות, כך שנקודת הקצה שלכם לא צריכה להשתמש ב-Actions API כדי לשלוח למשתמשים עדכונים לגבי ההזמנות שלהם. בנוסף, העדכונים נשלחים ל-Orders API כבקשות PATCH שמעדכנות את אובייקט order הקיים, במקום בקשות POST לשליחת עדכוני סטטוס.
  • סיוע בתשלומים – פעולות שבהן נעשה שימוש ב-Google Pay בגרסה 3 ה-API של ההזמנות מקונן את הפרטים של שער התשלומים במבנה JSON חדש, שמאפשר הרחבה וציות לחוקי האיחוד האירופי.

העברת Node.JS לגרסה 3

כדי להעביר פעולה שמשתמשת בספריית הלקוח של Node.JS, יש לבצע את השלבים הבאים.

1. הוספת הסימון של Orders v3

הפונקציות של ספריית הלקוח שהשתמשתם בהן לטיפול בעסקאות מתעדכנות בהזמנות מגרסה 3. צריך רק להוסיף סימון לקוד מילוי ההזמנות כדי לעדכן את הפונקציות כך שישלחו את גרסה 3 של JSON.

יש להוסיף את הקוד הבא למילוי הבקשה:

Node.js
const {dialogflow} = require('actions-on-google');
const app = dialogflow({ordersv3: true});

2. עדכון הרכבת של עגלת הקניות

הסוג ProposedOrder הוחלף באובייקט Order המפורט יותר. כדי להמיר את עגלת הקניות של ProposedOrder לעגלה מסוג Order, אפשר להיעזר בקובץ העזר ב-JSON.

3. עדכון פרמטרים של תשלומים

המבנה של פרטי התשלום בשלב של הצעת ההזמנה שונה בין גרסאות ה-API.

בבקשת ה-Intent actions.intent.TRANSACTION_DECISION, מחליפים את האובייקט paymentOptions הישן באובייקט paymentParameters החדש. רוב השדות הכלולים זהים, למעט חלק מהשינויים במבנה של אובייקט ה-JSON.

קטעי הקוד הבאים מציגים דוגמה של בקשת actions.intent.TRANSACTION_DECISION ל-Google Pay עם גרסה 3, ובקשת השוואה בגרסה 2 ישנה יותר.

Node.JS חדש (v3)
conv.ask(new TransactionDecision({
  orderOptions: {
    requestDeliveryAddress: false,
    userInfoOptions: {
      userInfoProperties: [
        'EMAIL',
      ],
    },
  },
  paymentParameters: {
    googlePaymentOption: {
      // facilitationSpec is expected to be a serialized JSON string
      facilitationSpec: JSON.stringify({
        apiVersion: 2,
        apiVersionMinor: 0,
        merchantInfo: {
          merchantName: 'Example Merchant',
        },
        allowedPaymentMethods: [
          {
            type: 'CARD',
            parameters: {
              allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
              allowedCardNetworks: [
                'AMEX', 'DISCOVER', 'JCB', 'MASTERCARD', 'VISA'],
            },
            tokenizationSpecification: {
              type: 'PAYMENT_GATEWAY',
              parameters: {
                gateway: 'example',
                gatewayMerchantId: 'exampleGatewayMerchantId',
              },
            },
          },
        ],
        transactionInfo: {
          totalPriceStatus: 'FINAL',
          totalPrice: '10.00',
          currencyCode: 'USD',
        },
      }),
    },
  },
  presentationOptions: {
    actionDisplayName: 'PLACE_ORDER',
  },
  order: order,
}));
Node.JS ישן (v2)
conv.ask(new TransactionDecision({
  orderOptions: {
    requestDeliveryAddress: false,
  },
  paymentOptions: {
    googleProvidedOptions: {
      prepaidCardDisallowed: false,
      supportedCardNetworks: ['VISA', 'AMEX', 'DISCOVER', 'MASTERCARD'],
      tokenizationParameters: {
        tokenizationType: 'PAYMENT_GATEWAY',
        // These will be provided by payment processor,
        // like Stripe, Braintree, Vantiv, Ayden, etc.
        parameters: {
          'gateway': 'stripe',
          'stripe:publishableKey': (conv.sandbox ? 'pk_test_key' : 'pk_live_key'),
          'stripe:version': '2018-11-08'
        },
      },
    },
  },
  proposedOrder: order,
}));
JSON New (גרסה 3)

שימו לב: בקובץ ה-JSON שלמטה מתוארת תגובה של תגובה לפעולה מאתר אחר (webhook).

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "systemIntent": {
        "intent": "actions.intent.TRANSACTION_DECISION",
        "data": {
          "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec",
          "orderOptions": {
            "requestDeliveryAddress": "false"
          },
          "paymentParameters": {
            "googlePaymentOption": {
              "facilitationSpec": "{\"apiVersion\":2,\"apiVersionMinor\":0,\"merchantInfo\":{\"merchantName\":\"Example Merchant\"},\"allowedPaymentMethods\":[{\"type\":\"CARD\",\"parameters\":{\"allowedAuthMethods\":[\"PAN_ONLY\",\"CRYPTOGRAM_3DS\"],\"allowedCardNetworks\":[\"AMEX\",\"DISCOVER\",\"JCB\",\"MASTERCARD\",\"VISA\"]},\"tokenizationSpecification\":{\"type\":\"PAYMENT_GATEWAY\",\"parameters\":{\"gateway\":\"example\",\"gatewayMerchantId\":\"exampleGatewayMerchantId\"}}}],\"transactionInfo\":{\"totalPriceStatus\":\"FINAL\",\"totalPrice\":\"10.00\",\"currencyCode\":\"USD\"}}"
            }
          },
          "presentationOptions": {
            "actionDisplayName": "PLACE_ORDER"
          },
          "order": {
            "createTime": "2019-08-01T17:12:13.765Z",
            "lastUpdateTime": "2019-08-01T17:12:13.765Z",
            "merchantOrderId": "UNIQUE_ORDER_ID",
            "userVisibleOrderId": "USER_VISIBLE_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
                    }
                  ],
                  "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
                          }
                        ],
                        "note": "Extra pepperoni",
                        "quantity": 1,
                        "subOptions": []
                      }
                    ]
                  }
                }
              ]
            },
            "buyerInfo": {
              "email": "janedoe@gmail.com",
              "firstName": "Jane",
              "lastName": "Doe",
              "displayName": "Jane Doe"
            },
            "priceAttributes": [
              {
                "type": "TOTAL",
                "name": "Total Price",
                "state": "ESTIMATE",
                "amount": {
                  "currencyCode": "USD",
                  "amountInMicros": 15770000
                },
                "taxIncluded": true
              },
              {
                "type": "TAX",
                "name": "Tax",
                "state": "ESTIMATE",
                "amount": {
                  "currencyCode": "USD",
                  "amountInMicros": 3780000
                },
                "taxIncluded": true
              },
              {
                "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
              }
            ],
            "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": "2017-01-16T01:30:15.01Z"
                },
                "location": {
                  "zipCode": "94086",
                  "city": "Sunnyvale",
                  "postalAddress": {
                    "regionCode": "US",
                    "postalCode": "94086",
                    "administrativeArea": "CA",
                    "locality": "Sunnyvale",
                    "addressLines": [
                      "222, Some other Street"
                    ]
                  }
                },
                "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"
            }
          }
        }
      }
    }
  }
}
JSON ישן (גרסה 2)

שימו לב: בקובץ ה-JSON שלמטה מתוארת תגובה של תגובה לפעולה מאתר אחר (webhook).

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "systemIntent": {
        "intent": "actions.intent.TRANSACTION_DECISION",
        "data": {
          "@type": "type.googleapis.com/google.actions.v2.TransactionDecisionValueSpec",
          "orderOptions": {
            "requestDeliveryAddress": false
          },
          "paymentOptions": {
            "googleProvidedOptions": {
              "prepaidCardDisallowed": false,
              "supportedCardNetworks": [
                "VISA",
                "AMEX",
                "DISCOVER",
                "MASTERCARD"
              ],
              "tokenizationParameters": {
                "tokenizationType": "PAYMENT_GATEWAY",
                "parameters": {
                  "gateway": "stripe",
                  "stripe:publishableKey": "pk_test_key",
                  "stripe:version": "2018-11-08"
                }
              }
            }
          },
          "proposedOrder": {
            "id": "UNIQUE_ORDER_ID222",
            "cart": {
              "merchant": {
                "id": "book_store_id",
                "name": "A Book Store"
              },
              "lineItems": [
                {
                  "name": "My Memoirs",
                  "id": "mymemoirs_id",
                  "price": {
                    "amount": {
                      "currencyCode": "USD",
                      "nanos": 990000000,
                      "units": 8
                    },
                    "type": "ACTUAL"
                  },
                  "quantity": 1,
                  "subLines": [
                    {
                      "note": "By Bestselling Novelist"
                    }
                  ],
                  "type": "REGULAR"
                },
                {
                  "name": "Biography",
                  "id": "biography_id",
                  "price": {
                    "amount": {
                      "currencyCode": "USD",
                      "nanos": 990000000,
                      "units": 10
                    },
                    "type": "ACTUAL"
                  },
                  "quantity": 1,
                  "subLines": [
                    {
                      "note": "Signed copy"
                    }
                  ],
                  "type": "REGULAR"
                }
              ],
              "notes": "Sale event",
              "otherItems": []
            },
            "otherItems": [
              {
                "name": "Subtotal",
                "id": "subtotal",
                "price": {
                  "amount": {
                    "currencyCode": "USD",
                    "nanos": 980000000,
                    "units": 19
                  },
                  "type": "ESTIMATE"
                },
                "type": "SUBTOTAL"
              },
              {
                "name": "Tax",
                "id": "tax",
                "price": {
                  "amount": {
                    "currencyCode": "USD",
                    "nanos": 780000000,
                    "units": 2
                  },
                  "type": "ESTIMATE"
                },
                "type": "TAX"
              }
            ],
            "totalPrice": {
              "amount": {
                "currencyCode": "USD",
                "nanos": 760000000,
                "units": 22
              },
              "type": "ESTIMATE"
            }
          }
        }
      }
    }
  }
}

4. שליחת עדכונים באמצעות Orders API

גרסה 3 של Orders API מטפלת בעדכוני הזמנות, כך שאין יותר צורך לשלוח בקשות POST ל-Actions API. במקום זאת, צריך לשלוח בקשת PATCH ל-Orders API, שמעדכן את התוכן של האובייקט Order.

אחזור אסימון חדש למוכ"ז

תוכלו להשתמש באותו מפתח של חשבון שירות JSON שבו השתמשתם כדי לאחזר אסימון למוכ"ז ל-Actions API, תצטרכו לבקש אסימון חדש למוכ"ז ל-Orders API. מחליפים את מפתח השירות בקוד למוכ"ז באמצעות ספריית הלקוח של Google APIs וההיקף של "https://www.googleapis.com/auth/actions.order.developer".

שלבי ההתקנה ודוגמאות מפורטים בדף של GitHub בספריית הלקוח של ה-API. אתם יכולים גם לעיין ב-order-update.js המעודכן בדוגמת Node.js לקבלת דוגמה להחלפת מפתחות API של Orders API.

שליחת עדכונים

תהליך השליחה של עדכון הזמנות באמצעות Orders API דומה לשליחת עדכונים באמצעות Actions API, אלא שאתם שולחים בקשת PATCH ולא בקשת POST. בקשת ה-PATCH צריכה לכלול גוף JSON בפורמט הבא:

{ "orderUpdate": OrderUpdate" }

הפורמט OrderUpdate שונה גם בגרסה 3. עיינו בחומר העזר בנושא בקשת PATCH ועדכנו את השדות של OrderUpdate בהתאם. קטע הקוד הבא מציג בקשת PATCH לדוגמה שמעדכנת את סטטוס ההזמנה ל-"DELIVERED":

Node.js
// Import the 'googleapis' module for authorizing the request.
const {google} = require('googleapis');
// Import the 'request' module for sending an HTTP POST request.
const request = require('request');
// 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. Replace the string path with a path to your service account key.
const key = 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(
    key.client_email,
    null,
    key.private_key,
    ['https://www.googleapis.com/auth/actions.order.developer'],
    null
);
// Authorize the client asynchronously, passing in a callback to run upon authorization.
jwtClient.authorize((err, tokens) => {
    if (err) {
        console.log(err);
        return;
    }
    // Declare the ID of the order to update.
    const orderId = '<UNIQUE_MERCHANT_ORDER_ID>';

    const orderUpdate = new OrderUpdate({
        updateMask: [
          'lastUpdateTime',
          'purchase.status',
          'purchase.userVisibleStatusLabel',
        ].join(','),
        order: {
          merchantOrderId: orderId,
          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.
    const bearer = 'Bearer ' + tokens.access_token;
    const options = {
        method: 'PATCH',
        url: `https://actions.googleapis.com/v3/orders/${orderId}`,
        headers: {
          'Authorization': bearer,
        },
        body: {
          header: {
            'isInSandbox': true,
          },
          orderUpdate,
        },
        json: true,
      };
    // Send the PATCH request to the Orders API.
    request.patch(options, (err, httpResponse, body) => {
        if (err) {
            console.log('There was an error...');
            console.log(err);
            return;
        }
    });
});

טיפול בסטטוסים נוספים של הזמנות

גרסה 3 של Orders API תומכת בערכים נוספים של סטטוס הזמנה שלא היו זמינים בגרסה 2. חשוב לשלוח עדכוני הזמנות לכל סטטוס שרלוונטי לכל עסקה.

ערכי הסטטוס הבאים הם חדשים בגרסה 3:

  • IN_PREPARATION - ההזמנה נמצאת בשלבי הכנה למשלוח/משלוח, כמו בישול אוכל של פריט באריזה.
  • READY_FOR_PICKUP - ההזמנה זמינה לאיסוף על ידי הנמען.
  • DELIVERED – ההזמנה נמסרה לנמען
  • OUT_OF_STOCK - פריט אחד או יותר בהזמנה חסרים במלאי.
  • CHANGE_REQUESTED – משתמש ביקש לבצע שינוי בהזמנה והשינוי נמצא בתהליך עיבוד.

הסטטוס FULFILLED הוצא משימוש והוחלף בסטטוס DELIVERED.

העברת Java ל-v3

כדי להעביר פעולה שמשתמשת בספריית הלקוח של Java, מבצעים את השלבים הבאים.

1. עדכון הרכבת של עגלת הקניות

הסוג ProposedOrder הוחלף באובייקט Order המפורט יותר. כדי להמיר את עגלת הקניות של ProposedOrder לעגלה מסוג Order, אפשר להיעזר בקובץ העזר ב-JSON.

2. עדכון פרמטרים של תשלומים

המבנה של פרטי התשלום בשלב של הצעת ההזמנה שונה בין גרסאות ה-API.

בבקשת ה-Intent actions.intent.TRANSACTION_DECISION, מחליפים את האובייקט paymentOptions הישן באובייקט paymentParameters החדש. רוב השדות הכלולים זהים, למעט חלק מהשינויים במבנה של אובייקט ה-JSON.

קטעי הקוד הבאים מציגים דוגמה של בקשת actions.intent.TRANSACTION_DECISION ל-Google Pay עם גרסה 3, ובקשת השוואה בגרסה 2 ישנה יותר.

Java (גרסה 3)
// Create order options
OrderOptionsV3 orderOptions = new OrderOptionsV3()
    .setRequestDeliveryAddress(false)
    .setUserInfoOptions(new UserInfoOptions()
        .setUserInfoProperties(Collections.singletonList("EMAIL")));

// Create presentation options
PresentationOptionsV3 presentationOptions = new PresentationOptionsV3()
    .setActionDisplayName("PLACE_ORDER");

// Create payment parameters
JSONObject merchantInfo = new JSONObject();
merchantInfo.put("merchantName", "Example Merchant");

JSONObject facilitationSpec = new JSONObject();
facilitationSpec.put("apiVersion", 2);
facilitationSpec.put("apiVersionMinor", 0);
facilitationSpec.put("merchantInfo", merchantInfo);

JSONObject allowedPaymentMethod = new JSONObject();
allowedPaymentMethod.put("type", "CARD");

JSONArray allowedAuthMethods = new JSONArray();
allowedAuthMethods.addAll(Arrays.asList("PAN_ONLY", "CRYPTOGRAM_3DS"));
JSONArray allowedCardNetworks = new JSONArray();
allowedCardNetworks.addAll(Arrays.asList("AMEX", "DISCOVER", "JCB", "MASTERCARD", "VISA"));

JSONObject allowedPaymentMethodParameters = new JSONObject();
allowedPaymentMethodParameters.put("allowedAuthMethods", allowedAuthMethods);
allowedPaymentMethodParameters.put("allowedCardNetworks", allowedCardNetworks);

allowedPaymentMethod.put("parameters", allowedPaymentMethodParameters);

JSONObject tokenizationSpecificationParameters = new JSONObject();
tokenizationSpecificationParameters.put("gateway", "example");
tokenizationSpecificationParameters.put("gatewayMerchantId", "exampleGatewayMerchantId");

JSONObject tokenizationSpecification = new JSONObject();
tokenizationSpecification.put("type", "PAYMENT_GATEWAY");
tokenizationSpecification.put("parameters", tokenizationSpecificationParameters);
allowedPaymentMethod.put("tokenizationSpecification", tokenizationSpecification);

JSONArray allowedPaymentMethods = new JSONArray();
allowedPaymentMethods.add(allowedPaymentMethod);

facilitationSpec.put("allowedPaymentMethods", allowedPaymentMethods);

JSONObject transactionInfo = new JSONObject();
transactionInfo.put("totalPriceStatus", "FINAL");
transactionInfo.put("totalPrice", "10.00");
transactionInfo.put("currencyCode", "USD");

facilitationSpec.put("transactionInfo", transactionInfo);

GooglePaymentOption googlePaymentOption = new GooglePaymentOption()
    .setFacilitationSpec(facilitationSpec.toJSONString());

PaymentParameters paymentParameters = new PaymentParameters()
    .setGooglePaymentOption(googlePaymentOption);

// Ask for transaction decision
return getResponseBuilder(request)
    .add("Placeholder for transaction decision text")
    .add(new TransactionDecision()
        .setOrder(order)
        .setOrderOptions(orderOptions)
        .setPresentationOptions(presentationOptions)
        .setPaymentParameters(paymentParameters)
    )
    .build();
Java Old (v2)
OrderOptions orderOptions;
PaymentOptions paymentOptions;

// Setup Google provided payment options
Map<String, String> parameters = new HashMap<>();
parameters.put("gateway", "stripe");
parameters.put("stripe:publishableKey", request.isInSandbox() ? "pk_test_key" : "pk_live_key");
parameters.put("stripe:version", "2017-04-06");
PaymentMethodTokenizationParameters tokenizationParameters =
    new PaymentMethodTokenizationParameters()
        .setTokenizationType("PAYMENT_GATEWAY")
        .setParameters(parameters);
orderOptions = new OrderOptions().setRequestDeliveryAddress(false);
GoogleProvidedPaymentOptions googleProvidedPaymentOptions =
    new GoogleProvidedPaymentOptions()
        .setPrepaidCardDisallowed(false)
        .setSupportedCardNetworks(Arrays.asList("VISA", "AMEX"))
        .setTokenizationParameters(tokenizationParameters);
paymentOptions = new PaymentOptions().setGoogleProvidedOptions(googleProvidedPaymentOptions);

return getResponseBuilder(request)
    .add("Placeholder for transaction decision text")
    .add(
        new TransactionDecision()
            .setOrderOptions(orderOptions)
            .setPaymentOptions(paymentOptions)
            .setProposedOrder(proposedOrder))
    .build();
JSON New (גרסה 3)

שימו לב: בקובץ ה-JSON שלמטה מתוארת תגובה של תגובה לפעולה מאתר אחר (webhook).

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "systemIntent": {
        "intent": "actions.intent.TRANSACTION_DECISION",
        "data": {
          "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec",
          "orderOptions": {
            "requestDeliveryAddress": "false"
          },
          "paymentParameters": {
            "googlePaymentOption": {
              "facilitationSpec": "{\"apiVersion\":2,\"apiVersionMinor\":0,\"merchantInfo\":{\"merchantName\":\"Example Merchant\"},\"allowedPaymentMethods\":[{\"type\":\"CARD\",\"parameters\":{\"allowedAuthMethods\":[\"PAN_ONLY\",\"CRYPTOGRAM_3DS\"],\"allowedCardNetworks\":[\"AMEX\",\"DISCOVER\",\"JCB\",\"MASTERCARD\",\"VISA\"]},\"tokenizationSpecification\":{\"type\":\"PAYMENT_GATEWAY\",\"parameters\":{\"gateway\":\"example\",\"gatewayMerchantId\":\"exampleGatewayMerchantId\"}}}],\"transactionInfo\":{\"totalPriceStatus\":\"FINAL\",\"totalPrice\":\"10.00\",\"currencyCode\":\"USD\"}}"
            }
          },
          "presentationOptions": {
            "actionDisplayName": "PLACE_ORDER"
          },
          "order": {
            "createTime": "2019-08-01T17:12:13.765Z",
            "lastUpdateTime": "2019-08-01T17:12:13.765Z",
            "merchantOrderId": "UNIQUE_ORDER_ID",
            "userVisibleOrderId": "USER_VISIBLE_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
                    }
                  ],
                  "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
                          }
                        ],
                        "note": "Extra pepperoni",
                        "quantity": 1,
                        "subOptions": []
                      }
                    ]
                  }
                }
              ]
            },
            "buyerInfo": {
              "email": "janedoe@gmail.com",
              "firstName": "Jane",
              "lastName": "Doe",
              "displayName": "Jane Doe"
            },
            "priceAttributes": [
              {
                "type": "TOTAL",
                "name": "Total Price",
                "state": "ESTIMATE",
                "amount": {
                  "currencyCode": "USD",
                  "amountInMicros": 15770000
                },
                "taxIncluded": true
              },
              {
                "type": "TAX",
                "name": "Tax",
                "state": "ESTIMATE",
                "amount": {
                  "currencyCode": "USD",
                  "amountInMicros": 3780000
                },
                "taxIncluded": true
              },
              {
                "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
              }
            ],
            "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": "2017-01-16T01:30:15.01Z"
                },
                "location": {
                  "zipCode": "94086",
                  "city": "Sunnyvale",
                  "postalAddress": {
                    "regionCode": "US",
                    "postalCode": "94086",
                    "administrativeArea": "CA",
                    "locality": "Sunnyvale",
                    "addressLines": [
                      "222, Some other Street"
                    ]
                  }
                },
                "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"
            }
          }
        }
      }
    }
  }
}
JSON ישן (גרסה 2)

שימו לב: בקובץ ה-JSON שלמטה מתוארת תגובה של תגובה לפעולה מאתר אחר (webhook).

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "systemIntent": {
        "intent": "actions.intent.TRANSACTION_DECISION",
        "data": {
          "@type": "type.googleapis.com/google.actions.v2.TransactionDecisionValueSpec",
          "orderOptions": {
            "requestDeliveryAddress": false
          },
          "paymentOptions": {
            "googleProvidedOptions": {
              "prepaidCardDisallowed": false,
              "supportedCardNetworks": [
                "VISA",
                "AMEX",
                "DISCOVER",
                "MASTERCARD"
              ],
              "tokenizationParameters": {
                "tokenizationType": "PAYMENT_GATEWAY",
                "parameters": {
                  "gateway": "stripe",
                  "stripe:publishableKey": "pk_test_key",
                  "stripe:version": "2018-11-08"
                }
              }
            }
          },
          "proposedOrder": {
            "id": "UNIQUE_ORDER_ID222",
            "cart": {
              "merchant": {
                "id": "book_store_id",
                "name": "A Book Store"
              },
              "lineItems": [
                {
                  "name": "My Memoirs",
                  "id": "mymemoirs_id",
                  "price": {
                    "amount": {
                      "currencyCode": "USD",
                      "nanos": 990000000,
                      "units": 8
                    },
                    "type": "ACTUAL"
                  },
                  "quantity": 1,
                  "subLines": [
                    {
                      "note": "By Bestselling Novelist"
                    }
                  ],
                  "type": "REGULAR"
                },
                {
                  "name": "Biography",
                  "id": "biography_id",
                  "price": {
                    "amount": {
                      "currencyCode": "USD",
                      "nanos": 990000000,
                      "units": 10
                    },
                    "type": "ACTUAL"
                  },
                  "quantity": 1,
                  "subLines": [
                    {
                      "note": "Signed copy"
                    }
                  ],
                  "type": "REGULAR"
                }
              ],
              "notes": "Sale event",
              "otherItems": []
            },
            "otherItems": [
              {
                "name": "Subtotal",
                "id": "subtotal",
                "price": {
                  "amount": {
                    "currencyCode": "USD",
                    "nanos": 980000000,
                    "units": 19
                  },
                  "type": "ESTIMATE"
                },
                "type": "SUBTOTAL"
              },
              {
                "name": "Tax",
                "id": "tax",
                "price": {
                  "amount": {
                    "currencyCode": "USD",
                    "nanos": 780000000,
                    "units": 2
                  },
                  "type": "ESTIMATE"
                },
                "type": "TAX"
              }
            ],
            "totalPrice": {
              "amount": {
                "currencyCode": "USD",
                "nanos": 760000000,
                "units": 22
              },
              "type": "ESTIMATE"
            }
          }
        }
      }
    }
  }
}

3. שליחת עדכונים באמצעות Orders API

גרסה 3 של Orders API מטפלת בעדכוני הזמנות, כך שאין יותר צורך לשלוח בקשות POST ל-Actions API. במקום זאת, צריך לשלוח בקשת PATCH ל-Orders API, שמעדכן את התוכן של האובייקט Order.

אחזור אסימון חדש למוכ"ז

תוכלו להשתמש באותו מפתח של חשבון שירות JSON שבו השתמשתם כדי לאחזר אסימון למוכ"ז ל-Actions API, תצטרכו לבקש אסימון חדש למוכ"ז ל-Orders API. מחליפים את מפתח השירות בקוד למוכ"ז באמצעות ספריית הלקוח של Google APIs וההיקף של "https://www.googleapis.com/auth/actions.order.developer".

שלבי ההתקנה ודוגמאות מפורטים בדף של GitHub בספריית הלקוח של ה-API. אתם יכולים גם לעיין ב-order-update.js המעודכן בדוגמת Java לדוגמה לחילופי מפתחות של Orders API.

שליחת עדכונים

תהליך השליחה של עדכון הזמנות באמצעות Orders API דומה לשליחת עדכונים באמצעות Actions API, אלא שאתם שולחים בקשת PATCH ולא בקשת POST. בקשת ה-PATCH צריכה לכלול גוף JSON בפורמט הבא:

{ "orderUpdate": OrderUpdate" }

הפורמט OrderUpdate שונה גם בגרסה 3. עיינו בחומר העזר בנושא בקשת PATCH ועדכנו את השדות של OrderUpdate בהתאם. קטע הקוד הבא מציג בקשת PATCH לדוגמה שמעדכנת את סטטוס ההזמנה ל-"DELIVERED":

Java
// Create order update
FieldMask fieldMask = FieldMask.newBuilder().addAllPaths(Arrays.asList(
    "last_update_time",
    "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());
request.setEntity(entity);

// Make request
HttpClient httpClient = HttpClientBuilder.create().build();
HttpResponse response = httpClient.execute(request);

טיפול בסטטוסים נוספים של הזמנות

גרסה 3 של Orders API תומכת בערכים נוספים של סטטוס הזמנה שלא היו זמינים בגרסה 2. חשוב לשלוח עדכוני הזמנות לכל סטטוס שרלוונטי לכל עסקה.

ערכי הסטטוס הבאים הם חדשים בגרסה 3:

  • IN_PREPARATION - ההזמנה נמצאת בשלבי הכנה למשלוח/משלוח, כמו בישול אוכל של פריט באריזה.
  • READY_FOR_PICKUP - ההזמנה זמינה לאיסוף על ידי הנמען.
  • DELIVERED – ההזמנה נמסרה לנמען
  • OUT_OF_STOCK - פריט אחד או יותר בהזמנה חסרים במלאי.
  • CHANGE_REQUESTED – משתמש ביקש לבצע שינוי בהזמנה והשינוי נמצא בתהליך עיבוד.

הסטטוס FULFILLED הוצא משימוש והוחלף בסטטוס DELIVERED.