Quy trình thanh toán sẽ được gọi khi người dùng tạo giỏ hàng. Nội dung của giỏ hàng của người dùng và thông tin chi tiết về đơn đặt hàng sẽ được gửi đến trang web Đặt hàng hai đầu của bạn . Thông tin này được dịch vụ web của bạn xác thực, sau đó bạn có thể tiếp tục hoặc điều chỉnh giỏ hàng nếu cần.
Trình xử lý quy trình thanh toán cho dịch vụ web của bạn phải phản hồi các yêu cầu POST. Khi một
khách hàng chọn thanh toán, Google sẽ gửi dịch vụ web Đặt hàng hai đầu
Nội dung yêu cầu JSON ở dạng CheckoutRequestMessage
, chứa phương thức
thông tin chi tiết về Cart
của một khách hàng. Sau đó, dịch vụ web của bạn sẽ phản hồi bằng
CheckoutResponseMessage
. Sơ đồ dưới đây minh hoạ quy trình.
Khi nhận được yêu cầu thanh toán, dịch vụ web Đặt hàng hai đầu phải đáp ứng các yêu cầu như sau:
- Kiểm tra tính hợp lệ của giỏ hàng dựa trên giá hiện tại của mặt hàng, tình trạng còn hàng, và nhà cung cấp dịch vụ của mình.
- Tính tổng giá (bao gồm mọi khoản chiết khấu, thuế và phí giao hàng ).
- Nếu thành công, hãy trả lời bằng một giỏ hàng chưa sửa đổi.
- Nếu không thành công, hãy trả lời bằng thông báo lỗi và đơn đặt hàng được đề xuất mới.
Trước khi bắt đầu triển khai quy trình thanh toán, bạn nên xem lại quy trình Thực hiện đơn hàng tổng quan tài liệu.
Thông báo yêu cầu thanh toán
Để xác thực giỏ hàng của khách hàng, khi khách hàng chọn thanh toán,
Google gửi yêu cầu đến dịch vụ web của bạn kèm theo nội dung JSON dưới dạng một
CheckoutRequestMessage
. Đơn đặt hàng của khách hàng không được gửi cho đến sau đó trong
Sắp xếp quy trình hai đầu.
Dữ liệu có trong một
CheckoutRequestMessage
bao gồm:
- Mục đích: Mục đích
inputs[0].intent
của mọi nội dung yêu cầu thanh toán chứa thông số Giá trị chuỗiactions.foodordering.intent.CHECKOUT
. - Giỏ hàng: Trường
inputs[0].arguments[0].extension
của một yêu cầu thanh toán chứa đối tượngCart
đại diện cho giỏ hàng của khách hàng. - Phân phối hoặc trích xuất: Trường tiện ích của đối tượng
Cart
chứa Đối tượngFoodCartExtension
chỉ định các thuộc tính để phân phối hoặc đồ ăn mang đi:- Đối với đơn đặt hàng giao, đối tượng
FoodCartExtension
bao gồm địa chỉ giao hàng của bạn. - Đối với đơn đặt hàng tự đến lấy hoặc mua mang đi, đối tượng
FoodCartExtension
không chứa bất kỳ thông tin vị trí nào.
- Đối với đơn đặt hàng giao, đối tượng
- Hộp cát: Trường
isInSandbox
của yêu cầu thanh toán có chứa boolean cho biết liệu giao dịch có sử dụng phương thức thanh toán trong hộp cát hay không.
Ví dụ về yêu cầu thanh toán
Dưới đây là một ví dụ về 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
}
Thông báo phản hồi về quy trình thanh toán
Sau khi nhận được yêu cầu từ dịch vụ Đặt hàng đầu cuối, trang web thanh toán của bạn
phải xử lý yêu cầu đó và phản hồi bằng CheckoutResponseMessage
. Chiến lược phát hành đĩa đơn
CheckoutResponseMessage
cần xác minh một trường hợp thành công hoặc không thành công
của bạn.
Yêu cầu thành công
Nếu yêu cầu thanh toán thành công, CheckoutResponseMessage
cần phải cung cấp
ProposedOrder
và
PaymentOptions
:
ProposedOrder
cart
: Đối tượngcart
giống hệt với giỏ hàng được cung cấp trongCheckoutRequestMessage
Nếu bất kỳ nội dung nào của giỏ hàng cần đã thay đổi,CheckoutResponseMessage
sẽ bao gồm mộtFoodErrorExtension
cóProposedOrder
đã sửa.otherItems
: Các mặt hàng do nhà cung cấp thêm vào, chẳng hạn như phí giao hàng, thuế và các phí khác. Cũng có thể chứa tiền thưởng do người dùng thêm.totalPrice
: Tổng giá của đơn đặt hàng.extension
: MộtFoodOrderExtension
xác định thông tin về phương thức thực hiện cho đơn đặt hàng, chẳng hạn như thời gian giao hàng.
PaymentOptions
- Thông tin về quá trình thiết lập quá trình xử lý thanh toán sẽ được đề cập sau trong phần Thiết lập Google
Thanh toán.
Bạn có thể sử dụng phần giữ chỗ JSON trong
CheckoutResponseMessage
cho đến khi sẵn sàng triển khai quá trình xử lý thanh toán. - Cách thêm phần giữ chỗ cho các phương thức thanh toán trong
CheckoutResponseMessage
: hãy tham khảo ví dụ bên dưới, trong đó sử dụng cổng thanh toán mẫu choPaymentOptions
.
- Thông tin về quá trình thiết lập quá trình xử lý thanh toán sẽ được đề cập sau trong phần Thiết lập Google
Thanh toán.
Bạn có thể sử dụng phần giữ chỗ JSON trong
Ví dụ về phản hồi thành công
{
"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": []
}
}
}
]
}
}
}
]
}
}
}
Yêu cầu không thành công
Nếu yêu cầu thanh toán không thành công, CheckoutResponseMessage
cần
bao gồm FoodErrorExtension
, chứa danh sách
FoodOrderError
các mục mô tả bất kỳ lỗi nào đã xảy ra. Nếu có bất kỳ mã nào
lỗi đối với đơn đặt hàng, chẳng hạn như thay đổi giá của một mặt hàng trong giỏ hàng,
FoodErrorExtension
phải bao gồm correctedProposedOrder
.
Ví dụ về phản hồi không thành công
{
"expectUserResponse": false,
"finalResponse": {
"richResponse": {
"items": [
{
"structuredResponse": {
"error": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
"foodOrderErrors": [
{
"error": "CLOSED",
"description": "The restaurant is closed."
}
]
}
}
}
]
}
}
}
Triển khai quy trình thanh toán
Bạn nên thực hiện các bước sau đây khi triển khai quy trình thanh toán.
Xác thực dịch vụ
Trả về FoodOrderError cho điều kiện lỗi dịch vụ đầu tiên đã tìm thấy. Không thể khôi phục những lỗi này, vì vậy, lỗi đầu tiên gặp phải là bị trả lại. Xem phần Xử lý lỗi để biết mô tả về lỗi có thể khôi phục.
- Đọc thuộc tính FulfillmentOptionInfo trong
để xác định xem kiểu phương thức thực hiện là cho
delivery
haypickup
. Trả về các loại lỗi sau nếu cần:
Loại lỗi Trường hợp sử dụng KHÔNG HỢP LỆ Loại phương thức thực hiện không hợp lệ. NOT_FOUND Không tìm thấy loại phương thức thực hiện. ĐÓNG - Không có cửa sổ OperationHours cho đơn đặt hàng.
- Đơn đặt hàng này là đơn đặt hàng càng sớm càng tốt và hiện không có ServiceHours sớm nhất có thể.
- Dịch vụ
isDisabled
đang hoạt động hoặc dịch vụ bị đóng trong trường hợp khẩn cấp.
UNAVAILABLE_SLOT Không thể thực hiện đơn đặt hàng trước. NO_CAPACITY Nhà hàng hiện đang bận và không nhận đơn đặt hàng. OUT_OF_SERVICE_AREA Không thể giao đơn đặt hàng đến địa chỉ của người dùng. Xem phần Xác thực địa chỉ giao hàng để biết ví dụ. NO_COURIER_AVAILABLE Không thể giao đơn đặt hàng do nhân viên giao hàng bị hạn chế.
Xác thực và định giá giỏ hàng
Tra cứu từng Giỏ hàng.
lineItems
rồi xác thực bằng dữ liệu hiện tại trong hệ thống của bạn hoặc trong hệ thống của người bán. Chiến lược phát hành đĩa đơn MenuItemOffer.sku
giá trị từ thực thể nguồn cấp dữ liệu được bao gồm dưới dạng LineItem.offerId
. Tạo một FoodOrderError cho mỗi mục hàng nếu cần. Tạo một tối đa một lỗi cho mỗi mục. Trả về các loại lỗi sau đây nếu cần thiết:Loại lỗi Trường hợp sử dụng Có thể khôi phục KHÔNG HỢP LỆ Dữ liệu mặt hàng hoặc bất kỳ dữ liệu nào về tuỳ chọn đều không hợp lệ. Không NOT_FOUND Không tìm thấy mục đó hoặc bất kỳ lựa chọn nào. Không PRICE_CHANGED Giá của một mặt hàng hoặc tổ hợp tiện ích bổ sung đã thay đổi. Lỗi này có thể được coi là có thể khôi phục. Có AVAILABILITY_CHANGED Số tiền được yêu cầu cho các mục hàng hoặc bất kỳ tùy chọn nào không có sẵn. Có REQUIREMENTS_NOT_MET Không đáp ứng đơn đặt hàng tối thiểu hoặc tối đa. Bạn có thể xác định điều này bằng cách kiểm tra xem giá giỏ hàng có thấp hơn Phí. eligibleTransactionVolumeMin
hoặc cao hơn Phí.eligibleTransactionVolumeMax
. Hãy xem ví dụ trong bài viết xác thực giá trị đơn đặt hàng tối thiểu.Không Trả về danh sách đã xác thực của mục hàng với LineItemType
REGULAR
. Tổng của tất cả giá của mục hàng trong giỏ hàng là giá của giỏ hàng hoặcSUBTOTAL
.
Xem ví dụ trong phần xác thực các mục trong giỏ hàng.
Tính phí dịch vụ
- Tìm đúng pháp nhân Phí cho dịch vụ dựa trên
eligibleRegion
,validFrom
,validThrough
vàpriority
. - Tính số tiền phí dựa trên việc thực thể có được xác định bằng
price
hay không, Thuộc tínhpercentageOfCart
hoặcpricePerMeter
. - Trả lại phí dịch vụ giao hàng hoặc lấy đi dưới dạng LineItem (Mục hàng) bằng
LineItemType
DELIVERY
hoặcFEE
tương ứng. Thêm phí vào danh sách Giỏ hàng.otherItems
.
Áp dụng chương trình khuyến mãi
- Tìm thực thể Deal (Giao dịch) dựa trên việc so khớp
Giá trị Khuyến mãi.
coupon
bằng Ưu đãi.dealCode
. Xác thực giao dịch rồi trả về FoodOrderError nếu cần. Những lỗi này có thể được coi là có thể khôi phục. Trả về các loại lỗi sau nếu cần:
Loại lỗi Trường hợp sử dụng PROMO_NOT_RECOGNIZED Không nhận dạng được mã giảm giá. PROMO_EXPIRED Hiệu lực của giao dịch đã hết hạn. PROMO_ORDER_INELIGIBLE Đơn đặt hàng không đủ điều kiện nhận phiếu giảm giá. PROMO_NOT_APPLICABLE Bất kỳ lý do nào khác. Tính toán giá ưu đãi dựa trên Giao dịch.
discount
hoặc Giao dịch.discountPercentage
.Áp dụng giá ưu đãi bằng cách sử dụng tổng giỏ hàng hoặc tổng phí tuỳ thuộc vào Deal (Giao dịch).
dealType
.Trả lại Giỏ hàng.
promotions
có áp dụng chương trình khuyến mãi.Trả về chương trình khuyến mãi dưới dạng LineItem với LineItemType
DISCOUNT
. Thêm chiết khấu vào Giỏ hàng.otherItems
Danh sách với giá âm.
Trả lại câu trả lời
- Tạo ProposedOrder (Đơn đặt hàng được đề xuất).
cart
, giỏ hàng phản hồi là giống như giỏ hàng yêu cầu nếu không gặp lỗi trong quá trình xác thực. - Trả về danh sách ProposedOrder.
otherItems
bao gồm thuế, phí, tiền thưởng và chiết khấu nếu áp dụng. Xem mục Miễn phí để thêm thông tin chi tiết về cách thiết lập mục tiền thưởng. - Bao gồm ProposedOrder.
totalPrice
bằng cách thêm giỏ hàng giá, phí, chiết khấu, thuế và tiền thưởng. - Trả lại
FoodOrderExtension.
availableFulfillmentOptions
với FulfillmentOption tương ứng. Cập nhật giá trị ước tính thời gian đến lấy hàng hoặc giao hàng đến thời gian dự kiến. - Nếu có FoodOrderErrors được tạo từ các lần kiểm tra xác thực trước đó:
- Bao gồm StructuredResponse.
error
và danh sách lỗi trong FoodErrorExtension.foodOrderErrors
. - Trả lại ProposedOrder (Đơn đặt hàng được đề xuất) trong
correctedProposedOrder
nếu tất cả lỗi đều có thể khôi phục. - Trả lại PaymentOptions trong
paymentOptions
nếu tất cả lỗi có thể khôi phục được. - Thêm
additionalPaymentOptions
(không bắt buộc) nếu có các lựa chọn thanh toán phù hợp nhất và tất cả lỗi đều có thể khôi phục được.
- Bao gồm StructuredResponse.
- Nếu không có lỗi xác thực, hãy trả về
proposedOrder
,paymentOptions
trong đối tượng CheckoutResponse (Phản hồi thanh toán). ThêmadditionalPaymentOptions
(không bắt buộc) nếu có các lựa chọn thanh toán phù hợp nhất.