Hacker News new | past | comments | ask | show | jobs | submit login

As a fellow designer, I've been scammed multiple times too. So, I totally feel you.

Here's my documented version of to-do's to avoid such awkward situations.

1) Always let the client know through email that whatever NDA or any other form you've signed is valid only after the project is complete(ie., the final invoice is paid). But, however, promise them that (legally) you will not leak anything about their project anywhere else until unless it goes too extreme, as in your case (add this clause, it's important). I say email specifically because it can be used as vital evidence if something goes wrong.

2) If it's just PSD's, watermark them in a way they will need to spend more time and money removing watermarks and editing than paying you.

3) Copyright. In your email to your client, the first thing you let them know is that the whole stuff belongs to you (owned by you, copyrighted) unless the final invoice is paid. So make sure the NDA doesn't mention/over-ride this before you sign it.

4) Many are against this tactic, but I will explain the reasons soon. Include a flipswitch.

Here's how -

If you are doing HTML/CSS, this is how you do it (I've already suggested it before):

Add redundant containers - I'm using the logo as an example, but really it could be some important element that provides value to the client. As an example, if you want to add styles for your logo, don't just write it as

    #logo{
    display:block;
    position:absolute;
    top:10px;
    background:url('some-image.jpg') no-repeat;
   }
But re-write it as:

   #aw469srfa #fewji903{
    display:block;
    position:absolute;
    top:10px;
    background:url('some-image.jpg') no-repeat;
   }
BUT, in your actual HTML file, what you do is DON'T include the logo container with ID 'fewji903'. Instead, write a tiny Jquery script to load this container dynamically. Something like:

    $(document).ready(function() {
    //do a check to see if current time is less than expiry date
    if( project_expired()){
    $('#aw469srfa').html('<div id="fewji903"></div>');
    }
    else{
    // don't load the container
    alert('fuck-off, expired');
    }

    function project_expired(){
    //do something to check the validity
    if (current_time==time_you_set_to_expire)
    return true
    else 
    return false    
    }
    });
What you're doing here is checking the time (you could maybe use even ajax to send a request to your server to see if the project is valid, but it will increase page loading time obviously) to see if it's less than some certain time frame you've set. Say about a month. This means, if the client doesn't pay you in a month, then the site would break automatically after a month.

Now:

Minify your CSS and make it unreadable. And finally, obfuscate your JS above:

This is how the above code, when obfuscated will look like this somewhat:

     eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('$(a).b(2(){5(0()){$(\'#9\').8(\'<1 6="7"></1>\')}3{j(\'h-i, c\')}2 0(){5(f==d)4 e 3 4 g}});',20,20,'project_expired|div|function|else|return|if|id|fewji903|html|aw469srfa|document|ready|expired|time_you_set_to_expire|true|current_time|false|fuck|off|alert'.split('|'),0,{}))


I always use http://www.jsobfuscate.com for this purpose.

At that point, your client could:

1) Reverse engineer the code to see how it works.

2) Try to re-design it from scratch

3) Cancel the project, or take too much time to complete it.

4) Pay you.

1-3 are extremely time-consuming and expensive for them. So, most likely, they will opt for 4.

Now for the DON'T's.

1)DO NOT obfuscate your code in production. This is only done till you get your final payment.

2) Remove all the shady tricks above in production (once you've received your payment) because it's

a)unprofessional and

b)most likely would break something.

This is not perfect. But you do understand that any locksmith can break your house door, right? So, this is for those non-tech clients who would rather pay when you push them too far..

This has worked really well for me all these years.




Wouldn't it be easier to schedule milestones with payments for work done? It creates a strong feedback loop, spreads the payments for the project out and you can gauge early if they are willing to actually pay.

(Edit: I am a not a designer so I'm not sure how many "stages" you can break a contract into)


Instead of some potentially impolite message in place of the logo or some other vital components, just display "This page is a preview for evaluation purposes. It has now expired." or something similar. That way you'll have little risk in case you overlooked it.


Point 4 we could just easily type cntrl+f and type the message being displayed or alert etc... It would hardly take a few minutes to find out the problem.


A good obfuscator can prevent that by breaking up the string literals and either scrambling or encoding them.


I wonder if there could be a service to protect freelancers. What if you could just go to a page, enter a URL, and you get another URL back. You send your client the 2nd URL and it's essentially a live stream of the first URL that they can fully interact with but can't view the source of.

Would any freelancers pay for that?


What about not deploying to a server that is resolving their DNS until payment is complete?

When final payment is received, final deployment occurs. Until then, it can be accessed via a URL you control.

Otherwise, if you're really looking for something like that, I'd suggest https://forwardhq.com


I was under the impression that the main concern is theft of HTML/CSS/JS sources without payment. Anything that allows access to those files would still be vulnerable. The idea was to have the site rendered real-time in the cloud and transmitted so that no source assets could be stolen.


Apologies, I believe I interpreted the protection for freelancers a bit more broadly. Rarely have I seen/heard of clients who have resorted to blatant theft of the sources without payment. They usually just try to get away with using the sources. That is no different from theft, in my book, but it seemed going so far overboard as to obfuscate/hide it all vs. just getting oneself a proper attorney and initiating legal action would be better. Better yet, get an attorney to draft a contract that you can reuse with [nearly] all clients.

I was speaking more to sensible protection--do not deploy & resolve DNS, do not transfer source code ownership, do not relinquish copyright ownership, etc. until the final invoice is paid. And make sure it is written that way in a contract and that the client signs the contract before work commences.


I'm not sure how you can do that from a technical standpoint. If it's on my screen, I can view the markup.


Check out browserling

http://browserling.com


Many clients don't know anything about viewing markup and recreating work. Especially if there is something powering a site/application on the server. The HTML doesn't help them much.


Think of something like VNC over WebRTC or Flash. Just rendered frames, no raw access to the source.


Many clients wouldn't find this sufficient for user acceptance testing.

Won't any mildly tech-saavy client want to try it on their laptop, phone and/or tablet to make sure it looks right in different browsers? Well, it'll look exactly the same, because they aren't actually rendering it....

The minify/obfuscate solution seems sufficient (and possibly an expiration date...) but even that would be obviously unnecessary with many clients.


It would be interesting if you could render a Flash depiction of a live website and allow interaction without degrading performance or having it "look like Flash."


You have:

function project_expired(){ //do something to check the validity if (current_time==time_you_set_to_expire) return true else return false }

Maybe you just want:

return current_time==time_you_set_to_expire;

O_o

Also note this is really easy to circumvent.


Or current_time >= time_you_set_to_expire...


The commenter was trying to illustrate a point, not provide actual code.


Thanks for the optimization tip, but it was just to explain the idea :)




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: