跳到主内容
@wquguru
精选85RevenueCat 博客(RSS)产品与增长

Mac 应用直接销售:RevenueCat + Stripe 收款授权方案

A license to bill: Selling a Mac app without a merchant of record

原文
发到 X
推荐理由

给 Mac 独立开发者一套可直接照做的绕过 App Store 的收款与授权方案,含具体服务组合、配置步骤和取舍,今天就能动手试。

I hang out in a couple of online communities focused on app development. One of my favorites is a Slack community called "AppKit Abusers." It's a great place for developers writing Mac apps to hang out, help each other work through problems, and share ideas. There's one question that gets asked regularly:

How do I make money?

This question comes up because many Mac developers choose to distribute their apps outside the Mac App Store. Sandboxing imposes restrictions on iOS apps, but it's even more extreme for Mac apps. Many of the things we've come to expect from "Mac-assed Mac apps" over the years are simply not possible with sandboxing. However, disabling the sandbox on a Mac app comes at a cost: you cannot ship your app on Apple's App Store. This means that all of the work of collecting money from customers, handling licensing, etc. falls squarely on the developer's shoulders. And so every couple of months, like clockwork, another developer is in the Slack group asking for recommendations on how to implement licensing.

This is a problem I've faced several times myself. I love writing Mac apps; I've got three I'm building for myself right now. On iOS, I've used RevenueCat to simplify the logic around dealing with in-app purchases, and it's been wonderful to offload that mental burden onto a reliable framework, and allow me to focus on the task of building my app. I've wished something as easy existed for Mac apps, too.

Earlier this year, I joined RevenueCat as a Senior SDK Engineer and learned more about all the ways they help developers make money. Of course, I immediately thought "Well, what about Mac developers?" One feature in particular caught my eye: web-based billing support. This is a way for web developers (and mobile developers selling outside their platform stores) to offer subscriptions to their customers. Since all the information is associated with RevenueCat's service, purchases made on the web get tied to the customer’s profile, which can then be accessed via the RevenueCat SDK in an app. And since the RevenueCat SDK works on macOS… I quickly started connecting the dots and forming a plan.

After thinking about this approach, I put it on my to-do list to see if it would actually work. As luck would have it, a couple of days later my friend Jared Sorge mentioned he was looking to solve this exact problem, and he was game to try my idea. After some careful reading of the documentation, a couple of Zoom chats, and a bit of trial and error, Jared got it to work. In the end, it was extremely straightforward:

  • Configure the product offerings and entitlements in the RevenueCat dashboard, like you would for any other app
  • Connect Stripe as a web provider and hook your offering up to a Web Purchase Link
  • Send identified users from your Mac app to the web to purchase
  • After purchase, ask the SDK to refresh, and see that they now have the purchased entitlement

That's the short version. The longer version is Jared's story—how he got there for Arborist, his new Mac app launching today.

Why not Paddle, FastSpring, or Lemon Squeezy?

Arborist is a native macOS command center for git repositories and worktrees. It works by running user-entered commands at arbitrary locations, which means sandboxing—and therefore the Mac App Store—was never an option. Jared settled on a one-time version 1 purchase of $39, "just like the Software Days of Yore," and then hit the question every direct-sales Mac developer hits: how do I do licensing on my own?

He knew the established options like Paddle, FastSpring, and Lemon Squeezy have worked for many apps like his over the years. But:

I also wanted something simple for my users. Not to mention Apple Pay was a must-have. I've experienced friction more times than I can count when an app doesn't support Apple Pay, and every time it happens I am ever so slightly less happy with that app because of it. Customers are also more familiar with the smooth in-app purchase experiences provided by the App Store, and if I could achieve something that easy I wanted to do just that.

No license server, no license keys

What Jared landed on contains three pieces:

  • RevenueCat serves as the source of truth for whether or not a customer is licensed.
  • Customer IDs come from local iCloud identifiers—specifically, calling userRecordID() on the app's CKContainer in CloudKit.
  • When the user makes a purchase, they earn an entitlement that Arborist looks for to grant them a license.

The second bullet is the clever one:

I didn't want to have to spin up a licensing server to send out codes (much less have to store them), and I didn't want to have an email-based system. I wished for something simple like StoreKit but without using the App Store as a backend.

Because the customer ID is the user's iCloud record ID, a license bought on one Mac automatically follows the customer to every Mac signed in to the same iCloud account. There are no license keys to email, no "Restore Purchases" button, and no personally identifying information collected by the app. As Jared puts it: "Stripe handles the payment process, and the iCloud's identifiers give nothing away."

The trade-off is that this strategy requires the customer to be signed in to iCloud—a reasonable assumption for a power-user app, and Jared is working on a web-based iCloud sign-in for everyone else, coming after 1.0.

The merchant of record question

Jared initially set up RevenueCat Billing, RevenueCat's own billing engine for web purchases, but then he ran into a term he'd never encountered:

I had never heard the term merchant of record (MoR) before and when I first did I didn't know it was something to care about (spoiler alert: it very much is).

The merchant of record is the entity legally responsible for the sale: collecting and remitting sales tax, VAT, and GST, and handling refunds. RevenueCat Billing does not act as your merchant of record: you are. For solo developers, this can add a significant amount of complexity. For Jared and his first direct-sale app, it was a dealbreaker.

The good news is that Stripe offers Managed Payments, a merchant-of-record service where Stripe takes on tax collection and remittance per transaction, and RevenueCat supports it out of the box. From an app developer’s perspective, it’s the same entitlements, same SDK, and same Web Purchase Links; Stripe just carries the compliance burden. It adds a cost, but that was worth it to Jared:

Thankfully I found Managed Payments and from everything I can tell, making Stripe my MoR puts all the burden of these collections and distributions on Stripe. So I'm happy to give them a few extra percent of each sale to handle that for me.

Setting up the backend

Jared has documented his full setup, including the places he tripped up, on his blog. The condensed version is short:

  • Create the entitlement in RevenueCat that the app checks for a license.
  • Add the product in the Stripe dashboard, making sure it meets Managed Payments' eligibility criteria.
  • Connect Stripe to RevenueCat as a web provider, checking the "Use Managed Payments when available" box.
  • Create the RevenueCat product by importing it from Stripe.
  • Add an offering containing the product with a lifetime duration—effectively a one-time purchase.
  • Generate a Web Purchase Link for the offering, including the callback URL the web checkout uses to deep-link back into the app.

Hooking up the app

The full purchase flow in Arborist looks very familiar to app users: open the License screen in the Settings, click “Buy,” complete the purchase in your browser, and automatically get returned to Arborist. That’s it.

Jared had initially hoped to keep everything in-app using a WKWebView, but a known WebKit bug prevents Apple Pay from working in that context. Instead, he accepted the small friction of jumping out to the user’s browser so customers can use Apple Pay instead of typing in card details by hand.

更进一步:量化金融体系

看懂新闻只是起点——沿量化金融路径,把它变成能交付的工程能力

进入量化体系 →

相似阅读

另一事件,读法相近