Configura Google Checkout

La procedura di pagamento viene attivata 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 di ordinazione. Queste informazioni vengono convalidate dal tuo servizio web, quindi puoi procedere o apportare modifiche al carrello in base alle tue esigenze.

Il gestore dei pagamenti per il tuo servizio web deve rispondere alle richieste POST. Quando un cliente sceglie di effettuare il pagamento, Google invia al servizio web end-to-end degli ordini un corpo della richiesta JSON sotto forma di CheckoutRequestMessage, che contiene i dettagli del Cart di un cliente. Il tuo servizio web risponde quindi con un CheckoutResponseMessage. Il seguente diagramma illustra il processo.

CheckoutResponseMessage restituisce il carrello non modificato del cliente oppure restituisce un errore.

Alla ricezione di una richiesta di pagamento, il servizio web end-to-end dell'ordine deve:

  • Controlla la validità del carrello in base agli attuali prezzi degli articoli, alla disponibilità e al servizio del fornitore.
  • Calcola il prezzo totale (inclusi eventuali sconti, tasse e commissioni di consegna).
  • In caso di esito positivo, rispondi con un carrello non modificato.
  • Se l'operazione non va a buon fine, rispondi con un messaggio di errore e con un nuovo ordine proposto.

Prima di iniziare a implementare il pagamento, ti consigliamo di consultare la documentazione della panoramica sull'evasione degli ordini.

Messaggio di richiesta 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 viene inviato solo in seguito nel flusso end-to-end dell'ordine.

I dati contenuti in un CheckoutRequestMessage includono quanto segue:

  • Intento: il campo inputs[0].intent del corpo di ogni richiesta di pagamento contiene il valore della stringa actions.foodordering.intent.CHECKOUT.
  • Carrello: il campo inputs[0].arguments[0].extension di una richiesta di pagamento contiene un oggetto Cart che rappresenta il carrello del cliente.
  • Consegna o estrazione: il campo dell'estensione dell'oggetto Cart contiene un oggetto FoodCartExtension che specifica le proprietà per la consegna o l'estrazione:
    • Per gli ordini con consegna, l'oggetto FoodCartExtension include l'indirizzo di consegna.
    • Per gli ordini con ritiro o asporto, l'oggetto FoodCartExtension non contiene informazioni sulla posizione.
  • Sandbox: il campo isInSandbox di una richiesta di pagamento contiene un valore booleano che indica se la transazione utilizza 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 ordinazione, il servizio web di pagamento deve elaborarla e rispondere con un CheckoutResponseMessage. CheckoutResponseMessage deve coprire una richiesta andata a buon fine o non riuscita.

Richiesta riuscita

Se una richiesta di pagamento ha esito positivo, CheckoutResponseMessage deve includere ProposedOrder e PaymentOptions:

  • ProposedOrder

    • cart: un oggetto cart identico al carrello fornito in CheckoutRequestMessage. Se è necessario modificare i contenuti del carrello, il CheckoutResponseMessage deve includere invece un FoodErrorExtension con un ProposedOrder corretto.
    • otherItems: articoli aggiunti dal fornitore, ad esempio spese di consegna, tasse e altre commissioni. Possono anche contenere mance aggiunte dall'utente.
    • totalPrice: il prezzo totale dell'ordine.
    • extension: un FoodOrderExtension che definisce le informazioni di evasione dell'ordine, come i tempi di consegna.
  • PaymentOptions

    • La configurazione dell'elaborazione dei pagamenti verrà trattata più avanti in Configurare Google Pay. Puoi utilizzare JSON segnaposto in CheckoutResponseMessage finché non è tutto pronto per implementare l'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 per PaymentOptions.

Esempio di risposta riuscita

{
    "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 FoodOrderError elementi che descrivono gli eventuali errori che si sono verificati. Se si verificano errori recuperabili nell'ordine, come una variazione di prezzo di un articolo nel carrello, l'elemento FoodErrorExtension deve includere il 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 di Google Checkout

Quando implementi il pagamento, devi seguire questi passaggi.

Convalidare il servizio

Restituisci un valore FoodOrderError per la prima condizione di errore del servizio rilevata. Questi errori non sono recuperabili, quindi il primo errore riscontrato deve essere restituito. Per una descrizione degli errori recuperabili, consulta Gestione degli errori.

  1. Leggi la proprietà FulfillmentOptionInfo nella richiesta per determinare se il tipo di evasione è per delivery o pickup.
  2. Se necessario, restituisci i seguenti tipi di errore:

    Tipo di errore Caso d'uso
    INVALID Il tipo di evasione non è valido.
    NOT_FOUND Il tipo di evasione non è stato trovato.
    CHIUSO
    • Non sono presenti finestre OperationHours per l'ordine.
    • L'ordine è di tipo "Appena possibile" e non sono disponibili ServiceHours il prima possibile per l'ora attuale.
    • C'è una chiusura di emergenza o il servizio isDisabled è attivo.
    Tieni presente che le finestre speciali hanno la precedenza sulle finestre normali. Consulta gli esempi relativi alla convalida delle finestre di ordinamento e alla rimozione temporanea delle entità di servizio.
    UNAVAILABLE_SLOT Impossibile completare l'ordine in anticipo.
    NO_CAPACITY Il ristorante è affollato 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 limitato addetto alla consegna.

Convalidare e impostare il prezzo del carrello

  1. Cerca ogni carrello.lineItems ed esegui la convalida con i dati attuali nel tuo sistema o nel sistema del commerciante. Il valore MenuItemOffer.sku dell'entità del feed è incluso come LineItem.offerId. Crea un valore FoodOrderError per ogni elemento pubblicitario, se necessario. Crea un massimo di un errore per ogni articolo. Se necessario, restituisci i seguenti tipi di errore:

    Tipo di errore Caso d'uso Recuperabile
    INVALID I dati dell'articolo o i dati delle opzioni non sono validi. No
    NOT_FOUND Impossibile trovare l'elemento o una delle opzioni. No
    PRICE_CHANGED Il prezzo di una combinazione di articoli o componenti aggiuntivi è cambiato. Questo errore può essere considerato recuperabile.
    AVAILABILITY_CHANGED L'importo richiesto per gli elementi pubblicitari o una qualsiasi delle opzioni non è disponibile.
    REQUIREMENTS_NOT_MET Il valore minimo o massimo dell'ordine non è stato soddisfatto. Per determinarlo, controlla se il prezzo del carrello è inferiore alla Tariffa.eligibleTransactionVolumeMin o superiore alla Tariffa.eligibleTransactionVolumeMax. Vedi l'esempio nella convalida del valore minimo dell'ordine. No
  2. Restituisci l'elenco convalidato di elementi pubblicitari con LineItemType REGULAR. La somma di tutti i prezzi degli articoli pubblicitari del carrello corrisponde al prezzo del carrello o SUBTOTAL.

Guarda gli esempi relativi alla convalida degli articoli del carrello.

Calcolare le commissioni di servizio

  1. Trova l'entità Fee corretta per il servizio in base a eligibleRegion, validFrom, validThrough e priority.
  2. Calcola l'importo della tariffa se l'entità è stata definita con una proprietà price, percentageOfCart o pricePerMeter.
  3. Restituisci la commissione di servizio di consegna o estrazione come LineItem con LineItemType rispettivamente DELIVERY o FEE. Aggiungi la tariffa all'elenco Carrello.otherItems.

Applica promozioni

  1. Trova l'entità Deal in base alla corrispondenza tra il valore di Promozione.coupon e il valore Deal.dealCode.
  2. Convalida il deal e restituisci un FoodOrderError, se necessario. Questi errori possono essere trattati come recuperabili. Se necessario, restituisci i seguenti tipi di errore:

    Tipo di errore Caso d'uso
    PROMO_NOT_RECOGNIZED Codice coupon non riconosciuto.
    PROMO_EXPIRED La validità del deal è scaduta.
    PROMO_ORDER_INELIGIBLE L'ordine non è idoneo per il coupon.
    PROMO_NOT_APPLICABLE Per qualsiasi altro motivo.
  3. Calcola l'importo del prezzo del deal in base al Dealdiscount o Deal.discountPercentage.

  4. Applica l'importo del prezzo dell'offerta utilizzando il totale del carrello o il totale della tariffa in base all'accordo.dealType.

  5. Restituisci il carrello.promotions con la promozione applicata.

  6. Restituisci la promozione come LineItem con LineItemType DISCOUNT. Aggiungi lo sconto all'elenco Carrello.otherItems con un prezzo negativo.

Restituire la risposta

  1. Crea il ProposedOrder.cart, il carrello delle risposte è uguale al carrello delle richieste se non vengono riscontrati errori durante la convalida.
  2. Restituisci l'elenco ProposedOrder.otherItems che include tasse, commissioni, mance e sconto, se applicati. Consulta Gratuity per ulteriori dettagli su come configurare l'elemento senza costi.
  3. Includi l'ProposedOrder.totalPrice aggiungendo il prezzo del carrello, le commissioni, lo sconto, le tasse e la mancia.
  4. Restituisci FoodOrderExtension.availableFulfillmentOptions con la rispettiva FulfillmentOption. Aggiorna i tempi di ritiro o consegna stimati all'orario previsto.
  5. Se sono stati generati errori FoodOrderError dai controlli di convalida precedenti:
    • Includi StructuredResponse.error e l'elenco degli errori in FoodErrorExtension.foodOrderErrors.
    • Se tutti gli errori sono recuperabili, restituisci il valore ProposedOrder nel campo correctedProposedOrder.
    • Restituisci PaymentOptions nel campo paymentOptions se tutti gli errori sono recuperabili.
    • (Facoltativo) Includi additionalPaymentOptions se sono disponibili altre opzioni di pagamento e se tutti gli errori sono recuperabili.
  6. Se non sono presenti errori di convalida, restituisci proposedOrder, paymentOptions nell'oggetto CheckoutResponse. Se vuoi, includi additionalPaymentOptions se sono disponibili altre opzioni di pagamento.