Thiết lập quy trình thanh toán

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.

CheckoutResponseMessage trả về giỏ hàng chưa sửa đổi của khách hàng hoặc một
.

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ỗi actions.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ượng Cart đạ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ượng FoodCartExtension 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.
  • 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 ProposedOrderPaymentOptions:

  • ProposedOrder

    • cart: Đối tượng cart giống hệt với giỏ hàng được cung cấp trong CheckoutRequestMessage 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ột FoodErrorExtensionProposedOrder đã 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ột FoodOrderExtension 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 cho PaymentOptions.

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.

  1. Đọc thuộc tính FulfillmentOptionInfo trong để xác định xem kiểu phương thức thực hiện là cho delivery hay pickup.
  2. 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.
    Xin lưu ý rằng Cửa sổ đặc biệt sẽ được ưu tiên hơn các cửa sổ thông thường. Xem ví dụ trong phần sắp xếp thứ tự xác thực cửa sổtạm thời xoá các thực thể dịch vụ.
    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

  1. 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.
    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.
    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
  2. 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ặc SUBTOTAL.

Xem ví dụ trong phần xác thực các mục trong giỏ hàng.

Tính phí dịch vụ

  1. Tìm đúng pháp nhân Phí cho dịch vụ dựa trên eligibleRegion, validFrom, validThroughpriority.
  2. 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ính percentageOfCart hoặc pricePerMeter.
  3. 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ặc FEE 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

  1. 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.
  2. 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.
  3. Tính toán giá ưu đãi dựa trên Giao dịch.discount hoặc Giao dịch.discountPercentage.

  4. Á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.

  5. Trả lại Giỏ hàng.promotions có áp dụng chương trình khuyến mãi.

  6. 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

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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ê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.