Ghost + Make.com: Building the Membership Workflow, and Where It Stops

COMPARISONGhost + Make.com: Building theMembership Workflow, and WhereIt Stops
On this page

Ghost only speaks Stripe. Everyone who hits that wall eventually asks the same question: can I not just wire this up with an automation tool?

You can. I have written about Zapier and n8n already. Make sits between them, and it is the strongest of the three for this specific job.

It also runs into a wall that catches people three steps in, and it is not the wall they expect.

Why Make is the better pick of the three

Three features matter here, and Make has all of them where Zapier does not.

Routers come first. A payment provider sends several event types to one URL, and in Zapier you generally end up with one Zap per event, which means the same Ghost logic copied several times and slowly drifting apart. Make lets a single scenario branch after the webhook, so order.created and subscription.cancelled take different paths from one starting point.

Then error handlers. You can attach a directive to a failing module, telling it to retry, ignore, break, or route somewhere else. Zapier sends you an email about a failed task. That difference decides whether a failed payment is recoverable or merely noticed.

The third is a data store, persistent key-value storage inside Make. It sounds like a footnote. It is what makes idempotency possible at all, because you need somewhere to record which event ids you have already handled.

Against n8n, Make is hosted and n8n can be self-hosted, which is mostly a question of whether you want to run a server. n8n’s code nodes make the hard part below easier, at the cost of it no longer really being a no-code tool.

The shape of the scenario

Roughly what you are building:

  1. Custom webhook receives the provider’s payload
  2. Verification confirms the payload is genuine
  3. Router branches on the event type
  4. Grant path creates or updates the Ghost member
  5. Revoke path removes access
  6. Data store records the event id so a repeat is ignored

Steps 1, 3 and 6 are straightforward in Make. Steps 2 and 4 are where the evening goes.

The wall: Ghost’s Admin API wants a token you have to build

This is the part that surprises people, so it is worth being precise.

Ghost’s Admin API does not accept a plain API key in a header. Your integration key arrives as two halves separated by a colon: an id and a secret. To make a request you have to build a JSON Web Token, signed HS256 with the hex-decoded secret, with the id set as the kid in the token header, an audience of /admin/, and an expiry a few minutes out.

Then you send it as Authorization: Ghost <token>.

Three consequences, all annoying in a visual builder:

You cannot store the token once and forget it, because it expires within minutes. A connection configured at setup time is useless an hour later, so the token has to be produced on every single run.

Producing it needs a real signing step: HMAC-SHA256 over a specific payload, with a hex-decoded key. Visual modules rarely offer that, because almost no other API asks for it.

And when you get it subtly wrong, it fails opaquely. A malformed token comes back as a 401, which looks exactly like a wrong key, so you spend an hour checking a credential that was correct all along.

This is why “just call the Ghost API” is more work in every no-code tool than it sounds. It is also why Zapier’s Ghost integration exists: somebody had to write this once so the rest of us do not.

Before you commit to Make for this, check whether its current Ghost support covers Admin API member creation, or whether you are going to be building tokens by hand in an HTTP module. That answer changes the size of the project by a lot, and it is the first thing to establish rather than the last.

The second wall: verifying the webhook

Providers sign their payloads. Polar, Lemon Squeezy, Paddle and PayPal all send a signature header you are meant to check against a shared secret before believing a word of the payload.

Skipping the check means your webhook URL is a public endpoint that grants Ghost memberships to anyone who guesses it and posts a plausible JSON body. That is not a theoretical risk; the URL travels through the provider’s dashboard, your browser history and possibly a support ticket.

Verifying it means another HMAC comparison, with the same problem as above.

Some people accept the risk on the grounds that the URL is hard to guess. That is a defensible position for a tip jar and a bad one for anything holding paid content behind it. What is not defensible is not knowing you made the choice.

The third wall, which arrives in month two

Everything above is a setup problem. This one is a design problem, and it is the reason I keep writing these articles.

A subscription is not an event. It is a stream. Created, renewed, payment failed, retried, recovered, cancelled at period end, expired. Each needs a different response in Ghost, and several of them mean the same thing.

Take Lemon Squeezy: subscription_cancelled, subscription_paused and subscription_expired all revoke access, while subscription_resumed restores it. Paddle adds subscription.past_due, which fires when a renewal fails and should revoke until it recovers. Miss one and you have members reading for free, silently, with nothing in any log to tell you.

Then there is ordering. Webhooks can arrive out of order, so a cancellation processed after a renewal leaves you in the wrong state.

And retries. Providers resend when they do not get a fast answer. Without the data store check, the same purchase applies twice.

None of these show up while you are testing, because testing is one clean purchase. They show up at month two, when the first renewals and cancellations arrive.

What it costs

Make charges per operation, and every module in a run counts. A branching scenario with a webhook, verification, router, token step, API call and a data store write is several operations per payment. Failed runs that retry count too.

At a handful of sales a month that is nothing. At a few hundred, with renewals, it is worth working out before you build rather than after. Estimate from your busiest expected month, not your average one.

An honest comparison

Make Zapier n8n PayGlue
One-off purchase Works Works Works Works
Recurring subscription You build the state machine You build it, harder You build it, with code Built in
Revoke on cancel You build it You build it You build it Automatic
Signature verification Manual HMAC Manual HMAC Code node Automatic
Ghost Admin token Manual JWT Handled by their app Code node Automatic
Duplicate protection Data store, if you build it None by default If you build it Idempotent by design
Setup time An evening or two An afternoon An evening, plus a server About ten minutes
Cost at low volume Per operation Often free Free if self-hosted Paid

I build the last column, so read it with that in mind. The first three columns are not wrong, and for one specific case they are the better answer.

When Make is genuinely the right call

Use it when you sell one thing once and access is permanent. The workflow is short, the failure modes are few, and it stays correct without maintenance. If you are already running other scenarios in Make, adding this one is a small step.

Do not use it for subscriptions, unless you actively want to own a billing state machine. Not because it cannot be built, but because it has to be kept correct while your provider changes its events and you are busy writing.

The question was never whether it can be built. It is whether you will notice the day it quietly stops being right.

The full comparison of ways to take payments on Ghost is here.

Frequently asked

Why can Make not simply call the Ghost Admin API?

Because the Admin API does not take a plain API key in a header. It wants a short-lived JSON Web Token that you sign yourself, using the secret half of your integration key, with the id half named in the token header. The token expires within minutes, so it has to be minted freshly on every run rather than pasted into a connection once.

Is Make better than Zapier for this?

For this particular job, yes. Routers let one scenario branch on event type instead of needing one automation per event, error handlers exist, and the data store gives you somewhere to record what you already processed. Those are the three things the Zapier version is missing.

What does it cost to run?

Make charges per operation, and every module in a scenario run counts. A branching scenario with a webhook, a router, a token step, an API call and a logging step is several operations per payment, and failed runs that retry count too. Estimate from your busiest month, not your average one.

So should I not use Make?

Use it if you are selling one thing once and grant permanent access. That workflow is short and stays correct. Reach for something else when you sell subscriptions, because then you are maintaining a billing state machine rather than an automation.

What happens if a webhook arrives twice?

Whatever you built. Providers resend when they do not get a fast answer, and nothing in Make deduplicates for you. Without a data store check keyed on the provider's event id, the same purchase is applied twice, which usually shows up as a doubled subscription length rather than as an error.