Custom development contracts: five clauses to check before comparing quotes
The same requirements document goes out to five vendors and the quotes come back 40% apart. The reflex is to negotiate, or to suspect padding. The real gap usually sits in the clauses: how much source code you actually get, how late delivery is priced, when maintenance starts, who prices a change request, whose servers hold the data. Each one moves the number, and each one turns into an argument somewhere in month four.
The cheaper vendor is not necessarily hiding a trap. It leaves the uncertain parts blank and settles them at delivery. What you bought is a "ship first, negotiate later" price, and every step after go-live is a fresh round of haggling.
1. Source code: not code you can read, code you can run
"Source code delivery" appears in almost every contract and means wildly different things. Three details decide whether a takeover team can work with it.
Delivery form. The acceptable version is a complete Git repository: commit history, branches, build scripts, dependency lock files, sample environment variables, database migration scripts, deployment notes. The unacceptable version is a zip with a runnable folder, no history, no CI configuration, dependencies installed globally, no lock file.
The difference shows up the first time you try to change something. With a lock file, anyone who clones gets identical dependency versions. Without one, reinstalling the environment six months later drifts a minor version and the build fails. That is not a theoretical risk; it is the first wall most takeover teams hit.
Reproducible deployment. Be specific about what you want: a Dockerfile or deployment scripts, gateway and Nginx configuration, the cron job list, environment variable names and what each does, callback URLs registered with third parties. One test settles it — can the vendor take a clean, empty server and get the system running from the deliverables alone within half a day. If not, the deliverables are incomplete.
Who owns the third-party accounts. Domain, cloud host, object storage, SMS gateway, payment merchant account, mail service, CDN, SSL certificate. If any of these are registered under the vendor's account, complete source code still leaves someone else holding the keys. Attach an asset list to the contract: service name, registered owner, admin account, renewal date, transfer date.
The IP clause needs one more boundary sentence: copyright transfers to the client, the vendor retains generic frameworks and components it already owned before signing, listed explicitly. Leave it out and the client assumes a full buyout. Write it rigidly and the vendor refuses to hand over its base libraries. A list is the least painful way through.
2. Late-delivery penalties: four details, not whether the clause exists
A daily penalty clause is common enough. What decides whether it has teeth is four details.
The start date. Counting from the signing date is the most common choice and the least fair — payment processing, interviews, waiting on client assets, waiting for third-party API approval all eat the schedule. Count from the day both sides sign the requirements confirmation instead, and write down the client's own obligations with deadlines: assets within 5 business days, feedback within 3 business days, with the schedule extending if those slip.
The daily rate. A percentage or a fixed sum both work. What matters is that it is anchored to the contract value. Set it too low and a month of delay costs less than a month of rent, which is no constraint at all.
The cap. Most often overlooked. "No more than 10% of the total contract value" reads sensible, but for a project whose delay misses the peak sales season, 10% does not cover the loss.
The right to terminate. This deters more than the daily rate: if delay exceeds an agreed number of days — 30, say — the client can terminate and demand a refund of payments already made. With that clause in place, a vendor thinks harder about whether it can actually staff the work.
Article 585 of China's Civil Code allows a court, on request, to reduce a contractual penalty that far exceeds actual loss. Astronomical numbers therefore buy nothing. What you want is a band both sides accept and that can actually be deducted when the day comes.
[TO VERIFY: how courts in different jurisdictions actually assess penalty caps — determines where the ceiling should sit]
3. Maintenance: start date and scope matter more than length
"Three months of free maintenance" means nothing on its own. It doesn't say when the clock starts or what is covered.
Three start dates show up in practice: contract signing, go-live, acceptance sign-off. Signing is the most common trick — on a two-month build, one month of the free period is already gone. Go-live sounds better until you notice the vendor controls the date; pushing an unfinished system live starts the clock. Acceptance sign-off is the only clean anchor: the clock starts the day the acceptance form is signed, and both sides know which day that is.
Write the scope in four categories: defect fixes (bugs in the deliverables), environment maintenance (servers, certificates, dependency upgrades, recovery after an attack), adaptation changes (third-party API revisions, platform rule changes), and new requirements. The first two normally sit inside free maintenance, the third depends on what you agreed, the fourth always goes through change control. Without the split, "maintenance" means whatever each side wants it to mean.
Tier the response times as well. A full business outage, an unusable main flow and one odd function do not deserve the same priority. 24/7 response refers to when a ticket is accepted, not when it is fixed, and mixing those two ideas is the surest way to a dispute. Workable wording is tier definitions plus two clocks — acknowledgement time and restoration time — started from when the ticket is filed in the system, not from a phone call.
4. Change control: without freeze points the schedule is alive
Get this clause wrong and the first three stop working. A project that runs late is rarely a slow build; it is a scope that keeps moving.
Set two freeze points. Sign-off on the prototype or interaction design freezes the interface structure. The start of UAT freezes scope: bugs only from then on, no new features. Without them the developer is chasing a moving target, the estimate stops meaning anything, and the penalty clause cannot be judged either.
Agree the pricing method in advance. Day rate is simplest, provided the rate is in the contract and each change order states the number of days and the work. Function points are finer-grained but invite argument; they suit a phase-two project whose requirements are already clear.
Fix a change-order template: what changes, which modules are affected, added hours, schedule impact, whether there is extra cost, both signatures. A verbal yes, or "just add it while you're in there" in a chat thread, becomes a dispute later without fail.
Then add a threshold. When cumulative change value passes a set share of the contract value — 15% to 20% is common — trigger a full scope review and re-estimate the remaining schedule and total price. That stops small requests from quietly accumulating into a second project, and it shows the client the budget trend early.
5. Data security: ownership, access, exit
This is the section most often missing entirely from an SME contract, and the one you reach for when something goes wrong.
Ownership goes in one sentence: business data, logs and derived data, and account assets belong to the client; the vendor processes them only within the authorised scope. Watch the phrase "derived data". Analytics events, reports and logs default to the vendor's side of the line unless you say otherwise.
Access should be layered. Production database access is by approval: who can look, for how long, with a trail afterwards. Personal data is masked, and test environments are not allowed to use production data. Without this clause, real phone numbers sitting in a test database is the normal state of affairs.
The exit mechanism is skipped more often than protections are. Four items at contract end: a list of accounts and permissions to revoke, handover of keys and certificates, the export format and deadline for data, and written confirmation that the vendor's own copies are destroyed. Leave these out and, six months after close, your data is still findable on their server — which is common, not exceptional.
6. Put two quotes side by side
When two quotes land, don't compare totals first. Lay the five clauses out next to each other.
| Clause | Vague wording | Workable wording | Who carries the risk |
|---|---|---|---|
| Source code | "Source code delivered" | Full repository with commit history, build scripts, asset list transferred | Client; takeover cost unknowable |
| Delay | "Penalty for late delivery" | From requirements sign-off, daily rate, cap plus termination right | Client; no way to stop the bleeding |
| Maintenance | "3 months free maintenance" | From acceptance sign-off, four scopes separated, acknowledgement and restoration split | Both; high cost of arguing |
| Change | "Changes negotiated separately" | Day rate in contract, change-order template, two freeze points, cumulative threshold review | Client; budget out of control |
| Data | "Data security guaranteed" | Ownership, layered access, masking, destruction on exit | Client; compliance exposure |
The vendor with detailed clauses usually quotes higher. The difference in price is essentially the cost of buying out the risk. A clean quote tends to include a longer requirements phase and fuller testing and documentation, and those are the two items easiest to cut and most likely to surface during delivery.
One more comparison that gets skipped: the contracting entity. Is the party quoting the same party that will do the work, and is anything subcontracted? Subcontracting is not rare on custom builds, and however detailed the clauses are, if a different team executes them the chain of accountability gets longer. A sentence saying no subcontracting without written consent costs almost nothing to add.
7. A one-question test
You don't need to hear a vendor describe its process. Ask it to send those five clauses as contract text. A team willing to put each one on paper usually has delivery management that holds up. A team that answers "we'll sort that out later" on every point will probably need double the effort to rescue in the second half of the project.
WANFENG TECHNOLOGY attaches these five as contract annexes: full source code delivery, late-delivery penalties and three months of free maintenance sit in the clauses rather than on a marketing page. Promises written into a contract bind; promises left on a page are just talk.
There is a problem the clauses don't solve: no penalty recovers a missed peak season. So the choice also comes down to how many projects the team is running at once, and whether it will show you the acceptance form from the last one.