Configurer le paiement

Le processus de paiement est appelé lorsqu'un utilisateur crée un panier. Le contenu de le panier de l'utilisateur et les informations relatives à la commande sont envoyés au service Google Cloud. Ces informations sont validées par votre service Web, poursuivre ou modifier son panier si nécessaire.

Le gestionnaire de paiement de votre service Web doit répondre aux requêtes POST. Lorsqu'un client décide de régler, Google envoie au service Web de commande de bout en bout un Corps de la requête JSON sous la forme d'un fichier CheckoutRequestMessage, qui contient le les détails du Cart d'un client. Votre service Web répond ensuite avec une CheckoutResponseMessage Le schéma suivant illustre le processus.

Le message "CheckoutResponseMessage" renvoie le panier non modifié du client ou une
.

À la réception d'une demande de paiement, votre service Web de commande de bout en bout doit les éléments suivants:

  • Vérifiez la validité du panier en fonction du prix actuel, de la disponibilité et de fournisseur de services.
  • Calculer le prix total (y compris les remises, les taxes et les frais de livraison) frais).
  • Si l'opération réussit, envoyez un panier non modifié.
  • En cas d'échec, envoyez un message d'erreur et une nouvelle proposition de commande.

Avant de commencer à implémenter le paiement, nous vous recommandons de consulter le Guide de traitement présentation dans la documentation Google Cloud.

Message de demande de paiement

Afin de valider le panier du client, lorsqu'un client choisit de passer au paiement, Google envoie une requête à votre service Web avec un corps JSON sous la forme d'un CheckoutRequestMessage La commande client n'est pas envoyée avant la fin du Flux de commande de bout en bout.

Les données contenues dans un CheckoutRequestMessage comprend les éléments suivants:

  • Intent : inputs[0].intent de chaque corps de requête de règlement contient le champ Valeur de chaîne actions.foodordering.intent.CHECKOUT.
  • Panier: champ inputs[0].arguments[0].extension d'une demande de règlement contient un objet Cart qui représente le panier du client.
  • Livraison ou récupération: le champ d'extension de l'objet Cart contient une un objet FoodCartExtension spécifiant les propriétés de diffusion ou récupération: <ph type="x-smartling-placeholder">
      </ph>
    • Pour les commandes à livrer, l'objet FoodCartExtension inclut le paramètre adresse de livraison.
    • Pour les commandes à emporter ou à emporter, l'objet FoodCartExtension ne ne contiennent aucune information de localisation.
  • Bac à sable: le champ isInSandbox d'une demande de règlement contient une valeur booléenne qui indique si la transaction utilise les paiements Sandbox.

Exemple de demande de paiement

Voici un exemple de 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
}

Message de réponse Google Checkout

Après avoir reçu une demande du service de commande de bout en bout, votre interface de paiement service doit le traiter et répondre avec un CheckoutResponseMessage. La CheckoutResponseMessage doit couvrir les cas de réussite ou d'échec requête.

Demande réussie

Si une demande de paiement aboutit, CheckoutResponseMessage doit inclure ProposedOrder et PaymentOptions:

  • ProposedOrder

    • cart: objet cart identique au panier fourni dans le CheckoutRequestMessage Si un élément du panier doit être modifié, CheckoutResponseMessage devrait plutôt inclure un FoodErrorExtension par une ProposedOrder corrigée.
    • otherItems: éléments ajoutés par le fournisseur, tels que les frais de livraison les taxes et autres frais. Peut également inclure des pourboires ajoutés par l'utilisateur.
    • totalPrice: prix total de la commande.
    • extension: FoodOrderExtension qui définit les informations de traitement comme le délai de livraison.
  • PaymentOptions

    • La configuration du traitement des paiements est abordée plus loin dans la section Configurer Payer. Vous pouvez utiliser un espace réservé JSON dans votre CheckoutResponseMessage jusqu'à prêts à implémenter le traitement des paiements.
    • Pour ajouter des options de paiement par espace réservé dans votre CheckoutResponseMessage, reportez-vous à l'exemple ci-dessous, qui utilise exemple de passerelle de paiement pour PaymentOptions.

Exemple de réponse réussie

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

Échec de la demande

Si une demande de paiement échoue, CheckoutResponseMessage doit inclure FoodErrorExtension, qui contient une liste de FoodOrderError qui décrivent les erreurs qui se sont produites. S'il y a des erreurs des erreurs dans la commande, comme un changement de prix d'un article dans le panier, le FoodErrorExtension doit inclure correctedProposedOrder.

Exemple de réponse non réussie

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

Implémentation d'une solution de paiement

Pour implémenter le paiement, procédez comme suit :

Valider le service

Renvoyez une erreur FoodOrderError pour la première condition d'erreur de service. trouvé. Comme ces erreurs ne peuvent pas être récupérées, la première erreur rencontrée devrait être renvoyé. Consultez la section Gérer les erreurs pour obtenir une description des les erreurs récupérables.

  1. Lisez la propriété FulfillmentOptionInfo dans le requête pour déterminer si le type de traitement est défini sur delivery ou pickup.
  2. Renvoyez les types d'erreurs suivants si nécessaire:

    Type d'erreur Cas d'utilisation
    NON VALIDE Le type de traitement n'est pas valide.
    NOT_FOUND Le type de traitement est introuvable.
    FERMÉE
    • Aucun créneau OperationHours n'est associé à cette commande.
    • Il s'agit d'une commande "Dès que possible", et aucun créneau ServiceHours n'est disponible pour l'heure actuelle.
    • Une fermeture d'urgence a lieu, ou le service isDisabled est défini sur "true".
    Notez que les fenêtres spéciales ont priorité sur les fenêtres classiques. Consultez les exemples de validation des périodes de classement et de suppression temporaire d'entités de service.
    UNAVAILABLE_SLOT Impossible de respecter le délai de commande à l'avance.
    NO_CAPACITY Le restaurant est très fréquenté et ne prend pas de commandes pour le moment.
    OUT_OF_SERVICE_AREA La commande ne peut pas être livrée à l'adresse de l'utilisateur. Consultez la section Validation des adresses de livraison pour obtenir un exemple.
    NO_COURIER_AVAILABLE La commande ne peut pas être livrée en raison d'un personnel de livraison limité.

Valider le panier et lui attribuer un prix

  1. Recherchez chaque panier.lineItems et validez-le avec les données actuelles dans dans votre système ou dans celui du marchand. La MenuItemOffer.sku de l'entité de flux est incluse. comme LineItem.offerId Créez un FoodOrderError pour chaque article, si nécessaire. Créez un une erreur par article au maximum. Renvoyez les types d'erreurs suivants si nécessaire:

    Type d'erreur Cas d'utilisation Restauration possible
    NON VALIDE Les données de l'article ou de l'une des options ne sont pas valides. Non
    NOT_FOUND L'élément ou l'une des options est introuvable. Non
    PRICE_CHANGED Le prix d'un article ou d'une combinaison de modules complémentaires a changé. Cette erreur peut être considérée comme récupérable. Oui
    AVAILABILITY_CHANGED Le montant demandé pour les lignes de commande ou l'une des options n'est pas disponible. Oui
    REQUIREMENTS_NOT_MET Le montant minimal ou maximal de commande n'est pas atteint. Pour déterminer cela, vérifiez si le prix du panier est inférieur aux FraiseligibleTransactionVolumeMin ou supérieur aux Frais.eligibleTransactionVolumeMax Consultez l'exemple dans la section Validation du montant minimal de commande. Non
  2. Renvoyer la liste validée des éléments de campagne avec LineItemType REGULAR La somme de tous les prix des éléments de ligne du panier est le prix du panier ou SUBTOTAL

Consultez des exemples de validation des éléments du panier.

Calculer les frais de service

  1. Recherchez l'entité Frais correspondant au service en fonction de la eligibleRegion, validFrom, validThrough et priority.
  2. Calculer le montant des frais selon que l'entité a été définie avec un price, percentageOfCart ou pricePerMeter.
  3. Renvoyez les frais de service de livraison ou de vente à emporter en tant qu'LineItem avec LineItemType, DELIVERY ou FEE, respectivement. Ajouter les frais à la liste Panier.otherItems.

Appliquer les promotions

  1. Recherchez l'entité Accord en fonction de la correspondance Promotion.coupon avec l'attribut Deal.dealCode
  2. Validez l'offre et renvoyez une erreur FoodOrderError si nécessaire. Ces erreurs peuvent être considérées comme récupérables. Renvoyer les types d'erreurs suivants si nécessaire:

    Type d'erreur Cas d'utilisation
    PROMO_NOT_RECOGNIZED Le code promotionnel n'a pas été reconnu.
    PROMO_EXPIRED L'accord a expiré.
    PROMO_ORDER_INELIGIBLE Cette commande ne permet pas d'utiliser ce bon de réduction.
    PROMO_NOT_APPLICABLE Toute autre raison.
  3. Calculez le montant de l'offre en fonction de l'attribut Deal.discount ou Accord.discountPercentage.

  4. Appliquez le montant de l'offre en utilisant le montant total du panier ou le montant total des frais, selon le Accord.dealType.

  5. Renvoyez le Cart.promotions avec la promotion appliquée.

  6. Renvoyez la promotion en tant qu'élément LineItem avec LineItemType DISCOUNT Ajoutez la remise Liste Cart.otherItems avec un prix négatif.

Renvoyer la réponse

  1. Créez ProposedOrder.cart, le panier de réponse est identique au panier de la demande si aucune erreur n'est détectée lors de la validation.
  2. Renvoyez la liste ProposedOrder.otherItems incluant les éléments taxes, frais, pourboires et remises, le cas échéant. Consultez la section Sans frais pour plus de détails sur la configuration de ce type de pourboire.
  3. Incluez l'élément ProposedOrder.totalPrice en ajoutant le panier (prix, frais, remises, taxes et pourboires).
  4. Renvoyez le FoodOrderExtension.availableFulfillmentOptions avec l'FulfillmentOption correspondante. Mettez à jour l'estimation de retrait ou de livraison à l'heure prévue.
  5. Si des erreurs FoodOrderErrors ont été générées lors des contrôles de validation précédents: <ph type="x-smartling-placeholder">
      </ph>
    • Incluez StructuredResponse.error et la liste des erreurs dans FoodErrorExtension.foodOrderErrors.
    • Renvoyez ProposedOrder dans le Champ correctedProposedOrder si toutes les erreurs peuvent être récupérées.
    • Renvoyez les PaymentOptions dans paymentOptions si toutes les erreurs peuvent être récupérées.
    • Incluez éventuellement additionalPaymentOptions s'il existe d'autres options de paiement disponibles et toutes les erreurs peuvent être corrigées.
  6. En l'absence d'erreurs de validation, renvoyez proposedOrder, paymentOptions dans l'objet CheckoutResponse. Incluez éventuellement additionalPaymentOptions s'il existe d'autres options de paiement disponibles.