Skonfiguruj Google Checkout

Proces płatności jest wywoływany, gdy użytkownik utworzy koszyk. Zawartość koszyka użytkownika i szczegóły zamówienia są wysyłane do kompleksowej usługi internetowej do obsługi zamówień. Informacje te są sprawdzane przez Twoją usługę internetową. W razie potrzeby możesz kontynuować lub wprowadzić zmiany w koszyku.

Moduł obsługi płatności Twojej usługi internetowej musi odpowiadać na żądania POST. Gdy klient zdecyduje się zapłacić za zakupy, Google wysyła do kompleksowej usługi sieciowej do obsługi zamówień treść żądania JSON w postaci CheckoutRequestMessage, która zawiera szczegóły identyfikatora Cart klienta. Następnie usługa internetowa odpowiada CheckoutResponseMessage. Poniższy diagram przedstawia cały proces.

CheckoutResponseMessage zwraca niezmodyfikowany koszyk klienta lub zwraca błąd.

Po otrzymaniu prośby o płatność Twoja kompleksowa usługa internetowa do obsługi zamówień musi wykonać te czynności:

  • Sprawdzanie poprawności koszyka na podstawie aktualnych cen produktów, dostępności i usługi dostawcy.
  • Oblicz łączną cenę (obejmującą rabaty, podatki i opłaty za dostawę).
  • Jeśli operacja się uda, w odpowiedzi prześlij niezmodyfikowany koszyk.
  • Jeśli się to nie powiedzie, w odpowiedzi prześlij komunikat o błędzie i nowe proponowane zamówienie.

Zanim zaczniesz implementować proces płatności, zapoznaj się z dokumentacją omówienia realizacji.

Wiadomość z prośbą o płatność

Gdy klient zdecyduje się dokonać płatności, Google wysyła do Twojej usługi internetowej żądanie z treścią JSON w postaci CheckoutRequestMessage. Zamówienie klienta jest przesyłane dopiero później w ramach kompleksowego procesu składania zamówień.

Dane zawarte w elemencie CheckoutRequestMessage to m.in.:

  • Intencja: pole inputs[0].intent każdej treści żądania płatności zawiera wartość ciągu tekstowego actions.foodordering.intent.CHECKOUT.
  • Koszyk: pole inputs[0].arguments[0].extension żądania płatności zawiera obiekt Cart reprezentujący koszyk klienta.
  • Dostarczanie lub eksportowanie: pole rozszerzenia obiektu Cart zawiera obiekt FoodCartExtension, który określa właściwości przesyłania lub eksportowania:
    • W przypadku zamówień z dostawą obiekt FoodCartExtension zawiera adres dostawy.
    • W przypadku zamówień z odbiorem lub na wynos obiekt FoodCartExtension nie zawiera informacji o lokalizacji.
  • Piaskownica: pole isInSandbox żądania płatności zawiera wartość logiczną, która wskazuje, czy transakcja korzysta z płatności w piaskownicy.

Przykład żądania płatności

Poniżej znajduje się przykład atrybutu 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
}

Wiadomość z odpowiedzią dotyczącą płatności

Gdy otrzymasz żądanie od usługi kompleksowej obsługi zamówień, usługa internetowa płatności musi ją przetworzyć i odpowiedzieć za pomocą polecenia CheckoutResponseMessage. CheckoutResponseMessage musi uwzględniać udane lub nieudane żądanie.

Żądanie przetworzone

Jeśli prośba o płatność zostanie zrealizowana, CheckoutResponseMessage musi zawierać tagi ProposedOrder i PaymentOptions:

  • ProposedOrder

    • cart: obiekt cart identyczny z koszykiem podanym w CheckoutRequestMessage. Jeśli chcesz zmienić zawartość koszyka, element CheckoutResponseMessage powinien zawierać w zamian element FoodErrorExtension z poprawioną wartością ProposedOrder.
    • otherItems: elementy dodane przez dostawcę, np. opłaty za dostawę, podatki i inne opłaty. Może również zawierać napiwek dodany przez użytkownika.
    • totalPrice: łączna cena zamówienia.
    • extension: element FoodOrderExtension, który określa informacje o realizacji zamówienia, takie jak czas dostawy.
  • PaymentOptions

    • Konfigurowanie przetwarzania płatności zostało opisane w dalszej części artykułu Konfigurowanie Google Pay. Dopóki nie przygotujesz się do zaimplementowania przetwarzania płatności, możesz używać zastępczego kodu JSON w CheckoutResponseMessage.
    • Aby dodać zastępcze opcje płatności na koncie CheckoutResponseMessage, zapoznaj się z poniższym przykładem, w którym użyto przykładowej bramy płatności do płatności PaymentOptions.

Przykład udanej odpowiedzi

{
    "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": []
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            ]
        }
    }
}

Żądanie nie powiodło się

Jeśli żądanie płatności nie powiedzie się, CheckoutResponseMessage musi uwzględnić element FoodErrorExtension, który zawiera listę elementów FoodOrderError opisujących wszelkie błędy, które wystąpiły. Jeśli w zamówieniu występują błędy, które można naprawić, np. zmiana ceny produktu w koszyku, FoodErrorExtension musi zawierać parametr correctedProposedOrder.

Przykład odpowiedzi nieudanej

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

Implementacja płatności

Podczas wdrażania płatności należy wykonać poniższe czynności.

Zweryfikuj usługę

Zwracaj wartość FoodOrderError w przypadku pierwszego znalezionego stanu błędu usługi. Tych błędów nie można odzyskać, więc należy zwrócić pierwszy napotkany błąd. Opis błędów możliwych do naprawienia znajdziesz w sekcji Obsługa błędów.

  1. Przeczytaj właściwość FulfillmentOptionInfo w żądaniu, aby określić, czy typ realizacji to delivery czy pickup.
  2. W razie potrzeby zwracaj te typy błędów:

    Typ błędu Przypadek użycia
    INVALID Typ realizacji jest nieprawidłowy.
    NOT_FOUND Nie znaleziono typu realizacji.
    ZAMKNIĘTE
    • Nie ma okien OperationHours dla tego zamówienia.
    • Zamówienie jest zamówieniem typu Jak najszybciej. W tej chwili nie ma dostępnych ServiceHours na karcie ASAP (jak najszybciej).
    • Zamknięcie awaryjne lub usługa isDisabled jest prawda.
    Pamiętaj, że okna specjalne mają pierwszeństwo przed zwykłymi oknami. Zapoznaj się z przykładami w sekcji Weryfikacja okna kolejności i tymczasowe usuwanie encji usługi.
    UNAVAILABLE_SLOT Nie można zrealizować zamówienia z wyprzedzeniem.
    NO_CAPACITY Restauracja jest zatłoczona i nie przyjmuje obecnie zamówień.
    OUT_OF_SERVICE_AREA Nie można dostarczyć zamówienia na adres użytkownika. Przykład znajdziesz w artykule Sprawdzanie poprawności adresu dostawy.
    NO_COURIER_AVAILABLE Nie można dostarczyć zamówienia ze względu na ograniczoną liczbę pracowników.

Zweryfikuj koszyk i wycen go

  1. Wyszukaj każdy Koszyk.lineItems i zweryfikuj go na podstawie bieżących danych w swoim systemie lub systemie sprzedawcy. Wartość MenuItemOffer.sku z elementu pliku danych jest uwzględniana jako LineItem.offerId W razie potrzeby utwórz dla każdego elementu zamówienia FoodOrderError. Utwórz maksymalnie 1 błąd dla każdego elementu. W razie potrzeby zwracaj te typy błędów:

    Typ błędu Przypadek użycia możliwy do odzyskania
    INVALID Dane produktu lub dane opcji są nieprawidłowe. Nie
    NOT_FOUND Nie znaleziono elementu lub jednej z opcji. Nie
    PRICE_CHANGED Zmieniła się cena produktu lub kombinacji dodatku. Ten błąd można potraktować jako możliwych do naprawienia. Tak
    AVAILABILITY_CHANGED Kwota żądana dla elementów zamówienia lub żadna z opcji jest niedostępna. Tak
    REQUIREMENTS_NOT_MET Nie osiągnięto minimalnej lub maksymalnej wartości zamówienia. Można to ustalić, sprawdzając, czy cena koszyka jest niższa niż Opłata.eligibleTransactionVolumeMin czy większa od Opłaty.eligibleTransactionVolumeMax. Zobacz przykład dotyczący weryfikacji minimalnej wartości zamówienia. Nie
  2. Zwraca weryfikację listy elementów lineItems z wartością LineItemType REGULAR. Suma cen wszystkich elementów zamówienia w koszyku to cena koszyka (SUBTOTAL).

Zapoznaj się z przykładami w artykule Sprawdzanie poprawności elementów koszyka.

Oblicz opłaty za obsługę

  1. Znajdź prawidłowy element Opłata dla usługi na podstawie eligibleRegion, validFrom, validThrough i priority.
  2. Oblicz kwotę opłaty na podstawie tego, czy podmiot został zdefiniowany za pomocą właściwości price, percentageOfCart czy pricePerMeter.
  3. Zwróć opłatę za dostawę lub na wynos jako element LineItem o wartości LineItemType DELIVERY lub FEE. Dodaj opłatę do listy Koszyk.otherItems.

Zastosuj promocje

  1. Znajdź element Umowa na podstawie dopasowania wartości Promocja.coupon do Umowa.dealCode.
  2. Sprawdź umowę i w razie potrzeby zwracaj błąd FoodOrderError. Takie błędy można uznać za możliwe do naprawienia. W razie potrzeby zwracaj te typy błędów:

    Typ błędu Przypadek użycia
    PROMO_NOT_RECOGNIZED Nie rozpoznano kodu kuponu.
    PROMO_EXPIRED Umowa wygasła.
    PROMO_ORDER_INELIGIBLE Zamówienie nie kwalifikuje się do otrzymania kuponu.
    PROMO_NOT_APPLICABLE Jakikolwiek inny powód.
  3. Oblicz kwotę ceny w umowie na podstawie wartości Umowa.discount lub Umowa.discountPercentage.

  4. Zastosuj kwotę ceny w umowie, używając łącznej kwoty w koszyku lub łącznej opłaty (w zależności od umowy).dealType

  5. Zwróć Koszyk.promotions z zastosowaną promocją.

  6. Zwróć promocję jako element LineItem z wartością LineItemType DISCOUNT. Dodaj rabat do listy Koszyk.otherItems z ujemną ceną.

Wysyłanie odpowiedzi

  1. Utwórz ProposedOrder.cart, jeśli podczas weryfikacji nie wystąpią błędy, koszyk odpowiedzi jest taki sam jak koszyk żądania.
  2. Zwraca listę ProposedOrder.otherItems zawierającą podatki, opłaty, napiwkę i rabatę, jeśli mają zastosowanie. Więcej informacji o konfigurowaniu bezpłatnych środków znajdziesz w sekcji Należność.
  3. Uwzględnij właściwość ProposedOrder.totalPrice, dodając cenę koszyka, opłaty, rabat, podatki i napiwek.
  4. Zwróć FoodOrderExtension.availableFulfillmentOptions z odpowiednią wartością FulfillmentOption. Zaktualizuj szacowany czas odbioru lub dostawy do oczekiwanego czasu.
  5. Jeśli w wyniku poprzednich testów weryfikacji wystąpiły błędy jedzenia:
    • Dołącz StructuredResponse.error i listę błędów w pliku FoodErrorExtension.foodOrderErrors.
    • Jeśli wszystkie błędy można odzyskać, zwracaj wartość ProposedOrder w polu correctedProposedOrder.
    • Jeśli wszystkie błędy można naprawić, zwróć PaymentOptions w polu paymentOptions.
    • Opcjonalnie uwzględnij wartość additionalPaymentOptions, jeśli dostępne są inne opcje płatności i wszystkie błędy można naprawić.
  6. Jeśli podczas weryfikacji nie wystąpiły żadne błędy weryfikacji, zwróć wartość proposedOrder, paymentOptions w obiekcie CheckoutResponse. Opcjonalnie uwzględnij additionalPaymentOptions, jeśli dostępne są inne opcje płatności.