Connect Stripe to Snowflake
Land Stripe in Snowflake so finance and analytics model revenue on the same data. Charges, invoices, subscriptions, refunds, and payouts load from the event stream with a historical backfill, amounts are normalized out of integer minor units, and each payout is tied to the balance transactions inside it. Every batch is an ordered run.
Why teams connect Stripe and Snowflake
Stripe holds the payments. Snowflake is where revenue, retention, and cohort analysis happen. Exporting CSVs from the Stripe dashboard gives you a snapshot with no history of state changes, amounts in cents, and no link between a payout and the transactions that made it up.
- Objects load from the event stream, so you keep every state change (a subscription that went past due then recovered), not just the current row
- A historical backfill walks the API once at setup so the warehouse has data from before the integration existed
- Amounts are normalized to major units and currency-tagged, so an analyst never divides by 100 or trips over a zero-decimal currency
- Each payout is joined to its balance transactions, so "what was in the deposit" is a query, not a support ticket
Worked example
The revenue-warehouse flow, backfill then stream.
Stripe objects loaded into Snowflake from events, with a backfill and a reconcile
One-time backfill, then continuous event load, plus a daily reconciliation pass.
- Backfill: at setup, page the Stripe API for charges, invoices, subscriptions, customers, and payouts over the chosen history window and load each to its Snowflake table.
- Trigger: Stripe
Event receivedfor the configured types (charge.*,invoice.*,customer.subscription.*,payout.*), carrying the full object. - Normalize: divide
amountfields by the currency's minor-unit factor, keep the raw value too, and add the ISO currency code as its own column. - Upsert: merge each object into its table keyed on the Stripe ID, keeping a row per version with
_valid_fromso state history is preserved. - Payout join: on
payout.paid, list the balance transactions and load them tostripe_balance_transactionswith the payout ID, so deposits reconcile in SQL. - Reconcile: a daily flow compares Snowflake row counts and sums against the Stripe reporting API for the prior day and alerts on any drift.
Field mapping
The starting map for a Stripe charge to the Snowflake table.
| Stripe | Snowflake | Notes |
|---|---|---|
charge.id | CHARGE_ID (merge key) | Idempotency key. Merge, not insert, so a redelivered event updates the row. |
charge.amount (integer) | AMOUNT (NUMBER(38,4)) + AMOUNT_MINOR | Currency gotcha: divide by 100, or by 1 for zero-decimal currencies like JPY. Both forms kept. |
charge.currency | CURRENCY (STRING) | ISO 4217, uppercased. Drives the minor-unit factor. |
charge.created (Unix) | CREATED_AT (TIMESTAMP_TZ) | Epoch seconds to timestamp, UTC. |
charge.customer | CUSTOMER_ID | Foreign key to stripe_customers. Null for a guest charge. |
charge.metadata | METADATA (VARIANT) + promoted columns | Override: teams that put an internal order ID or account ID in metadata promote it to a typed column for joins. |
charge.balance_transaction | BALANCE_TXN_ID | Links the charge to the payout via stripe_balance_transactions. |
| (event id + version) | _EVENT_ID, _VALID_FROM, _LOADED_AT | Lineage and slowly-changing history. |
What syncs, each direction
- Transactions. Charges, refunds, disputes, and balance transactions, loaded from events with amounts normalized. (Stripe to Snowflake)
- Billing. Invoices, subscriptions, subscription items, and price changes, with a row per state so churn and expansion are queryable. (Stripe to Snowflake)
- Payouts. Each payout and the balance transactions inside it, so deposits reconcile to the bank in SQL. (Stripe to Snowflake)
- Backfill and reconcile. A one-time history load and a daily count-and-sum check against the Stripe reporting API. (Stripe to Snowflake)
Governance and audit
The same controls apply to this sync as to every other Neblex workload.
- Ordered run log. Every batch records the event IDs, the objects touched, and the Snowflake load result. The daily reconcile is logged with the compared figures.
- Reconciliation check. A drift between the warehouse and the Stripe reporting API alerts rather than sitting undiscovered until a board meeting.
- Scoped access. Stripe uses a restricted API key with read on the object types in scope, no write. Snowflake uses a role with write on the finance database only.
- Environments. Backfill from Stripe test mode into a scratch schema, verify the reconcile, then switch to the live key and the production schema.
Frequently asked questions
How is this different from the Stripe Data Pipeline or Fivetran?
Stripe Data Pipeline (the native Snowflake share) is excellent if you want exactly Stripe's schema and are on a plan that includes it. Fivetran is a solid managed connector. Neblex fits when you want control over the schema, amounts normalized your way, a reconciliation check you can see, state history modeled how you want, and the same run log as your other pipelines.
Do I keep history of subscription changes?
Yes. Objects load from events with a row per version and a _valid_from, so a subscription that went past due and recovered shows both transitions, not just the latest state.
How are amounts handled?
Stripe sends integer minor units. The flow loads both the raw value and a major-unit NUMBER, and tags every row with its ISO currency, including zero-decimal currencies.
Can I reconcile payouts to my bank?
Yes. Each payout is loaded with its balance transactions keyed by payout ID, so "what was in this deposit and what were the fees" is a single query.
What about a redelivered Stripe event?
Every write is a merge keyed on the Stripe object ID, and the event ID is recorded, so a redelivered event updates in place and never double-loads.
How far back can it backfill?
As far as the Stripe API allows for each object type. The backfill is chunked and logged, and the event stream picks up from the backfill's end with no gap.
Connectors on this page
Stripe
Payments
- Operations
- 589
- Typed outputs
- 99.7%
- Change triggers
- 10 (webhook)
- Authentication
- Bearer
Snowflake
Snowflake
- Operations
- 7
- Typed outputs
- 85.7%
- Change triggers
- Poll or inbound webhook
- Authentication
- ConnectionString
Bring one real integration
We will build it with you against your own systems, with the run log open.