Skip to main content
GUIDE · STRIPE9 min read

Forwarding Stripe webhooks to TrackLayer + ad platforms

A production guide for turning Stripe payment and subscription webhooks into durable TrackLayer events that flow into Meta, Google, and other ad platforms with correct value, lifecycle state, and refund adjustments.

Context

Why Stripe webhooks matter for attribution

Subscription attribution breaks when the only event you trust is the browser moment before the customer disappears into hosted checkout. Stripe is where the financially meaningful truth is established: whether the payment actually succeeded, whether the invoice was paid, whether the trial converted, whether the plan changed, and whether revenue later reversed through a refund. When TrackLayer ingests those webhook events directly, ad-platform reporting stops depending on page loads, thank-you pages, or client-side scripts that can be blocked, skipped, or delayed.

That matters even more for recurring-revenue businesses than for one-time commerce. A first purchase is only the start of the value story. Platforms should learn which campaigns create durable subscribers, which channels lead to trial conversions, and which audiences generate renewals instead of churn. Stripe webhooks give TrackLayer the state transitions needed to translate billing events into canonical attribution events, then forward them with proper value weighting into Meta, Google, and any other connected destination.

Requirements

Prerequisites

01

A Stripe account with permission to create webhook endpoints, inspect event deliveries, and run test events from the Dashboard.

02

The Stripe webhook signing secret for the endpoint that will post events into TrackLayer.

03

A TrackLayer API key and access to the TrackLayer settings area where Stripe credentials and verification status are configured.

04

A Shopify storefront or a custom store or app backend that already connects customer identity, checkout context, and downstream ad-platform destinations.

Build

Step-by-step setup

Step 1

Create the Stripe webhook endpoint

In the Stripe Dashboard, add a new webhook endpoint that sends events directly to TrackLayer. This keeps Stripe as the system of record for payment and subscription state while letting TrackLayer normalize the payload into canonical lifecycle events for attribution and audience sync.

Stripe Dashboard → Developers → Webhooks → Add endpoint

Endpoint URL:
https://edge.tracklayer.io/v1/webhooks/stripe

Mode:
Account

Version:
Use your current Stripe API version for the account
Step 2

Subscribe to the revenue and lifecycle events

Choose the event set deliberately. The goal is not to ingest every Stripe event. It is to capture the moments that change attributable revenue, subscription state, or customer value. These events cover checkout completion, recurring billing, renewal success, and refund corrections.

checkout.session.completed
customer.subscription.created
customer.subscription.updated
customer.subscription.deleted
invoice.paid
payment_intent.succeeded
charge.refunded
Step 3

Copy the webhook signing secret into TrackLayer

After Stripe creates the endpoint, reveal the signing secret and store it inside TrackLayer. Signature verification matters because it prevents synthetic webhook traffic from creating false conversions, especially when downstream platforms are using these events for bidding and ROAS calculations.

TrackLayer settings → Sources → Stripe

TRACKLAYER_STRIPE_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxxxxxxxxxx
TRACKLAYER_API_KEY=tl_live_xxxxxxxxxxxxxxxxxxxxx

Verification:
signature = valid
source = stripe
status = active
Step 4

Test delivery with Stripe Event test mode

Use Stripe's test mode to generate representative events before you involve a live subscription. Fire checkout, invoice, and refund events, then watch TrackLayer receive and normalize them. This is the quickest way to confirm the endpoint, secret, and mapping rules are all correct before launch.

Stripe Dashboard → Webhooks → Send test webhook

Test sequence:
1. checkout.session.completed
2. invoice.paid
3. charge.refunded

Expected TrackLayer response:
HTTP 200
{
  "ok": true,
  "source": "stripe",
  "normalized_events": 3
}
Step 5

Verify the TrackLayer events stream

Open the TrackLayer event stream and confirm each Stripe payload becomes the expected canonical event with value, currency, customer ID, and source metadata. Validation should happen before you trust downstream Meta or Google reporting, because mistakes here compound after the events have been forwarded.

{
  "source": "stripe",
  "event": "subscription_renewed",
  "stripe_event": "invoice.paid",
  "customer_id": "cus_Q91rF2L8",
  "subscription_id": "sub_1R8Yd4",
  "value": 129.00,
  "currency": "USD",
  "status": "forwarded"
}
Schema

Event mapping

Stripe event names are implementation detail. TrackLayer event names should stay canonical, stable, and destination-neutral. The value of the bridge is that ad destinations do not need to know whether revenue originated from a session checkout, an invoice, or a subscription mutation. They receive the business event that matters, with the right value and customer context attached.

Stripe eventTrackLayer canonical eventMapping intent
checkout.session.completedcheckout_completedInitial checkout confirmation with customer and order context
customer.subscription.createdtrial_startedNew subscription begins, often with trial metadata
invoice.paidsubscription_renewedRecurring invoice paid, renewals and conversions included
payment_intent.succeededpayment_capturedSuccessful payment capture for one-time or subscription revenue
customer.subscription.updatedsubscription_updatedPlan change, quantity change, paused state, or reactivation
customer.subscription.deletedsubscription_cancelledSubscription ends or is cancelled
charge.refundedrefundNegative revenue correction for attribution and ROAS
Lifecycle

Subscription lifecycle

The most useful subscription bridge is not a flat purchase feed. It is a lifecycle model. A new subscription with a free trial can map to trial_started. The first paid invoice can then map to trial_converted. Every later paid invoice can map to subscription_renewed. If the customer cancels, TrackLayer can emit subscription_cancelled. If they later resume, the next paid event can map to reactivated.

That sequence matters because ad platforms treat those states very differently. A trial start is usually a lower-confidence outcome than a paid conversion, so it should often carry lower value or be optimized separately. A renewal is strong evidence of customer quality and can be sent as a value-bearing repeat conversion. A cancellation is not always forwarded as a standard conversion event, but it can trigger suppression, audience exclusions, or negative lifecycle analysis. Reactivation is often one of the highest-signal events for retention campaigns because it proves the channel can recover dormant revenue, not just acquire net-new signups.

trial_started → trial_converted → subscription_renewed
subscription_cancelled → reactivated

Meta:
StartTrial → Subscribe → Purchase → Custom: Reactivated

Google:
begin_trial → subscribe_paid → renewal_value → reactivation_value
Corrections

Refund handling

Refund handling is where many attribution setups become quietly wrong. If Stripe emits charge.refundedand that event stays trapped inside billing operations, the ad platforms keep credit for revenue that no longer exists. That inflates ROAS, overstates campaign quality, and trains bidding systems on distorted economics. TrackLayer should convert refund events into a negative value adjustment or refund conversion, matched to the original customer and order or subscription identifiers whenever the destination supports it.

In practice this means a customer who paid 499 USD and later received a full refund should not leave a permanent 499 USD positive signal in Meta or Google. The refund event should reduce or reverse that attributed value. Partial refunds should do the same on the refunded amount only. This is especially important for subscription and app businesses with long trial windows, upgrade credits, chargebacks, or support-driven billing reversals. Correct ROAS depends on net revenue, not gross checkout totals.

Usage Pricing

Metered billing

Metered billing creates a second attribution problem: value does not arrive all at once. The first checkout may establish the customer, but meaningful revenue can accumulate later through API usage, seat expansion, overages, or monthly true-ups. When Stripe posts paid invoices that include metered usage, TrackLayer can attribute that value back to the original acquisition source or to the most recent eligible touch model used in your reporting.

That makes the destination event stream far more honest. Instead of optimizing only for initial signups, platforms can receive additional value-bearing renewal or usage events as the account grows. For products with high expansion revenue, this is often the difference between campaigns that look average at signup time and campaigns that are actually driving the best long-term customers.

FAQ

Common questions

Do I still need frontend tracking if Stripe webhooks are connected?

Usually yes for landing-page and pre-checkout behavior. Stripe webhooks do not replace ad-click capture, page views, or lead context. They close the loop on payment truth after checkout and make revenue reporting durable.

Why use invoice.paid instead of only checkout.session.completed?

Because checkout.session.completed mostly captures the first purchase moment. Subscription businesses need renewals, trial conversions, upgrades, and reactivations reflected in attribution. invoice.paid is what turns recurring billing into measurable revenue.

Can TrackLayer distinguish trial starts from paid conversions?

Yes. Trial creation can map to trial_started while the first successful paid invoice can map to trial_converted or subscription_renewed depending on the subscription state transition. That separation is useful for platform optimization and lifecycle reporting.

What happens if Stripe retries the same webhook?

TrackLayer should deduplicate by Stripe event ID and canonical event ID so retries do not create duplicate downstream conversions. This matters because Stripe retries are normal and should not inflate Meta or Google results.

Should refunds be sent back to ad platforms?

Yes when the platform supports conversion adjustments or negative value correction. If you do not propagate refunds, ROAS becomes overstated and bidding models keep optimizing toward revenue that did not stick.

Next reads

Related implementation guides

We use essential cookies to keep the site secure and functional. Analytics and third-party tags run only with your consent. See our Cookie Policy.

We use essential cookies to keep the site secure and functional. Analytics and third-party tags run only with your consent. See our Cookie Policy.