결제 설정

결제 프로세스는 사용자가 장바구니를 만들 때 호출됩니다. 사용자의 장바구니 콘텐츠와 주문 세부정보가 주문 엔드 투 엔드 웹 서비스로 전송됩니다. 이 정보는 웹 서비스에서 확인한 후 필요에 따라 장바구니를 진행하거나 조정할 수 있습니다.

웹 서비스의 결제 핸들러는 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 기간이 없습니다.
    • 주문이 최대한 빨리 처리되어야 하는 주문이지만 현재 이용 가능한 최대한 빨리 처리되어야 하는 ServiceHours가 없습니다.
    • 긴급 폐쇄가 있거나 서비스 isDisabled가 true입니다.
    특별 기간은 일반 기간보다 우선 적용됩니다. 주문 기간 유효성 검사일시적으로 서비스 항목 삭제의 예를 참고하세요.
    UNAVAILABLE_SLOT 주문한 시간에 맞춰 배송할 수 없습니다.
    NO_CAPACITY 음식점이 바빠 현재 주문을 받지 않고 있습니다.
    OUT_OF_SERVICE_AREA 사용자의 주소로 주문 제품을 배송할 수 없습니다. 예시는 배송지 주소 유효성 검사를 참고하세요.
    NO_COURIER_AVAILABLE 배송 인력이 부족하여 주문 제품을 배송할 수 없습니다.

장바구니 유효성 검사 및 가격 책정

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

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

장바구니 상품 검증의 예를 참고하세요.

서비스 수수료 계산

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

프로모션 적용

  1. Promotion.coupon 값과 Deal.dealCode 값을 일치시켜 Deal 항목을 찾습니다.
  2. 거래를 확인하고 필요한 경우 FoodOrderError를 반환합니다. 이러한 오류는 복구 가능한 것으로 간주될 수 있습니다. 필요한 경우 다음 오류 유형을 반환합니다.

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

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

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

  6. LineItemType DISCOUNT으로 LineItem으로 프로모션을 반환합니다. 장바구니.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를 포함할 수도 있습니다.