DocsIntegrations

Integrations

Stripe

4 min readReviewed July 2026

The Stripe integration creates a GraphJSON-managed webhook destination and forwards Stripe event objects into a collection you choose.

Connect Stripe#

  1. Create the destination collection, such as stripe_events.
  2. Open Integrations.
  3. Choose Stripe and connect the intended Stripe account.
  4. Select Create Webhook.
  5. Choose the GraphJSON collection.
  6. Complete the connection and trigger a Stripe test event.

GraphJSON registers a webhook for Stripe events and uses the event’s created value as the GraphJSON event timestamp.

Verify the first event#

Open the destination collection and select Samples. Look for:

  • the Stripe event id
  • the event type, such as invoice.paid
  • the created time
  • the object under data.object
  • account or customer identifiers you will use in analysis

GraphJSON flattens nested fields by default. A property may appear as:

data.object.customer
data.object.amount_paid
data.object.currency

Use the exact field names shown in Samples.

Build a revenue query#

Provider event shapes vary by type. For an invoice.paid workflow, inspect a real payload and adapt:

SELECT
  JSONExtractString(json, 'data.object.currency') AS currency,
  sum(JSONExtractFloat(json, 'data.object.amount_paid')) AS paid_minor_units
FROM stripe_events
WHERE
  JSONExtractString(json, 'type') = 'invoice.paid'
  AND toDateTime(timestamp) >= subtractDays(now(), 30)
GROUP BY currency
ORDER BY paid_minor_units DESC

Stripe amounts are commonly represented in the currency’s minor unit. Confirm the meaning for the specific object and currency before displaying or combining the value.

Handle webhook realities#

Webhook delivery systems can retry and may deliver events more than once. Use Stripe’s event id to deduplicate metrics that must be exact:

WITH invoices AS (
  SELECT
    JSONExtractString(json, 'id') AS event_id,
    argMax(
      JSONExtractFloat(json, 'data.object.amount_paid'),
      timestamp
    ) AS amount_paid
  FROM stripe_events
  WHERE JSONExtractString(json, 'type') = 'invoice.paid'
  GROUP BY event_id
)
SELECT sum(amount_paid)
FROM invoices

Do not assume delivery order represents object state order. For current subscription state, group by the subscription ID and use the source object’s relevant creation or update field when available.

Select useful events#

Raw provider events are valuable for audit and exploration but can be broad. Focus dashboards on a documented set:

  • checkout.session.completed
  • customer.subscription.created
  • customer.subscription.updated
  • customer.subscription.deleted
  • invoice.paid
  • invoice.payment_failed
  • charge.refunded

The right set depends on your Stripe integration. Verify every event’s semantics in Stripe’s official event types reference.

Separate test mode and live mode#

Stripe test events and live financial events must not silently feed one production metric.

Inspect the stored payload for the provider’s livemode field and enforce the intended mode in saved queries. Prefer separate GraphJSON collections or workspaces when testing needs strict isolation.

Test-mode reconciliation proves the connection works. It does not prove a live financial dashboard matches settled billing.

Handle API-version and object drift#

Stripe event objects reflect provider versioning and the event type’s object shape. A field present on invoice.paid is not automatically present or equivalent on checkout.session.completed.

Before depending on a field:

  1. inspect that exact event type
  2. record its unit and null behavior
  3. include a provider event ID
  4. keep a regression query
  5. monitor missing-field counts

For a stable cross-provider metric, transform Stripe events in your billing service and emit a normalized fact to a separate collection.

Do not combine raw Stripe events and normalized copies without a documented deduplication boundary.

Monitor the destination#

Keep both views:

  • Stripe destination delivery status
  • GraphJSON collection health

Monitor:

  • last Stripe created time observed
  • unique event IDs by type
  • duplicate deliveries
  • unknown event types
  • live/test mode
  • missing customer or subscription IDs
  • event volume by type

If delivery stops:

  1. confirm Stripe is producing the expected event
  2. inspect the managed event destination in Stripe
  3. record the last successful Stripe event ID
  4. confirm GraphJSON collection and workspace
  5. trigger one safe test-mode event
  6. reconnect only after recording any live-mode gap

Recover missing history#

Recreating a destination does not necessarily replay earlier Stripe events.

For a gap:

  1. define exact start and end times
  2. export or list the required Stripe events through an approved server-side process
  3. preserve each Stripe event ID and created time
  4. import into a controlled collection or through the documented migration path
  5. deduplicate against events already received
  6. reconcile by event type, currency, and authoritative billing totals

Do not manually resend an unbounded history from a browser session.

Reconcile#

Before relying on a revenue dashboard:

  1. choose a fixed date range and time zone
  2. group by currency
  3. deduplicate by Stripe event ID
  4. compare the total with Stripe
  5. document refunds, disputes, taxes, and failed payments included or excluded

GraphJSON does not replace Stripe as the financial system of record.

Disconnect#

Use the GraphJSON Stripe integration page to remove managed webhooks, and confirm the destination is gone in Stripe. Stripe’s current dashboard calls webhook endpoints “event destinations”; see Stripe’s webhook endpoint guide.

For a normalized billing contract, recurring revenue queries, and finance reconciliation boundaries, use the Revenue and subscription analytics reference architecture.

Use Operate managed integrations for shared monitoring, incident, reconnection, and retirement procedures.

Need a hand?

Tell us what you’re building and we’ll point you in the right direction.

Contact support