How Not to Run a Saas - Paddle.com Woes with Solutions

Paddle.com is a British startup handling customer payments for you. They take care of taxes, card charge retries, currency conversions, and they send you a reverse invoice at the end of the month.

Very convenient for a bootstrapper. Unfortunately not so convenient for a programmer, or someone based in a country that doesn’t take kindly to that.

It’s Written in PHP

And it expects you to do things the PHP way. To verify a webhook you need the PHP-specific ksort() function that sorts a dictionary. Difficult to do in other languages, as shown by the fact that all implementations cook up their own phpserialize() function.

If you use Go save yourself a day of work and check out my implementation.

The API Is Crappy

The company has been around since 2012 and the API is versioned at 2.0, but it’s still immature.

Lousy Documentation

The custom checkout endpoint documentation does not tell you what types the different parameters are. This requires some trial and error, especially for parameters like recurring_prices which it turns out is a list of strings. Check out my implementation to save yourself some time, but keep in mind that I might not have gotten it right in all cases. As of 15.09.2019 this is no longer true, they documented the types.

Lousy Design

Setting up webhooks for one time payments is even worse. It’s not obvious which webhook type will be sent (is it Fulfillment Webhook or Payment Succeeded?). By analyzing the received payload I learned it’s the former - a webhook type that’s missing the alert_name field needed to differentiate between payload types. Did they forget to include it? A significant road bump - but you’re clever! You want to work around it and add a custom field with the missing data. Not so fast - custom fields get ignored by the Test Webhook dialog. What can you do here, other than specifying a different URL for this one particular webhook type?

PS. Remember that quantity is a string, not an int. And if your webhook handler returns a 400 don’t get mislead by the test dialog telling you it got aPage Not Found error.

Lousy Consistency

Some API requests will go to vendors.paddle.com/api/2.0/, while others to checkout.paddle.com/api/2.0/. The former expects arrays to be in the HTTP Post format (e.g. ?arr=1&arr=2). The later expects arrays to be a string (e.g. ?arr=1,2).

Lousy Practices

Oh, and did you add links to the documentation in your code’s comments, or a blog post such as this one? Tough luck, the Paddle team likes to change and break them from time to time.

They May Block Your Account

They’re known to block people’s accounts, and there are cases when they did it by accident. See Paddle May Block Your Account for details.

It’s Designed for a Company with Just One Product

An indie hacker, their typical customer, will commonly have a company registered in the country they live in. And under that company they’ll have multiple money making products - you know, with different websites and on different servers.

You cannot have two accounts registered for the same legal entity. That is fine, as you can just create multiple subscriptions for each of your products. However, as it turns out, you cannot set different webhook URLs for them.

See Multiple Webhook URLs With Paddle for a solution.

They Don’t Want Help

In January 2019 I contacted Paddle and offered to write a Golang library for them. They kindly declined, stating that they’re working on it internally. Over year later it’s still not released…

Not Compatible With Startup Incubators or Cheap Accountants (In Poland)

Paddle is designed to be convenient. You don’t even have to send them an invoice, they generate one for you. That seems like a good idea, until the reality of the law hits you.

Because the invoice is generated by Paddle you have no control over it. The government recommends that invoices be numbered sequentially - if they are not then it’s considered highly suspicious and increases the chances of inspection. And an inspector’s job is to find something - they always do.

Because of that all startup incubators have refused to handle Paddle’s invoices for me. Discussing this with my friends I learned that it’s to be expected and cheap accountants will refuse to handle them as well.

Solution: get an expensive accountant and don’t use a startup incubator. Unfortunately that will cost you $400/month, as opposed to $60/month for an incubator.

The Good

I question their code quality and worry that one day everything will go down and never come back. But their support team really tries to make up for it. My experience with them so far has been outstanding.

You contact them by email. A real human talks to you, takes the time to understand your problem and perform manual steps, if necessary, to solve your particular problem. Big thank you to Paddle’s support team.

Summary

There is a lesson to be learned here. If your tool solves a real need for real people they will use it, even if it’s crap. Polishing your stealth mode product and adding “just one more feature” changes nothing.

See also