Pembaruan pesanan asinkron

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

Berikut adalah 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 akan tersedia.

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

Status pesanan transisi

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

Transisi status pesanan

Saat pelanggan pertama kali mengirimkan 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 aggregator pengiriman. Agregator pengiriman menerima pesanan dari Google, dan agregator mengirimkan informasi tersebut ke restoran. Setelah restoran menerima dan mengonfirmasi ketersediaan pesanan, status kini dapat menjadi CONFIRMED, jika tidak REJECTED.

Pesanan dalam status CONFIRMED selanjutnya akan berpindah ke status IN_PREPARATION. Bergantung pada apakah pesanan untuk diambil atau diantarkan, selanjutnya gunakan status READY_FOR_PICKUP atau IN_TRANSIT. Saat makanan telah diantar atau diambil, pesanan akan ditetapkan ke status FULFILLED.

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

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

Memberikan perkiraan waktu pemenuhan

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

Kirim estimatedFulfillmentTimeIso8601 pada waktu berikut:

  • Saat estimasi waktu tersedia, idealnya dalam status pesanan 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, buat estimasi yang konservatif dan berikan rentang tanggal dan waktu, bukan tanggal dan waktu tetap. Anda harus mempertimbangkan variasi seperti kondisi lalu lintas jika memungkinkan. Misalnya, Anda dapat mengirimkan estimasi pukul 12.45 (batas bawah) hingga pukul 13.15 (batas atas) untuk pesanan dengan estimasi waktu pengiriman pukul 13.00.

Memberikan tindakan pengelolaan pesanan

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

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

Tindakan pengelolaan pesanan mencakup jenis berikut:

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

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

Mengirim pembaruan pesanan

Anda menggunakan jenis pesan AsyncOrderUpdateRequestMessage untuk mengirim pembaruan pesan ke layanan Pemesanan End-to-End. Google akan merespons dengan AsyncOrderUpdateResponseMessage. Misalnya, jika ingin memberi tahu pelanggan bahwa pesanannya 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 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."
        }
      ]
      }
    }
  }
}
    

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 estimasi 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"
      }
    }
  }
}
  

FULFILLED

Contoh ini menunjukkan contoh permintaan pembaruan pesanan yang memberi tahu pengguna bahwa pesanan 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 pembaruan pesanan lainnya dalam berbagai kasus penggunaan, baca Menerapkan pembaruan pesanan lanjutan.

Membuat token otorisasi dan mengirim pesan

Pembaruan pesanan memerlukan token otorisasi agar layanan Pemesanan Menyeluruh dapat memverifikasi bahwa pesan berasal dari layanan web Pemesanan Menyeluruh Anda.

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

  1. Buat token otorisasi dengan mengikuti langkah-langkah berikut:
    1. Gunakan Library Google Auth untuk membaca kredensial dari file akun layanan Anda.
    2. Minta token 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. Tetapkan header Content-Type ke application/json sebagai bagian dari permintaan Anda.

Contoh berikut menunjukkan cara menerapkan 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 pembaruan pesanan yang berhasil tanpa error, Google akan menampilkan respons HTTP 200 dengan payload kosong. Jika terjadi masalah, seperti update yang berbentuk tidak benar, Google akan menampilkan error.