프로모션

프로모션을 통해 귀하와 Google은 고객이 할인 가격으로 음식 주문 서비스를 시도하도록 유도할 수 있습니다. Google은 주문 엔드 투 엔드 작업을 프로모션 관리 시스템에 통합할 수 있도록 지원합니다.

다음과 같은 유형의 할인이 지원됩니다.

  • Google 스폰서 프로모션 코드: Google에서 자동으로 미리 입력하거나 사용자가 입력하는 프로모션 코드입니다.
  • 서드 파티 스폰서 프로모션 코드: 음식 주문 서비스에서 제공하는 사용자가 입력할 프로모션 코드입니다.
  • 서드 파티 스폰서 자동 할인: 프로모션 코드 없이 음식 주문 서비스에서 자동으로 적용되는 할인입니다.

할인 유형과 관계없이 Google은 할인을 확인하고 적용하기 위해 음식 주문 처리에 결제 호출을 보냅니다.

음식 주문 서비스의 개발자는 구현을 약간 변경하여 유효한 프로모션 코드에 대한 할인을 계산하거나, 유효하지 않은 프로모션 코드에 대한 오류를 전송하고, 프로모션 코드 사용 제한을 관리하고, 환급을 위한 회계 데이터를 추적해야 합니다.

프로모션 처리 방법

프로모션을 지원하는 처리를 구현하려면 다음을 실행하세요.

  1. 프로모션 통합을 설정합니다. (Google에서 후원하는 프로모션 코드를 사용하지 않는 경우 이 단계를 건너뛰세요.)
  2. 프로모션을 통한 결제를 구현합니다.
  3. 프로모션을 통한 주문 제출을 구현합니다.

프로모션 통합 설정

이 섹션에서는 Google에서 후원하는 프로모션 코드를 사용하려는 경우 프로모션 통합을 설정하는 방법을 설명합니다. 서드 파티가 스폰서하는 프로모션 코드 또는 할인만 지원하려는 경우 자체 설정을 지정하고 이 섹션을 건너뛰어도 됩니다.

Google에서 후원할 프로모션 유형을 지정한 후 통합을 설정하기 위해 개발자에게 연락합니다. Google에서 제공하는 세부정보는 다음과 같습니다.

  • 할인 금액입니다.
  • 장바구니의 최소 금액입니다.
  • 프로모션 코드 사용 시작일과 종료일입니다.
  • 프로모션 캠페인 예산으로 책정된 최대 금액(달러)입니다.
  • 프로모션 코드를 사용할 수 있는 횟수입니다.

프로모션 코드의 예:

  • FopaNewUser: 10% (고정 비율)이며 최대 $50 할인됩니다.
  • FopaMoreThan50: $10 (정액 할인)

Google에서 코드 적용을 중단하기로 결정한 경우 연락을 드리겠습니다.

지불 설정

Google EAP 컨설턴트에게 연락하여 지급 절차를 설정합니다. Google은 최종 주문 상태가 다음 중 하나인 경우에만 Google 스폰서 프로모션 코드와 관련된 거래에 대해 환불을 제공합니다.

  • CONFIRMED
  • IN_TRANSIT
  • READY_FOR_PICKUP
  • IN_PREPARATION
  • FULFILLED

프로모션으로 결제 구현

이 섹션에서는 Google 후원 또는 서드 파티 후원 프로모션 코드를 지원할 때 결제 처리를 구현하는 방법을 설명합니다. 서드 파티가 후원하는 자동 할인의 경우 CheckoutResponseMessage에서 할인 광고 항목만 반환하면 됩니다 (프로모션 코드 확인은 필요하지 않음).

음식 주문 처리 중에 Google은 CheckoutRequestMessage에 있는 단일 프로모션 코드를 처리에 전송합니다. 사용자는 반복되는 결제 요청에서 장바구니나 프로모션 코드를 변경할 수 있습니다.

사용자가 프로모션 코드를 처음 적용한 것인지 확인하려면 다음 단계를 따르세요.

  • Google에서 후원하는 프로모션 코드: Google에서 재방문자가 동일한 프로모션 코드를 다시 사용하려고 하는지 확인합니다. 아무 조치도 취할 필요가 없습니다.
  • 서드 파티 스폰서 프로모션 코드 또는 자동 할인: 계정 연결 및 사용자 선택을 구현하지 않은 경우 결제 요청을 처리하는 동안 사용자의 세부정보를 확인할 수 없습니다. 대신 SubmitOrderRequestMessage 처리 중에 FoodCartExtension 객체의 Contact 세부정보 (예: 사용자의 이메일 주소)를 사용하여 이를 확인하세요.

최신 결제 요청을 기준으로 처리에서 오류를 식별하거나 할인을 계산합니다. 이 때 시스템이 오래된 상태 정보를 유지하지 않도록 해야 합니다.

프로모션 코드 유효성 확인

처리에서는 만료일, 최대 사용량, 최대 할인과 같은 명시된 조건을 기준으로 지정된 프로모션 코드의 유효성 또는 자격 여부를 확인해야 합니다. 그런 다음 계산된 할인 또는 프로모션 코드를 적용할 수 없는 경우 foodOrderErrors를 사용하여 CheckoutResponseMessage에서 적절하게 응답합니다. 프로모션 코드 오류가 감지되면 프로모션 오류 처리에 설명된 프로세스를 따르세요.

다음 스니펫은 프로모션 코드의 foodOrderErrors 예를 보여줍니다. correctedProposedOrder에 프로모션 노드가 포함되어 있지 않은지 확인하세요.

"foodOrderErrors": [
  {
    "error": "PROMO_NOT_APPLICABLE",
    // Copy promotions.coupon string from CheckoutRequest as the ID
    "id": "GoogleNewUser",
    "description": "Promotion could not be applied"
  }
],
"correctedProposedOrder": {// required ...},
"paymentOptions": {// required ...}

컴퓨팅 할인

프로모션 코드가 유효하면 처리에서 할인 금액 값을 계산하고 계산된 할인 값을 otherItems 배열에 포함하여 CheckoutResponseMessage를 다시 전송해야 합니다. 총 주문 가격은 음수가 아니어야 합니다. 할인 금액이 장바구니 금액을 초과하면 최대 달러 금액을 반환하여 총 주문 가격을 $0로 렌더링합니다.

다음 스니펫은 프로모션 할인의 CheckoutResponseMessage 섹션 예시를 보여줍니다.

"proposedOrder": {
   "otherItems": [
      . . .
      {
        "name": "Discount",
        // copy promotions.coupon field from CheckoutRequest as the id
        "id": "GoogleNewUser",
        "price": {
          "type": "ESTIMATE",
          "amount": {
          "currencyCode": "USD",
          "units": "-3",
          "nanos": -500000000
        }
      },
      "type": "DISCOUNT",
    }
  ]
}

사용하지 않는 프로모션 출시

모든 결제 요청이 주문 제출 요청으로 이어지는 것은 아닙니다. 결제 호출 시 처리에서 프로모션을 보류하는 경우 일정 기간이 지난 후 제출 주문을 통해 프로모션을 요청하지 않으면 보류를 해제할 수 있는 메커니즘이 있어야 합니다. 이렇게 하면 음식 주문 서비스에서 올바른 캠페인 할당량을 유지할 수 있습니다.

프로모션 오류 처리

처리에서 CheckoutRequestMessage의 프로모션 코드가 유효하지 않다고 판단하면 (예: 만료되었거나 유효하지 않거나 인식할 수 없음) correctedProposedOrderpaymentOptions 객체와 함께 관련 오류 코드 및 이유 텍스트가 포함된 foodOrderError와 함께 CheckoutResponseMessage를 전송합니다.

처리가 동일한 요청에서 프로모션 코드 오류를 여러 개 발견한 경우 복구할 수 없는 오류를 다시 전송하기 전에 복구할 수 없습니다. 다음과 같이 확인 우선순위를 지정합니다 (높은 우선순위부터 낮은 우선순위 순으로).

  • PROMO_NOT_RECOGNIZED
  • PROMO_EXPIRED
  • PROMO_USER_INELIGIBLE
  • PROMO_ORDER_INELIGIBLE
  • PROMO_NOT_APPLICABLE

다음은 프로모션 코드가 포함된 결제 요청의 예입니다.

{
    "accessToken": "test_access_token",
    "lastSeen": "2018-06-22T19:25:39Z"
  },
  "conversation": {
    "conversationId": "XYZ"
  },
  "inputs": [
    {
      "intent": "actions.foodordering.intent.CHECKOUT",
      "arguments": [
        {
          "extension": {
            "@type": "type.googleapis.com/google.actions.v2.orders.Cart",
            "merchant": {
              "id": "https://www.exampleprovider.com/merchant/id1",
              "name": "Falafel Bite"
            },
            "lineItems": [
              {
                "name": "Falafel Tray",
                "type": "REGULAR",
                "id": "sample_item_offer_id_1",
                "quantity": 1,
                "price": {
                  "type": "ESTIMATE",
                  "amount": {
                    "currencyCode": "USD",
                    "units": "9",
                    "nanos": 950000000
                  }
                },
                "offerId": "https://www.exampleprovider.com/menu/item/offer/id1",
                "extension": {
                  "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                }
              }
            ],
            "promotions": [
              {
                "coupon": "FOPAACTIVECODE"
              }
            ],
            "extension": {
              "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
              "fulfillmentPreference": {
                "fulfillmentInfo": {
                  "pickup": {
                    "pickupTimeIso8601": "P0M"
                  }
                }
              }
            }
          }
        }
      ]
    }
  ],
  "directActionOnly": true,
  "isInSandbox": true
}

다음은 프로모션 코드가 유효한 경우 처리의 해당 결제 응답입니다.

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "checkoutResponse": {
              "proposedOrder": {
                "otherItems": [
                  {
                    "name": "Delivery Fees",
                    "price": {
                      "type": "ESTIMATE",
                      "amount": {
                        "currencyCode": "USD",
                        "units": "3",
                        "nanos": 500000000
                      }
                    },
                    "type": "DELIVERY"
                  },
                  {
                    "name": "Tax",
                    "price": {
                      "type": "ESTIMATE",
                      "amount": {
                        "currencyCode": "USD",
                        "units": "1",
                        "nanos": 370000000
                      }
                    },
                    "type": "TAX"
                  },
                  {
                    "name": "Promotion",
                    "price": {
                      "type": "ESTIMATE",
                      "amount": {
                        "currencyCode": "USD",
                        "units": "-5",
                        "nanos": 0
                      }
                    },
                    "id": "FOPAACTIVECODE",
                    "type": "DISCOUNT"
                  }
                ],
                "cart": {
                  "merchant": {
                    "id": "https://www.exampleprovider.com/merchant/id1",
                    "name": "Falafel Bite"
                  },
                  "lineItems": [
                    {
                      "name": "Falafel Tray",
                      "type": "REGULAR",
                      "id": "2529103",
                      "quantity": 1,
                      "price": {
                        "type": "ESTIMATE",
                        "amount": {
                          "currencyCode": "USD",
                          "units": "9",
                          "nanos": 950000000
                        }
                      },
                      "offerId": "https://www.exampleprovider.com/menu/item/offer/id1",
                      "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                      }
                    }
                  ],
                  "promotions": [
                    {
                      "coupon": "FOPAACTIVECODE"
                    }
                  ],
                  "extension": {
                    "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
                    "fulfillmentPreference": {
                      "fulfillmentInfo": {
                        "pickup": {
                          "pickupTimeIso8601": "P0M"
                        }
                      }
                    }
                  }
                },
                "totalPrice": {
                  "type": "ESTIMATE",
                  "amount": {
                    "currencyCode": "USD",
                    "units": "9",
                    "nanos": 820000000
                  }
                },
                "extension": {
                  "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension",
                  "availableFulfillmentOptions": [
                    {
                      "fulfillmentInfo": {
                        "pickup": {
                          "pickupTimeIso8601": "P0M"
                        }
                      },
                      "expiresAt": "2018-06-22T19:30:52.596Z"
                    }
                  ]
                }
              },
              "orderOptions": {},
              "paymentOptions": {
                "googleProvidedOptions": {
                  "tokenizationParameters": {
                    "tokenizationType": "PAYMENT_GATEWAY",
                    "parameters": {
                      "gateway": "stripe",
                      "stripe:publishableKey": "example_stripe_client_key",
                      "stripe:version": "2017-04-06"
                    }
                  },
                  "supportedCardNetworks": [
                    "AMEX",
                    "DISCOVER",
                    "MASTERCARD",
                    "VISA",
                    "JCB"
                  ],
                  "prepaidCardDisallowed": true
                }
              }
            }
          }
        }
      ],
      "suggestions": []
    }
  }
}

다음은 프로모션 코드가 잘못된 경우의 결제 응답의 예입니다.

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "error": {
              "foodOrderErrors": [
                {
                  "error": "PROMO_NOT_RECOGNIZED",
                  "id": "SOMEPROMO",
                  "description": "Coupon not found"
                }
              ],
              "correctedProposedOrder": {
                "cart": {
                  "merchant": {
                    "id": "https://www.exampleprovider.com/merchant/id1",
                    "name": "Falafel Bite"
                  },
                  "lineItems": [
                    {
                      "id": "sample_item_offer_id_4",
                      "name": "Prawns Biryani",
                      "type": "REGULAR",
                      "quantity": 1,
                      "price": {
                        "type": "ESTIMATE",
                        "amount": {
                          "currencyCode": "USD",
                          "units": "18",
                          "nanos": 750000000
                        }
                      },
                      "offerId": "https://www.exampleprovider.com/menu/item/offer/id4",
                      "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                      }
                    }
                  ],
                  "extension": {
                    "fulfillmentPreference": {
                      "fulfillmentInfo": {
                        "pickup": {
                          "pickupTimeIso8601": "P0M"
                        }
                      }
                    },
                    "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension"
                  },
                  "promotions": []
                },
                "otherItems": [
                  {
                    "name": "Tax",
                    "type": "TAX",
                    "price": {
                      "type": "ESTIMATE",
                      "amount": {
                        "currencyCode": "USD",
                        "units": "1",
                        "nanos": 650000000
                      }
                    }
                  }
                ],
                "termsOfServiceUrl": "https://exampleprovider.com/terms",
                "totalPrice": {
                  "type": "ESTIMATE",
                  "amount": {
                    "currencyCode": "USD",
                    "units": "20",
                    "nanos": 400000000
                  }
                },
                "extension": {
                  "availableFulfillmentOptions": [
                    {
                      "fulfillmentInfo": {
                        "pickup": {
                          "pickupTimeIso8601": "PT0M"
                        }
                      }
                    }
                  ],
                  "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension"
                }
              },
              "paymentOptions": {
                "googleProvidedOptions": {
                  "prepaidCardDisallowed": false,
                  "billingAddressRequired": true,
                  "tokenizationParameters": {
                    "tokenizationType": "PAYMENT_GATEWAY",
                    "parameters": {
                      "gateway": "braintree",
                      "braintree:apiVersion": "v1",
                      "braintree:sdkVersion": "1.4.0",
                      "braintree:merchantId": "example_braintree_merchant_ID",
                      "braintree:clientKey": "example_braintree_client_key",
                      "braintree:authorizationFingerprint": "example_braintree_fingerprint"
                    }
                  }
                }
              },
              "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension"
            }
          }
        }
      ]
    }
  }
}

프로모션으로 주문 제출 구현

주문 제출 처리에서 사용자가 프로모션 코드를 처음 적용하는 것인지 확인합니다. SubmitOrderRequestMessage 처리 중에 FoodCartExtension 객체의 Contact 세부정보 (예: 사용자의 이메일 주소)를 사용하여 이를 확인할 수 있습니다.

프로모션 코드의 적용 대상도 다시 확인해야 합니다.

  • 코드가 적용되는 경우: 주문을 확인하고 사용된 쿠폰으로 표시합니다.
  • 코드를 더 이상 적용할 수 없는 경우: PROMO_NOT_APPLICABLE 오류를 표시하여 주문을 거부합니다. FoodOrderUpdateExtension와 동일한 메커니즘을 사용하여 특정 거부 이유를 제공할 수 있습니다.

다음은 프로모션이 포함된 주문 요청 제출의 예입니다.

{
  "conversation": {
    "conversationId": "example_conversation_ID"
  },
  "inputs": [
    {
      "intent": "actions.intent.TRANSACTION_DECISION",
      "arguments": [
        {
          "transactionDecisionValue": {
            "order": {
              "finalOrder": {
                "cart": {
                  "merchant": {
                    "id": "https://www.exampleprovider.com/merchant/id1",
                    "name": "Falafel Bite"
                  },
                  "lineItems": [
                    {
                      "name": "Falafel Tray",
                      "type": "REGULAR",
                      "id": "sample_item_offer_id_1",
                      "quantity": 1,
                      "price": {
                        "type": "ESTIMATE",
                        "amount": {
                          "currencyCode": "USD",
                          "units": "9",
                          "nanos": 950000000
                        }
                      },
                      "offerId": "https://www.exampleprovider.com/menu/item/addon/offer/id1",
                      "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                      }
                    }
                  ],
                  "promotions": [
                    {
                      "coupon": "FOPAACTIVECODE"
                    }
                  ],
                  "extension": {
                    "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
                    "fulfillmentPreference": {
                      "fulfillmentInfo": {
                        "pickup": {
                          "pickupTimeIso8601": "P0M"
                        }
                      }
                    },
                    "contact": {
                      "displayName": "Food Ordering",
                      "email": "example.provider@gmail.com",
                      "phoneNumber": "+19993334444",
                      "firstName": "Food",
                      "lastName": "Ordering"
                    }
                  }
                },
                "otherItems": [
                  {
                    "name": "Delivery Fees",
                    "type": "DELIVERY",
                    "price": {
                      "type": "ESTIMATE",
                      "amount": {
                        "currencyCode": "USD",
                        "units": "3",
                        "nanos": 500000000
                      }
                    }
                  },
                  {
                    "name": "Tax",
                    "type": "TAX",
                    "price": {
                      "type": "ESTIMATE",
                      "amount": {
                        "currencyCode": "USD",
                        "units": "1",
                        "nanos": 370000000
                      }
                    }
                  },
                  {
                    "name": "Promotion",
                    "type": "DISCOUNT",
                    "price": {
                      "type": "ESTIMATE",
                      "amount": {
                        "currencyCode": "USD",
                        "units": "-5"
                      }
                    },
                    "id": "FOPAACTIVECODE"
                  },
                  {
                    "name": "Subtotal",
                    "type": "SUBTOTAL",
                    "price": {
                      "type": "ESTIMATE",
                      "amount": {
                        "currencyCode": "USD",
                        "units": "9",
                        "nanos": 950000000
                      }
                    }
                  },
                  {
                    "name": "Tip",
                    "type": "GRATUITY",
                    "price": {
                      "type": "ESTIMATE",
                      "amount": {
                        "currencyCode": "USD"
                      }
                    }
                  }
                ],
                "totalPrice": {
                  "type": "ESTIMATE",
                  "amount": {
                    "currencyCode": "USD",
                    "units": "9",
                    "nanos": 820000000
                  }
                },
                "extension": {
                  "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension"
                }
              },
              "googleOrderId": "example_google_order_ID",
              "orderDate": "2018-06-22T19:30:59.502Z",
              "paymentInfo": {
                "displayName": "example_display_name",
                "googleProvidedPaymentInstrument": {
                  "instrumentToken": "example_instrument_token"
                },
                "paymentType": "PAYMENT_CARD"
              },
              "locale": "en"
            }
          }
        }
      ]
    }
  ],
  "directActionOnly": true,
  "isInSandbox": true
}

다음은 프로모션 코드가 유효한 경우 처리에서 상응하는 주문 제출 응답의 예입니다.

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "orderUpdate": {
              "actionOrderId": "example_action_order_ID",
              "orderState": {
                "state": "CREATED",
                "label": "Order is created with partner."
              },
              "updateTime": "2018-06-22T19:31:01.556Z",
              "orderManagementActions": [
                {
                  "type": "CALL_RESTAURANT",
                  "button": {
                    "title": "Call Us",
                    "openUrlAction": {
                      "url": "tel:+1-111-111-1111"
                    }
                  }
                },
                {
                  "type": "EMAIL",
                  "button": {
                    "title": "Email Us",
                    "openUrlAction": {
                      "url": "mailto:example.provider@gmail.com"
                    }
                  }
                },
                {
                  "type": "CUSTOMER_SERVICE",
                  "button": {
                    "title": "Customer Service",
                    "openUrlAction": {
                      "url": "http://www.google.com"
                    }
                  }
                }
              ]
            }
          }
        }
      ],
      "suggestions": []
    }
  }
}

다음은 프로모션 코드가 잘못된 경우 주문 제출 응답의 예입니다.

"orderUpdate": {
  "actionOrderId": "sample_action_order_id",
  "orderState": {
    "state": "REJECTED",
    "label": "Order rejected."
  },
  "updateTime": "2017-05-10T02:30:00.000Z",
  "rejectionInfo": {
    "type": "PROMO_NOT_APPLICABLE",
    "reason": "Sorry, there's something wrong. Try another code?"
  },
  "orderManagementActions": [
    {
      "type": "CUSTOMER_SERVICE",
      "button": {
        "title": "Contact customer service",
        "openUrlAction": {
          "url": "mailto:support@example.com"
        }
      }
    },
    {
      "type": "EMAIL",
      "button": {
        "title": "Email restaurant",
        "openUrlAction": {
          "url": "mailto:example.provider@example.com"
        }
      }
    },
    {
      "type": "CALL_RESTAURANT",
      "button": {
        "title": "Call restaurant",
        "openUrlAction": {
          "url": "tel:+19993334444"
        }
      }
    }
  ],
  "infoExtension": {
    "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
    "foodOrderErrors": [
      {
        "error": "PROMO_USER_INELIGIBLE",
        "description": "Sorry, you can only use this promotion once."
      }
    ]
  }
}