UX Case study

Improving price display through clarity

The number a traveller saw when they picked a hotel and the number they were asked for at the checkout page were not the same. This is the work that took the price apart on the page instead of at the end, and the experiment that measured whether saying more about a price sells more stock.

8
Platforms compared, our own amongst them
7
Countries, each with its own tax rules
+3.5%
Conversion, outside the United States
Client
Role UX Designer, sole designer on price display
Team 1 UX designer, 1 product owner, 1 data scientist, 1 copywriter, an external translation agency, a scrum team
Timeline Ongoing when this was written; the benchmark ran in September 2020
Platform The booking funnel, on desktop and mobile web
Tools Figma, Zeplin, FullStory
A hotel price broken into a nightly rate, taxes and fees, local tax, a resort fee, other local taxes, a total, a saving, and what is paid now against what is paid at the property

The key panel in the design. Every line under the room rate is money somebody used to meet for the first time at checkout.

Problem

A price that grew on the way to the till

Findhotel is a smaller player in accommodation. It works the localised markets the largest platforms tend to leave alone, and much of its portfolio is distress inventory: rooms a hotel expects not to sell and cannot list itself without being pushed down the rankings by the bigger sites.

Selling that inventory means winning on price, and the funnel was undermining its own strongest argument. The price shown when somebody chose a room was not the price they were asked for two screens later in the funnel. Data showed a large drop-off of users concentrated in the checkout page.

The gap was widest for travellers outside the United States, because that is where the extra lines live: a city tax collected by the municipality, a resort fee collected by the hotel, other local charges that vary street by street. None of it was hidden on purpose. It simply appeared late, unnamed, and all at once.

Two arguments pointed the same way for once. The business wanted a higher conversion rate. I wanted our users to be able to answer the question what am I paying for and why without opening a second tab.

Deal details, the one screen in the funnel whose entire job is to answer that question.

Goals

What the work had to do

Say the number early
Put what a stay actually costs in front of somebody whilst they are still choosing, not once they have committed.
Name every charge
A fee with a name can be understood and possibly forgiven. An unlabelled sum at the end can only be resented.
Roll it out without betting the funnel
Reach every market eventually, and be able to stop after the first one if the numbers went the wrong way.

Price display sits on the revenue path of every booking the company takes, so a change to it is a change nobody can be relaxed about. Being able to point at a staged rollout was what made the conversation possible at all.

Team & audience

Who did what

The product owner brought the business case and set the priorities. The data scientist supplied the numbers the decisions rested on and designed the A/B tests that measured them. A copywriter owned the wording of every label. A third-party agency translated that wording into the languages the site runs in.

Everything between the problem and the handover was mine: the benchmark, the ideation and scoping sessions, the wireframes and the prototype, the guerrilla tests, the development plan, the high-fidelity screens, the manual testing before release, the watching afterwards, and the write-up that let anybody else in the company follow what had changed.

Audience

Who we aimed at, and in what order

The first release went to American travellers arriving from Google hotel ads onto the room selection page. That was the largest and most valuable group on the site, which made it the audience worth improving and the audience worth being careful with.

Once a hypothesis had survived, the change went out to the rest of the English-speaking markets, and only then to the twenty-six other languages the site supported at the time. Each step was a smaller bet than the one it followed was worth, which is how a team is allowed to touch the revenue path more than once.

The group we aimed at first is not the group the result came from.

Scope and constraints

What we could reach, and what we could not

The company was organised so that the room selection page and everything after it belonged to us, meaning that the search and landing pages did not. That is a hard boundary drawn through the middle of the problem: a traveller forms their expectation of the price on a screen we were not allowed to change, and then meets ours.

There was also no budget for moderated testing. A handful of customers were called, but the purpose of those calls was to collect what they already disliked about the current experience, not to put a prototype in front of them. So the qualitative half of this project is a benchmark and a set of session recordings rather than a study.

Two screens, then more
It started on room selection and payment. As evidence arrived it reached deal details, the confirmation screen, confirmation emails and booking management.
Desk research, not a lab
Eight platforms in seven countries, worked through by hand. No moderated sessions.
Five weeks of live traffic
One A/B test, split evenly, long enough to survive a weekend pattern and short enough to act on.

The first card is the one worth dwelling on, because it is the difference between a change to a screen and a change to a product. A price breakdown that is only fully visible at the moment of payment is not honest; it is a disclosure. So the same rows had to survive past the point where the money moves, into the screen that confirms the booking and the email that follows it.

This wireframe is where that was settled. It is the confirmation screen, carrying the identical breakdown the checkout carries, with two additional lines that checkout did not have: what has already been paid, and what the property is still going to collect. Everything later in this page is downstream of that decision.

Confirmation, wireframed. The breakdown does not stop at the payment, and the currency placeholders in the small print are there because it had to be true in every market too.

Process

Nine steps, repeated every iteration

This was never one project with an end. It is a loop that has run several times, and each pass leaned on whichever of these steps the product needed most at that moment. The benchmark is the exception: it was done thoroughly once and consulted afterwards.

01

Mapping where a price appears

A rough diagram of the interactions a traveller can have with a price and what follows from each. It is not a complete account of every state the funnel can be in, and it was never going to be. What it buys is the edge cases you can see in advance rather than the ones a developer finds in a sprint, and a shared object to point at when somebody asks whether we thought about a very specific edge case.

02

Benchmarking eight platforms in seven countries

It started as one question with a complex answer: what do other platforms include in the nightly price?

Answering it honestly meant deciding who to compare against, where, and under what booking. So: Findhotel against Expedia, Booking, Agoda, Skyscanner, TripAdvisor, Airbnb and Kayak, because those are the ones the company already measured itself against. In the Netherlands, Germany, the United Kingdom, Australia, Belarus, Indonesia and Israel, because those are the markets where our own price display rules already differed.

Comparable results need a control, so every search was the same search: Park Plaza Victoria in Amsterdam, one adult, one room, for the night of 13 October 2020, a hotel chosen precisely because it carries both a city tax and a tourism fee. The searches themselves were run in September, a month out, which is roughly when somebody books a city break. A second pass asked for two nights, 13 to 15 October, in the five markets where the first pass had raised a question. Where a platform did not carry that hotel, the nearest equivalent was used and the substitution written down.

Vendor includes general tax in nightly rate?

Yes, from the search results onwards

No, only at checkout

Names the base rate and the total together

Vendor includes local tax in nightly rate?

Yes, from the search results onwards

No, only at checkout

Names the base rate and the total together

Two questions, asked at every platform

Does the nightly rate include the general tax – the sales tax the platform itself collects?

Does the nightly rate include the local tax – the city or tourist tax the destination collects?

  • Included from the start
  • Revealed in checkout
  • Inconsistent
  • Stated separately

Two searches, one hotel

FindHotel
Local General
Market Incl.: Included from the start Held: Revealed in checkout Mix: Inconsistent Split: Stated separately Incl.: Included from the start Held: Revealed in checkout Mix: Inconsistent Split: Stated separately
GermanyDE: Germany Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
NetherlandsNL: Netherlands Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
United KingdomUK: United Kingdom Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
AustraliaAU: Australia Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
BelarusBY: Belarus Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
IndonesiaID: Indonesia Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
IsraelIL: Israel Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
Expedia
Local General
Market Incl.: Included from the start Held: Revealed in checkout Mix: Inconsistent Split: Stated separately Incl.: Included from the start Held: Revealed in checkout Mix: Inconsistent Split: Stated separately
GermanyDE: Germany Included from the startNot: Revealed in checkoutNot: InconsistentStated separately Included from the startNot: Revealed in checkoutNot: InconsistentStated separately
NetherlandsNL: Netherlands Included from the startNot: Revealed in checkoutNot: InconsistentStated separately Included from the startNot: Revealed in checkoutNot: InconsistentStated separately
United KingdomUK: United Kingdom Included from the startNot: Revealed in checkoutNot: InconsistentStated separately Included from the startNot: Revealed in checkoutNot: InconsistentStated separately
AustraliaAU: Australia Included from the startNot: Revealed in checkoutNot: InconsistentStated separately Included from the startNot: Revealed in checkoutNot: InconsistentStated separately
BelarusBY: Belarus Included from the startNot: Revealed in checkoutNot: InconsistentStated separately Included from the startNot: Revealed in checkoutNot: InconsistentStated separately
IndonesiaID: Indonesia Included from the startNot: Revealed in checkoutNot: InconsistentStated separately Included from the startNot: Revealed in checkoutNot: InconsistentStated separately
IsraelIL: Israel Included from the startNot: Revealed in checkoutNot: InconsistentStated separately Included from the startNot: Revealed in checkoutNot: InconsistentStated separately
Airbnb
Local General
Market Incl.: Included from the start Held: Revealed in checkout Mix: Inconsistent Split: Stated separately Incl.: Included from the start Held: Revealed in checkout Mix: Inconsistent Split: Stated separately
GermanyDE: Germany Included from the startNot: Revealed in checkoutNot: InconsistentStated separately Included from the startNot: Revealed in checkoutNot: InconsistentStated separately
NetherlandsNL: Netherlands Included from the startNot: Revealed in checkoutNot: InconsistentStated separately Included from the startNot: Revealed in checkoutNot: InconsistentStated separately
United KingdomUK: United Kingdom Included from the startNot: Revealed in checkoutNot: InconsistentStated separately Included from the startNot: Revealed in checkoutNot: InconsistentStated separately
AustraliaAU: Australia Included from the startNot: Revealed in checkoutNot: InconsistentStated separately Included from the startNot: Revealed in checkoutNot: InconsistentStated separately
BelarusBY: Belarus Included from the startNot: Revealed in checkoutNot: InconsistentStated separately Included from the startNot: Revealed in checkoutNot: InconsistentStated separately
IndonesiaID: Indonesia Not recorded Not: Included from the startRevealed in checkoutNot: InconsistentNot: Stated separately
IsraelIL: Israel Included from the startNot: Revealed in checkoutNot: InconsistentStated separately Included from the startNot: Revealed in checkoutNot: InconsistentStated separately

More platforms

Agoda
Local General
Market Incl.: Included from the start Held: Revealed in checkout Mix: Inconsistent Split: Stated separately Incl.: Included from the start Held: Revealed in checkout Mix: Inconsistent Split: Stated separately
GermanyDE: Germany Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
NetherlandsNL: Netherlands Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
United KingdomUK: United Kingdom *Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately *Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
AustraliaAU: Australia *Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately *Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
BelarusBY: Belarus Not: Included from the start*Revealed in checkoutNot: InconsistentNot: Stated separately Not: Included from the start*Revealed in checkoutNot: InconsistentNot: Stated separately
IndonesiaID: Indonesia Not: Included from the start*Revealed in checkoutNot: InconsistentNot: Stated separately Not: Included from the start*Revealed in checkoutNot: InconsistentNot: Stated separately
IsraelIL: Israel Not: Included from the start*Revealed in checkoutNot: InconsistentNot: Stated separately Not: Included from the start*Revealed in checkoutNot: InconsistentNot: Stated separately
Booking.com
Local General
Market Incl.: Included from the start Held: Revealed in checkout Mix: Inconsistent Split: Stated separately Incl.: Included from the start Held: Revealed in checkout Mix: Inconsistent Split: Stated separately
GermanyDE: Germany Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
NetherlandsNL: Netherlands Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
United KingdomUK: United Kingdom Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
AustraliaAU: Australia Not: Included from the startRevealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
BelarusBY: Belarus Not: Included from the startRevealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
IndonesiaID: Indonesia Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
IsraelIL: Israel Not: Included from the startRevealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
KAYAK
Local General
Market Incl.: Included from the start Held: Revealed in checkout Mix: Inconsistent Split: Stated separately Incl.: Included from the start Held: Revealed in checkout Mix: Inconsistent Split: Stated separately
GermanyDE: Germany Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
NetherlandsNL: Netherlands Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
United KingdomUK: United Kingdom Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
AustraliaAU: Australia Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Not: Included from the startNot: Revealed in checkoutInconsistentNot: Stated separately
BelarusBY: Belarus Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Not: Included from the startNot: Revealed in checkoutInconsistentNot: Stated separately
IndonesiaID: Indonesia Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Not: Included from the startNot: Revealed in checkoutInconsistentNot: Stated separately
IsraelIL: Israel Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
Skyscanner
Local General
Market Incl.: Included from the start Held: Revealed in checkout Mix: Inconsistent Split: Stated separately Incl.: Included from the start Held: Revealed in checkout Mix: Inconsistent Split: Stated separately
GermanyDE: Germany Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
NetherlandsNL: Netherlands Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
United KingdomUK: United Kingdom *Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately *Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
AustraliaAU: Australia Not: Included from the startNot: Revealed in checkoutInconsistentNot: Stated separately Not: Included from the startNot: Revealed in checkoutInconsistentNot: Stated separately
BelarusBY: Belarus Not: Included from the startNot: Revealed in checkoutInconsistentNot: Stated separately Not: Included from the startNot: Revealed in checkoutInconsistentNot: Stated separately
IndonesiaID: Indonesia Not: Included from the startNot: Revealed in checkoutInconsistentNot: Stated separately Not: Included from the startNot: Revealed in checkoutInconsistentNot: Stated separately
IsraelIL: Israel Not: Included from the startNot: Revealed in checkoutInconsistentNot: Stated separately Not: Included from the startNot: Revealed in checkoutInconsistentNot: Stated separately
TripAdvisor
Local General
Market Incl.: Included from the start Held: Revealed in checkout Mix: Inconsistent Split: Stated separately Incl.: Included from the start Held: Revealed in checkout Mix: Inconsistent Split: Stated separately
GermanyDE: Germany Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
NetherlandsNL: Netherlands Not: Included from the startRevealed in checkoutNot: InconsistentNot: Stated separately Not: Included from the startRevealed in checkoutNot: InconsistentNot: Stated separately
United KingdomUK: United Kingdom *Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately *Included from the startNot: Revealed in checkoutNot: InconsistentNot: Stated separately
AustraliaAU: Australia Not: Included from the startRevealed in checkoutNot: InconsistentNot: Stated separately Not: Included from the startRevealed in checkoutNot: InconsistentNot: Stated separately
BelarusBY: Belarus Did not appear to sell into Belarus that month.
IndonesiaID: Indonesia Not: Included from the startRevealed in checkoutNot: InconsistentNot: Stated separately Not: Included from the startRevealed in checkoutNot: InconsistentNot: Stated separately
IsraelIL: Israel Not: Included from the start*Revealed in checkoutNot: InconsistentNot: Stated separately Not: Included from the start*Revealed in checkoutNot: InconsistentNot: Stated separately

* Added the nights together only at checkout – search and room selection still quoted them one at a time.

The finding is in the two starred rows. Airbnb and Expedia were the only platforms that answered both questions the same way in every market, and the answer they gave was neither yes nor no: they name the base rate and the total at the same time. Everyone else, Findhotel included, picked one number and hoped it was the right one for that country.

The board also records what did not work. Skyscanner's figures did not add up, and TripAdvisor did not appear to sell in Belarus at all.

The table below displayed their prices in November 2020 for a single and multiple rooms.

Single room
Multiple rooms
Single room
Price details
1 room x 1 night$123.37
You saved 20% ⓘ
Taxes and fees ⓘ$11.10
Local taxPayable at property$7.06
Local taxPayable at property$8.64
Total$150.17
Pay now$134.47
Pay at property$15.70

Rates are quoted in US dollars. Taxes and/or property imposed fees of $15.70 will be collected by the property in the local currency (€13.34). Taxes and/or fees due at the property are based on current exchange rates, which may vary at time of travel.

Multiple rooms
Price details
2 rooms x 1 night$663.44
🏷 You saved 30% ⓘ
Taxes and fees ⓘ$59.72
Local taxPayable at property$14.12
Local taxPayable at property$46.44
Total$783.72
Pay now$723.16
Pay at property$60.56

Rates are quoted in US dollars. Taxes and/or property imposed fees of $60.56 will be collected by the property in the local currency (€51.47). Taxes and/or fees due at the property are based on current exchange rates, which may vary at time of travel.

Single room
Your Genius Price Summary
Small Double RoomIncludes Genius benefit€ 58.83
9 % VAT€ 5.29
Tourism fee€ 3
7 % City tax€ 4.12
Price € 71.24 (for 1 guest)
Multiple rooms
Check-in
Thu 22 Oct 2020
Check-out
Fri 23 Oct 2020
1 night, 2 roomsChange dates

FREE cancellation before 23:59 on 20 October 2020

2 rooms€ 249.36
9 % VAT€ 22.44
Tourism fee€ 12
7 % City tax€ 17.46
Total price due at stay:€ 301.26
Now you’ll pay€ 0

No payment needed now. You’ll pay at the property.

Single room
Original price (1 room x 1 night)€ 413.76
Price (1 room x 1 night)€ 60.00
Booking feesFREE
Price ⓘ€ 60.00

Included in price: Hotel tax and service fees € 4.95

Not included in price (collected by the property): City Tax € 3.85

We price match. Find it for less, and we’ll match it! ⓘ

YOU SAVED € 353.76 ON THIS BOOKING!

Multiple rooms

14% OFF TODAY

Original price (2 rooms x 1 night)€ 139.36
Our price€ 135.00
✓ 24HOURSALE Coupon applied-€ 15.96
Price (2 rooms x 1 night)€ 119.04
Booking feesFREE
Price ⓘ€ 119.04

Included in price: VAT 9%

Not included in price (collected by the property): City Tax € 12.50

We price match. Find it for less, and we’ll match it! ⓘ

YOU SAVED € 15.96 ON THIS BOOKING!

Single room
1 night£205.25
Taxes and fees£36.06
Value Added Tax£18.66
Local tax (Pay on arrival)£17.40
Total£241.31
Pay now £223.91
Pay on arrival £17.40 (19.22 EUR) ⓘ
The price shown in GBP is for reference only and it may change. Payment at check-in must be in EUR. Reference exchange rate: 1.00 GBP=1.1046028974 EUR

🚗 Free cancellation

Multiple rooms
Single room
Budget Twin Room Shared Bathroom
📅 Tue, 10/20 - Wed, 10/21Change Dates
Nightly Rate€55.05
Rooms1
Nights1
Guests2
Subtotal€55.05
Taxes and Fees€14.80
Total:€69.85

Book now. Pay later when you stay.

Free Cancellation until Oct 18, 2020 ⓘ

Multiple rooms
Standaard driepersoonskamer, 3 eenpersoonsbedden
📅 Wed, 10/21 - Thu, 10/22Change Dates
Nightly Rate€57.80
Rooms2
Nights1
Adults4
Children1
Subtotal€115.60
Taxes and Fees€30.50
Total:€146.10

Non Refundable ⓘ

Single room
Summary

1 room, 2 guests, 2 nights
Fri 09-11-2020 - Sun 09-13-2020


Charges
Standard Double Room$281.39
Taxes, Fees & Surcharges$25.31
City taxPayable at hotel.$33.86
Total ⓘ$340.56
€288.70
Multiple rooms
Summary

2 rooms, 4 guests, 2 nights
Fri 09-11-2020 - Sun 09-13-2020


Charges
Standard Queen Room$389.61
Taxes, Fees & Surcharges$35.05
City taxPayable at hotel.$55.59
Total ⓘ$480.25
€407.12
Single room
Price
Room Subtotal:USD 105.60
USD 88.00

(US$44.00/night x 2 nights)

Taxes & Fees:USD 19.97
Total Price:USD 107.97
You Saved:USD 17.60
Cancellation Policy:
Learn more
Refundable until Oct 02, 2020
Promo Code ▾ Credits ▾
Multiple rooms
1 Night, 4 GuestsChange Dates
☐ VIP Package for $2.99 ⓘ Included: Free upgrade call, 24hr Concierge, Priority Support line

Price
Room Subtotal:USD 87.92
USD 79.29

(US$79.29/night x 1 night)

Tips:USD 1.00
Taxes & Fees:USD 14.27
Total Price:USD 94.56
You Saved:USD 8.63
Tip $1 for saving you $8.63? ⓘ Your support helps us deliver the best in hotel deals.
$1
No Tip$10
Cancellation Policy:
Learn more
Non Refundable
Single room
1 room x 1 night€61.98
Taxes & fees€5.26
VAT€5.26
Special Discount- €3.60
Subtotal (Pay to Trip.com)€63.64

Additional Fees (Pay at Hotel)

City Tax€4.09
City Fee€6.00
Total€73.73

Taxes and fees may vary upon arrival

Multiple rooms
Check-in: Tue, Oct 13
Check-out: Wed, Oct 14
1 night
Rooms: 2
Prepay Online €138.04

Taxes due at hotel: ≈ €53.72


×Price Summary

Prepay Online
An online prepayment of €138.04 is required to book this room.

Included in the price: Breakfast not included

2 rooms x 1 night€140.63
Taxes & fees ⓘ€11.41
Silver Tier Deal-€14
Subtotal (Pay to Trip.com)approx. €138.04
Additional Fees (Pay at Hotel)€53.72

other tax and fee

Totalapprox. €191.76
(Local currency: US$225.58)

Taxes and fees may vary upon arrival

Receive after stay:★ 130

130 Trip Coins = €1.11

Best stay with free cancellation

Single room
Summary
🔒 Price Guarantee
Friday, September 11, 202070,18€
Taxes and fees6,31€
City tax10,91€
Includes Your Secret Price: You’re saving 9% as a member
Total price87,40€

for 1 room, 2 guests, 1 night
including taxes and fees

Payment schedule
Due now76,49€
Due at property10,91€

📈 This price may increase if you book later.

Multiple rooms
Summary
🔒 Price Guarantee
Average nightly rate$204.14 CAD

Superior Twin Room 👤👤

Free cancellation

Wednesday, October 14, 2020$189.13 CAD

Executive Double Room 👤👤👤

Free cancellation

Wednesday, October 14, 2020$219.15 CAD
Taxes and fees$36.74 CAD
City tax$47.28 CAD
Includes Your Secret Price:
Total price$492.30 CAD*

for 2 rooms, 5 guests, 1 night
including taxes and fees

Payment schedule
Due now$445.02 CAD
Due at property$47.28 CAD
(30,34€)

*Prices are quoted in CAD based on the current exchange rate. The amount due at the property is payable in EUR.

📈 This price may increase if you book later.

Those seven images represent the raw material the matrix was read off. Each is one country's whole landscape captured in a single pass, which is also why the study has a date on it: this is what these sites looked like in September 2020.

03

Ideation, then scoping it down

I ran the ideation sessions, and the benchmark is what made them worth running. Walking a team through what eight competitors do to the same booking is a faster way to establish what is possible than any opinion. It moves the conversation from opinions about price to observations about prices.

Scoping followed each session, with the product owner and the data scientist. Two questions, always in this order: "What would the right answer look like if nothing were in the way of development?", and "What is the smallest piece we could develop to put in real traffic?". The gap between those two answers made the roadmap.

04

A prototype cheap enough to argue with

The wireframes became a clickable prototype, kept deliberately rough. The audience was stakeholders and anybody in the company with a stake in the outcome, and a finished-looking screen invites a conversation about how finished it looks. A grey one invites a conversation about the price.

Then guerrilla testing, which here means grabbing whoever was available and watching them try. It does not replace a study and it was never offered as one. It catches the obvious, and it generates the questions that go back to the team as real research: what happens when the currency of the traveller is not the currency of the provider, what happens across several rooms, what happens when the fee is larger than the room.

The whole flow on a phone, banded by stage, in the form it was first argued about. It runs past checkout into the emails, booking management and cancellation.

05

Turning it into tickets

A diagram of the happy path and the edge cases that matter, each branch carrying the screen it produces. That drawing is what a product owner writes tickets from. It is also the artefact I go back to in step seven, when the question is whether the build does what was agreed.

06

Handing it to the front end

High fidelity screens, designed with the company's style guide and component library so that a developer is assembling known parts rather than interpreting a picture. The key screens went into Zeplin in both desktop and mobile, which is where the padding, the colour and the icon come from.

07

Checking the build against the scenarios

Once developers had something unreleased, I worked back through the scenarios agreed for that sprint by hand. This is where the map from step one and the diagram from step five pay for themselves, because otherwise the answer to whether everything was covered is somebody's memory of a conversation.

08

Two recordings from production

Once it was live the question changes from whether it works to what people do with it. FullStory records real sessions and lets you segment by behaviour or by where somebody is, and anything I found worth keeping, a bug or an idea or a habit nobody had predicted, went into a document.

Two of those sessions are here because each shows something a conversion rate cannot. One is an American traveller on the B side going from room selection through to checkout. The other is a traveller in Japan opening the price breakdown on a room, which is the exact gesture this project existed to make worth making.

United States, room selection through to checkout, on the B side of the test

Japan, opening the price breakdown from the room selection page

09

Making the change legible to colleagues

The last step is the one that decides whether any of the others travel. The product owner and the data scientist wrote the readable account; my part was to draw the two sides against each other so that somebody who had never been in a single meeting about this could scroll once and see what moved.

Both boards below run the same journey twice, room selection on the left and checkout on the right, with the decision points presented in questions and the resulting panel under each branch. Put them side by side and the whole change is three things: the fee gets its name back, what you pay now is separated from what you pay there, and a sentence says who collects it.

Room selection

More than one night, or more than one room?

1 night, 1 room
You found the best deal
FH FindHotel
CLP 59,803CLP 51,381

Resort Tower Two Queen …

14% off Partially refundable rate
Deal details

Compared with 2 other sites No changes

Hotels
Resort Tower Two Queen …

Non-refundable rate
Booking
Resort Tower Two Queen …

Non-refundable rate

Nightly price including taxes and fees

CLP 59,803

CLP 51,381 Nightly price including taxes and fees

Price details 14% off

1 night x 1 room
CLP 17,540.28
Taxes and fees
CLP 2,699.71
Due at property
CLP 31,140.86
Resort fee
CLP 31,109.12
Total
CLP 51,380.86
Total
CLP 51,328.48
2 nights, 2 rooms
You found the best deal
FH FindHotel
CLP 74,531CLP 62,031

Resort Tower Two Queen …

17% off Partially refundable rate
Deal details

Compared with 2 other sites No changes

Hotels
Resort Tower Two Queen …
CLP 74,507
Non-refundable rate
Booking
Resort Tower Two Queen …
CLP 74,531
Non-refundable rate

Nightly price per room including taxes and fees

CLP 74,531

CLP 62,031 Nightly price per room including taxes and fees

Price details 17% off

2 nights x 2 rooms
CLP 26,773.45 average per night per room
CLP 107,093.81
Taxes and fees
CLP 4,116.28 average per night per room
CLP 16,465.10
Due at property
CLP 124,563.46
Resort fee
CLP 31,109.12 average per night per room
CLP 124,436.48
Total
CLP 248,122.37
Total
CLP 247,869.44
Checkout

Is the guest’s currency different from the property’s?

Nothing tells the guest which currency they will pay in at the property.

Pay now
$25.79
Pay at property
$39.68

Pay at property amount will be collected by the property in the local currency.

Is anything due at the property?

More than one night, or more than one room?

1 night, 1 room

1 King Bed, Nonsmoking

Non-refundable rate

Price details 5% off

1 night x 1 room
CLP 41,437.44
Taxes and fees
CLP 12,690.22
Total price
with taxes & fees
CLP 54,127.66
($68.97)
Total
CLP 54,127.66
Total saving
CLP 2,862.46
Total saving
CLP 2,862.46

The price is converted to show you the approximate cost in CLP. You’ll pay in USD.

The price is converted to show you the approximate cost in CLP. You’ll pay now in USD ($68.97).

2 nights, 2 rooms

1 King Bed, Nonsmoking

Non-refundable rate

Price details 5% off

2 nights x 2 rooms
CLP 41,437.44 per night per room
CLP 165,749.76
Taxes and fees
CLP 12,643.13 per night per room
CLP 50,572.51
Total price
with taxes & fees
CLP 216,322.27
($275.64)
Total
CLP 216,322.27
Total saving
CLP 11,633.11
Total saving
CLP 11,633.11

The price is converted to show you the approximate cost in CLP. You’ll pay in USD.

The price is converted to show you the approximate cost in CLP. You’ll pay now in USD ($275.64).

More than one night, or more than one room?

1 night, 1 room

Resort Tower Two Queen Room

Partially refundable rate

Price details 14% off

1 night x 1 room
CLP 17,540.28
Taxes and fees
CLP 2,699.71
Due now
CLP 20,239.99
Due at property
CLP 31,109.12
Resort fee
CLP 31,109.12
Total price
with taxes & fees
CLP 51,380.86
($65.47)
Total
CLP 51,328.48
Total saving
CLP 8,422.44
Total saving
CLP 8,474.82
Pay now
CLP 20,219.36
Pay at property
CLP 31,109.12

The price is converted to show you the approximate cost in CLP. You’ll pay in USD.

The price is converted to show you the approximate cost in CLP. You’ll pay now in USD ($25.79). Pay at property amount will be collected by the property in the local currency.

2 nights, 2 rooms

Resort Tower Two Queen Room

Partially refundable rate

Price details 17% off

2 nights x 2 rooms
CLP 26,773.45 per night per room
CLP 107,093.81
Taxes and fees
CLP 4,112.08 per night per room
CLP 16,465.10
Due now
CLP 123,558.91
Due at property
CLP 124,436.48
Resort fee
CLP 31,109.12 per night per room
CLP 124,436.48
Total price
with taxes & fees
CLP 248,122.37
($316.16)
Total
CLP 247,869.44
Total saving
CLP 50,001.57
Total saving
CLP 50,254.50
Pay now
CLP 123,432.96
Pay at property
CLP 124,436.48

The price is converted to show you the approximate cost in CLP. You’ll pay in USD.

The price is converted to show you the approximate cost in CLP. You’ll pay now in USD ($157.44). Pay at property amount will be collected by the property in the local currency.

Prototype

The prototype itself

The scenario selector, offering a one night one room stay and choice of World, French or American user

Scenario selector

One flow, three locales: the same shared figure that runs the X-ray planner’s prototype, pointed at this file instead. Pick a locale to see how the total price is put together for it.

Prototype

The Figma prototype the concept was tested on, one flow shown for three locales. Click anywhere off a control to see what can be clicked.

Conclusion

What five weeks of traffic said

+3.5%

Conversion, for travellers outside the United States, over a five-week test.

Taxes-included markets moved most

The effect was sharpest where people already expect a displayed price to contain the tax. What we had folded in was not tax at all: it was the accommodation fees sitting beside it.

Desktop up, mobile down

Desktop traffic converted better. Mobile traffic converted slightly worse, on the same change, in the same weeks.

A week ahead, better

Bookings made about a week in advance improved. Last-minute bookings were slightly worse off, which is the pattern you would expect if reading takes time somebody does not have.

We aimed this at American travellers arriving from Google hotel ads, on the argument that they were the largest and most valuable group on the site. The gain came from everywhere else.

That is not a failure, but it is a result about the target rather than about the change, and it deserves to be read as one. A market where the displayed price already contains the tax has trained its travellers to expect the number on the tile to be the number they pay. Break that expectation and the correction is worth a lot. A market where tax is added at the end has trained the opposite expectation, and there was less to correct.

Every charge given its own line is another line, and a phone is where a line costs the most. Nobody measured which of the two effects was doing the work, so what the result really says is that clarity is not free everywhere and this project never found out where it stops paying.

What came next

By December 2020 the work had become a document rather than a screen: one map of how a price should be stated at each stage of the funnel, from the search results through room selection and deal details to checkout. Four boards, one per stage, each of them the rule rather than an example of it.

This is also where the two Findhotel projects on this site meet. The bottom of that checkout board is a choice between paying now and paying at the property, and giving somebody that choice properly is its own case study. Naming what the property collects is what made it possible to offer.

Those boards are the rules. What the original page offered next was the thing itself: a clickable prototype of the three price display logics the site was running at once, so that a reader could try them instead of reading about them.

Lessons

The winners refused the question
Two platforms out of eight answered both questions identically in every market, and their answer was to show the base rate and the total together rather than choosing between them. I had built the study around a binary and the best result in it was a third option. Worth remembering the next time a research instrument only offers the answers I thought of.
A name is the cheapest fix on the page
The measurable part of this change is one word. An amount due at the property became a resort fee, and the same money became something a traveller could reason about. No layout, no component, no sprint of engineering did as much as the copywriter renaming a row.
Clarity has a screen size
Desktop went up and mobile went down on the same release. An itemised price is more information, and more information is cheap on a wide screen and expensive on a narrow one. I would now treat a breakdown as something that has to be designed twice rather than reflowed once.
FPS: -- MEM: --