Menyiapkan Checkout

Proses checkout dipanggil saat pengguna membuat keranjang. Isi dari keranjang pengguna dan detail tentang pesanan dikirim ke web Pemesanan Menyeluruh layanan. Informasi ini divalidasi oleh layanan web Anda, lalu Anda dapat melanjutkan atau melakukan penyesuaian pada keranjang sesuai kebutuhan.

Pengendali checkout untuk layanan web Anda harus merespons permintaan POST. Ketika seorang pelanggan memilih check out, Google mengirimkan Isi permintaan JSON dalam bentuk CheckoutRequestMessage, yang berisi detail Cart pelanggan. Layanan web Anda kemudian merespons kembali dengan CheckoutResponseMessage. Diagram berikut menggambarkan prosesnya.

CheckoutResponseMessage menampilkan keranjang pelanggan yang tidak dimodifikasi atau
{i>error<i}.

Setelah menerima permintaan checkout, layanan web End-to-End Pemesanan Anda harus hal berikut:

  • Periksa validitas keranjang berdasarkan harga item saat ini, ketersediaan, dan layanan penyedia.
  • Hitung total harga (termasuk diskon, pajak, dan pengiriman biaya tambahan).
  • Jika berhasil, balas dengan keranjang yang belum dimodifikasi.
  • Jika gagal, balas dengan pesan error dan pesanan baru yang diusulkan.

Sebelum Anda mulai menerapkan checkout, sebaiknya tinjau halaman ringkasan dokumentasi tambahan.

Pesan Permintaan Checkout

Untuk memvalidasi keranjang pelanggan, saat pelanggan memilih untuk melakukan check out, Google mengirimkan permintaan ke layanan web Anda dengan isi JSON dalam bentuk CheckoutRequestMessage. Pesanan pelanggan tidak dikirim hingga nanti di Alur Pemesanan Menyeluruh.

Data yang dimuat dalam CheckoutRequestMessage mencakup hal berikut:

  • Niat: inputs[0].intent setiap isi permintaan {i>checkout<i} berisi Nilai string actions.foodordering.intent.CHECKOUT.
  • Keranjang: Kolom inputs[0].arguments[0].extension dalam permintaan checkout berisi objek Cart yang mewakili keranjang pelanggan.
  • Pengiriman atau bawa pulang: Kolom ekstensi objek Cart berisi Objek FoodCartExtension yang menentukan properti untuk pengiriman atau bawa pulang:
    • Untuk pesanan pengiriman, objek FoodCartExtension menyertakan alamat pengiriman.
    • Untuk pesanan ambil atau bawa pulang, objek FoodCartExtension tidak berisi informasi lokasi.
  • Sandbox: Kolom isInSandbox dalam permintaan checkout berisi boolean yang menunjukkan apakah transaksi menggunakan pembayaran {i>sandbox<i}.

Contoh permintaan checkout

Berikut adalah contoh CheckoutRequestMessage:

{
    "user": {},
    "conversation": {
        "conversationId": "CTZbZfUlHCybEdcz_5PB3Ttf"
    },
    "inputs": [
        {
            "intent": "actions.foodordering.intent.CHECKOUT",
            "arguments": [
                {
                    "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.Cart",
                        "merchant": {
                            "id": "restaurant/Restaurant/QWERTY",
                            "name": "Tep Tep Chicken Club"
                        },
                        "lineItems": [
                            {
                                "name": "Spicy Fried Chicken",
                                "type": "REGULAR",
                                "id": "299977679",
                                "quantity": 2,
                                "price": {
                                    "type": "ESTIMATE",
                                    "amount": {
                                        "currencyCode": "AUD",
                                        "units": "39",
                                        "nanos": 600000000
                                    }
                                },
                                "offerId": "MenuItemOffer/QWERTY/scheduleId/496/itemId/143",
                                "extension": {
                                    "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                                }
                            }
                        ],
                        "extension": {
                            "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
                            "fulfillmentPreference": {
                                "fulfillmentInfo": {
                                    "delivery": {
                                        "deliveryTimeIso8601": "P0M"
                                    }
                                }
                            },
                            "location": {
                                "coordinates": {
                                    "latitude": -33.8376441,
                                    "longitude": 151.0868736
                                },
                                "formattedAddress": "Killoola St, 1, Concord West NSW 2138",
                                "zipCode": "2138",
                                "city": "Concord West",
                                "postalAddress": {
                                    "regionCode": "AU",
                                    "postalCode": "2138",
                                    "administrativeArea": "NSW",
                                    "locality": "Concord West",
                                    "addressLines": [
                                        "Killoola St",
                                        "1"
                                    ]
                                }
                            }
                        }
                    }
                }
            ]
        }
    ],
    "directActionOnly": true,
    "isInSandbox": true
}

Pesan Respons Checkout

Setelah menerima permintaan dari layanan Pemesanan Menyeluruh, situs web checkout layanan harus memprosesnya dan merespons dengan CheckoutResponseMessage. Tujuan CheckoutResponseMessage harus mencakup keberhasilan atau kegagalan permintaan.

Permintaan berhasil

Jika permintaan check out berhasil, CheckoutResponseMessage harus menyertakan ProposedOrder dan PaymentOptions:

  • ProposedOrder

    • cart: Objek cart yang identik dengan keranjang yang diberikan di CheckoutRequestMessage. Jika salah satu isi keranjang perlu diubah, CheckoutResponseMessage harus menyertakan FoodErrorExtension dengan ProposedOrder yang dikoreksi.
    • otherItems: Item yang ditambahkan oleh penyedia, seperti biaya pengiriman, pajak, dan biaya lainnya. Dapat juga berisi tip yang ditambahkan oleh pengguna.
    • totalPrice: Harga total pesanan.
    • extension: FoodOrderExtension yang menentukan informasi fulfillment untuk pesanan, seperti waktu pengiriman.
  • PaymentOptions

    • Penyiapan pemrosesan pembayaran akan dibahas nanti di bagian Menyiapkan Google Bayar. Anda dapat menggunakan JSON placeholder di CheckoutResponseMessage hingga Anda siap menerapkan pemrosesan pembayaran.
    • Untuk menambahkan opsi pembayaran placeholder di CheckoutResponseMessage, lihat contoh di bawah ini, yang menggunakan contoh gateway pembayaran untuk PaymentOptions.

Contoh respons yang berhasil

{
    "finalResponse": {
        "richResponse": {
            "items": [
                {
                    "structuredResponse": {
                        "checkoutResponse": {
                            "proposedOrder": {
                                "cart": {
                                    "merchant": {
                                        "id": "restaurant/Restaurant/QWERTY",
                                        "name": "Tep Tep Chicken Club"
                                    },
                                    "lineItems": [
                                        {
                                            "name": "Spicy Fried Chicken",
                                            "type": "REGULAR",
                                            "id": "299977679",
                                            "quantity": 2,
                                            "price": {
                                                "type": "ESTIMATE",
                                                "amount": {
                                                    "currencyCode": "AUD",
                                                    "units": "39",
                                                    "nanos": 600000000
                                                }
                                            },
                                            "offerId": "MenuItemOffer/QWERTY/scheduleId/496/itemId/143",
                                            "extension": {
                                                "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                                            }
                                        }
                                    ],
                                    "extension": {
                                        "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
                                        "fulfillmentPreference": {
                                            "fulfillmentInfo": {
                                                "delivery": {
                                                    "deliveryTimeIso8601": "P0M"
                                                }
                                            }
                                        },
                                        "location": {
                                            "coordinates": {
                                                "latitude": -33.8376441,
                                                "longitude": 151.0868736
                                            },
                                            "formattedAddress": "Killoola St, 1, Concord West NSW 2138",
                                            "zipCode": "2138",
                                            "city": "Concord West",
                                            "postalAddress": {
                                                "regionCode": "AU",
                                                "postalCode": "2138",
                                                "administrativeArea": "NSW",
                                                "locality": "Concord West",
                                                "addressLines": [
                                                    "Killoola St",
                                                    "1"
                                                ]
                                            }
                                        }
                                    }
                                },
                                "totalPrice": {
                                    "type": "ESTIMATE",
                                    "amount": {
                                        "currencyCode": "AUD",
                                        "units": "43",
                                        "nanos": 100000000
                                    }
                                },
                                "extension": {
                                    "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension",
                                    "availableFulfillmentOptions": [
                                        {
                                            "fulfillmentInfo": {
                                                "delivery": {
                                                    "deliveryTimeIso8601": "P0M"
                                                }
                                            }
                                        }
                                    ]
                                },
                                "otherItems": [
                                    {
                                        "name": "Delivery fee",
                                        "price": {
                                            "type": "ESTIMATE",
                                            "amount": {
                                                "currencyCode": "AUD",
                                                "units": "3",
                                                "nanos": 500000000
                                            }
                                        },
                                        "type": "DELIVERY"
                                    }
                                ]
                            },
                            "paymentOptions": {
                                "googleProvidedOptions": {
                                    "facilitationSpecification": "{\"apiVersion\":2,\"apiVersionMinor\":0,\"merchantInfo\":{\"merchantName\":\"merchantName\"},\"allowedPaymentMethods\":[{\"type\":\"CARD\",\"parameters\":{\"allowedAuthMethods\":[\"PAN_ONLY\"],\"allowedCardNetworks\":[\"VISA\",\"MASTERCARD\"],\"billingAddressRequired\":true,\"cvcRequired\":false},\"tokenizationSpecification\":{\"type\":\"PAYMENT_GATEWAY\",\"parameters\":{\"gatewayMerchantId\":\"YOUR_MERCHANT_ID\",\"gateway\":\"cybersource\"}}}],\"transactionInfo\":{\"currencyCode\":\"AUD\",\"totalPriceStatus\":\"ESTIMATED\",\"totalPrice\":\"43.1\"}} "
                                }
                            },
                            "additionalPaymentOptions": [
                                {
                                    "actionProvidedOptions": {
                                        "paymentType": "ON_FULFILLMENT",
                                        "displayName": "Pay when you get your food.",
                                        "onFulfillmentPaymentData": {
                                            "supportedPaymentOptions": []
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            ]
        }
    }
}

Permintaan gagal

Jika permintaan checkout tidak berhasil, CheckoutResponseMessage harus menyertakan FoodErrorExtension, yang berisi daftar FoodOrderError item yang menjelaskan error yang terjadi. Jika ada konfigurasi yang dapat dipulihkan, kesalahan pada pesanan, seperti perubahan harga item di keranjang, FoodErrorExtension harus menyertakan correctedProposedOrder.

Contoh respons yang gagal

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "error": {
              "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
              "foodOrderErrors": [
                {
                  "error": "CLOSED",
                  "description": "The restaurant is closed."
                }
              ]
            }
          }
        }
      ]
    }
  }
}

Penerapan Checkout

Langkah-langkah berikut harus dilakukan saat menerapkan checkout.

Memvalidasi layanan

Menampilkan FoodOrderError untuk kondisi error layanan pertama ditemukan. Kesalahan ini tidak dapat dipulihkan sehingga kesalahan pertama harus dikembalikan. Lihat Menangani error untuk mengetahui deskripsi dan {i>error<i} yang dapat dipulihkan.

  1. Baca properti FulfillmentOptionInfo di permintaan untuk menentukan apakah jenis pemenuhan adalah untuk delivery atau pickup.
  2. Tampilkan jenis error berikut jika diperlukan:

    Jenis error Kasus penggunaan
    TIDAK VALID Jenis pemenuhan tidak valid.
    NOT_FOUND Jenis pemenuhan tidak ditemukan.
    DITUTUP
    • Tidak ada periode OperationHours untuk pesanan tersebut.
    • Pesanan adalah pesanan SEGERA dan tidak ada ServiceHours yang tersedia untuk waktu saat ini.
    • Ada penutupan darurat atau layanan isDisabled bernilai benar.
    Perhatikan bahwa Periode khusus lebih diutamakan daripada periode reguler. Lihat contoh dalam validasi periode pemesanan dan menghapus entity layanan untuk sementara.
    UNAVAILABLE_SLOT Pesanan di muka tidak dapat dipenuhi.
    NO_CAPACITY Restoran sedang sibuk dan tidak menerima pesanan saat ini.
    OUT_OF_SERVICE_AREA Pesanan tidak dapat dikirim ke alamat pengguna. Lihat Validasi alamat pengiriman untuk mengetahui contohnya.
    NO_COURIER_AVAILABLE Pesanan tidak dapat dikirim karena staf pengiriman terbatas.

Memvalidasi dan menentukan harga keranjang

  1. Cari setiap Keranjang.lineItems dan validasi dengan data saat ini di di sistem Anda atau di sistem penjual. Tujuan MenuItemOffer.sku nilai dari entitas feed disertakan sebagai LineItem.offerId. Buat FoodOrderError untuk setiap item baris jika diperlukan. Buat maksimum satu error untuk setiap item. Tampilkan jenis error berikut jika diperlukan:

    Jenis error Kasus penggunaan Dapat dipulihkan
    TIDAK VALID Data item atau data opsi apa pun tidak valid. Tidak
    NOT_FOUND Item atau opsi apa pun tidak ditemukan. Tidak
    PRICE_CHANGED Harga item atau kombinasi add-on telah berubah. Error ini dapat dianggap dapat dipulihkan. Ya
    AVAILABILITY_CHANGED Jumlah yang diminta untuk item baris atau opsi apa pun tidak tersedia. Ya
    REQUIREMENTS_NOT_MET Jumlah minimum atau maksimum pesanan tidak terpenuhi. Hal ini dapat ditentukan dengan memeriksa apakah harga keranjang di bawah Biaya.eligibleTransactionVolumeMin atau di atas Biaya.eligibleTransactionVolumeMax. Lihat contoh di validasi nilai pesanan minimum. Tidak
  2. Menampilkan daftar lineItems yang sudah divalidasi dengan LineItemType REGULAR. Jumlah semua harga item baris keranjang adalah harga keranjang atau SUBTOTAL.

Lihat contoh di validasi item keranjang.

Menghitung tarif layanan

  1. Temukan entitas Fee yang benar untuk layanan berdasarkan eligibleRegion, validFrom, validThrough, dan priority.
  2. Hitung jumlah biaya berdasarkan apakah entity ditentukan dengan price, percentageOfCart atau pricePerMeter.
  3. Kembalikan biaya layanan pesan antar atau bawa pulang sebagai LineItem dengan LineItemType DELIVERY atau FEE. Tambahkan biaya ke daftar Cart.otherItems.

Menerapkan promosi

  1. Temukan entitas Transaksi berdasarkan pencocokan Promosi.coupon dengan Transaksi.dealCode.
  2. Validasi transaksi dan tampilkan FoodOrderError jika diperlukan. Error ini dapat dianggap dapat dipulihkan. Tampilkan jenis error berikut jika diperlukan:

    Jenis error Kasus penggunaan
    PROMO_NOT_RECOGNIZED Kode kupon tidak dikenal.
    PROMO_EXPIRED Validitas transaksi sudah tidak berlaku.
    PROMO_ORDER_INELIGIBLE Pesanan tidak memenuhi syarat untuk kupon.
    PROMO_NOT_APPLICABLE Alasan lain.
  3. Hitung jumlah harga promo berdasarkan Transaksi.discount atau Transaksi.discountPercentage.

  4. Terapkan jumlah harga transaksi menggunakan total keranjang atau total biaya, bergantung pada Transaksi.dealType.

  5. Kembalikan Keranjang.promotions dengan promosi yang diterapkan.

  6. Tampilkan promosi sebagai LineItem dengan LineItemType DISCOUNT. Tambahkan diskon ke Keranjang.otherItems dengan harga negatif.

Tampilkan respons

  1. Buat ProposedOrder.cart, keranjang respons adalah sama dengan keranjang permintaan jika tidak ada error yang ditemukan selama validasi.
  2. Kembalikan daftar ProposedOrder.otherItems termasuk pajak, biaya, tip, dan diskon jika diterapkan. Lihat Gratuity untuk detail lebih lanjut tentang cara mengkonfigurasi item berat.
  3. Sertakan ProposedOrder.totalPrice dengan menambahkan keranjang harga, biaya, diskon, pajak, dan tip.
  4. Tampilkan FoodOrderExtension.availableFulfillmentOptions dengan FulfillmentOption masing-masing. Perbarui estimasi waktu pengambilan atau pengiriman hingga waktu yang diharapkan.
  5. Jika ada FoodOrderErrors yang dihasilkan dari pemeriksaan validasi sebelumnya:
    • Sertakan StructuredResponse.error dan daftar error di FoodErrorExtension.foodOrderErrors
    • Kembalikan ProposedOrder di correctedProposedOrder jika semua error dapat dipulihkan.
    • Tampilkan PaymentOptions di paymentOptions jika semua {i>error<i} dapat dipulihkan.
    • Secara opsional, sertakan additionalPaymentOptions jika ada opsi pembayaran yang tersedia dan semua kesalahan dapat dipulihkan.
  6. Jika tidak ada error validasi, tampilkan proposedOrder, paymentOptions di objek CheckoutResponse. Secara opsional, sertakan additionalPaymentOptions jika ada opsi pembayaran yang tersedia.