A template for Make or n8n that turns every paid Shopify order into a sale in your referral program, credited to the partner whose link or discount code brought the customer.
Most stores do not need it. Bolt Claw's Shopify app, or the webhooks on the program's Setup tab (see Referrals with Shopify), report the same sales and their refunds and disputes too. Use this template when the order should pass through an automation of your own first. Run only one of the three for a store: each records an order under its own event id, so two of them would count every sale twice.
What it sends
For each order Shopify reports as paid, one
POST /v1/referrals/conversions:
{
"program_id": "<your program id>",
"event": "sale",
"event_id": "shopify:5432109876543",
"customer": { "id": "7012345678901" },
"referral": { "code": "jane-20", "discount_code": "JANE10" },
"amount": 4990,
"currency": "USD"
}
event_idisshopify:and the order's id. Shopify may deliver an order more than once; the sameevent_idrecords it once.- The customer is Shopify's customer id, or
order-<order id>for an order with no customer. - The referral code comes from the
?via=Bolt Claw's links add to the landing page (Shopify keeps it in the order'slanding_site), and the discount code is the order's first one. Either is enough to credit a partner; anything that is not a code's letters, digits and hyphens is left out. - The amount is the order total in the currency's minor units: 49.90 USD is
4990, 1500 JPY is1500(no decimals), 12.345 KWD is12345(three). - A test order (Shopify's test payments, or a development store) is sent
with
"test": trueand recorded as test data.
The n8n template also sends the order's time and the click id from the landing page; Make's sends neither, so the sale is dated when it arrives.
Before you start
- A key with the Referral tracking preset (
conversions:writeand nothing else), made under Settings, Developers. - The program's id, on its Setup tab.
In Make
- Download
https://boltclaw.ai/referrals/templates/make/shopify-order-to-sale.jsonand import it (... menu, Import Blueprint). - In the first module, Add a webhook. Under Show advanced settings, set Get request headers and JSON pass-through to Yes. Copy its address.
- In Shopify admin: Settings, Notifications, Webhooks, Create webhook, the event Order payment, format JSON, and the address. At the bottom of that page Shopify shows the key its webhooks are signed with.
- Expected signature: replace
PASTE_THE_SHOPIFY_WEBHOOK_SIGNING_KEYwith that key. Keep the quotes. - Record the sale in Bolt Claw: replace
bc_live_PASTE_YOUR_KEYin theAuthorizationheader with your key, andPASTE_YOUR_PROGRAM_IDin the body with the program's id. - Switch the scenario on.
The filter after the webhook lets an order through only when Shopify's
signature matches and the topic is orders/paid: anybody who finds the address
could otherwise send a made-up order and pay a partner for it.
In n8n
- Download
https://boltclaw.ai/referrals/templates/n8n/shopify-order-to-sale.jsonand import it (Import from File). - Shopify Trigger: choose a Shopify Access Token credential (the
store's subdomain, an Admin API access token that can read orders, and the
app's secret key, which the trigger checks every delivery with). It
subscribes to
orders/paiditself when you publish the workflow. - Build the sale: replace
PASTE_YOUR_PROGRAM_IDwith the program's id. - Record the sale: a Header Auth credential, Name
Authorization, ValueBearer bc_live_.... - Publish the workflow.
No Shopify app token? Apps made in Shopify's Dev Dashboard since January
2026 get tokens that last 24 hours, and the trigger needs its token when the
workflow is published. The workflow has a second entry for that: disable
Shopify Trigger, enable Shopify webhook (no app), add an Order
payment webhook in Shopify admin (as in step 3 for Make) pointing at that
node's production address, and put the signing key Shopify shows in Verify
Shopify signature (or in an n8n Variable SHOPIFY_WEBHOOK_KEY).
Test it
Place an order with Shopify's test payments. It arrives with test set, so the
sale is recorded as test data: credited to the program's Test partner,
never paid, never counted, and deleted with Clear test data. Check:
- the run in Make's history, or the execution in n8n, ending with a
201from Bolt Claw; - the sale on the program's conversions, marked Test.
When Shopify delivers the same order again, Bolt Claw answers 200 with
duplicate: true and nothing changes. Test with a real order paid with test
payments rather than Shopify's Send test notification: that sends a sample
order, and a sample not marked as a test would be recorded as a live sale.
What it does not do
Refunds and disputes. Add a second scenario or workflow on Shopify's
refunds/create, sending each refund with its own event_id and the sale's
in refund_of:
{
"program_id": "<your program id>",
"event": "refund",
"event_id": "shopify-refund:1234567890",
"refund_of": "shopify:5432109876543",
"amount": 1000,
"currency": "USD"
}
Or use the app or the Setup tab's webhooks, which handle both.