Integrations¶
Wilderness Window is an integration hub as much as an application: roughly a third of its
modules exist to talk to something else, and integration modules hold the largest domain
models after BookingMasterData and Booking.
Outbound / bi-directional: reservation and channel systems¶
| System | Modules | What flows | Notes |
|---|---|---|---|
| TourPlan (tour operator system) | DataManagement/MFTourplanNew (276 flows), MFTourplan (81), hostConnect, HTI (114 entities), TourplanItineraries, TourplanInvoicing |
Bookings, service lines, rooming lists, vouchers, invoices, exchange rates, itineraries | The deepest integration. TP_CreateTPServiceLinesByBookingline mirrors every booking line; TP_ConfirmBooking, TP_UncancelBooking, TP_CheckExchangeRates. Also a direct MSSQL connection TourPlan_PAF. hostConnect is TourPlan's XML API |
| WISH (reservation system) | WishAPI (41 import + 40 export mappings), DataManagement/MF WISH, WishWindowReconciliation, History, GuestManagement/WishGuests |
Sector bookings, rooming lists, guests, history, expired lines | Reconciliation is a first-class concern: WishWindowReconciliation, Maintenance.SE_HH_UpdateWishHistory, SE_ProcessExpiredWishSBs. Payloads logged to disk |
| ResRequest | ResRequest, SRM.SE_BulkRR_Avail, DataManagement.CancelBooking_LR |
Availability, bookings, guest assignment | Bulk availability refresh on a schedule |
| NightsBridge | Nightsbridge, NightsBridge_V5 (80 entities), published BridgeConnectService, SRM.SE_BulkNightsBridge_Avail |
Availability, bookings, cancellations | Two generations live side by side |
| SiteMinder | Siteminder (115 entities), BookingMasterData/RARA/Siteminder Config, DataManagement/SiteminderPricing |
Rates, availability, inbound bookings | ConfirmBookingReceived, ConfirmBookingReceived_Errors |
| Profitroom | Profitroom (91 entities), DataManagement/ProfitroomPricing, RARA/ProfitRoom |
Rates, availability, bookings | ConfirmProfitRoomBookingReceived |
| SiteConnect | SiteConnect (110 entities), published SiteConnect service |
Rates, room types, availability | Rate/room-type creation flows in LiveRequest |
| HConnect | HConnect (73 entities) |
Bookings, cancellations | HSAPI_Cancel_Booking; ships with HSApi.jar |
| Agoda and other channels | LiveRequest (146 flows) |
Availability lookups | Agoda_GetAvail, ChooseChannel - generic multi-channel availability |
| Exo | Exo |
Hotels, rooms, rates, availability, booking | Small connector |
| PanStrat | PanStrat |
Hotels, availability | Very small connector |
| Mautourco (Mauritius DMC) | Mautourco (66 entities) |
Bookings / services | |
| Wetu (itinerary content) | BookingMasterData/RARA/Wetu Management, wetu.rar in javasource |
Camp/itinerary content | Role WetuAdmin |
| itrvl | API.itrvlWebhook -> SE_CheckforBookingChanges, AdvEmail.ItrvlEmail |
Booking changes | Inbound partner polling/webhook |
| Schedwin | SchedwinAPI, published BookingExport |
Booking export | Role SchedwinApiUser |
| OnBase (Hyland, document management) | Onbase, published WWAPI_Rest_Onbase |
Booking status changes → documents | Reached only asynchronously: Onbase.BookingStatus_Post is called fire-and-forget from 27 sites — on convert, provisional, confirm and cancel, and from the API booking flows. The return value is never checked, so a failure is silent. See Asynchronous handoffs |
CRM, marketing and web¶
| System | Modules | What flows |
|---|---|---|
| HubSpot | HubSpot (15 import mappings), HubSpot_DMC, Hubspot_Task_Queue, published HubSpotWebhook |
Contacts, bookings, deal/lodge data; queue-based outbound sync every scheduled run, webhook inbound |
| Wilderness public website | Enquiries |
Enquiries, newsletter signups, Google Click IDs |
| Google Analytics | GoogleAnalytics + widget, scheduled DS_GetGoogleData |
Traffic/reporting data pulled into the app |
| Windfall (wealth data) | Windfall |
Net wealth, career, household, NAICS/NTEE enrichment for donors |
| TripAdvisor | GuestManagement/Tripadvisor |
Guest feedback/reviews |
| Jotform | Jotform |
Form definitions and submissions via API |
Travel content and money¶
| System | Modules | What flows |
|---|---|---|
| TravelStart | TravelStart (78 entities) |
Commercial flight content/bookings |
| Payment gateway | PaymentGateway, Booking/Guest Payments, EAH credit-card capture |
Card payments, guest payments |
| OpenAI | OpenAIConnector, GenAICommons, WrittingAssistant widget |
Text generation inside the app |
Infrastructure integrations¶
| What | Where |
|---|---|
| LDAP / Active Directory | Ldap module, scheduled LdapSync -> IVK_SE_SyncAllFlow; role EmployeeWithoutLDAP for exceptions |
| Email (IMAP/POP3 + SMTP) | Email_Connector (+ published OAuthHandler for OAuth2 mailbox auth), AdvEmail, Maintenance.SE_GetEmails / SE_ProcessEmails / SE_EmailSend |
| External SQL Server databases | ExternalDatabaseConnector with connections TourPlan_PAF and WildernessWindow_DB; MSSQLPoolingDriver.jar in userlib |
| File server | LocalFileOperations, InformationCentre.DocumentRepository_Fileserver |
| Corporate HTTP proxy | -Dhttps.proxyHost=172.22.0.17 in most server configurations |
Inbound: what this app publishes¶
15 REST services, 4 SOAP services - full list in generated/published-interfaces.md. The notable ones:
| Service | Module | Purpose |
|---|---|---|
wwapi_v3 |
API_V3 |
Current public API |
WWAPI_Rest, WWAPI_V2 / WWAPI_V2_20240724 (SOAP) |
API |
Previous generations, still published |
JSONLeadInput, NewLeadInput (SOAP) |
Booking |
Lead intake from web/partners |
GuestManagementApi |
GuestManagementAPI |
Guest data for other Wilderness systems |
WildernessAvailability |
XtremeAvailability |
Camp availability to partners |
BookingExport |
SchedwinAPI |
Booking export |
Invoicing |
TourplanInvoicing |
Invoice exchange |
HubSpotWebhook, RTWebhook |
HubSpot, Transfers |
Inbound webhooks |
UptimeMonitor |
Tools |
External health check |
DbService |
ExternalDatabaseConnector |
Marketplace-provided |
Booking creation over the API is the biggest single orchestration in the model:
API.CreateWindowBooking calls 73 distinct microflows, API.ReplaceQuote 60,
API.ReplaceBooking 50 - each with dated clones alongside them (see
05-conventions-and-risks.md).
API.CreateWindowBooking is not itself published. It is the shared creation engine behind
GetQuote_B2B, GetQuote_V2, BookRooms_ProfitRoom, BookRooms_SM and
Nightsbridge.CreateNightsBridgeBooking - so ProfitRoom, SiteMinder and NightsBridge bookings
all converge on the same code path as the B2B quote API.
The partner booking-mutation surface¶
Of the 266 published operations across the app, ~25 mutate a booking's lifecycle - creating it, moving it through the wizard states, editing its itinerary or cancelling it. They are a second implementation of journeys the UI also implements, under names that share almost no vocabulary with it:
| Group | Operations |
|---|---|
| Create / convert | API.GetQuote_B2B, API.GetQuote_V2 (both create, despite the names), API.BookQuote |
| Replace wholesale | API.ReplaceQuote, API.ReplaceBooking |
| Edit itinerary | API.AddAccomodationToBooking, API.AddAccomodationToStartEnd, API.AddDaysToBooking, API.ChangeAccomNumberOfNights, API.DeleteAccomodation, API.SwitchAccomodation, API.AddFlightToStartEnd, API.AddTravelHubAndFlightToStartEnd |
| Other mutations | API.CopyBooking, API.ConfirmRooms, API.UpdateBookingService, API.UpdateDMCOverrideLine, API.CancelBooking, API.CancelBookingLines, API.DeleteQuotes |
| Inbound webhook | Transfers.AddGuideToBooking, Transfers.AddRTConsultant |
Two consequences worth planning around:
- A booking can be changed without any Window user touching it, so audit trails and "who changed this" questions must account for the partner path.
- The itinerary-edit operations reuse the cancellation machinery. They set
BookingLine.Cancel = truewhen removing a line, so that flag counts amendments as well as cancellations - see deep-dives/cancellation-and-fees.md §13.
Only BookQuote and CancelBooking are documented so far; see
03-business-flows.md §12a.
Asynchronous handoffs: the invisible integration surface¶
Not every integration is reached by a normal call. Two mechanisms move work out of the caller's transaction, and neither shows up in a synchronous call graph — so "who calls this system" answers nothing for them. Full inventory: reports/async-handoffs.md.
Fire-and-forget — CommunityCommons.executeMicroflowInBackground¶
The target runs in its own transaction after the caller commits, and the return value is never checked at any of the 49 call sites. A failure is invisible to the user, the caller and the calling system.
The Java action documents its own semantics, and three of them have consequences nobody
appears to have designed around (CommunityCommons/other.txt, verbatim):
"The microflow is delayed for at least 200ms and then run with low priority in a system context. Since the microflow run in its own transaction, it is not affected with rollbacks (due to exceptions) or commits in this microflow. Invocations to this method are guaranteed to be run in FIFO order, only one microflow is run at a time. Note that since the microflow is run as system transaction,
$currentUseris not available and no security restrictions are applied. … Returns true if scheduled successfully."
| Property | Consequence here |
|---|---|
| One at a time, FIFO, globally | All 49 call sites share a single serialised lane. A slow Onbase.BookingStatus_Post delays every other background handoff in the application, including partner webhooks and HubSpot deal updates |
No security restrictions, no $currentUser |
Every background target runs unrestricted. Booking.IVK_ConfirmFromBookingFile is invoked this way from Tools.IVK_ConfirmBookings — so a booking confirmation runs with entity access disabled and no user attribution |
| Returns "scheduled", not "succeeded" | Even if a caller checked the result — none do — a true would only mean the work was queued |
| Unaffected by caller rollback | The notification still fires if the calling transaction later rolls back, so OnBase can be told about a state that was never committed |
None of this is exotic — it is the documented behaviour of a standard Marketplace action. It matters because the volume (49 sites) and the criticality of some targets (confirmation, partner webhooks) were probably not weighed against a single-threaded, unattributed, unobservable lane.
| Target | Sites | What it means |
|---|---|---|
Onbase.BookingStatus_Post |
27 | OnBase is told about every booking status change. If this fails, documents are silently not generated |
HubSpot.AddBookingLinkToDeal |
4 | Booking link pushed onto the HubSpot deal |
API.SendWebhookUpdate |
3 | Outbound partner webhooks — lock, unlock and update, reached from SendWebHookLockBooking / _UnlockBooking / _UpdateForBooking |
Booking.CheckAgencyInvoicingCurrencies |
2 | Invoicing-currency check after pricing totals are re-summed |
Windfall.GetWindfallDataForContact |
1 | Donor wealth enrichment, triggered from Booking.ProcessNewLead |
Nightsbridge.NightsBridgeAPIBooking |
1 | Channel booking dispatched in the background |
DataManagement.ProcessWishUpdates |
1 | WISH catch-up |
Booking.IVK_ConfirmFromBookingFile |
1 | A booking confirmation run fire-and-forget, from Tools.IVK_ConfirmBookings |
| 9 others | 1 each | leads, referrals, one-click bookings, TP pricing, log rotation |
That last one is worth a second look: confirmation is the most consequential operation in the application, and one path runs it with no way to observe whether it worked.
Queued — Mendix task queue¶
Delayed and retried, and survives an outage in the target without failing the caller. Used almost entirely for HubSpot and guest-data sync:
| Target | Sites | Notes |
|---|---|---|
GuestManagementAPI.UpdateHubSpotGuest |
13 | Every GuestManagement.Sub_SyncContact*ToGuest flow |
HubSpot_DMC.TSK_SendEnquiryToHubSpot |
3 | Agency enquiries from API_V3.POST_AgencyEnquiry |
GuestManagement.Sub_SyncContact*ToGuest |
8 | Inbound guest-detail writes from GuestManagementAPI |
HubSpot.AddProvisionalExpiryDateToHubSpot, HubSpot_DMC.UpdateDealAfterProv |
1 each | Only from Booking.IVK_ProvisionalAll — not from IVK_ProvisionalAll_Agents, so one of the two provisional buttons does not update HubSpot at all |
Booking.IVK_UpdateTPLineBalances |
1 | TourPlan line balances |
Choosing between them matters. Queued work is retried and observable; fire-and-forget is neither. HubSpot guest sync is queued; OnBase document generation is not.
Integration architecture pattern¶
The consistent shape across channels:
- Partner payloads are mapped into partner-specific entities (hence 80-115 entity domain models per channel) using import/export mappings + JSON/XML structures.
- A per-channel adapter module translates those onto core
Bookingstructures. - Availability is refreshed in bulk on a schedule per channel (
SRM.SE_Bulk*_Avail) and on demand during wizard step 2. - Every request/response is logged (
LogWishMessagesToDisk,LogXMLRequestResponse,LogRestfulMessage) for reconciliation and dispute handling. - Downstream drift is expected and handled explicitly - reconciliation, duplicate detection and revive/uncancel flows exist for TourPlan and WISH.
- Notification-only systems are reached asynchronously and unobserved - OnBase and the partner webhooks are told what happened without any check that they heard it. This is a deliberate decoupling, but it means those two are the integrations most likely to drift silently, and the least likely to raise an alert when they do.
Where each system enters the booking lifecycle¶
Reading integration coverage by module hides the sequencing. The order matters:
| Stage | Wish | TourPlan | HubSpot | OnBase | Partner webhook |
|---|---|---|---|---|---|
| Quote created | — | — | — | — | — |
| Convert to booking | — | — | — | notified | lock (API path) |
| Provisional | space held | — | deal updated (one button only) | notified | — |
| Confirm | sectors confirmed, guests written | booking written, reference returned | confirmed lodges | notified | — |
| Cancel | header cancelled | flagged pending | — | notified | — |
TourPlan appears once, at confirmation. Everything before that is invisible to the system of record — see deep-dives/quote-to-booking.md for why that gap exists and what it means for anything counting "confirmed" bookings.