این روش، گروههای بلیطفروشی سطح بالایی را برای یک سفر مشخص ارائه میدهد. این گروهها شامل مجموعهای از بخشها با کلاسهای خدماتی منتخب هستند که در همان بلیط قابل رزرو هستند، و همچنین اطلاعات کرایه و موجودی برای کل بلیط را نیز شامل میشوند. توجه داشته باشید که:
- تمام ticketing_.*_id (بخشی از SegmentKey ) به موارد ارائه شده در افزونه Google Transit Ticketing ارجاع خواهند داد.
- شناسهها باید پایدار باشند و هرگونه تغییر در آنها باید مطابق با الزامات یکپارچهسازی GTFS، با نسخههای قبلی سازگار باشد.
درخواست GetTripOptions
تعریف پروتو
// Request sent to partners. message GetTripOptionsRequest { // All segments together should form a single trip for which a ticket can be // booked. repeated ext.travel.transport.partner.SegmentKey segment_keys = 1; }
نمونه JSON
{ "segment_keys": [ { "ticketing_trip_id": "123456", "from_ticketing_stop_time_id": "ZRH-1234", "to_ticketing_stop_time_id": "LUZ-1235", "service_date": { "year": 2022, "month": 4, "day": 6 }, "boarding_time": { "year": 2022, "month": 4, "day": 6, "hours": 14, "minutes": 25, "seconds": 0, "nanos": 0, "utc_offset": "0s" }, "arrival_time": { "year": 2022, "month": 4, "day": 6, "hours": 16, "minutes": 25, "seconds": 0, "nanos": 0, "utc_offset": "0s" } }, { "ticketing_trip_id": "234567", "from_ticketing_stop_time_id": "LUZ-2759", "to_ticketing_stop_time_id": "WOL-2455", "service_date": { "year": 2022, "month": 4, "day": 6 }, "boarding_time": { "year": 2022, "month": 4, "day": 6, "hours": 18, "minutes": 13, "seconds": 0, "nanos": 0, "utc_offset": "0s" }, "arrival_time": { "year": 2022, "month": 4, "day": 6, "hours": 20, "minutes": 13, "seconds": 0, "nanos": 0, "utc_offset": "0s" } } ] }
GetTripOptionsResponse
تعریف پروتو
// Response received from partners. message GetTripOptionsResponse { oneof response { TripOptionsResult trip_options_result = 1; TripOptionsError trip_options_error = 2; } } // A successful partner response. message TripOptionsResult { // Note: // - A TripOption represents the fare for a combination of available service // classes for the segments in the request. // - If the seats within a service class are sold at different fares of // limited availability, a different TripOption instance with the same // sequence of segments can be returned for each fare. // Partners should also include options that are unavailable because they are // fully booked, using the appropriate Unavailable message below. repeated TripOption trip_options = 1; } // A travel option for users covering the whole end-to-end journey with the // partner. message TripOption { // A series of Segments that cover the whole trip option, one for each // SegmentKey in the request. repeated Segment segments = 1; // This is the lowest standard fare of all seats with the specified segments. // This field is optional if the series of segments is unavailable. // This "standard fare" should be the lowest seat price where no age or other // booking restrictions apply. The currency should be the local currency of // the origin of the first segment. Fare lowest_standard_fare = 2; // The availability status for bookings of this trip option at the // lowest_standard_fare. Availability availability = 3; // This is used to receive optional extra data via the Travel Transport API // and pass it into the ticketing deep link. // Booking links should still work without the booking token, but the token // can be used to ensure price consistency between Google Search results and // the partner booking page. string booking_token = 4 [features.field_presence = EXPLICIT]; } // A segment traveled on a single vehicle in a given Service Class. message Segment { SegmentKey segment_key = 1; // The service class used on this segment. ServiceClass service_class = 2; }
نمونه JSON
{ "trip_options_result": { "trip_options": [ { "segments": [ { "segment_key": { "ticketing_trip_id": "123456", "from_ticketing_stop_time_id": "ZRH-1234", "to_ticketing_stop_time_id": "LUZ-1235", "service_date": { "year": 2022, "month": 4, "day": 6 }, "boarding_time": { "year": 2022, "month": 4, "day": 6, "hours": 14, "minutes": 25, "seconds": 0, "utc_offset": "0s" }, "arrival_time": { "year": 2022, "month": 4, "day": 6, "hours": 16, "minutes": 25, "seconds": 0, "utc_offset": "0s" } }, "service_class": { "type": "FIRST_CLASS" } }, { "segment_key": { "ticketing_trip_id": "234567", "from_ticketing_stop_time_id": "LUZ-2759", "to_ticketing_stop_time_id": "WOL-2455", "service_date": { "year": 2022, "month": 4, "day": 6 }, "boarding_time": { "year": 2022, "month": 4, "day": 6, "hours": 18, "minutes": 13, "seconds": 0, "utc_offset": "0s" }, "arrival_time": { "year": 2022, "month": 4, "day": 6, "hours": 20, "minutes": 13, "seconds": 0, "utc_offset": "0s" } }, "service_class": { "type": "FIRST_CLASS" } } ], "lowest_standard_fare": { "total_amount": { "units": 15, "nanos": 0, "currency_code": "CHF" }, "line_items": [ { "line_item_type": "BASE_FARE", "amount": { "units": 13, "nanos": 950000000, "currency_code": "CHF" } }, { "line_item_type": "SERVICE_CHARGE", "amount": { "units": 1, "nanos": 50000000, "currency_code": "CHF" } } ] }, "availability": { "available": { "available_seat_count": 10, "total_seat_count": 30 } } }, { "segments": [ { "segment_key": { "ticketing_trip_id": "123456", "from_ticketing_stop_time_id": "ZRH-1234", "to_ticketing_stop_time_id": "LUZ-1235", "service_date": { "year": 2022, "month": 4, "day": 6 }, "boarding_time": { "year": 2022, "month": 4, "day": 6, "hours": 14, "minutes": 25, "seconds": 0, "utc_offset": "0s" }, "arrival_time": { "year": 2022, "month": 4, "day": 6, "hours": 16, "minutes": 25, "seconds": 0, "utc_offset": "0s" } }, "service_class": { "type": "SECOND_CLASS" } }, { "segment_key": { "ticketing_trip_id": "234567", "from_ticketing_stop_time_id": "LUZ-2759", "to_ticketing_stop_time_id": "WOL-2455", "service_date": { "year": 2022, "month": 4, "day": 6 }, "boarding_time": { "year": 2022, "month": 4, "day": 6, "hours": 18, "minutes": 13, "seconds": 0, "utc_offset": "0s" }, "arrival_time": { "year": 2022, "month": 4, "day": 6, "hours": 20, "minutes": 13, "seconds": 0, "utc_offset": "0s" } }, "service_class": { "type": "SECOND_CLASS" } } ], "lowest_standard_fare": { "total_amount": { "units": 10, "nanos": 0, "currency_code": "CHF" }, "line_items": [ { "line_item_type": "BASE_FARE", "amount": { "units": 9, "nanos": 750000000, "currency_code": "CHF" } }, { "line_item_type": "SERVICE_CHARGE", "amount": { "units": 0, "nanos": 250000000, "currency_code": "CHF" } } ] }, "availability": { "available": { "available_seat_count": 44, "total_seat_count": 200 } } } ] } }
نمونه خطای JSON
{ "trip_options_error": { "error_type": "SEGMENT_KEY_NOT_FOUND", "error_message": "No matching segments found, no departures at 14:25" } }
نکته پیادهسازی API:
برای سازگاری رو به جلو با تغییرات احتمالی، اگر پارامترهای اضافی در کلیدهای سگمنت مشاهده شدند، همیشه آنها را در پاسخ برگردانید. در غیر این صورت، پارامترها را نادیده بگیرید و با درخواست طوری رفتار کنید که انگار وجود ندارند، تا زمانی که پشتیبانی خاصی برای پارامترها پیادهسازی کنید.
قیمت و موجودی
در پاسخها، موجودی و قیمت باید با هم مطابقت داشته باشند. فقط در صورتی که برنامه سفر موجود باشد، قیمت را گزارش دهید. برای برنامههای سفری که موجود نیستند، قیمت ارائه ندهید.
پاسخهای خطا
جدول زیر انتظارات گزارش خطا برای این روش را شرح میدهد:
| نوع خطا | قابل امتحان مجدد | کد وضعیت HTTP | توضیحات |
|---|---|---|---|
SEGMENT_KEY_NOT_FOUND | خیر | ۴۰۴ | قطعه مربوط به یکی از SegmentKey های ارائه شده یافت نمیشود. |
TRIP_OPTION_CACHE_STALE | بله | ۴۰۴ | دادههای مربوط به گزینه سفر درخواستی در شریک بهروز نیست و برای ارائه به گوگل باید بهروزرسانی شود. |
INTERNAL_ERROR | بله | ۵۰۰ | هنگام بازیابی این سفر، خطای غیرمنتظرهای رخ داده است. این نشان دهندهی اشکالی است که باید توسط همکار برطرف شود. |
SUBOPTIMAL_ITINERARY | خیر | ۴۰۴ | سفر پیدا شد اما شریک آن را نامناسب میداند و تصمیم میگیرد برای آن بلیط نفروشد. |
TICKETING_PROHIBITED | خیر | ۴۰۴ | سفر پیدا شد اما به دلیل محدودیتهای عمومی فروش بلیط که توسط اپراتور یا سازمان راهآهن اعمال شده است، شریک مجاز به فروش بلیط برای آن نیست. |
BOOKING_WINDOW_NOT_SUPPORTED | خیر | ۴۰۴ | شریک از برنامههای سفر با قیمت مناسب برای تاریخ درخواستی پشتیبانی نمیکند. |
برای جزئیات بیشتر به TripOptionsErrorType مراجعه کنید.
برای اطلاع از بازگشت کد وضعیت در پاسخهای HTTP، به کدهای وضعیت و مدیریت خطا مراجعه کنید.