انتقال تراکنش‌های کالاهای فیزیکی به نسخه 3 (Dialogflow)

از 7 آگوست 2019، Orders v2 API منسوخ شد و Orders نسخه 3 جایگزین آن شد. اگر اقدامی ساخته‌اید که تراکنش‌های فیزیکی را قبل از این تاریخ انجام می‌دهد، این راهنما را دنبال کنید تا Action خود را برای استفاده از Orders v3 به‌روزرسانی کنید.

API تغییر می کند

نسخه 3 Orders API دارای تغییرات کلیدی زیر نسبت به نسخه 2 است:

  • ساختار درخواست - ساختار سفارش نسخه 3 شامل تمام جزئیات سفارش است، نه تنها حاوی محتویات سبد خرید.
  • به‌روزرسانی‌های سفارش - نسخه 3 Orders API علاوه بر انجام سفارش، به‌روزرسانی‌های سفارش را مدیریت می‌کند، بنابراین نقطه پایانی شما برای ارسال به‌روزرسانی‌های سفارش‌های کاربران، نیازی به استفاده از Actions API ندارد. همچنین به‌جای درخواست‌های POST برای ارسال به‌روزرسانی‌های وضعیت، به‌روزرسانی‌ها را به‌عنوان درخواست‌های PATCH به Orders API ارسال می‌کنید که شی order موجود را به‌روزرسانی می‌کند.
  • تسهیل پرداخت - اقداماتی که از Google Pay با نسخه 3 Orders 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 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 جدید (نسخه 3)

توجه داشته باشید که Dialogflow 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 Old (v2)

توجه داشته باشید که Dialogflow 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 به API Action ندارید. در عوض، یک درخواست PATCH را به Orders API ارسال می‌کنید که محتوای شی Order شما را به‌روزرسانی می‌کند.

یک توکن حامل جدید را بازیابی کنید

می‌توانید از همان کلید حساب سرویس JSON استفاده کنید که برای بازیابی توکن حامل برای Action API استفاده کردید، باید یک توکن حامل جدید برای Orders API درخواست کنید. با استفاده از کتابخانه سرویس گیرنده Google APIs و محدوده «https://www.googleapis.com/auth/actions.order.developer»، کلید سرویس خود را با یک توکن حامل تعویض کنید.

می‌توانید مراحل و نمونه‌های نصب را در صفحه GitHub کتابخانه سرویس گیرنده API پیدا کنید. همچنین می‌توانید به سفارش به‌روزرسانی شده order-update.js در نمونه Node.js ما برای نمونه تبادل کلید Orders API مراجعه کنید.

ارسال به روز رسانی

فرآیند ارسال به‌روزرسانی سفارش با Orders API مشابه ارسال به‌روزرسانی‌ها با API Action است، اگرچه شما به جای درخواست POST یک درخواست PATCH ارسال می‌کنید. درخواست 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 جایگزین شده است.

جاوا را به نسخه 3 منتقل کنید

برای انتقال اکشنی که از کتابخانه سرویس گیرنده جاوا استفاده می کند، این مراحل را دنبال کنید.

1. مجموعه سبد خرید خود را به روز کنید

نوع ProposedOrder با شیء Order با جزئیات بیشتر جایگزین شده است. برای تبدیل سبد ProposedOrder خود به سبد Order به مرجع JSON مراجعه کنید.

2. به روز رسانی پارامترهای پرداخت

ساختار اطلاعات پرداخت در مرحله پیشنهاد سفارش بین نسخه های API متفاوت است.

در درخواست intent actions.intent.TRANSACTION_DECISION ، شیء paymentOptions قدیمی را با شیء جدید paymentParameters جایگزین کنید. بسیاری از فیلدهای موجود یکسان هستند، به جز برخی تغییرات در ساختار شی JSON.

قطعه کد زیر نمونه ای از درخواست قصد actions.intent.TRANSACTION_DECISION برای Google Pay با استفاده از نسخه 3 و درخواست نسخه 2 قدیمی برای مقایسه را نشان می دهد.

جاوا (نسخه 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();
جاوا قدیمی (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 جدید (نسخه 3)

توجه داشته باشید که Dialogflow 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 Old (v2)

توجه داشته باشید که Dialogflow 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 به API Action ندارید. در عوض، یک درخواست PATCH را به Orders API ارسال می‌کنید که محتوای شی Order شما را به‌روزرسانی می‌کند.

یک توکن حامل جدید را بازیابی کنید

می‌توانید از همان کلید حساب سرویس JSON استفاده کنید که برای بازیابی توکن حامل برای Action API استفاده کردید، باید یک توکن حامل جدید برای Orders API درخواست کنید. با استفاده از کتابخانه سرویس گیرنده Google APIs و محدوده «https://www.googleapis.com/auth/actions.order.developer»، کلید سرویس خود را با یک توکن حامل تعویض کنید.

می‌توانید مراحل و نمونه‌های نصب را در صفحه GitHub کتابخانه سرویس گیرنده API پیدا کنید. همچنین می‌توانید به سفارش به‌روزرسانی‌شده order-update.js در نمونه جاوای ما برای نمونه تبادل کلید Orders API مراجعه کنید.

ارسال به روز رسانی

فرآیند ارسال به‌روزرسانی سفارش با Orders API مشابه ارسال به‌روزرسانی‌ها با API Action است، اگرچه شما به جای درخواست POST یک درخواست PATCH ارسال می‌کنید. درخواست PATCH باید بدنه JSON با فرمت زیر داشته باشد:

{ "orderUpdate": OrderUpdate" }

فرمت OrderUpdate نیز در نسخه 3 متفاوت است. به مرجع درخواست PATCH مراجعه کنید و فیلدهای OrderUpdate خود را بر این اساس به روز کنید. قطعه کد زیر نمونه ای از درخواست PATCH را نشان می دهد که وضعیت سفارش را به " DELIVERED " به روز می کند:

جاوا
// 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 جایگزین شده است.