La procedura di pagamento viene invocata quando un utente crea un carrello. I contenuti del carrello dell'utente e i dettagli dell'ordine vengono inviati al servizio web end-to-end per gli ordini. Queste informazioni vengono convalidate dal tuo servizio web, dopodiché puoi procedere o apportare modifiche al carrello in base alle esigenze.
L'handler di pagamento per il tuo servizio web deve rispondere alle richieste POST. Quando un
cliente sceglie di effettuare il pagamento, Google invia al servizio web Ordering End-to-End un
corpo della richiesta JSON sotto forma di CheckoutRequestMessage
, che contiene i dettagli del Cart
di un cliente. Il servizio web risponde con un messaggio
CheckoutResponseMessage
. Il seguente diagramma illustra la procedura.
Al ricevimento di una richiesta di pagamento, il tuo servizio web end-to-end di ordini deve svolgere quanto segue:
- Verifica la validità del carrello in base ai prezzi, alla disponibilità e al servizio del fornitore correnti degli articoli.
- Calcola il prezzo totale (inclusi eventuali sconti, tasse e commissioni di consegna).
- In caso di esito positivo, rispondi con un carrello non modificato.
- In caso di esito negativo, rispondi con un messaggio di errore e un nuovo ordine proposto.
Prima di iniziare a implementare il pagamento, ti consigliamo di consultare la documentazione relativa alla panoramica dell'evasione degli ordini.
Messaggio di richiesta di pagamento
Per convalidare il carrello del cliente, quando un cliente sceglie di effettuare il pagamento,
Google invia una richiesta al tuo servizio web con un corpo JSON sotto forma di
CheckoutRequestMessage
. L'ordine del cliente non viene inviato fino a un momento successivo nel flusso di Ordine end-to-end.
I dati contenuti in un
CheckoutRequestMessage
includono quanto segue:
- Intent: il campo
inputs[0].intent
di ogni corpo della richiesta di pagamento contiene il valore della stringaactions.foodordering.intent.CHECKOUT
. - Carrello: il campo
inputs[0].arguments[0].extension
di una richiesta di pagamento contiene un oggettoCart
che rappresenta il carrello del cliente. - Consegna o ritiro: il campo di estensione dell'oggetto
Cart
contiene un oggettoFoodCartExtension
che specifica le proprietà per la consegna o il ritiro:- Per gli ordini di consegna, l'oggetto
FoodCartExtension
include l'indirizzo di consegna. - Per gli ordini da asporto o da ritirare, l'oggetto
FoodCartExtension
non contiene informazioni sulla posizione.
- Per gli ordini di consegna, l'oggetto
- Sandbox: il campo
isInSandbox
di una richiesta di pagamento contiene un valore booleano che indica se la transazione utilizza i pagamenti sandbox.
Esempio di richiesta di pagamento
Di seguito è riportato un esempio di 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
}
Messaggio di risposta al pagamento
Dopo aver ricevuto una richiesta dal servizio end-to-end di ordini, il servizio web di pagamento deve elaborarla e rispondere con un CheckoutResponseMessage
. CheckoutResponseMessage
deve coprire una richiesta andata a buon fine o meno.
Richiesta riuscita
Se una richiesta di pagamento va a buon fine, CheckoutResponseMessage
deve includere
ProposedOrder
e
PaymentOptions
:
ProposedOrder
cart
: un oggettocart
identico al carrello fornito inCheckoutRequestMessage
. Se è necessario modificare uno dei contenuti del carrello,CheckoutResponseMessage
deve includere unFoodErrorExtension
con unProposedOrder
corretto.otherItems
: elementi aggiunti dal fornitore, come spese di consegna, imposte e altre commissioni. Può contenere anche la mancia aggiunta dall'utente.totalPrice
: il prezzo totale dell'ordine.extension
: unFoodOrderExtension
che definisce le informazioni di evasione dell'ordine, ad esempio i tempi di consegna.
PaymentOptions
- La configurazione dell'elaborazione dei pagamenti è descritta più avanti in Configurare Google Pay.
Puoi utilizzare un segnaposto JSON in
CheckoutResponseMessage
finché non è tutto pronto per l'implementazione dell'elaborazione dei pagamenti. - Per aggiungere opzioni di pagamento segnaposto in
CheckoutResponseMessage
, consulta l'esempio riportato di seguito, che utilizza un gateway di pagamento di esempio perPaymentOptions
.
- La configurazione dell'elaborazione dei pagamenti è descritta più avanti in Configurare Google Pay.
Puoi utilizzare un segnaposto JSON in
Esempio di risposta corretta
{
"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": []
}
}
}
]
}
}
}
]
}
}
}
Richiesta non riuscita
Se una richiesta di pagamento non va a buon fine, CheckoutResponseMessage
deve includere FoodErrorExtension
, che contiene un elenco di elementi FoodOrderError
che descrivono gli eventuali errori che si sono verificati. Se sono presenti errori recuperabili nell'ordine, ad esempio una variazione di prezzo di un articolo nel carrello, il valore FoodErrorExtension
deve includere correctedProposedOrder
.
Esempio di risposta non riuscita
{
"expectUserResponse": false,
"finalResponse": {
"richResponse": {
"items": [
{
"structuredResponse": {
"error": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
"foodOrderErrors": [
{
"error": "CLOSED",
"description": "The restaurant is closed."
}
]
}
}
}
]
}
}
}
Implementazione del pagamento
Quando implementi il pagamento, devi seguire i passaggi che seguono.
Convalida il servizio
Restituire un FoodOrderError per la prima condizione di errore del servizio ritrovata. Questi errori non sono recuperabili, pertanto deve essere restituito il primo errore rilevato. Per una descrizione degli errori recuperabili, consulta Gestione degli errori.
- Leggi la proprietà FulfillmentOptionInfo nella richiesta per determinare se il tipo di evasione è per
delivery
opickup
. Se necessario, restituisci i seguenti tipi di errore:
Tipo di errore Caso d'uso INVALID Il tipo di adempimento non è valido. NOT_FOUND Il tipo di evasione degli ordini non è stato trovato. CHIUSO - Non sono presenti finestre OperationHours per l'ordine.
- L'ordine è un ordine Il prima possibile e non sono disponibili ServiceHours Il prima possibile per l'ora corrente.
- È in corso una chiusura per motivi di emergenza o il servizio
isDisabled
è true.
UNAVAILABLE_SLOT Non è possibile soddisfare l'ordine anticipato. NO_CAPACITY Il ristorante è occupato e non accetta ordini al momento. OUT_OF_SERVICE_AREA L'ordine non può essere consegnato all'indirizzo dell'utente. Per un esempio, consulta la sezione Convalida dell'indirizzo di consegna. NO_COURIER_AVAILABLE L'ordine non può essere consegnato a causa del personale di consegna limitato.
Convalida e fissa il prezzo del carrello
Cerca ogni Carrello.
lineItems
e convalidalo con i dati correnti nel tuo sistema o nel sistema del commerciante. Il valore MenuItemOffer.sku
dell'entità del feed è incluso come LineItem.offerId
. Se necessario, crea un FoodOrderError per ogni elemento pubblicitario. Crea un massimo di un errore per ogni elemento. Se necessario, restituisci i seguenti tipi di errore:Tipo di errore Caso d'uso Recuperabile INVALID I dati dell'articolo o di una delle opzioni non sono validi. No NOT_FOUND L'elemento o nessuna delle opzioni non è stato trovato. No PRICE_CHANGED Il prezzo di un articolo o di una combinazione di componenti aggiuntivi è cambiato. Questo errore può essere considerato recuperabile. Sì AVAILABILITY_CHANGED L'importo richiesto per gli elementi pubblicitari o per le opzioni non è disponibile. Sì REQUIREMENTS_NOT_MET Il valore minimo o massimo dell'ordine non è stato raggiunto. Questo può essere determinato controllando se il prezzo del carrello è inferiore alla tariffa. eligibleTransactionVolumeMin
o superiore alla tariffa.eligibleTransactionVolumeMax
. Consulta l'esempio nella sezione Convalida del valore minimo dell'ordine.No Restituisce l'elenco convalidato di lineItems con LineItemType
REGULAR
. La somma di tutti i prezzi degli elementi pubblicitari del carrello è il prezzo del carrello oSUBTOTAL
.
Consulta gli esempi nella sezione Convalida degli articoli del carrello.
Calcolare le commissioni di servizio
- Trova l'entità Tariffa corretta per il servizio in base a
eligibleRegion
,validFrom
,validThrough
epriority
. - Calcola l'importo della commissione in base al fatto che l'entità sia stata definita con una proprietà
price
,percentageOfCart
opricePerMeter
. - Restituire la commissione di servizio per la consegna o il ritiro come LineItem con LineItemType
DELIVERY
oFEE
rispettivamente. Aggiungi la commissione all'elenco Carrello.otherItems
Applicare promozioni
- Trova l'entità Deal in base alla corrispondenza del valore Promotion.
coupon
con Deal.dealCode
. Convalida il deal e, se necessario, restituisci un FoodOrderError. Questi errori possono essere considerati recuperabili. Se necessario, restituisci i seguenti tipi di errore:
Tipo di errore Caso d'uso PROMO_NOT_RECOGNIZED Il codice coupon non è stato riconosciuto. PROMO_EXPIRED La validità dell'offerta è scaduta. PROMO_ORDER_INELIGIBLE L'ordine non è idoneo per il coupon. PROMO_NOT_APPLICABLE Qualsiasi altro motivo. Calcola l'importo del prezzo del deal in base a Deal.
discount
o Deal.discountPercentage
.Applica l'importo del prezzo dell'offerta utilizzando il totale del carrello o il totale delle commissioni, a seconda del deal.
dealType
.Restituire il Carrello.
promotions
con la promozione applicata.Restituire la promozione come LineItem con LineItemType
DISCOUNT
. Aggiungi lo sconto all'elenco Cart.otherItems
con un prezzo negativo.
Restituire la risposta
- Crea ProposedOrder.
cart
. Se non si verificano errori durante la convalida, il carrello della risposta è uguale a quello della richiesta. - Restituisce l'elenco ProposedOrder.
otherItems
, incluse tasse, commissioni, mancia e sconto, se applicati. Consulta la sezione Mancia per maggiori dettagli su come configurare l'elemento mancia. - Includi ProposedOrder.
totalPrice
aggiungendo al carrello prezzo, commissioni, sconto, tasse e mancia. - Restituire FoodOrderExtension.
availableFulfillmentOptions
con la rispettiva FulfillmentOption. Aggiorna il giorno e l'ora di ritiro o consegna stimati con l'orario previsto. - Se sono presenti errori FoodOrderErrors generati dai controlli di convalida precedenti:
- Includi StructuredResponse.
error
e l'elenco di errori in FoodErrorExtension.foodOrderErrors
. - Restituire ProposedOrder nel
correctedProposedOrder
campo se tutti gli errori sono recuperabili. - Restituire PaymentOptions nel campo
paymentOptions
se tutti gli errori sono recuperabili. - Se vuoi, includi
additionalPaymentOptions
se sono disponibili altre opzioni di pagamento e tutti gli errori sono recuperabili.
- Includi StructuredResponse.
- Se non ci sono errori di convalida, restituisci
proposedOrder
,paymentOptions
nell'oggetto CheckoutResponse. Se vuoi, includiadditionalPaymentOptions
se sono disponibili altre opzioni di pagamento.