Integration · Stripe Connect · Churn engine input

Stripe Connect for the Kustiq churn engine.

Available on the Pro plan. Connect Stripe in 4 minutes and Kustiq listens to 11 subscription and invoice events, scores live churn risk on every customer, and writes nothing back to Stripe.

Last updated 2026-05-16Last verified · 2026-05-16v1.1 releaseChangelog
Pro plan onlyOAuth 2.0 · revocableRead-onlyEU + US regionsread_only + customer_readPCI scope · zero PAN
On this page · 11 sections

Overview

The Stripe Connect integration is the input source for Kustiq’s churn engine. It listens to subscription, invoice, and dispute events on your Stripe account and turns them into a live churn-risk score on every paying customer. It does not run Kustiq’s own billing, and it does not run your reporting.

One direction, Stripe to Kustiq. We never call POST, PATCH, or DELETE against your Stripe account. The OAuth token is requested with the read-only Connect role, and the dashboard reflects that scope. 11 event types feed the engine: 5 churn signals, 3 recovery signals, 3 context events. The full list is in the Event reference below.

With the integration on, a customer who hits invoice.payment_failed twice inside 14 days appears at the top of the at-risk segment within 90 seconds. With Stripe alone, the same signal stays in the dashboard event log nobody scrolls.

Setup, in 4 minutes

Five steps. Stripe-side OAuth, no API key paste, no restricted-key creation. The grant is scoped read_only from the consent screen and you can downgrade or revoke it from your Stripe dashboard at any time.

Open Integrations in your Kustiq workspace

~ 20 seconds

From the dashboard, go to Settings → Integrations. Find the Stripe card, click Connect. The Stripe Connect button opens in the same tab.

Authorise the Stripe Connect consent screen

~ 60 seconds

Stripe shows the consent dialog. Pick the account, review the role (read_only), the resources (customer_read, subscription_read, invoice_read, charge_read, dispute_read), click Connect my Stripe account. Stripe redirects back to Kustiq and the integration card flips to Connected.

Choose mode and backfill window

~ 30 seconds

Pick live or test mode and the backfill window: 30 days, 90 days, or all-time. Kustiq pulls past invoices and subscription events for that window so the engine has cohort context on day one. All-time on a 5-year-old account takes 6 to 12 minutes.

Confirm the customer match

~ 1 minute

Kustiq matches Stripe customers to your existing churn-engine profiles by email and domain. The match table shows Stripe customer ID on the left, Kustiq profile on the right, confidence in the middle. Anything below 90% confidence stays unmatched until you review.

Verify in the churn dashboard

~ 30 seconds

Open /dashboard/churn. The at-risk segment populates from the backfill within minutes; the live event stream drives updates from there forward. Median end-to-end latency for a Stripe webhook to a dashboard score change is 90 seconds.

Event reference

11 event types in total. The engine ignores everything else Stripe sends, so an extra event in your account does not cost you anything and does not affect the score.

Churn signals

5 events
  • customer.subscription.deletedChurn
  • customer.subscription.updatedDowngrade
  • customer.subscription.pausedPause
  • invoice.payment_failedDunning
  • charge.dispute.createdDispute

Recovery signals

3 events
  • invoice.payment_succeededRecovered
  • customer.subscription.resumedResumed
  • customer.subscription.updatedUpgrade

subscription.updated appears in two columns; the engine reads previous_attributes.items to decide direction.

Context events

3 events
  • customer.createdProfile
  • customer.updatedProfile
  • invoice.finalizedCycle

Context events do not move the score on their own. They feed cohort and tenure features the score depends on.

Wire Stripe in 4 minutes, churn scores within 90 seconds.

Pro plan ($119/mo). The Stripe Connect integration is included; no per-event fee on usage.

Permissions and scopes

Kustiq requests one Stripe Connect role and five read resources, no more. Every grant is read-only and revocable from Stripe → Settings → Connected apps without contacting support.

  • read_only · the Connect role. Cannot create, update, or delete anything in your Stripe account.
  • customer_read · read customer name, email, metadata. Used for matching and tenure features.
  • subscription_read · read subscription state, plan, cancellation reason, pause schedule.
  • invoice_read · read invoice status, attempt count, amount, currency. Drives the dunning signal.
  • charge_read + dispute_read · read dispute reason and outcome on a charge. Drives the dispute signal.

Kustiq does not request balance_read, transfer_read, payout_read, tax_read, or any write role. If your IT review asks for a written list of what we touch, the six lines above are the answer.

Webhook verification

Kustiq registers one webhook endpoint on your account at connect time. We verify Stripe’s signature on every inbound request before the event hits the engine. The snippet below mirrors how we verify on our side, so you can audit the exact code path.

POST /webhooks/stripe
// Express handler. Use express.raw({ type: "application/json" }).
const stripe = require("stripe")(process.env.STRIPE_SECRET);
const SECRET = process.env.STRIPE_WEBHOOK_SECRET;

function verify(req) {
  const sig = req.headers["stripe-signature"];
  try {
    const event = stripe.webhooks.constructEvent(
      req.body,    // raw bytes, not parsed JSON
      sig,
      SECRET,
    );
    return event;
  } catch (err) {
    // invalid signature, replay, or stale timestamp (> 5 min)
    return null;
  }
}

Retry policy mirrors Stripe. A 5xx response or no response inside 10s triggers exponential backoff (1m, 5m, 30m, 2h, 12h) for up to 24 hours, then the event is marked failed in /dashboard/integrations with the underlying Stripe event ID.

Sync rules

  • Cadence. Real-time via webhook. The backfill runs once on connect; after that, no polling.
  • Direction. One way, Stripe to Kustiq. The integration cannot write, update, refund, or cancel anything on your account.
  • Mode. Live and test grants are separate OAuth connections. Re-run the connect flow on the matching mode if you switch.
  • Match key. Stripe customer email first, customer- metadata kustiq_profile_id override second, domain fallback third. Confidence below 90% never feeds the score.
  • Latency. Median 90 seconds from Stripe webhook to dashboard score change. p95 under 4 minutes.
  • Backfill. 30 / 90 / all-time. Picked once at setup, replayable from /dashboard/integrations.
  • Rate limit.Stripe’s read API limits apply during backfill; live mode caps at 100 req / sec, test mode at 25.

Trust and data handling

This section is the answer to your IT review. What we store, what we never touch, where it lives.

What Kustiq stores, what Kustiq never touches

Kustiq stores only Stripe customer and subscription IDs and aggregate signals derived from the events listed above. No card numbers, no charge tokens, no PII beyond what is needed to match a Stripe customer to a Kustiq profile. Token storage is encrypted at rest with AES-256 and rotated every 6 hours.

What we store
  • +customer.id, subscription.id, invoice.id
  • +Customer email, name (for matching only)
  • +Aggregate signals: status, amount band, attempt count
  • +Encrypted OAuth refresh token
  • +Event ID + timestamp (idempotency)
What we never touch
  • Card numbers (PAN), CVC, full BIN
  • Charge tokens, payment-method tokens
  • Beyond-match PII (address, tax IDs, phone)
  • Bank-account numbers, payouts, balance
  • Anything write-side on your account

Region pinning matches the rest of the platform. EU workspaces route Stripe events through Frankfurt; US workspaces route through Virginia. Cross-region routing is opt-in per workspace and visible from Settings → Region. Full DPA at /dpa, security posture at /trust.

Disconnect

Two paths. From Stripe: Stripe → Settings → Connected apps → Kustiq → Revoke access. From Kustiq: Settings → Integrations → Stripe → Disconnect. Either revokes the OAuth grant within 5 minutes; live webhook delivery stops immediately.

What disconnect does, and what it does not do

Disconnect stops Kustiq from receiving any new event from your Stripe account. Existing churn scores stay on your Kustiq profiles until you delete them or reconnect; backfilled history is preserved so you can re-enable without losing context.

Stripe-side data is untouched. Disconnecting from either side does not delete, archive, or modify anything in your Stripe account. Customers, subscriptions, invoices, charges, and disputes remain exactly as they were. To purge data Kustiq retained, use Settings → Data → Erase Stripe-derived signals or email support.

Troubleshooting

Ten known states. Each has a stable anchor so you can link a teammate to the exact row.

ERR_ST_401

OAuth grant revoked by Stripe #

The Stripe-side admin revoked the connected app, or the access token expired without a successful refresh. Reconnect from Settings → Integrations. Past scores stay; no Stripe data is lost.

ERR_ST_403

Connect role downgraded below read_only #

The grant was changed to a custom Connect role that no longer includes read on subscriptions or invoices. Restore the read_only role, or re-run OAuth from Kustiq.

ERR_MODE_MISMATCH

Live webhook signed with test secret #

You connected the test account but the workspace is set to live, or vice versa. Disconnect, reconnect on the matching mode. Test events never move live scores.

ERR_ST_429

Stripe rate-limit during backfill #

Another integration on the same Stripe account is consuming the read budget. Kustiq pauses the backfill, retries on the schedule above. No action needed unless backfill stalls past 12 hours.

ERR_MATCH_LOW

Customer match confidence under 90% #

The Stripe customer has no email and no kustiq_profile_id on metadata. Add the metadata key in Stripe, or set the email, then run a manual rematch from /dashboard/integrations.

ERR_WEBHOOK_SIG

Webhook signature mismatch #

The endpoint secret in our store drifted from Stripe’s. This happens after a Stripe-side rotate. Press Rotate secret in /dashboard/integrations to refresh both ends.

ERR_WEBHOOK_STALE

Webhook timestamp older than 5 minutes #

Server clock drift. Sync the host with NTP. Stripe’s t= timestamp is always in UTC seconds.

ERR_REGION_MISMATCH

Workspace region differs from Stripe account region #

An EU workspace can connect a US Stripe account, but the data crosses regions. Move the workspace from Settings → Region, or accept the cross-region note shown at connect time.

ERR_PLAN_REQUIRED

Stripe integration requires Pro #

The Stripe Connect integration is gated to Pro ($119/mo). Upgrade from /pricing#pro; existing OAuth grants resume automatically.

ERR_ACCT_RESTRICTED

Stripe account in restricted state #

Stripe restricted the account (KYC pending, payouts paused, or under review). Read access on subscriptions can be denied. Resolve the restriction in Stripe; sync resumes within 10 minutes.

FAQ

Is this the same Stripe integration that handles my Kustiq subscription?
No. This page covers Stripe Connect as a read-only data source for the churn engine. For your own Kustiq subscription, invoices, or card on file, see /docs/billing and the Stripe customer portal. The OAuth grants are distinct, even when both use the same Stripe account.
Which Stripe events does Kustiq listen to?
11 types: 5 churn signals (subscription deleted / updated / paused, invoice payment failed, dispute created), 3 recovery signals (invoice payment succeeded, subscription resumed, subscription updated), and 3 context events (customer created, customer updated, invoice finalized). The full list is in the Event reference above.
Does Kustiq write anything to Stripe?
The OAuth grant is read_only by design, so Kustiq cannot create, update, refund, cancel, or disable any object on your Stripe account. If you need a write integration, build a workflow on your side that reads our churn-event webhook.
Where does the Stripe data live?
EU workspaces store in Frankfurt, US workspaces store in Virginia. Refresh tokens are encrypted at rest with AES-256, rotated every 6 hours. Pick your region in Settings → Region before first connect; moving regions is a manual support request.
Is the Stripe integration available on the free tier?
Free workspaces enrich 3 profiles a week and the Stripe integration stays disabled. The integration is available on the Pro plan ($119/mo). Insight ($39/mo) keeps it locked because the churn engine is Pro-only.
What happens to the data Kustiq stored if I disconnect?
Past churn scores and matched profile IDs stay on your Kustiq workspace until you erase them. Disconnect stops new events from flowing in; it does not retroactively wipe history. Use Settings → Data → Erase Stripe-derived signals to purge.
Does the integration touch any card data?
Card numbers (PAN), CVC, BIN, charge tokens, and payment-method tokens are out of scope. Stripe never sends them on the events Kustiq subscribes to, and Kustiq does not request the resources that contain them. The Trust and data handling section above lists the full inventory.

Changelog

  • 2026-05-16 · v1.1 Pair-lock production-ready audit. BreadcrumbList position-1 fixed to “Home”. SoftwareApplication JSON-LD @id-graph linked to root #org and #site. New per-page OG image at /docs/stripe/opengraph-image. FAQ trust-card reference converted to anchor link. Free-tier copy unified to 3 profiles a week. Eleven → 11 numeric consistency.
  • 2026-05-08 · v1.0 Initial release. Disambiguation banner against billing-docs collision. Pro-plan link on the lede. Trust section above Disconnect. Footer cross-link row. Last-verified badge.
  • 2026-04-24 · v0.9 Backfill window picker added (30 / 90 / all-time). Customer match confidence raised from 80% to 90%.
  • 2026-03-11 · v0.7 11th event added: charge.dispute.created. Dispute signal feeds the score with a 7-day decay.
  • 2026-01-29 · v0.5 Test-mode wiring split out from live mode. Test events no longer affect live scores.
  • 2025-12-04 · v0.1 Closed beta with three design partners.
Ship it · Pro plan

Stripe wired. Engine scoring within 90 seconds.

4-minute OAuth connect, read-only by design. The integration backfills 30, 90, or all-time history on the first run. Available on the Pro plan ($119/mo).