Configurare il pagamento

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.

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

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 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 ritiro: il campo di estensione dell'oggetto Cart contiene un oggetto FoodCartExtension 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.
  • 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 oggetto cart identico al carrello fornito in CheckoutRequestMessage. Se è necessario modificare uno dei contenuti del carrello, CheckoutResponseMessage deve includere un FoodErrorExtension con un ProposedOrder 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: un FoodOrderExtension 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 per PaymentOptions.

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.

  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 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.
    Tieni presente che le finestre speciali hanno la precedenza sulle finestre normali. Consulta gli esempi nella convalida della finestra di ordinazione e nella rimozione temporanea delle entità di servizio.
    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

  1. 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.
    AVAILABILITY_CHANGED L'importo richiesto per gli elementi pubblicitari o per le opzioni non è disponibile.
    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
  2. Restituisce l'elenco convalidato di lineItems con LineItemType REGULAR. La somma di tutti i prezzi degli elementi pubblicitari del carrello è il prezzo del carrello o SUBTOTAL.

Consulta gli esempi nella sezione Convalida degli articoli del carrello.

Calcolare le commissioni di servizio

  1. Trova l'entità Tariffa corretta per il servizio in base a eligibleRegion, validFrom, validThrough e priority.
  2. Calcola l'importo della commissione in base al fatto che l'entità sia stata definita con una proprietà price, percentageOfCart o pricePerMeter.
  3. Restituire la commissione di servizio per la consegna o il ritiro come LineItem con LineItemType DELIVERY o FEE rispettivamente. Aggiungi la commissione all'elenco Carrello.otherItems

Applicare promozioni

  1. Trova l'entità Deal in base alla corrispondenza del valore Promotion.coupon con Deal.dealCode.
  2. 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.
  3. Calcola l'importo del prezzo del deal in base a Deal.discount o Deal.discountPercentage.

  4. Applica l'importo del prezzo dell'offerta utilizzando il totale del carrello o il totale delle commissioni, a seconda del deal.dealType.

  5. Restituire il Carrello.promotions con la promozione applicata.

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

Restituire la risposta

  1. Crea ProposedOrder.cart. Se non si verificano errori durante la convalida, il carrello della risposta è uguale a quello della richiesta.
  2. 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.
  3. Includi ProposedOrder.totalPrice aggiungendo al carrello prezzo, commissioni, sconto, tasse e mancia.
  4. Restituire FoodOrderExtension.availableFulfillmentOptions con la rispettiva FulfillmentOption. Aggiorna il giorno e l'ora di ritiro o consegna stimati con l'orario previsto.
  5. 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.
  6. Se non ci sono errori di convalida, restituisci proposedOrder, paymentOptions nell'oggetto CheckoutResponse. Se vuoi, includi additionalPaymentOptions se sono disponibili altre opzioni di pagamento.