The final payment should be the easy one. How I run client projects
How I run client projects so the client pays, trusts me and comes back: a written proposal with phases, every phase live on their server, tests they can read, and a handover pack.
How I keep a 322,000-line accounting system correct on my own: one save gate, append-only money, a hash-chained audit trail, real-database tests, and the audit that caught what they missed.
Why ESC/POS printers mangle Arabic, how to print it as a 1-bit image at the head's exact width, and the geometry bug that turned a 12 cm receipt into a roll on the floor.
Offline-first billing for electricity stations: one id from the phone to the receipt, why bill totals must never be added, an outbox that knows what to retry, and the 500 that looped.
It is the last week of a freelance project. The system runs on your laptop and nowhere else. The client has never seen it on their own server. The largest payment is still unpaid, and what was promised lives in a chat thread from months ago. Every demo from here on is a negotiation.
Some of the business owners who write to me have sat on the other side of that week. They paid for software and never received it in a state their staff could use.
I run projects so that week never comes. This is the method, written for developers and freelancers. By the end you will have the outline of a proposal that settles most arguments before they start, a phase loop that puts working software on the client's server from the first phase, a way to make your tests part of what the client buys, a handover pack, and the questions good clients ask, answered in writing before they ask.
Two things below do more work than the rest: one section of the proposal that heads off more arguments than any other, and one line in the terms that makes the final payment the easy one.
Where projects go wrongHow I run them
Scope lives in a chat threadA written proposal with phases and a not-included list
One big reveal at the endEvery phase live on the client's server
It works on the developer's laptopThe client's team tests it on their own server
Tests are a cost hidden in the estimateTests are a line in what the client buys
Handover is a zip fileCode, documentation, scripts and an acceptance report
Changes agreed in a voice noteChanges estimated and approved in writing
A short description is enough to start: what the business does, who will use the system, and what is not working today. My contact form also asks for the type of project and a rough budget range, and "not sure yet" is one of the answers.
Then I map the business. Three questions carry most of the weight:
Who uses the system? Reception, accountants, branch managers, drivers, customers.
What data matters? Invoices, stock, patient files, readings, cash boxes.
Who may do what? Who can cancel an invoice, who sees cost prices, who approves a refund.
The third question decides more of the design than any screen. On a network operations platform I built, the answer became 49 separate permissions grouped into four roles. On an ordering platform for a clothing retailer, the central rule was that a customer must never see another tier's price, and that rule is enforced inside the database with its own tests.
Then ask to see the tools they use today: the shared spreadsheet, the paper form, the old program. They show the real workflow better than anyone's description of it.
#The proposal: six sections, and the one that prevents arguments
Nothing is built before the client holds a written proposal. Mine follow one outline:
Section
What it answers
Current situation
What is not working today, in the client team's own words
What we will build
Each part of the system, described by what it does and for whom
Phases and schedule
What is delivered at the end of each phase
Investment
The cost of each phase and when each payment is due
Included and not included
What the price covers, and the outside fees it does not
Terms
Who owns the code, how changes are handled, how long the offer stands
The section that heads off more arguments than any other is the "not included" list. Server and domain fees, a WhatsApp Business account, the app stores' fees: all of them are paid to other companies. Written down before the client signs, none of them can arrive later as a surprise with your name on it.
The "included" list earns its place too. In my template it reads: design, programming, automated tests, deployment on the client's server, training for the reception team, and a support period after the final handover. Automated tests are a line the client reads. That matters later.
Each phase has its own cost, and my template ties each payment to the start of its phase. The client never pays more than one phase ahead of software they have used, and you never work more than one phase ahead of the money.
The client receives the proposal as a page on my site, in Arabic or English, with a reference number and the date it stays valid until. Nothing on the site links to it. If you build the same, three rules from my build are worth copying.
The file name is the link, so the build refuses any name without a random tail of at least six characters:
The prerender stops if a proposal page is not noindex. Proposals stay out of the sitemap, robots.txt disallows their paths, and the list of proposals is never bundled for the browser.
The server keeps search engines away and keeps the link out of referrers when the client clicks onward:
Before code, we agree on four things: the data the system keeps, the permissions, the connections to other systems, and the main screens.
This is the cheapest moment for anyone to change their mind. Moving a field on a sketch takes minutes. Changing how data is stored once the system is live is real engineering: when I moved FinyxWatt, my own platform for electricity and water stations, from Firebase to PostgreSQL, it took 107 ordered and checksummed migrations to do it while the stations kept working.
The work is split into phases, and each phase is useful on its own. In my proposal template, a clinic system is split like this:
Phase
What is delivered
1. Foundation
Appointments, the patient file, and permissions
2. Billing
The invoice created from the visit, payments, reports
3. Patient app
Booking and reminders on Android and iOS
Each phase ends with a version running on the client's server, or the hosting the proposal names, and their team tests it before the next phase begins. Inside a phase I work in short iterations, with working software, tests and a staging environment.
That order protects both sides. The client sees working software from the first phase. Their staff find the problems that matter to them while those are still cheap to fix. If priorities change, the next phase changes with them. And every payment after the first follows software the client has already used.
Buildshort iterations, a staging environment
Automated testson every change
Deployto the client's server
Their team testsfixes go back to build
Inside every phase. A three-phase project runs this loop three times.
Delivering every phase to a real server only works when a release is cheap and reversible. The network operations platform's deploy script takes a verified backup before it stops a single container, refuses to go on if the backup fails, runs the migrations and waits for the health check. The heart of this site's rollback is five lines:
bash
CURRENT=$(readlink -f "$ROOT/current")PREVIOUS=$(ls -1dt "$ROOT"/releases/*/ | sed 's:/$::' | grep -vx "$CURRENT" | head -n 1 || true)[ -n "$PREVIOUS" ] || { echo "!! No earlier release to go back to."; exit 1; }ln -sfn "$PREVIOUS" "$ROOT/current.new"mv -Tf "$ROOT/current.new" "$ROOT/current"
It takes under a second. When going back costs that little, putting a phase on the client's server stops being a gamble.
An automated test is a small program that checks one rule of the business every time the code changes. Across twenty products I have written over four thousand of them.
4,000+
Automated tests across twenty products
1,580+
FinyxWatt: app and server tests
1,240+
A network operations platform: server and app tests
530+
FinyX-ERP: accounting, permissions and server
Tests are easy to treat as a cost hidden inside the estimate. In my template they sit in the "included" list, where the client reads them. The trick is to describe each one in the client's words.
In FinyX-ERP, my accounting and point-of-sale product, the owner can delete a posted invoice through an administrative tool. A set of tests checks that the deletion happens, that the protections which stop anyone from editing posted amounts are switched back on afterwards, and that they come back even when the deletion fails halfway. The comment at the top of the file explains the stakes: the owner asked for the deletion, so the deletion is fine. The danger is a ledger left without its guards, silently, until someone edits a posted amount.
Its first check is worth copying into every suite:
csharp
Require(before > 0, "The database carries no integrity triggers, so the test proves nothing.");
A test that cannot fail proves nothing, so this one confirms it can before it checks anything else. And "posted amounts can never be edited, even after an administrative delete" is a sentence an owner wants to read in a proposal.
On larger projects the tests run before any release goes out. On FinyxWatt, the app suites run on every push and pull request, and an automatic server deployment starts only after the server's suites have passed in CI. On the Bin Masoud store, every backend change runs through lint, type checks, unit tests with coverage, the database migrations and end-to-end tests.
The client's own testing comes on top, and it deserves a document. For the network operations platform, the release candidate came with a written acceptance report:
Section
What it shows the client
Clean deployment
Deployment on a fresh Ubuntu server, step by step
Backup and restore drill
The backup and restore scripts, with checksum verification
Restart and reboot
Every service returns after a restart and after a full reboot
Integrity
The books balance: zero unbalanced entries, zero orphan lines, zero double reversals
Test results
Per project, passed and failed
Known limitations and remaining risks
What is not done yet, each risk with its mitigation
Verdict
Ready for a pilot or not, and what to do first
The last two rows build more trust than all the others. A developer who writes down his own limitations is believed about everything else.
Now the line in the terms. My template says the source code belongs to the client once the final payment is made. By then their team has used every phase on their own server, so the final payment transfers ownership of a system they already run. It is the easiest payment to ask for, because nothing in it is taken on trust.
What they receive:
Item
What it holds
Source code
Every repository, the client's once the final payment is made
Documentation
Deployment guide, operations runbook, backup and restore guide, permissions reference, API guide, architecture decisions and their reasons, security notes, troubleshooting, release notes
Scripts
Server setup, deployment, rollback, backups, backup verification, rotating the secret keys
Acceptance report
The evidence above, limitations included
Training
For the people who use the system every day; the reception team in the clinic template
The documentation and script lists are what the network operations platform's repository holds. The test of a pack is simple: could the next developer run the system without calling you? A client who knows they could leave is a client who can afford to trust you.
Projects change. The term in my template takes one line: anything outside the agreed scope is estimated and approved in writing before work starts. That keeps the proposal the client signed meaningful, and it keeps you from doing free work in silence.
Phases make it easier. A change can be estimated and placed in the next phase, and when priorities shift, the next phase shifts with them. A written change needs five things: what changes, why, the estimate, the phase it lands in, and the client's approval.
Real use always finds things testing did not. Deployment, backups, monitoring and those fixes are part of the work, and a support period after the final handover is written into the proposal. I run seven live systems today: their releases, servers, security and the fixes that keep them up.
First conversationwho uses it, what data matters, who may do what
Written proposalphases, included and not included, terms, a private link
Designdata, permissions, connections and main screens, agreed before code
Phaseseach one live on the client's server and tested by their team
Handovercode, documentation, scripts, acceptance report, training
Supporta period written into the proposal, then the fixes real use finds
Good clients ask these before they sign. Put every answer in the proposal, and you will never have to give one in an argument.
Will I get a written proposal with phases, and a list of what is not included?
Where will the system run, and whose name are the server and the domain in?
Will I test each phase on my own server before the next one starts?
Who owns the source code, and from when?
How many automated tests are there, and do they run before every release?
How are backups made, and when was a restore last tested?
What documentation will I receive at handover?
How are changes outside the scope priced and approved?
If a release goes wrong, how is it undone, and how long does that take?
After go-live, who fixes problems, and for how long?
The final payment is easy when nothing about it is new. The client has used every phase on their own server, read the not-included list before signing, approved every change in writing, and holds a pack that lets them run the system without you. That is also why they come back.
Comments
Join the conversation
Sign in with Google to like articles and comment. It takes one tap.