Hold the fare while the traveler is still on the payment step
A traveler picked a fare from Boston to Lisbon, filled in two passengers and has been on the payment step for four minutes. They may be in another tab pricing the same route, or looking for a card. The fare expiry runs on its own clock, and the message about it usually reaches the traveler after the fare has gone, when they come back to the tab. A line above the payment form saying the fare is held for a few more minutes, for as long as your fare rules allow, answers the question before they leave the tab to settle it.
current_step- The step of the booking flow they are on now
seconds_on_step- Seconds since they reached it
selected_route_session- The route of the fare they picked this visit
Holds the fare and says so above the payment form once a traveler has been on the payment step for several minutes without finishing, for the time your fare rules allow, and does nothing for the traveler who has just arrived on the step.
from snowplow_signals import (
Attribute, Event, EventProperty, StreamAttributeGroup, domain_sessionid,
)
booking_step = Event(name="booking_step", vendor="com.example", version="1-0-0")
fare_selected = Event(name="fare_selected", vendor="com.example", version="1-0-0")
current_step = Attribute(
name="current_step",
type="string",
events=[booking_step],
aggregation="last",
property=EventProperty(vendor="com.example", name="booking_step", major_version=1, path="step"),
)
seconds_on_step = Attribute(
name="seconds_on_step",
type="double",
events=[booking_step],
aggregation="time_since_last",
time_unit="s",
)
selected_route_session = Attribute(
name="selected_route_session",
type="string",
events=[fare_selected],
aggregation="last",
property=EventProperty(vendor="com.example", name="fare_selected", major_version=1, path="route"),
)
# Keyed on the visit, so the clock starts again when the traveler comes back another day.
trip_booking_idle = StreamAttributeGroup(
name="trip_booking_idle",
version=1,
attribute_key=domain_sessionid,
owner="you@example.com",
attributes=[current_step, seconds_on_step, selected_route_session],
)// In the code that renders the payment step
const traveler = await signals.getServiceAttributes({
name: "trip_booking_idle",
attribute_key: "domain_sessionid",
identifier: sessionId,
});
// { current_step: "payment", seconds_on_step: 243.0, selected_route_session: "BOS-LIS" }
if (traveler.current_step === "payment" && traveler.seconds_on_step >= 240) {
const hold = booking.holdFare({ route: traveler.selected_route_session, minutes: fareRules.holdMinutes });
booking.notice(`This fare is held for you for another ${hold.minutes} minutes.`);
}