I find the best way to get paid is contribute more to the project than just source code. Contracts, withholding code, time locks, all effective means for us to control our labor and prevent being cheated. However at the end of the day most disagreements come about for business and communication reasons and not actual cheating.
What I mean is that in my experience most people do not set out to intentionally screw you. It may turn out that is the end result but there were probably opportunities to save it. Withholding source code may be your only viable option but it also confirms that it was the only thing you really brought to the table. A true "consultant" offers more than just source code and so losing you on the team is a much bigger pill to swallow then some code.
I know from experience that often when a developer picks up some source code from another developer the first thing we ask is:
- What happened to the original developer?
- Can I rewrite all this cause its sucks?
So you kind of end up in this situation where you are trying to withhold the source code from the customer but they may not even care about it or want it because what are they going to do with it? Short of being developers themselves it has no practical use to them. If they pay you off and give it to the next person then that person will tell them how much work has to be done to make it "correct". It's a cycle and it starts with not communicating about the real outcomes.
Customer: "I want widget to do X."
Widget was never very important to the customer. Doing X was what was important so having a deep understanding of the expected outcomes and the amount of work over the lifetime of the enterprise is essential. I may be able to build widget X all day long but I also may know that the widget will not work the way they expect. I can provide alternative ideas, solutions, give them different things to consider as I am the expert at widget building and they are the expert at X (their problem).
Lastly if I know that I will not be around to see this enterprise through to completion (aka profit) then I generally will not engage the project. The short term benefits of additional cash flow are not worth the pains created when I inevitably have to say "I do not have time for this" or "my heart is not in it".
That may not be the best way to construct a software consulting business but it is the best way I have found to build good software. Should the customer's problem actually be relevant and should they know the solution to it and should I actually solve it then a lasting relationship can be had. If nothing else there is a profit so if I have to leave the project there is resources available to replace me and I often help with that as well.
My time is as valuable as the customers even if I am the one charging for it because that means I'm not charging for something else that could be potentially more viable in the long term. If you keep all that in mind and approach the situation honestly then I would say it's hard to get screwed.