Pembaruan urutan asinkron

Setelah pelanggan mengirimkan pesanan makanan, Anda dapat mengirim pesan pembaruan pesanan ke layanan Pemesanan End-to-End untuk memberi tahu kami tentang perubahan tersebut.

Berikut ini beberapa alasan umum untuk mengirim pembaruan pesanan:

  • Perkiraan waktu pemenuhan pesanan tersedia atau berubah.
  • Status pesanan berubah.
  • Pesanan tidak dapat lagi dipenuhi.
  • Harga item menu yang disertakan dalam pesanan berubah.
  • Pelanggan memiliki cara baru untuk mengelola pesanannya, seperti dukungan pelanggan atau nomor telepon restoran.
  • Tanda terima untuk pesanan tersedia.

Bagian berikutnya memberikan detail tentang cara mengatasi berbagai skenario ini menggunakan pembaruan pesanan.

Mentransisi status pesanan

Sebuah pesanan memiliki enam kemungkinan status. Status ini dan kemungkinan transisinya diuraikan dalam diagram berikut:

Transisi status urutan

Saat pelanggan pertama kali mengirim pesanan, pesanan dimulai dengan status CREATED, CONFIRMED, atau REJECTED. Anda dapat mengirim pesan pembaruan pesanan untuk memperbarui status pesanan, selama transisi status valid. Status CREATED digunakan saat platform partner tidak dapat langsung mengonfirmasi atau menolak pesanan. Contoh kasus penggunaan adalah saat pelanggan memesan melalui agregator pengiriman. Agregator pengiriman menerima pengiriman dari Google, dan agregator mengirimkan informasi ke restoran. Setelah restoran menerima dan mengonfirmasi ketersediaan pesanan, status sekarang dapat menjadi CONFIRMED, jika tidak, REJECTED.

Urutan dalam status CONFIRMED berikutnya akan berpindah ke status IN_PREPARATION. Bergantung pada apakah pesanannya untuk pesan ambil atau antar, gunakan status READY_FOR_PICKUP atau IN_TRANSIT. Setelah makanan dikirim atau diambil, pesanan ditetapkan ke status FULFILLED.

Jika Anda mengizinkan pelanggan untuk membatalkan pesanan, Anda dapat menggunakan status CANCELLED. Pesanan dapat dibatalkan saat berada dalam status CREATED, CONFIRMED, IN_PREPARATION, READY_FOR_PICKUP, atau IN_TRANSIT. Layanan Pemesanan Menyeluruh harus melakukan pengembalian dana bergantung pada kebijakan pembatalan Anda dan status pembayaran pada saat pembatalan.

Layanan Pemesanan Menyeluruh Anda tidak harus mendukung semua status dan transisi yang tersedia. Namun, status akhir pesanan harus berupa FULFILLED, REJECTED, atau CANCELLED.

Memberikan estimasi waktu pemenuhan

Anda dapat memberi pengguna perkiraan rentang waktu kapan pesanan mereka siap diambil (atau dikirim). Gunakan kolom estimatedFulfillmentTimeIso8601 dari FoodOrderUpdateExtension untuk memberikan perkiraan rentang waktu kapan pesanan pelanggan siap diambil atau dikirim.

Kirim estimatedFulfillmentTimeIso8601 pada waktu berikut:

  • Saat perkiraan waktu tersedia, idealnya dalam urutan status CREATED atau CONFIRMED.
  • Saat estimasi waktu berubah, seperti memperbarui estimasi waktu agar lebih akurat saat pesanan adalah IN_TRANSIT.

Untuk mengelola ekspektasi pengguna secara efektif, lakukan konservatif dalam estimasi dan berikan rentang tanggal dan waktu, bukan tanggal dan waktu yang tetap. Anda harus memperhitungkan variasi seperti kondisi traffic jika memungkinkan. Misalnya, Anda dapat mengirim perkiraan pukul 12.45 (batas bawah) hingga 13.15 (batas atas) untuk pesanan dengan perkiraan waktu pengiriman adalah pukul 13.00.

Menyediakan tindakan pengelolaan pesanan

Saat mengirim pembaruan pesanan, Anda dapat memberikan resource kepada pelanggan yang membantu mereka mengelola pesanan dalam bentuk OrderManagementAction. Setelah pelanggan melakukan pemesanan, mereka mungkin perlu menghubungi Anda atau restoran yang memenuhi pesanan untuk melacak progres, melakukan perubahan, atau membatalkan pesanan.

OrderManagementAction memungkinkan pelanggan mengirim email, menelepon, atau menautkan ke URL langsung dari perangkat. Gunakan informasi yang sama di OrderManagementAction seperti dalam konfirmasi pesanan email yang Anda kirimkan kepada pengguna.

Tindakan pengelolaan pesanan mencakup jenis berikut:

  • CUSTOMER_SERVICE: Berikan tindakan kepada pelanggan untuk menghubungi layanan pelanggan. Jenis tindakan pengelolaan ini wajib ada untuk pembaruan pesanan.
  • EMAIL: Memberikan tindakan kepada pelanggan untuk mengirim email ke alamat email yang diberikan.
  • CALL: Beri pelanggan tindakan untuk menelepon nomor telepon yang disediakan.
  • VIEW_DETAIL: Beri pelanggan tindakan untuk melihat detail pesanan mereka.

Setiap pembaruan pesanan harus berisi minimal satu tindakan pengelolaan pesanan. Namun, tindakan pengelolaan pesanan yang diberikan dapat bervariasi berdasarkan status pesanan. Misalnya, jika pesanan berada dalam status CONFIRMED, tindakan CUSTOMER_SERVICE dapat mengarah ke nomor telepon layanan pelanggan Anda. Saat status pesanan tersebut berubah menjadi IN_TRANSIT, tindakan CUSTOMER_SERVICE dapat mengarah ke nomor telepon restoran fulfillment.

Mengirim pembaruan pesanan

Anda menggunakan jenis pesan AsyncOrderUpdateRequestMessage untuk mengirim pembaruan pesanan ke layanan Pengurutan Menyeluruh. Google akan merespons kembali dengan AsyncOrderUpdateResponseMessage. Misalnya, jika ingin memberi tahu pelanggan bahwa pesanan mereka valid dan diterima, Anda dapat mengirim AsyncOrderUpdateRequestMessage untuk mengubah status pesanan menjadi CONFIRMED dengan label Accepted by restaurant.

Diagram pembaruan pesanan

Menetapkan pesan pembaruan pesanan

Saat mengirim AsyncOrderUpdateRequestMessage ke Google, Anda harus menyertakan informasi tentang status pesanan menggunakan kolom OrderUpdate.

Contoh berikut menunjukkan contoh AsyncOrderUpdateRequestMessage untuk setiap status pesanan:

DIKONFIRMASI

Contoh ini menunjukkan contoh permintaan pembaruan pesanan yang memberi tahu pengguna bahwa pesanan telah dikonfirmasi dengan tanda terima dan perkiraan waktu pengiriman.

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
        "state": "CONFIRMED",
        "label": "Provider confirmed"
      },
      "receipt": {
        "userVisibleOrderId": "userVisibleId1234"
      },
      "updateTime": "2017-07-17T12:00:00Z",
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ],
      "infoExtension": {
        "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
        "estimatedFulfillmentTimeIso8601": "2017-07-17T13:00:00Z/2017-07-17T13:30:00Z"
      }
    }
  }
}
    

DITOLAK

Contoh ini menunjukkan contoh permintaan pembaruan pesanan yang memberi tahu pengguna bahwa pesanan ditolak dengan alasan penolakan.

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
        "state": "REJECTED",
        "label": "Order rejected"
      },
      "updateTime": "2017-05-10T02:30:00.000Z",
      "rejectionInfo": {
        "type": "UNKNOWN",
        "reason": "Sorry, the restaurant cannot take your order right now."
      },
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ],
      "infoExtension": {
      "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
      "foodOrderErrors": [
        {
        "error": "NO_CAPACITY",
        "description": "Sorry, the restaurant cannot take your order right now."
        }
      ]
      }
    }
  }
}
    

CANCELLED (DIBATALKAN)

Contoh ini menunjukkan contoh permintaan pembaruan pesanan yang memberi tahu pengguna bahwa pesanan dibatalkan dengan alasan pembatalan.

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
        "state": "CANCELLED",
        "label": "Order cancelled"
      },
      "updateTime": "2017-05-10T02:30:00.000Z",
      "cancellationInfo": {
        "reason": "Customer requested"
      },
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ]
    }
  }
}
    

IN_PREPARATION

Contoh ini menunjukkan contoh permintaan pembaruan pesanan yang memberi tahu pengguna bahwa makanan sedang disiapkan.

{
  "isInSandbox":true,
  "customPushMessage":{
    "orderUpdate":{
      "actionOrderId":"sample_action_order_id",
      "orderState":{
        "state":"IN_PREPARATION",
        "label":"Order is being prepared"
      },
      "receipt": {
        "userVisibleOrderId": "userVisibleId1234"
      },
      "updateTime":"2018-04-15T11:30:00Z",
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ],
      "infoExtension":{
        "@type":"type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
        "estimatedFulfillmentTimeIso8601":"PT20M"
      }
    }
  }
}
    

READY_FOR_PICKUP

Contoh ini menunjukkan contoh permintaan pembaruan pesanan yang memberi tahu pengguna bahwa makanan siap diambil.

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
        "state": "READY_FOR_PICKUP",
        "label": "Order is ready for pickup"
      },
      "receipt": {
        "userVisibleOrderId": "userVisibleId1234"
      },
      "updateTime": "2018-04-15T12:00:00Z",
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ],
      "infoExtension": {
        "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
        "estimatedFulfillmentTimeIso8601": "PT20M"
      }
    }
  }
}
    

IN_TRANSIT

Contoh ini menunjukkan contoh permintaan pembaruan pesanan yang memberi tahu pengguna bahwa pesanan sedang dalam pengiriman dengan perkiraan waktu pengiriman.

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
        "state": "IN_TRANSIT",
        "label": "Order is on the way"
      },
      "inTransitInfo": {
        "updatedTime": "2017-07-17T12:00:00Z"
      },
      "updateTime": "2017-07-17T12:00:00Z",
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ],
      "infoExtension": {
        "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
        "estimatedFulfillmentTimeIso8601": "PT20M"
      }
    }
  }
}
  

TERPENUHI

Contoh ini menunjukkan contoh permintaan pembaruan pesanan yang memberi tahu pengguna bahwa pesanan sudah diambil atau dikirim:

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
      "state": "FULFILLED",
      "label": "Order delivered"
      },
      "updateTime": "2017-05-10T02:30:00.000Z",
      "fulfillmentInfo": {
        "deliveryTime": "2017-05-10T02:30:00.000Z"
      },
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ]
    }
  }
}
    

Untuk contoh permintaan update pesanan lainnya dalam berbagai kasus penggunaan, baca Menerapkan update pesanan lanjutan.

Membuat token otorisasi dan mengirim pesan

Pembaruan pesanan memerlukan token otorisasi agar layanan Pemesanan End-to-End dapat memverifikasi bahwa pesan tersebut berasal dari layanan web Pemesanan End-to-End Anda.

Untuk menerapkan pembaruan pesanan untuk project Anda, ikuti langkah-langkah berikut:

  1. Buat token otorisasi dengan mengikuti langkah-langkah berikut:
    1. Gunakan Google Auth Library untuk membaca kredensial dari file akun layanan Anda.
    2. Token permintaan menggunakan cakupan API berikut: https://www.googleapis.com/auth/actions.fulfillment.conversation
  2. Gunakan token ini untuk mengirim permintaan POST HTTP yang diautentikasi ke endpoint berikut: https://actions.googleapis.com/v2/conversations:send
  3. Setel header Content-Type ke application/json sebagai bagian dari permintaan Anda.

Contoh berikut menunjukkan cara mengimplementasikan pembaruan pesanan:

Node.js

Kode ini menggunakan library autentikasi Google untuk Node.js.

const {auth} = require('google-auth-library')
const request = require('request');
// The service account client secret file downloaded from the Google Cloud Console
const serviceAccountJson = require('./service-account.json')
// order-update.json is a file that contains the payload
const jsonBody = require('./order-update.json')

/**
 * Get the authorization token using a service account.
 */
async function getAuthToken() {
  let client = auth.fromJSON(serviceAccountJson)
  client.scopes = ['https://www.googleapis.com/auth/actions.fulfillment.conversation']
  const tokens = await client.authorize()
  return tokens.access_token;
}

/**
 * Send an order update request
 */
async function sendOrderUpdate() {
  const token = await getAuthToken()
  request.post({
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    url: 'https://actions.googleapis.com/v2/conversations:send',
    body: jsonBody,
    json: true
  },
  (err, res, body) => {
    if (err) { return console.log(err); }
    console.log(`Response: ${JSON.stringify(res)}`)
  })
}
    

Python

Kode ini menggunakan library autentikasi Google untuk Python.

from google.oauth2 import service_account
from google.auth.transport.requests import AuthorizedSession
import json

# service-account.json is the service account client secret file downloaded from the
# Google Cloud Console
credentials = service_account.Credentials.from_service_account_file(
    'service-account.json')

scoped_credentials = credentials.with_scopes(
    ['https://www.googleapis.com/auth/actions.fulfillment.conversation'])

authed_session = AuthorizedSession(scoped_credentials)

# order-update.json is a file that contains the payload
json_payload=json.load(open('order-update.json'))

response = authed_session.post(
    'https://actions.googleapis.com/v2/conversations:send',
    json=json_payload)
    

Java

Kode ini menggunakan library autentikasi Google untuk Java.

/**
 * Get the authorization token using a service account.
 */
private static String getAuthToken() {
  InputStream serviceAccountFile = Example.class.getClassLoader().getResourceAsStream("service-account.json");
  ServiceAccountCredentials.Builder credentialsSimpleBuilder =
      ServiceAccountCredentials.fromStream(serviceAccountFile).toBuilder();
  credentialsSimpleBuilder.setScopes(ImmutableList.of("https://www.googleapis.com/auth/actions.fulfillment.conversation"));
  AccessToken accessToken = credentialsSimpleBuilder.build().refreshAccessToken();
  return accessToken.getTokenValue();
}

/**
 * Send an order update request
 */
public void sendOrderUpdate() {
  String authToken = getAuthToken();
  // Execute POST request
  executePostRequest("https://actions.googleapis.com/v2/conversations:send",
      authToken, "update_order_example.json",);
}
    

Untuk update pesanan yang berhasil tanpa error, Google akan menampilkan respons HTTP 200 dengan payload kosong. Jika ada masalah, seperti update yang rusak, Google akan menampilkan error.