نقل معاملات السلع المادية إلى الإصدار 3 (Dialogflow)

اعتبارًا من 7 آب (أغسطس) 2019، تم إيقاف واجهة برمجة التطبيقات Orders v2 API واستبدالها بالإصدار 3 من "الطلبات". إذا كنت قد أنشأت "إجراءً" يعالج معاملات مادية قبل هذا التاريخ، يُرجى اتّباع هذا الدليل لتعديل الإجراء الخاص بك لاستخدام الإصدار الثالث من الطلبات.

التغييرات في واجهة برمجة التطبيقات

يعرض الإصدار 3 من Orders API التغييرات الرئيسية التالية من الإصدار 2:

  • بنية الطلب - تحتوي بنية الطلب للإصدار 3 على جميع تفاصيل الطلب وليس محتوى سلة التسوق فقط.
  • تحديثات الطلبات - يعالج الإصدار 3 من Orders API تحديثات الطلبات بالإضافة إلى التعامل مع طلب تقديم الطلب، لذا لا تحتاج نقطة النهاية إلى استخدام Actions API لإرسال تحديثات إلى المستخدمين عن طلباتهم. يمكنك أيضًا إرسال التعديلات كطلبات PATCH إلى Orders API لتعديل عنصر order الحالي بدلاً من طلبات POST لإرسال تعديلات الحالة.
  • تسهيل عمليات الدفع: الإجراءات التي تستخدم Google Pay مع الإصدار 3 تدمج Orders API تفاصيل بوابة الدفع الخاصة بها في بنية JSON جديدة تسمح بمزيد من قابلية التوسّع والامتثال لقوانين الاتحاد الأوروبي

نقل Node.JS إلى الإصدار v3

اتّبِع الخطوات التالية لنقل إجراء يستخدم مكتبة عملاء Node.JS.

1- إضافة علامة الإصدار 3 من الطلبات

يتم تحديث وظائف مكتبة العملاء التي استخدمتها لمعالجة المعاملات لإصدار الطلبات 3، وما عليك سوى إضافة علامة إلى رمز التنفيذ الذي تستخدمه لتحديث الدوال لإرسال الإصدار 3 من JSON.

أضِف الرمز التالي إلى طريقة التنفيذ:

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

2. تعديل مجموعة سلة التسوّق

تم استبدال النوع ProposedOrder بالكائن Order الأكثر تفصيلاً. يمكنك الرجوع إلى مرجع JSON لتحويل سلة تسوّق ProposedOrder إلى سلة تسوّق Order.

3. تعديل مَعلمات الدفع

تختلف بنية معلومات الدفع في خطوة اقتراح الطلب بين إصدارات واجهة برمجة التطبيقات.

في طلب الغرض من actions.intent.TRANSACTION_DECISION، استبدِل الكائن paymentOptions القديم بالكائن paymentParameters الجديد. معظم الحقول المضمّنة هي نفسها، فاحفظ بعض التغييرات في بنية كائن JSON.

تعرض مقتطفات الرمز التالية مثالاً على طلب نية actions.intent.TRANSACTION_DECISION لخدمة Google Pay باستخدام الإصدار 3، وطلبًا قديمًا من الإصدار 2 للمقارنة.

Node.JS New (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 Old (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 (v3)

تجدر الإشارة إلى أنّ ملف JSON بتنسيق Dialogflow أدناه يصف استجابة الردّ التلقائي على الويب.

{
  "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 بتنسيق Dialogflow أدناه يصف استجابة الردّ التلقائي على الويب.

{
  "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. بدلاً من ذلك، يمكنك إرسال طلب تصحيح إلى واجهة Orders API لتعديل محتوى عنصر Order.

استرداد رمز حامل مميز جديد

يمكنك استخدام مفتاح حساب خدمة JSON نفسه الذي استخدمته لاسترداد رمز الحامل المميز لواجهة برمجة تطبيقات Actions API، وعليك طلب رمز حامل مميز جديد لواجهة برمجة التطبيقات Orders API. يمكنك استبدال مفتاح الخدمة برمز حامل مميّز باستخدام مكتبة برامج Google APIs والنطاق "https://www.googleapis.com/auth/actions.order.developer".

يمكنك العثور على خطوات التثبيت وأمثلة عليه في صفحة GitHub في مكتبة عميل واجهة برمجة التطبيقات. يمكنك أيضًا الرجوع إلى order-update.js المعدَّلة في نموذج Node.js كمثال لتبادل مفتاح واجهة برمجة التطبيقات Orders API.

إرسال آخر الأخبار

تتشابه عملية إرسال تحديث طلب باستخدام Orders API مع إرسال التحديثات باستخدام Actions API، على الرغم من أنّك ترسل طلب تصحيح بدلاً من طلب POST. يجب أن يأخذ طلب PATCH نص JSON بالتنسيق التالي:

{ "orderUpdate": OrderUpdate" }

يختلف تنسيق OrderUpdate أيضًا في الإصدار 3. يُرجى مراجعة مرجع طلب التصحيح وتعديل حقول 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 إلى الإصدار 3

اتبع هذه الخطوات لنقل إجراء يستخدم مكتبة عملاء Java.

1- تعديل مجموعة سلة التسوّق

تم استبدال النوع ProposedOrder بالكائن Order الأكثر تفصيلاً. يمكنك الرجوع إلى مرجع JSON لتحويل سلة تسوّق ProposedOrder إلى سلة تسوّق Order.

2. تعديل مَعلمات الدفع

تختلف بنية معلومات الدفع في خطوة اقتراح الطلب بين إصدارات واجهة برمجة التطبيقات.

في طلب الغرض من 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 (v3)

تجدر الإشارة إلى أنّ ملف JSON بتنسيق Dialogflow أدناه يصف استجابة الردّ التلقائي على الويب.

{
  "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 بتنسيق Dialogflow أدناه يصف استجابة الردّ التلقائي على الويب.

{
  "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. بدلاً من ذلك، يمكنك إرسال طلب تصحيح إلى واجهة Orders API لتعديل محتوى عنصر Order.

استرداد رمز حامل مميز جديد

يمكنك استخدام مفتاح حساب خدمة JSON نفسه الذي استخدمته لاسترداد رمز الحامل المميز لواجهة برمجة تطبيقات Actions API، وعليك طلب رمز حامل مميز جديد لواجهة برمجة التطبيقات Orders API. يمكنك استبدال مفتاح الخدمة برمز حامل مميّز باستخدام مكتبة برامج Google APIs والنطاق "https://www.googleapis.com/auth/actions.order.developer".

يمكنك العثور على خطوات التثبيت وأمثلة عليه في صفحة GitHub في مكتبة عميل واجهة برمجة التطبيقات. يمكنك أيضًا الرجوع إلى order-update.js المعدَّلة في نموذج Java للحصول على مثال على تبادل مفاتيح واجهة برمجة التطبيقات Orders API.

إرسال آخر الأخبار

تتشابه عملية إرسال تحديث طلب باستخدام Orders API مع إرسال التحديثات باستخدام Actions API، على الرغم من أنّك ترسل طلب تصحيح بدلاً من طلب POST. يجب أن يأخذ طلب PATCH نص JSON بالتنسيق التالي:

{ "orderUpdate": OrderUpdate" }

يختلف تنسيق OrderUpdate أيضًا في الإصدار 3. يُرجى مراجعة مرجع طلب التصحيح وتعديل حقول 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.