Skip to main content

Zapier recipes

Zapier's Catch Hook is one URL, and a StorePilot webhook destination is one URL with the events it receives ticked beside it — so the first thing to do here is give Zapier a destination that receives everything you want to act on.

Setting it up​

  1. In Zapier, create a Zap with the Webhooks by Zapier → Catch Hook trigger and copy its URL.
  2. In StorePilot: Settings → Notifications → Add destination, choose Webhook, paste the URL and tick every event this Zap should handle.
  3. If you split events across several Zaps, give each its own destination instead — each receives exactly what it ticked, so nothing is quietly taken from another.
  4. Make sure the destination's Payload version is Version 2. A new destination starts there; one carried over from the old settings may be on version 1, whose events have five different shapes — a single Zap cannot branch on them cleanly, which is the reason version 2 exists.

Press Send test on the destination. The drill arrives in the destination's own version, so what you build the Zap against is what the real events will look like.

Branching on the event​

Every version 2 payload has the same shape, so one Filter or Paths step keyed on event splits the whole stream:

event → what to do
lead.created → create a CRM contact
lead.converted → mark that contact as a customer, stop any nurture sequence
error.created → post to a Slack channel if data.error.severity is "critical"
uptime.down → page whoever is on call
revenue.silence → tell the shop owner nothing has sold in the window

The fields a Zap usually needs are in the same place for every event:

FieldMeaning
eventWhich of the twelve events this is
site.nameWhich shop, by name — no id→shop table to maintain
occurredAtWhen it happened (sentAt is when we posted)
links.dashboardA link straight to the thing, for the Slack message or the ticket
idAn idempotency key, for de-duplicating a replayed delivery

Cancelling an abandoned-cart flow​

This is the recipe worth writing down, because until version 2 it could not be built.

A cart arrives as lead.created with data.lead.leadKind = "checkout". If you mail that cart an hour later, you are racing the customer to their own receipt: they may have paid in the meantime, and nothing told you.

lead.converted is what tells you. It fires when the checkout is paid, carries the same data.lead.id, and adds data.order with the external order id, the total and paidAt.

  1. Path A — event is lead.created and data.lead.leadKind is checkout: start a Zapier Delay For of one hour, then send the recovery mail.
  2. Path B — event is lead.converted: look the customer up by data.lead.email and set a field your Path A mail checks, or remove them from the sequence in your ESP.

Path B needs somewhere to write, because Zapier cannot reach into a delay that is already running. A single-row lookup table (Zapier Tables, Airtable, a Google Sheet) keyed on data.lead.id is enough: Path B writes converted = true, and Path A reads it after the delay and stops if it is set.

:::note A declined card is not a conversion lead.converted fires only on paid. A checkout that was created and then failed at the gateway stays a live cart — and that shopper is exactly the person the recovery mail is for. :::

Verifying the signature​

Zapier's Catch Hook does not verify signatures for you. If you set a signing secret, add a Code by Zapier step as the first action and reject anything that fails — otherwise the URL alone is the whole credential, and it travels in every Zap history entry.

See the signature section for the exact material: on version 2 it is <timestamp>.<raw body>, and the timestamp is in X-StorePilot-Timestamp.

What this cannot do​

There are no retries. Delivery is fire-and-forget; if Zapier is unreachable, the event is gone. For anything you cannot afford to miss, point a webhook destination at a queue you control and let Zapier read from that.