결제 설정

결제 프로세스는 사용자가 장바구니를 만들 때 호출됩니다. 사용자의 장바구니 내용과 주문에 대한 세부정보가 주문 엔드 투 엔드 웹 서비스로 전송됩니다. 이 정보는 웹 서비스에서 검증한 다음 필요에 따라 계속 진행하거나 장바구니를 조정할 수 있습니다.

웹 서비스의 결제 핸들러는 POST 요청에 응답해야 합니다. 고객이 결제를 선택하면 Google은 주문 엔드 투 엔드 웹 서비스에 고객의 Cart 세부정보가 포함된 CheckoutRequestMessage 형식의 JSON 요청 본문을 보냅니다. 그러면 웹 서비스가 CheckoutResponseMessage로 다시 응답합니다. 다음 다이어그램은 이러한 프로세스를 보여줍니다.

CheckoutResponseMessage는 고객의 수정되지 않은 장바구니 또는 오류를
반환합니다.

결제 요청을 받으면 주문 엔드 투 엔드 웹 서비스는 다음을 수행해야 합니다.

  • 현재 상품 가격, 재고, 제공업체 서비스를 기반으로 장바구니의 유효성을 확인합니다.
  • 할인, 세금, 배송료를 포함한 총가격을 계산합니다.
  • 성공하면 수정되지 않은 장바구니로 응답합니다.
  • 실패하면 오류 메시지와 새로 제안된 주문을 포함하여 응답합니다.

결제 구현을 시작하기 전에 처리 개요 문서를 검토하는 것이 좋습니다.

결제 요청 메시지

고객의 장바구니를 검증하기 위해 고객이 결제를 선택하면 Google은 CheckoutRequestMessage 형식의 JSON 본문과 함께 웹 서비스에 요청을 전송합니다. 고객 주문이 주문 엔드 투 엔드 흐름에서 나중까지 제출되지 않습니다.

CheckoutRequestMessage에 포함된 데이터에는 다음이 포함됩니다.

  • 인텐트: 모든 결제 요청 본문의 inputs[0].intent 필드에는 actions.foodordering.intent.CHECKOUT 문자열 값이 포함됩니다.
  • 장바구니: 결제 요청의 inputs[0].arguments[0].extension 필드에는 고객의 장바구니를 나타내는 Cart 객체가 포함됩니다.
  • 배달 또는 테이크아웃: Cart 객체의 확장 필드에는 배달 또는 테이크아웃 속성을 지정하는 FoodCartExtension 객체가 포함됩니다.
    • 배달 주문의 경우 FoodCartExtension 객체에는 배송 주소가 포함됩니다.
    • 수령 또는 테이크아웃 주문의 경우 FoodCartExtension 객체에는 위치 정보가 포함되지 않습니다.
  • 샌드박스: 결제 요청의 isInSandbox 필드에는 거래에 샌드박스 결제를 사용하는지 여부를 나타내는 불리언 값이 포함됩니다.

결제 요청 예시

다음은 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
}

결제 응답 메시지

주문 엔드 투 엔드 서비스로부터 요청을 받으면 결제 웹 서비스에서 요청을 처리하고 CheckoutResponseMessage로 응답해야 합니다. CheckoutResponseMessage는 성공 또는 실패 요청을 처리해야 합니다.

요청 성공

결제 요청이 성공하면 CheckoutResponseMessageProposedOrderPaymentOptions가 포함되어야 합니다.

  • ProposedOrder

    • cart: CheckoutRequestMessage에 제공된 장바구니와 동일한 cart 객체입니다. 장바구니의 콘텐츠를 변경해야 하는 경우 CheckoutResponseMessage에는 수정된 ProposedOrder가 있는 FoodErrorExtension가 대신 포함되어야 합니다.
    • otherItems: 배송료, 세금, 기타 수수료 등 제공업체가 추가한 항목입니다. 사용자가 추가한 봉사료도 포함될 수 있습니다.
    • totalPrice: 총 주문 가격입니다.
    • extension: 주문의 처리 정보(예: 배송 시간)를 정의하는 FoodOrderExtension입니다.
  • PaymentOptions

    • 결제 처리 설정은 나중에 Google Pay 설정에서 다룹니다. 결제 처리를 구현할 준비가 될 때까지 CheckoutResponseMessage에서 자리표시자 JSON을 사용할 수 있습니다.
    • CheckoutResponseMessage에 자리표시자 결제 옵션을 추가하려면 PaymentOptions에 결제 게이트웨이 예시를 사용하는 아래 예시를 참조하세요.

성공적인 응답 예

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

요청 실패

결제 요청이 실패하면 CheckoutResponseMessage에 발생한 오류를 설명하는 FoodOrderError 항목 목록이 포함된 FoodErrorExtension를 포함해야 합니다. 장바구니에 있는 상품의 가격 변경과 같이 주문에 복구 가능한 오류가 있는 경우 FoodErrorExtensioncorrectedProposedOrder가 포함되어야 합니다.

실패한 응답 예

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

결제 구현

결제를 구현할 때 다음 단계를 따라야 합니다.

서비스 검증

찾은 첫 번째 서비스 오류 조건에 대해 FoodOrderError를 반환합니다. 이러한 오류는 복구할 수 없으므로 발생한 첫 번째 오류가 반환되어야 합니다. 복구할 수 있는 오류에 관한 설명은 오류 처리를 참고하세요.

  1. 요청의 FulfillmentOptionInfo 속성을 읽어 처리 유형이 delivery인지 pickup인지 확인합니다.
  2. 필요한 경우 다음 오류 유형을 반환합니다.

    오류 유형 사용 사례
    INVALID 처리 유형이 잘못되었습니다.
    NOT_FOUND 처리 유형을 찾을 수 없습니다.
    종료됨
    • 주문의 OperationHours 기간은 없습니다.
    • 주문이 ASAP 주문이며 현재 시간에 사용할 수 있는 ASAP ServiceHours가 없습니다.
    • 긴급 휴업 상태이거나 isDisabled 서비스가 참입니다.
    특수 기간은 일반 기간보다 우선합니다. 주문 기간 유효성 검사일시적으로 서비스 항목 삭제의 예를 참고하세요.
    UNAVAILABLE_SLOT 사전 주문을 처리할 수 없습니다.
    NO_CAPACITY 음식점이 붐비며 지금은 주문을 받지 않습니다.
    OUT_OF_SERVICE_AREA 사용자의 주소로 주문 상품을 배송할 수 없습니다. 예시는 배송 주소 확인을 참고하세요.
    NO_COURIER_AVAILABLE 배송 인력이 제한적이어서 주문을 배송할 수 없습니다.

장바구니 확인 및 가격 책정

  1. 장바구니.lineItems를 조회하고 자체 시스템 또는 판매자 시스템의 현재 데이터를 검증합니다. 피드 항목의 MenuItemOffer.sku 값이 LineItem으로 포함됩니다.offerId. 필요한 경우 각 광고 항목에 대해 FoodOrderError를 생성합니다. 항목마다 최대 1개의 오류를 만듭니다. 필요한 경우 다음 오류 유형을 반환합니다.

    오류 유형 사용 사례 복구 가능
    INVALID 항목 데이터 또는 옵션 데이터가 올바르지 않습니다. No
    NOT_FOUND 항목 또는 옵션을 찾을 수 없습니다. No
    PRICE_CHANGED 상품 또는 부가기능 조합의 가격이 변경되었습니다. 이 오류는 복구 가능한 것으로 취급할 수 있습니다. 지원됨
    AVAILABILITY_CHANGED 광고 항목 또는 모든 옵션에 대해 요청된 금액을 사용할 수 없습니다. 지원됨
    REQUIREMENTS_NOT_MET 최소 주문 금액 또는 최대 주문 금액이 충족되지 않았습니다. 이는 장바구니 가격이 수수료보다 낮거나eligibleTransactionVolumeMin 수수료보다 높은지 확인하면 알 수 있습니다eligibleTransactionVolumeMax. 최소 주문 금액 검증의 예를 참고하세요. No
  2. LineItemTypeREGULAR인 검증된 광고 항목 목록을 반환합니다. 모든 장바구니 항목 가격의 합계가 장바구니 가격 또는 SUBTOTAL입니다.

장바구니 항목 확인의 예를 참고하세요.

서비스 수수료 계산

  1. eligibleRegion, validFrom, validThrough, priority에 따라 서비스에 적합한 요금 항목을 찾습니다.
  2. 항목이 price, percentageOfCart 또는 pricePerMeter 속성으로 정의되었는지를 기준으로 수수료 금액을 계산합니다.
  3. LineItemType DELIVERY 또는 FEE를 사용하여 배달 또는 테이크아웃 서비스 수수료를 LineItem으로 반환합니다. 장바구니.otherItems 목록에 수수료를 추가합니다.

프로모션 적용

  1. Promo.coupon 값을 거래와 일치시켜 거래 항목을 찾습니다.dealCode
  2. 거래를 검증하고 필요한 경우 FoodOrderError를 반환합니다. 이러한 오류는 복구 가능한 것으로 취급할 수 있습니다. 필요한 경우 다음 오류 유형을 반환합니다.

    오류 유형 사용 사례
    PROMO_NOT_RECOGNIZED 쿠폰 코드를 인식할 수 없습니다.
    PROMO_EXPIRED 거래의 유효 기간이 만료되었습니다.
    PROMO_ORDER_INELIGIBLE 주문에 쿠폰을 사용할 수 없습니다.
    PROMO_NOT_APPLICABLE 기타 이유
  3. Deal.discount 또는 DealdiscountPercentage을 기준으로 거래 가격 금액을 계산합니다.

  4. 거래에 따라 장바구니 총액 또는 수수료 합계를 사용하여 거래 가격 금액을 적용합니다.dealType

  5. 프로모션이 적용된 장바구니.promotions를 반품합니다.

  6. 프로모션을 LineItemTypeDISCOUNTLineItem으로 반환합니다. 장바구니.otherItems 목록에 음수 가격을 추가하여 할인을 추가합니다.

응답 반환

  1. ProposedOrder.cart를 만듭니다. 검증 중에 오류가 발생하지 않으면 응답 장바구니가 요청 장바구니와 동일합니다.
  2. 적용된 경우 세금, 수수료, 봉사료, 할인이 포함된 ProposedOrder.otherItems 목록을 반환합니다. 봉사료 항목을 구성하는 방법에 관한 자세한 내용은 간격을 참고하세요.
  3. 장바구니 가격, 수수료, 할인, 세금, 봉사를 추가하여 ProposedOrder.totalPrice를 포함합니다.
  4. FulfillmentOption을 사용하여 FoodOrderExtension.availableFulfillmentOptions을 반환합니다. 예상 수령 또는 배송 시간을 예상 시간으로 업데이트합니다.
  5. 이전 유효성 검사에서 생성된 FoodOrderErrors가 있는 경우:
    • StructuredResponse.errorFoodErrorExtension.foodOrderErrors의 오류 목록을 포함합니다.
    • 모든 오류를 복구할 수 있는 경우 correctedProposedOrder 필드에 ProposedOrder를 반환합니다.
    • 모든 오류를 복구할 수 있는 경우 paymentOptions 필드에서 PaymentOptions를 반환합니다.
    • 다른 결제 옵션이 있고 모든 오류를 복구할 수 있는 경우 선택적으로 additionalPaymentOptions를 포함합니다.
  6. 유효성 검사 오류가 없으면 CheckoutResponse 객체에서 proposedOrder, paymentOptions를 반환합니다. 다른 결제 옵션이 있는 경우 선택적으로 additionalPaymentOptions를 포함합니다.