offer.proto
// Feeds declaration
syntax = "proto3";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "timeofday.proto";
import "dayofweek.proto";
import "money.proto";
import "date.proto";
package ext.maps.booking.feeds.offers;
message OfferFeed {
repeated Offer data = 1;
}
message Offer {
// Unique ID of the offer.
// Required.
string offer_id = 1;
// List of merchants who are participating in this offer.
repeated string entity_ids = 2;
// If true, this offer is applicable to all entities under the aggregator.
// Only applicable for add on offers.
bool add_on_offer_applicable_to_all_entities = 17;
// An offer can be provided by the aggregator, an individual merchant, or even
// a third party as an add on.
// Required.
OfferSource offer_source = 3;
// The service that is providing the offer. An offer_id can belong to only one
// action_type. If an offer can be shared across multiple service types then
// duplicate offers with unique Ids are expected to be created for each
// service type.
// Required.
ActionType action_type = 4;
// The methods the offer can be availed - walk in, reservation, online, etc.
// Required.
repeated OfferMode offer_modes = 5;
// The category of the offer.
// Required.
OfferCategory offer_category = 6;
// Non-negative integer ([1-100], where 1 represents the highest priority)
// indicating the priority level of the offer assigned by the source. When
// multiple offers are available for the same merchant, this will be a signal
// for ranking offers. 0 would represent that the priority is not set.
int32 source_assigned_priority = 7;
// Details of the offer such as the discount, booking cost, etc.
// Required.
OfferDetails offer_details = 8;
// Describes how the offer is restricted i.e. whether a subscription/payment
// instrument is required, whether this offer can be combined with other
// offers (and what types), etc.
// Required.
OfferRestrictions offer_restrictions = 9;
// Details of a coupon.
// Required for offer_category: OFFER_CATEGORY_ADD_ON_COUPON_OFFER.
Coupon coupon = 10;
// Details of a payment instrument.
// Required for offer_category: OFFER_CATEGORY_ADD_ON_PAYMENT_OFFER.
PaymentInstrument payment_instrument = 11;
// Details of a subscription.
// Required for offer_category: OFFER_CATEGORY_ADD_ON_SUBSCRIPTION_OFFER.
Subscription subscription = 12;
// Terms and conditions of the offer.
// Required.
Terms terms = 13
;
// The validity period of the offer. Describes what time period the offer is
// valid for including start and end times, days of the week, etc.
// Required.
repeated ValidityPeriod validity_periods = 14;
// URL to the merchant's offer page.
// Required for offer_category: OFFER_CATEGORY_BASE_OFFER.
string offer_url = 15;
// URL to the merchant’s offer image.
string image_url = 16;
// Special tags associated with the offer. This is used to identify special
// offers like "Festive", "Top Rated", "Most booked", etc.
repeated OfferTag tags = 24;
}
enum OfferSource {
OFFER_SOURCE_UNSPECIFIED = 0;
OFFER_SOURCE_AGGREGATOR = 1;
}
// Represents the fulfillment mode of the offer. If an offer can be shared
// across multiple fulfillment modes then duplicate offers are expected to be
// created for each fulfillment mode.
enum ActionType {
ACTION_TYPE_UNSPECIFIED = 0;
// The offer is applicable for food delivery services.
ACTION_TYPE_FOOD_DELIVERY = 1;
// The offer is applicable for food takeout or pickup orders.
ACTION_TYPE_FOOD_TAKEOUT = 2;
// The offer is for on-site dining at a restaurant.
ACTION_TYPE_DINING = 4;
}
// Specifies the method or channel through which the user can avail the offer.
enum OfferMode {
// Use for fulfillment methods not covered by other specific modes.
OFFER_MODE_OTHER = 0;
// The offer is available for on-site visits without a prior reservation.
OFFER_MODE_WALK_IN = 1;
// The offer applies when a user makes a reservation that does not require
// an upfront fee.
OFFER_MODE_FREE_RESERVATION = 2;
// The offer applies when a user makes a reservation that requires an
// upfront payment.
OFFER_MODE_PAID_RESERVATION = 3;
// The offer is valid for orders placed through a website or digital platform.
OFFER_MODE_ONLINE_ORDER = 4;
}
// Category of the offer. A base offer is a standard offer available to all
// customers such as 10% off spending over $100. A base offer restricted by a
// coupon or payment instrument will have the respective fields set. We also
// have add on x offers such as ADD_ON_PAYMENT_OFFER. Such offers can be added
// to other offers to gain additional discounts.
enum OfferCategory {
OFFER_CATEGORY_UNSPECIFIED = 0;
OFFER_CATEGORY_BASE_OFFER = 1;
OFFER_CATEGORY_ADD_ON_PAYMENT_OFFER = 2;
OFFER_CATEGORY_ADD_ON_COUPON_OFFER = 3;
OFFER_CATEGORY_ADD_ON_SUBSCRIPTION_OFFER = 4;
}
message OfferDetails {
// The offer text the offer provider wants to display to customers on the
// search results page.
// Required.
string offer_display_text = 1;
// The discount can be a percentage or a fixed value subtracted from the total
// value.
// For example:
// 1. 10% off the final bill.
// 2. $15 off an order.
// Merchants can also offer custom discounts such as ‘buy one get one free’
// through the relevant specification fields.
// Required.
oneof offer_specification {
// Percentage of the bill that is discounted.
//
// For 1+1 or 50% off offers that are applicable to the whole meal
// (e.g. 1+1 buffet, 1+1 on entire bill, 1+1 on set menu), this value can
// be set to 50.
float discount_percent = 2;
// Fixed value of the discount.
google.type.Money discount_value = 3;
// Free-form text to describe the discount.
// For specific 1+1 offers (e.g. 1+1 drinks, +1 main course, 1+1
// selected menu items), these details should be described here.
string other_offer_detail_text = 4;
}
// The maximum discount that can be availed. For example, 10% off up to $100.
google.type.Money max_discount_value = 5;
// The minimum spend value to avail the discount.
// For example, 10% off when the total price is $100 or more.
google.type.Money min_spend_value = 6;
// The cost to book this offer. For example, $100 off the final bill when a
// table is reserved at the cost of $15.
google.type.Money booking_cost = 7;
// The unit of the booking cost. For example, per person, per transaction.
FeeUnit booking_cost_unit = 11;
Fee convenience_fee = 12;
// Whether the booking cost is adjustable i.e. the booking cost is subtracted
// from the final bill.
// For example:
// 30% off dinner with reservation. Cost to reserve $15 and it will be
// applied to the final bill.
// Hence final bill: Total Spent - 30% - $15
bool booking_cost_adjustable = 8;
// Additional fees that are charged to the user.
// Examples: convenience, handling, delivery, packaging, service fee etc.
repeated AdditionalFee additional_fees = 10;
}
message OfferRestrictions {
// Whether this offer can be combined with other offers.
// When true, partners can specify what offers this offer can be combined
// with. If both combinable_offer_categories & combinable_offer_ids are set
// then any offer matching one of the conditions above will be combinable.
bool combinable_with_other_offers = 1;
// List of offer types that this offer can be combined with. For example, this
// offer may be combinable with other Coupons. If combinable_with_other_offers
// is true and this field is unset all types will be combinable.
repeated OfferCategory combinable_offer_categories = 2;
// List of offer_ids that this offer can be combined with. Some offers may
// only be combined with certain specific other offer_ids (can be
// considered parent offers). If combinable_with_other_offers is true and this
// field is unset all offer ids will be combinable.
repeated string combinable_offer_ids = 3;
// List of conditions that must be met for the offer to be valid (e.g.,
// non-alcoholic drinks, food).
repeated OfferCondition inclusions = 5;
// List of conditions that would invalidate the offer (e.g., buffet, combo
// offers, and cocktails ).
repeated OfferCondition exclusions = 6;
// The minimum number of people required to avail the offer.
int32 min_guest = 7;
// Restrictions specific to food offers.
FoodOfferRestrictions food_offer_restrictions = 4;
}
message FoodOfferRestrictions {
// The meal types the offer can be applied to, such as lunch or dinner.
// If unset, the offer can be applied to all meal types.
repeated MealType meal_types = 1;
// Whether the offer can only be applied to certain courses.
bool restricted_to_certain_courses = 2;
}
enum MealType {
MEAL_TYPE_UNSPECIFIED = 0;
MEAL_TYPE_BREAKFAST = 1;
MEAL_TYPE_LUNCH = 2;
MEAL_TYPE_DINNER = 3;
}
message PaymentInstrument {
// List of payment instruments that can be used to avail the offer.
// Required.
repeated PaymentInstrumentItem items = 1;
// Name of the payment instrument provider. Could be a banking partner, name
// of a bank, etc. For example: American Express, HDFC, ICICI.
// Required.
string provider_name = 2;
}
enum PaymentInstrumentType {
PAYMENT_INSTRUMENT_TYPE_UNSPECIFIED = 0;
PAYMENT_INSTRUMENT_CREDIT_CARD = 1;
PAYMENT_INSTRUMENT_DEBIT_CARD = 2;
PAYMENT_INSTRUMENT_BANK_ACCOUNT = 3;
PAYMENT_INSTRUMENT_UPI = 4;
PAYMENT_INSTRUMENT_ONLINE_WALLET = 5;
}
message PaymentInstrumentItem {
// Type of the payment instrument.
// Required.
PaymentInstrumentType type = 1;
// Name of the payment instrument item like the name of the credit card.
// For example: HDFC Infinia, American Express Platinum.
// Required.
string name = 2;
}
message Coupon {
// The coupon text the offer provider wants to display to users.
string text = 1;
// Coupon code required to redeem the offer.
// Required.
string code = 2;
}
message Subscription {
// The name of the subscription.
// Required.
string name = 1;
// Whether the subscription is auto added when a user avails this offer
bool subscription_auto_added = 2;
// The cost of the subscription.
// Required.
google.type.Money cost = 3;
// How long the subscription is valid for at the subscription_cost.
// Required.
google.protobuf.Duration subscription_duration = 4;
// URL to the partner's terms and conditions relevant to this subscription.
string terms_and_conditions_url = 5;
}
message Terms {
// URL to the partner's terms and conditions.
string url = 1;
// Whether the offer is restricted to certain users.
bool restricted_to_certain_users = 2;
// Primary T&C text provided by the partner.
string terms_and_conditions = 3;
// Terms and conditions in addition to the primary T&C from the partner.
repeated string additional_terms_and_conditions = 4;
}
message ValidityPeriod {
// The start and end timestamp that the offer is valid for.
// These times must represent distinct days i.e. the start time must be 00:00
// (beginning of the day) and the end time must be 00:00 (exclusive) on the
// day the validity period ends.
ValidityRange valid_period = 1;
// Specifies the valid time interval on a given day and which days are
// available for the offer. For timeframes crossing midnight (e.g., 10 PM to
// 2 AM), use separate windows for each day: one ending at 11:59:59 PM and
// another starting at 12:00 AM the next day.
// For example:
// Monday: 10AM to 5PM
// Tuesday: 10AM to 2PM
// Tuesday: 5PM to 7PM
// Wed, Thur, Fri, Sat, Sun: 3PM to 7PM
// If none set, it means the offer is available for all time within
// `valid_period`.
repeated TimeOfDayWindow time_of_day = 2;
// Specifies exceptions to the above valid_period and valid_time_of_week
repeated ValidTimeException time_exceptions = 3;
// Specifies exceptions in days to the above valid_period and time_of_day
repeated google.type.Date date_exceptions = 4;
}
// A closed-open timestamp range.
message ValidityRange {
// The beginning time of the range (inclusive).
// Required.
google.protobuf.Timestamp valid_from_time = 1;
// The ending time of the range (exclusive).
// If not set, it means that this period is never ending.
// Optional.
google.protobuf.Timestamp valid_through_time = 2;
}
message TimeOfDayWindow {
// The time window the order can be placed/fulfilled.
// Required.
TimeOfDayRange time_windows = 1;
// The list of days in a week the windows are applied.
// If none set, it means that it applies for all days of the week.
// Optional.
repeated google.type.DayOfWeek day_of_week = 2;
}
// A closed-open time range.
message TimeOfDayRange {
// A Time indicating the beginning time of the day of the range (inclusive).
// If not set, it means 00:00:00.
// Optional.
google.type.TimeOfDay open_time = 1;
// A Time indicating the ending time of the day of the range (exclusive).
// If not set, it means 23:59:59.
// Optional.
google.type.TimeOfDay close_time = 2;
}
message ValidTimeException {
// The start and end timestamp that the offer is not valid for.
// These times must represent distinct days i.e. the start time must be 00:00
// (beginning of the day) and the end time must be 00:00 (exclusive) on the
// day the exception period ends.
ValidityRange exceptional_period = 1;
}
message AdditionalFee {
// The name of the additional fee. Examples: convenience fee, handling fee
// etc.
// Required.
string name = 1;
Fee fee = 2;
}
// Next ID: 5
message Fee {
FeeUnit unit = 1;
FeeType type = 2;
oneof cost {
google.type.Money amount = 3;
MoneyRange amount_range = 4;
}
}
enum FeeType {
FEE_TYPE_UNSPECIFIED = 0;
FEE_TYPE_FIXED = 1;
FEE_TYPE_VARIABLE = 2;
}
enum FeeUnit {
FEE_UNIT_UNSPECIFIED = 0;
FEE_UNIT_PER_GUEST = 1;
FEE_UNIT_PER_TRANSACTION = 2;
}
// Wrapper for a range of monetary amount that could be bounded or unbounded.
// At least one of min_amount and max_amount is required.
message MoneyRange {
// Minimum amount.
google.type.Money min_amount = 1
;
// Maximum amount.
google.type.Money max_amount = 2;
}
message OfferCondition {
string description = 1;
}
enum OfferTag {
OFFER_TAG_NEW_YEAR_SPECIAL = 1;
OFFER_TAG_VALENTINES_SPECIAL = 2;
}
money.proto
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package google.type;
option cc_enable_arenas = true;
option go_package = "google.golang.org/genproto/googleapis/type/money;money";
option java_multiple_files = true;
option java_outer_classname = "MoneyProto";
option java_package = "com.google.type";
option objc_class_prefix = "GTP";
// Represents an amount of money with its currency type.
message Money {
// The three-letter currency code defined in ISO 4217.
string currency_code = 1;
// The whole units of the amount.
// For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar.
int64 units = 2;
// Number of nano (10^-9) units of the amount.
// The value must be between -999,999,999 and +999,999,999 inclusive.
// If `units` is positive, `nanos` must be positive or zero.
// If `units` is zero, `nanos` can be positive, zero, or negative.
// If `units` is negative, `nanos` must be negative or zero.
// For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.
int32 nanos = 3;
}
dayofweek.proto
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package google.type;
option go_package = "google.golang.org/genproto/googleapis/type/dayofweek;dayofweek";
option java_multiple_files = true;
option java_outer_classname = "DayOfWeekProto";
option java_package = "com.google.type";
option objc_class_prefix = "GTP";
// Represents a day of the week.
enum DayOfWeek {
// The day of the week is unspecified.
DAY_OF_WEEK_UNSPECIFIED = 0;
// Monday
MONDAY = 1;
// Tuesday
TUESDAY = 2;
// Wednesday
WEDNESDAY = 3;
// Thursday
THURSDAY = 4;
// Friday
FRIDAY = 5;
// Saturday
SATURDAY = 6;
// Sunday
SUNDAY = 7;
}
timeofday.proto
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package google.type;
option cc_enable_arenas = true;
option go_package = "google.golang.org/genproto/googleapis/type/timeofday;timeofday";
option java_multiple_files = true;
option java_outer_classname = "TimeOfDayProto";
option java_package = "com.google.type";
option objc_class_prefix = "GTP";
// Represents a time of day. The date and time zone are either not significant
// or are specified elsewhere. An API may choose to allow leap seconds. Related
// types are [google.type.Date][google.type.Date] and
// `google.protobuf.Timestamp`.
message TimeOfDay {
// Hours of day in 24 hour format. Should be from 0 to 23. An API may choose
// to allow the value "24:00:00" for scenarios like business closing time.
int32 hours = 1;
// Minutes of hour of day. Must be from 0 to 59.
int32 minutes = 2;
// Seconds of minutes of the time. Must normally be from 0 to 59. An API may
// allow the value 60 if it allows leap-seconds.
int32 seconds = 3;
// Fractions of seconds in nanoseconds. Must be from 0 to 999,999,999.
int32 nanos = 4;
}
date.proto
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package google.type;
option cc_enable_arenas = true;
option go_package = "google.golang.org/genproto/googleapis/type/date;date";
option java_multiple_files = true;
option java_outer_classname = "DateProto";
option java_package = "com.google.type";
option objc_class_prefix = "GTP";
// Represents a whole or partial calendar date, such as a birthday. The time of
// day and time zone are either specified elsewhere or are insignificant. The
// date is relative to the Gregorian Calendar. This can represent one of the
// following:
//
// * A full date, with non-zero year, month, and day values
// * A month and day value, with a zero year, such as an anniversary
// * A year on its own, with zero month and day values
// * A year and month value, with a zero day, such as a credit card expiration
// date
//
// Related types are [google.type.TimeOfDay][google.type.TimeOfDay] and
// `google.protobuf.Timestamp`.
message Date {
// Year of the date. Must be from 1 to 9999, or 0 to specify a date without
// a year.
int32 year = 1;
// Month of a year. Must be from 1 to 12, or 0 to specify a year without a
// month and day.
int32 month = 2;
// Day of a month. Must be from 1 to 31 and valid for the year and month, or 0
// to specify a year by itself or a year and month where the day isn't
// significant.
int32 day = 3;
}
Các thông số kỹ thuật chung khác