Stripe Integration

Automatically track revenue and attribute it to the visitors who converted.

Overview

The Stripe integration connects your Stripe account to Ripples so you can:

  • See revenue attributed to each visitor and their acquisition source
  • Track charges, subscriptions, and invoices automatically
  • Backfill historical payment data when you first connect
  • Handle refunds (negative revenue events are created automatically)

Revenue events appear in the visitor timeline and contribute to each profile’s lifetime revenue total.

Prerequisites

Before connecting Stripe, make sure you have:

  1. Persist mode enabled — Ripples uses a cookie (_rpl_vid) to track visitors across sessions. This is the default behavior.
  2. User identification — Call ripples.identify() when users sign in so we can match Stripe charges to visitor profiles by email.
// Call this after login / signup
ripples.identify({
  id: "user_123",
  email: "[email protected]",
  name: "Jane Doe",
  plan: "pro",
})

Create a Restricted API Key

We recommend using a restricted API key with minimal permissions rather than your secret key.

  1. Go to Stripe Dashboard → API Keys
  2. Click “Create restricted key”
  3. Give it a name like Ripples Metrics
  4. Set the following permissions to Read:
PermissionAccess
ChargesRead
CustomersRead
Checkout SessionsRead
SubscriptionsRead
InvoicesRead
Webhook EndpointsWrite

The Webhook Endpoints: Write permission allows Ripples to automatically create a webhook in your Stripe account to receive payment events in real-time.

  1. Click “Create key” and copy the key (it starts with rk_live_ or rk_test_)

Connect in Settings

  1. Open your project dashboard in Ripples
  2. Click the Integrations link in the header
  3. Find the Stripe card and click Connect
  4. Paste your restricted API key and click Connect

Once connected, Ripples will:

  • Create a webhook endpoint in your Stripe account automatically
  • Begin importing your historical charges (backfill)
  • Start receiving new payment events in real-time

Revenue Attribution

Ripples uses a 3-tier fallback to attribute each Stripe payment to a visitor:

Tier 1: Checkout Metadata (Best)

Pass the visitor ID directly in your Stripe Checkout session metadata. This gives the most accurate attribution because it directly links the payment to the browsing session.

// Next.js (Server-side)
import { cookies } from "next/headers"
import Stripe from "stripe"

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY)

export async function createCheckout() {
  const cookieStore = await cookies()
  const visitorId = cookieStore.get("_rpl_vid")?.value

  const session = await stripe.checkout.sessions.create({
    metadata: { ripples_visitor_id: visitorId },
    // ... other checkout options
  })
}
// Vanilla JavaScript (Client-side)
// Get visitor ID from the Ripples SDK
const visitorId = ripples.getVisitorId()

// Send to your server when creating a checkout session
const res = await fetch("/api/checkout", {
  method: "POST",
  body: JSON.stringify({ visitorId }),
})
// Laravel (Server-side)
use Stripe\StripeClient;

$visitorId = $request->cookie('_rpl_vid');
// or from frontend: $request->input('visitorId')

$stripe = new StripeClient(config('services.stripe.secret'));

$session = $stripe->checkout->sessions->create([
  'metadata' => ['ripples_visitor_id' => $visitorId],
  // ... other options
]);

Your own user id

If you already know the user when you create the checkout session or the subscription, put your user id in its metadata as ripples_user_id (the same id you pass to identify()). It beats every other tier: it still matches when the billing email differs from the login email (a finance@ address on a company card), and it carries over to every renewal, which ripples_visitor_id cannot do because invoices don’t carry checkout metadata.

$stripe->subscriptions->create([
    'customer' => $customerId,
    'items' => [['price' => $priceId]],
    'metadata' => ['ripples_user_id' => (string) $user->id],
]);

Ripples reads it from charges, checkout sessions, subscriptions and invoices (including the subscription metadata Stripe copies onto each invoice).

Tier 2: Email Matching (Automatic)

If Tier 1 metadata is not present, Ripples matches the Stripe customer email to a visitor profile. This works when you have called ripples.identify() with the user’s email.

No extra setup needed — this happens automatically.

Tier 3: Customer ID (Returning Customers)

For subsequent payments, Ripples remembers the Stripe customer ID from previous attributions. If a customer was attributed once (via Tier 1 or 2), all future payments from that customer are automatically attributed to the same visitor.

Events Tracked

The following Stripe events are processed:

Stripe EventRipples EventDescription
charge.succeededCharge SucceededOne-time or first-time payment
charge.refundedCharge RefundedOne negative revenue row per refund, for that refund's amount (partial refunds included)
checkout.session.completedCheckout CompletedCheckout with Tier 1 attribution
invoice.paidInvoice PaidRecurring subscription payment
customer.subscription.created(no event)New subscription: updates MRR, plan and subscription status
customer.subscription.updated(no event)Plan change / upgrade: updates MRR and plan
customer.subscription.deleted(no event)Cancellation: removes it from MRR, marks the customer churned

MRR Tracking

Ripples automatically calculates your Monthly Recurring Revenue (MRR) from Stripe subscriptions. Subscription amounts are extracted from webhook events and normalized to monthly (yearly plans are divided by 12, etc.).

MRR updates automatically when subscriptions are created, upgraded, downgraded, or canceled. No configuration needed. Subscriptions in a trial are not counted in MRR until they turn active; they are shown beside it. Each subscription is converted to your project currency.

One Stripe Account, Several Products

A single Stripe account often bills more than one product — two apps sold from the same account, or a product that has since moved to its own account but left its old subscriptions renewing on the first one. By default Ripples books every payment on the account against the project that connected the key, so the other product’s revenue and MRR show up here.

Tell Ripples which products are not yours:

  1. Open Integrations settings and click Products on the connected Stripe card
  2. Paste the Stripe price or product ids that belong to another project — one per line
  3. Click Save

Their charges, checkouts, invoices and subscriptions are skipped from then on, so they never reach this project’s revenue, its subscription/one-time split, or its MRR. A price id covers that one price; a product id covers every price under it.

A payment that mixes an ignored product with one of yours is still recorded in full — Ripples never drops revenue it cannot cleanly separate.

This applies to new events only. Use Re-sync afterwards to re-import historical payments with the filter applied.

Historical Backfill

When you first connect Stripe, Ripples automatically imports all your historical charges and refunds and attributes them using the same 3-tier fallback, so a refunded payment nets to zero. Active subscriptions are also synced to update visitor plan fields and populate MRR data.

You can check the backfill status on the Integrations settings page. If needed, use the Re-sync button to clear and re-import all data.

Deduplication

Ripples automatically prevents duplicate revenue events:

  • Each Stripe charge, invoice, checkout session and refund is tracked by its unique ID
  • Webhook retries and backfill re-runs are automatically deduplicated
  • If you use the Stripe integration, you do not need to send revenue events from the frontend SDK — Stripe handles it automatically

Disconnecting

To disconnect the integration, go to Integrations settings and click Disconnect on the Stripe card. You can choose to keep or remove the imported revenue data.