Menyiapkan Checkout

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

Pengendali checkout untuk layanan web Anda harus merespons permintaan POST. Saat pelanggan memilih untuk melakukan checkout, Google akan mengirimkan isi permintaan JSON ke layanan web Pemesanan End-to-End dalam bentuk CheckoutRequestMessage, yang berisi detail Cart pelanggan. Layanan web Anda kemudian merespons dengan CheckoutResponseMessage. Diagram berikut menggambarkan prosesnya.

CheckoutResponseMessage menampilkan keranjang pelanggan yang tidak diubah atau
error.

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

  • Periksa validitas keranjang berdasarkan harga item, ketersediaan, dan layanan penyedia saat ini.
  • Hitung harga total (termasuk diskon, pajak, dan biaya pengiriman).
  • Jika berhasil, respons dengan keranjang yang tidak diubah.
  • Jika tidak berhasil, balas dengan pesan error dan urutan baru yang diusulkan.

Sebelum Anda mulai menerapkan checkout, sebaiknya tinjau dokumentasi Ringkasan fulfillment.

Pesan Permintaan Checkout

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

Data yang terdapat dalam CheckoutRequestMessage mencakup hal berikut:

  • Intent: Kolom inputs[0].intent dari setiap isi permintaan checkout berisi nilai string actions.foodordering.intent.CHECKOUT.
  • Keranjang: Kolom inputs[0].arguments[0].extension permintaan checkout berisi objek Cart yang mewakili keranjang pelanggan.
  • Pesan antar atau bawa pulang: Kolom ekstensi objek Cart berisi objek FoodCartExtension yang menentukan properti untuk pesan antar atau bawa pulang:
    • Untuk pesanan pengiriman, objek FoodCartExtension menyertakan alamat pengiriman.
    • Untuk pesanan ambil sendiri atau pesan antar, objek FoodCartExtension tidak berisi informasi lokasi apa pun.
  • Sandbox: Kolom isInSandbox permintaan checkout berisi nilai Boolean yang menunjukkan apakah transaksi menggunakan pembayaran sandbox.

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 End-to-End, layanan web checkout Anda harus memprosesnya dan merespons dengan CheckoutResponseMessage. CheckoutResponseMessage harus mencakup permintaan yang berhasil atau gagal.

Permintaan berhasil

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

  • ProposedOrder

    • cart: Objek cart yang identik dengan keranjang yang disediakan di CheckoutRequestMessage. Jika ada konten keranjang yang perlu diubah, CheckoutResponseMessage harus menyertakan FoodErrorExtension dengan ProposedOrder yang dikoreksi.
    • otherItems: Item yang ditambahkan oleh penyedia, seperti biaya pengiriman, pajak, dan biaya lainnya. Juga dapat 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 Menyiapkan Google Pay. Anda dapat menggunakan JSON placeholder di CheckoutResponseMessage hingga Anda siap menerapkan pemrosesan pembayaran.
    • Untuk menambahkan opsi pembayaran placeholder di CheckoutResponseMessage, lihat contoh di bawah, 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 gagal, CheckoutResponseMessage harus menyertakan FoodErrorExtension, yang berisi daftar item FoodOrderError yang menjelaskan error yang terjadi. Jika ada error yang dapat dipulihkan 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

Tampilkan FoodOrderError untuk kondisi error layanan pertama yang ditemukan. Error ini tidak dapat dipulihkan sehingga error pertama yang ditemukan harus ditampilkan. Lihat Menangani error untuk mengetahui deskripsi error yang dapat dipulihkan.

  1. Baca properti FulfillmentOptionInfo dalam permintaan untuk menentukan apakah jenis fulfillment ditujukan untuk delivery atau pickup.
  2. Tampilkan jenis error berikut jika diperlukan:

    Jenis error Kasus penggunaan
    INVALID Jenis fulfillment tidak valid.
    NOT_FOUND Jenis fulfillment tidak ditemukan.
    DITUTUP
    • Tidak ada periode OperationHours untuk pesanan.
    • Pesanan ini adalah pesanan SEGERA dan tidak ada ServiceHours SEGERA yang tersedia untuk waktu saat ini.
    • Ada penutupan darurat atau layanan isDisabled bernilai benar.
    Perhatikan bahwa Jendela khusus lebih diutamakan daripada jendela reguler. Lihat contoh di validasi periode pemesanan dan menghapus entity layanan untuk sementara.
    UNAVAILABLE_SLOT Waktu pemesanan sebelumnya 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 personel pengiriman terbatas.

Memvalidasi dan menetapkan harga keranjang

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

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

Lihat contoh di validasi item keranjang.

Menghitung biaya layanan

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

Menerapkan promosi

  1. Temukan entity Deal berdasarkan pencocokan nilai Promotion.coupon dengan Deal.dealCode.
  2. Validasi promo 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 dikenali.
    PROMO_EXPIRED Masa berlaku promo sudah berakhir.
    PROMO_ORDER_INELIGIBLE Pesanan tidak memenuhi syarat untuk kupon.
    PROMO_NOT_APPLICABLE Alasan lain.
  3. Hitung jumlah harga transaksi berdasarkan Deal.discount atau Deal.discountPercentage.

  4. Terapkan jumlah harga promo menggunakan total keranjang atau total biaya, bergantung pada Promo.dealType.

  5. Menampilkan Cart.promotions dengan promosi yang diterapkan.

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

Menampilkan respons

  1. Buat ProposedOrder.cart, keranjang respons sama dengan keranjang permintaan jika tidak ada error yang terjadi selama validasi.
  2. Menampilkan daftar ProposedOrder.otherItems termasuk pajak, biaya, tip, dan diskon jika diterapkan. Lihat Tip untuk mengetahui detail selengkapnya tentang cara mengonfigurasi item tip.
  3. Sertakan ProposedOrder.totalPrice dengan menambahkan harga, biaya, diskon, pajak, dan tip keranjang.
  4. Tampilkan FoodOrderExtension.availableFulfillmentOptions dengan FulfillmentOption masing-masing. Perbarui perkiraan waktu pengambilan atau pengiriman ke waktu yang diharapkan.
  5. Jika ada FoodOrderErrors yang dihasilkan dari pemeriksaan validasi sebelumnya:
    • Sertakan StructuredResponse.error dan daftar error di FoodErrorExtension.foodOrderErrors.
    • Tampilkan ProposedOrder di kolom correctedProposedOrder jika semua error dapat dipulihkan.
    • Tampilkan PaymentOptions di kolom paymentOptions jika semua error dapat dipulihkan.
    • Secara opsional, sertakan additionalPaymentOptions jika ada opsi pembayaran lain yang tersedia dan semua error dapat dipulihkan.
  6. Jika tidak ada error validasi, tampilkan proposedOrder, paymentOptions dalam objek CheckoutResponse. Secara opsional, sertakan additionalPaymentOptions jika ada opsi pembayaran lain yang tersedia.