Tumblr has recently released features for creators to earn a living with their art. Whenever you turn those features on, we provision an entire WordPress site, complete with WooCommerce (and WooCommerce Payments) plugins to facilitate billing. This post explains why (in case it’s not obvious).
When I am not writing blog posts on this site, I work at WordPress.com (actually, the company is called Automattic) on helping creators earn a living without sacrificing artistic freedom. When we bought Tumblr, we wanted to extend that option to Tumblr creators as well. Only, Tumblr isn’t running WordPress.
Or is it?
At Automattic, we also work on WooCommerce – the most extensible eCommerce platform on the web. Why not extend it to power Tumblr features as well? Actually, there are lots of reasons not to do it, but we did it anyway.
How does it work?
Whenever you enable Tumblr monetization features, we:
- Create a new WordPress site on WordPress.com infrastructure to serve as a payments backend
- Install WooCommerce, and WooCommerce-Subscriptions plugins to power the payments
- Create a Stripe account for you via WooCommerce-Payments
- Create products on that site with the price point you set on Tumblr
- Link that backend site to your Tumblr blog
From now on, your Tumblr blog will use that site as its billing API.
At Automattic, we like to eat our dogfood. And eat the dog food bowl. And eat the table under which the dog food is served. It is really surprising how the dog has managed to survive.
The above design is definitely inefficient from data perspective: Yes, we do have some duplication. Yes, we create 38 new SQL tables each time somebody decides to try out tipping on Tumblr.
But it is very efficient from an organizational perspective. We already have composable pieces for each requirement. Even if any one piece is not fitting exactly right, we would have to make it so.
WordPress.com is a giant multisite (It’s one installation of WordPress running all the blogs – read more about multisites). Our systems teams made it run on bare metal, effectively turning WordPress into “serverless”. New WordPress sites have a marginal cost for us. The ones with WooCommerce are slightly more problematic, but that is something we have to solve anyway.
WooCommerce is an eCommerce platform based on WordPress distributed as a plugin. It is designed with extensibility in mind to suit any use case, including our billing system (dubbed “Tumblrpay”).
Hundreds of open source contributors and our colleagues are making sure WooCommerce is reliable, secure, and a perfect solution for any payment-related use case. It powers a thriving ecosystem of extensions that make it do exactly what you want, although some use cases are easier than others.
By far, the biggest challenge of our work was making it run on the giant multisite of WordPress.com. We had to improve security, reliability, stability, and data handling. We are streamlining database structure and plugin APIs and fixing bugs that are only uncovered at this scale.
WooCommerce Payments is an Automattic-owned payment gateway based on Stripe. It leverages Automattic’s infrastructure and experience from running WooCommerce at scale to provide the most convenient merchant experience of any WooCommerce payment method.
Our teams are monitoring fraud, paying attention to the payment flow and a set of processes to ensure security, stability, and maintenance on the payment side.
But the main reason we made it handle Tumblr web payments and renewals is because it’s fully vertically integrated with the rest of our business and existing workflows.
I am pretty confident that this is not how you would imagine monetization features on Tumblr to work. The design had the following goals:
- Use each component of the existing ecosystem for its strenghts.
- Find gaps in those, and improve each component so other efforts (including the Open Source users) can benefit.
- Leave minimal footprint. No new dashboards, no new systems.
Ideally, each subsequent billing need should be a configuration, not a custom project to be maintained.
The alternative architectures we were discussing did not meet these goals:
- Combined backend for all Tumblr blogs, running on top of Stripe Connect (the obvious SAAS-like architecture with 4-5 bigger tables):
- Does not utilize our infrastructure
- Does not contribute to other products
- Requires custom management UIs and new dashboards for Fraud, Systems, and Accounting teams
- Creates issues with In-App-Purchases
- Running “One Big WooCommerce” – a design where it’s still WooCommerce under the hood, but are payments are aggregated on one store, instead of per-merchant:
- Cannot use WooCommerce Payments, requiring a custom payment gateway
- Requires us to write custom logic for splitting revenue across “merchants”
Running hundreds of thousands of WooCommerce sites is easy compared to the gymnastics we had to perform to enable In-App-Purchases in the app.
We are effectively running a Marketplace on top of the Apple IAP API, and it’s not easy. I will describe it in a seperate post – subscribe to know where it’s ready:
Some lessons learned
This is a random assortment of lessons we learned:
- Just because you find a clever way to do it, it is not always worth it. You have to design for ease of maintenance in the future
- Real problems are org-chart problems. Everything technical is solvable, but organizational issues are much harder to untangle.
- Chekhov’s function: If you deploy a function to a shared codebase, chances are somebody is going to use it without the same precautions as you would take. Sanitize your inputs.
- It’s always the cache.
- Tumblr users really want to share porn, while both Apple and Stripe really do not want that.
- Running 80 000 database updates per minute is a bad idea.
- Complexity grows at an exponential rate. If you have 3 untested features, when something breaks, you don’t know what you can depend on. Even if you build on a stable foundation, it’s best to do it one story at a time.
- When your
wp_userstable is bigger than 300 million, than don’t create a user that owns more than 100 000 sites. As a role on each site is stored as a
user_meta, that giant entry will create cache timeouts.
- Composer autoloader filenames are incompatible with WordPress coding standards.
- WooCommerce boot order is a delicate beast.
- Your job is to code yourself out of the job
I want to give huge huge huge kudos to my amazing teammates who made this challenging architecture a reality:
And the entire product team using this infrastructure to build amazing features like crabs, so you can give crabs to other Tumblr users. It has been a joy to work with them.