The developer built exactly what you asked for. That is the problem.
Most disappointing development work is not incompetence. It is a brief that was clear in your head and ambiguous on the page, answered literally by somebody who had no way to know what you actually meant. You said "a booking form." You meant the thing you have been picturing for three weeks. They built a booking form.
A good brief is not a long brief. It is one that makes the assumptions visible before anyone writes code.
Start with the problem, not the solution
The most common failure is a brief that describes a feature instead of a situation.
"We need a customer portal" is a solution. It tells the developer what to build and nothing about what success looks like, so every decision inside it gets made on their guess about your intent.
"Customers call us to ask where their order is, about fifteen times a day, and answering takes our office manager two hours" is a problem. Now the developer can tell you that a status page might solve eighty percent of it for a fraction of a portal, or that the real fix is an automated email at dispatch.
You may still want the portal. But you will be choosing it, rather than defaulting to it.
Say what it must do, in the customer's words
Write the actual sequence, in plain language, from the point of view of the person using it.
Not: "user authentication with role-based access."
But: "A customer clicks the link in their confirmation email, sees their order, and can change the delivery date up to 48 hours before dispatch. After that the date is fixed and they get a phone number instead."
That paragraph contains a business rule, a deadline, an edge case and a fallback. The technical version contained none of them, and every one of those details would otherwise have been decided by a developer guessing.
Name what is out of scope
This is the single highest-value paragraph in any brief, and almost nobody writes it.
"This does not include payments. It does not include a mobile app. Customers do not create accounts, the link in the email is enough. We are not migrating historical orders."

Two things happen when you write this down. The obvious one is that scope stops creeping. The less obvious one is that the developer will often push back on an exclusion, and that conversation is valuable. "You have excluded accounts, but without them the link has to work forever, which has a security implication. Do you want to talk about that?"
That is exactly the conversation you want, and it happens in week one instead of week six.
Describe the unhappy paths
Most briefs describe the day everything works. Most support tickets come from the other days.
For every important flow, answer three questions:
- What happens if the input is wrong?
- What happens if a connected service is down?
- What happens if the same thing is submitted twice?

That third one is responsible for an enormous number of duplicate orders and double-charged customers, because the brief never mentioned it and the developer never thought to ask.
Be explicit about the things everybody assumes
These get skipped because they feel obvious, and they are the most common source of "that is out of scope, it will be extra."
Who writes the words? If the brief does not say, everybody assumes someone else is doing it, and the site launches with placeholder text.
Does it need to work on a phone? Say yes explicitly. Say which phone if it matters.
Does it need to be accessible? If you have any public sector or enterprise customers, this is not optional, and retrofitting it costs several times what building it in does.
What happens to the existing URLs? If you have a site with search traffic, this single line is the difference between keeping it and starting over.
Who owns the accounts? Hosting, domain, repository, any third-party services. In whose name, on whose card.
What does done mean? Not "when it works." What specifically has to be true for you to pay the final invoice.
Ask for the shape of the work, not just the price
When you get a quote back, the number matters less than the structure.
Ask for milestones with something you can look at in each one. Not "week one: backend." Something you can open in a browser and react to. A developer who cannot break the work into reviewable pieces is either building something genuinely indivisible, which is rare, or has not thought it through.
Ask what they need from you and when. Most projects that run late run late because the client was the bottleneck on content, feedback or access, and nobody said so at the start.
Ask what they think is risky. A good answer is specific: "the integration with your accounting system, because their API documentation is out of date and I will not know for certain until I try it." An answer of "nothing, it is straightforward" means either they have done it many times or they have not looked closely.
The test before you send it
Read your brief and ask one question of every sentence: could a competent, well-intentioned person read this and build something other than what I am picturing?
Every yes is a sentence to rewrite. That is the whole method.
The short version
- Lead with the problem, not the feature.
- Write the flow in the customer's words, with the rules and the edge cases in it.
- State what is out of scope. This is the most valuable paragraph you will write.
- Cover the unhappy paths, especially double submission.
- Nail down content, URLs, accounts and the definition of done before anyone quotes.
If you have had an audit done and need it turned into something a developer can actually price and build, that translation is Audit and Implementation Planning. It is the document above, written for your situation, with the risky parts flagged.