The Stripe integration creates a GraphJSON-managed webhook destination and forwards Stripe event objects into a collection you choose.
Connect Stripe#
- Create the destination collection, such as
stripe_events. - Open Integrations.
- Choose Stripe and connect the intended Stripe account.
- Select Create Webhook.
- Choose the GraphJSON collection.
- 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 asinvoice.paid - the
createdtime - 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.completedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedinvoice.paidinvoice.payment_failedcharge.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:
- inspect that exact event type
- record its unit and null behavior
- include a provider event ID
- keep a regression query
- 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
createdtime 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:
- confirm Stripe is producing the expected event
- inspect the managed event destination in Stripe
- record the last successful Stripe event ID
- confirm GraphJSON collection and workspace
- trigger one safe test-mode event
- reconnect only after recording any live-mode gap
Recover missing history#
Recreating a destination does not necessarily replay earlier Stripe events.
For a gap:
- define exact start and end times
- export or list the required Stripe events through an approved server-side process
- preserve each Stripe event ID and
createdtime - import into a controlled collection or through the documented migration path
- deduplicate against events already received
- 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:
- choose a fixed date range and time zone
- group by currency
- deduplicate by Stripe event ID
- compare the total with Stripe
- 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.