Connect Stripe to Analytiics
Connect Stripe in project settings to import payments, partial refunds and subscription renewals. No webhook or SDK revenue code is needed. Imported Stripe events do not count toward the monthly event cap.
Connect a restricted key
- Open your project's Settings → Stripe revenue and click Create restricted key in Stripe, or open the prefilled Stripe form.
- Choose the correct Stripe account or sandbox. The key is named Analytiics and its read permissions are already selected. Review them, then click Create key and complete any verification Stripe requests.
- Copy the
rk_live_…orrk_test_…key and paste it into Analytiics settings. Click Connect Stripe.
Required permissions: Charges and Refunds, Customers, Events, Payment Disputes, Invoices (including invoice payments), Subscriptions, and Checkout Sessions — all Read; everything else, including Connect permissions, None. The link only prepares the form; Stripe creates the key when you confirm. If the shortcut does not prefill the form, open Stripe API keys, choose Create restricted key, name it Analytiics, and select the permissions above.
Full sk_… secret keys are refused. Keys are encrypted on the server and never returned by the API; settings shows only the mode and last four characters.
The first scheduled sync starts the import. It checks up to 90 days of charges, in pages, with a 5,000-charge limit. Current payments continue syncing during backfill. Settings shows progress, the last successful sync, imported payments, and error categories. Hosted sync is scheduled every five minutes, subject to deployment configuration. Large imports take multiple runs.
Test keys import test data. Use a separate Analytiics project to verify test payments before connecting your live project. Disconnecting stops future imports and deletes the stored key; existing analytics remain. Reconnecting the same account reuses stable payment IDs rather than counting them again. Do not send SDK revenue for payments already imported by this integration.
Credit the channel that brought the customer
Payments count even without attribution, under Unattributed. To connect them to a customer's first visit, identify the user after signup and login:
window.analytiics?.identify(user.id);Use that same opaque user ID in server-side Checkout creation:
const session = await stripe.checkout.sessions.create({
mode: "subscription",
line_items: [{ price: priceId, quantity: 1 }],
client_reference_id: user.id,
subscription_data: {
metadata: { analytiics_user_id: user.id },
},
success_url: successUrl,
cancel_url: cancelUrl,
});For one-time Checkout, omit subscription_data. Checkout metadata analytiics_user_id, subscription metadata, and customer metadata also resolve user IDs. client_reference_id has priority: do not put an order ID there when you expect user attribution. Renewals reuse the saved customer-to-user mapping. Never use an email address or name as the ID.
For a checkout without sign-in, read window.analytiics?.session() in the browser, pass it through your checkout request, and merge it into the Checkout Session's metadata.analytiics_session_id. This read-only getter returns the current session ID without extending its life. An empty ID means attribution is unavailable. Session metadata credits that session's entry source directly; it does not link later purchases from the same customer.
Declare the integration in your tracking plan:
version: 1
project: your-domain.com
integrations: [stripe]
events: {}Run analytiics push. analytiics check warns if a signed-in project's connection and manifest disagree. Install revenue-wire-up with analytiics skills install revenue-wire-up for an agent to make these edits.
Verify and read revenue
analytiics integrations stripe status reads the owner-only status endpoint. payments_30d counts confirmed deliveries; linked_30d counts those carrying a user or session ID. attributed_30d and latest_source verify the source join in analytics. Null means analytics verification was unavailable. Imported rows can take another dashboard cache refresh to appear.
The dashboard shows net revenue per currency, its previous-period comparison, new revenue and renewals by source, and an owner-only list of the latest 100 payments in the selected period. Source and channel filters apply. Browser, page and device filters do not narrow revenue. The existing public Revenue switch controls the revenue KPI and source card; payment-level user IDs remain private even when Revenue is published.
Refunds use their original dates and lower net revenue. Dispute withdrawals lower it and returned dispute funds restore it. Amounts stay separate by currency. The analytics contract stores hundredths: fractional hundredths in three-decimal currencies pause sync with unsupported_currency rather than being rounded. If sync falls behind Stripe's event retention, history_gap requires attention; it does not silently claim a complete import.
For Paddle, Polar, Lemon Squeezy or custom billing, use the server SDK revenue guide. Those manifest-declared events continue to work independently.
Last updated 2026-09-13. This page is also available as Markdown at /docs/stripe.md, or from this URL with Accept: text/markdown.