Skip to main content
Stripe → PostgreSQL

Sync Stripe to PostgreSQL
on the schedule you set.

Pipe Stripe customers, charges, payment intents, invoices, subscriptions, products, prices, and refunds into PostgreSQL — described in plain English. Scheduled batch on the cadence you set, idempotent by Stripe ID. The Stripe connector is in preview on rsync.ai Cloud; self-hosting is available now.

TL;DR

rsync.ai's Stripe connector calls the REST API (paginated with `starting_after` cursor) for Customers, Charges, PaymentIntents, Invoices, Subscriptions, Products, Prices, and Refunds. It runs on the schedule you set, reading new records by created time (or re-reading in full for subscriptions, products, prices and refunds) and upserting them by Stripe ID, so every run is idempotent. Stripe metadata lands in JSONB. Works with PostgreSQL 12+, RDS, Aurora, Cloud SQL, Supabase, and Neon.

  • Scheduled batch with cursor pagination, on the cadence you set
  • Idempotent upserts by Stripe ID — safe to re-run
  • Stripe metadata stored as JSONB, ready for ->> queries and GIN indexes
  • PII column masking before the PostgreSQL write
  • Self-host in your own VPC — source-available under the rsync.ai Source-Available License
How it works

How to sync Stripe to PostgreSQL — 5 steps

From restricted API key to rows in PostgreSQL — under 10 minutes. Once the data lands, query it in the SQL Explorer or with Ask rsync.ai, shape it with Models, and publish Charts and Dashboards.

  1. 1

    Generate a Stripe restricted API key

    In the Stripe Dashboard, go to Developers → API keys → Create restricted key. Grant read-only access to: Charges and Refunds, Customers, Subscriptions, Invoices, PaymentIntents, Products, and Prices. A restricted key limits the blast radius if credentials are ever leaked. Copy the `rk_live_…` key — rsync.ai never uses your secret key.

    rk_live_… (restricted, read-only)
  2. 2

    Connect your PostgreSQL database

    Provide host, port, user, password, and database name — or paste a connection string. rsync.ai supports PostgreSQL 12+, Amazon RDS for PostgreSQL, Amazon Aurora PostgreSQL, Google Cloud SQL for PostgreSQL, Azure Database for PostgreSQL, Supabase, and Neon. SSL mode `require` is the default.

    postgresql://user:pass@host:5432/db
  3. 3

    Describe the sync in plain English

    Type what you want: 'Sync Stripe charges, customers, subscriptions to PostgreSQL every 5 minutes.' rsync.ai discovers the Stripe resources you've granted access to, estimates record counts, and proposes PostgreSQL tables with the right column types — `BIGINT` for Stripe amounts (cents), `TIMESTAMPTZ` for Unix timestamps, `JSONB` for metadata and nested objects.

    No SQL · No YAML · No DAGs
  4. 4

    rsync.ai discovers resources and proposes schema

    rsync.ai calls the Stripe API list endpoints (paginated via `starting_after` cursor) to sample your data, infers column types, and generates a `CREATE TABLE` statement for each resource. Stripe metadata fields (arbitrary key-value pairs) land in a `metadata JSONB` column. Nested objects like `payment_method_details` are stored as JSONB by default, with optional column-extraction for common fields.

    Auto type inference · JSONB for metadata
  5. 5

    Approve schema and pipeline runs on schedule

    Review and approve the proposed PostgreSQL DDL. The pipeline runs on the cadence you set. rsync.ai uses scheduled batch sync with cursor pagination: on each run it pages through the Stripe REST API (via the `starting_after` cursor). Customers, invoices, charges and payment intents are read incrementally by created time; subscriptions, products, prices and refunds are re-read in full. Rows are upserted by Stripe ID on every run, so retries are idempotent.

    Scheduled batch with cursor pagination · idempotent upserts

Stripe → PostgreSQL schema mapping

Standard mapping rsync.ai proposes. Customize column names, types, JSONB extraction, and PII masking before approving. Customers, charges, payment intents and invoices are read incrementally by created time; subscriptions, products, prices and refunds are re-read in full each run.

Stripe resourcePostgreSQL tableNotes
Customercustomersemail, name, phone stored; PII columns flagged for optional masking.
Chargechargesamount in cents (BIGINT), currency, status, failure_code, payment_method_details (JSONB).
PaymentIntentpayment_intentsamount, currency, status, last_payment_error (JSONB), metadata (JSONB).
Subscriptionsubscriptionscurrent_period_start/end as TIMESTAMPTZ, items (JSONB), discount (JSONB).
Invoiceinvoicesamount_due, amount_paid, lines (JSONB), hosted_invoice_url.
ProductproductsRe-read in full on each run.
PricepricesRe-read in full on each run.
RefundrefundsRe-read in full on each run.

rsync.ai vs. Fivetran, Airbyte, Zapier for Stripe → PostgreSQL

What you give up — and gain — choosing rsync.ai.

Featurersync.aiyouFivetranAirbyteZapier
Plain-English pipeline setup
Scheduled Stripe → PostgreSQL sync
Source-available connector code
Stripe metadata stored as JSONB
Self-host in your own VPC
No per-MAR / per-row / per-task pricing
PII column masking before the PostgreSQL write

Stripe to PostgreSQL — frequently asked

How does rsync.ai stay within Stripe API rate limits?

The Stripe REST API allows up to 100 list requests per second in live mode. rsync.ai paginates with `starting_after` cursor (up to 100 objects per page) and respects HTTP 429 responses with exponential backoff. For most use cases — a few hundred thousand Stripe objects synced every 5 minutes — you'll be well within limits. For very large accounts (millions of charges), rsync.ai runs incremental syncs with the `created` filter for customers, invoices, charges and payment intents, so only new objects are fetched.

How does rsync.ai guarantee idempotency when syncing Stripe data?

Every Stripe object has a globally unique string ID (e.g. `ch_3OxY…`, `cus_9MZ…`). rsync.ai uses these as the PostgreSQL primary key and performs `INSERT … ON CONFLICT (id) DO UPDATE SET …` on every sync run. This means re-running the same sync — or retrying after a failure — never creates duplicate rows.

How fresh is the synced Stripe data?

rsync.ai runs on the schedule you set — as frequently as every minute or as slow as daily. On each run it pages through the Stripe REST API with the `starting_after` cursor and upserts by Stripe ID. Subscriptions, products, prices and refunds are re-read in full, so a subscription cancelling shows up on the next run. Customers, invoices, charges and payment intents are read by created time, so new objects arrive on the next run, but later edits to an existing object are not picked up by an incremental run. Every run is idempotent: reruns never create duplicate rows.

How does rsync.ai handle Stripe metadata in PostgreSQL?

Stripe's metadata field is an arbitrary key-value map (up to 50 keys, 500 chars per value). rsync.ai stores it as a `JSONB` column on each table, enabling rich querying with PostgreSQL's `->` and `->>` operators and GIN indexes. If you have consistent metadata keys across objects (e.g. `metadata->>'internal_id'`), you can add a generated column or a partial index in the DDL approval step.

Does syncing Stripe data to PostgreSQL bring card data into PCI scope?

rsync.ai never handles raw card numbers or CVVs — Stripe tokenizes these at the source and they are never present in the API responses rsync.ai reads. The data that does flow (amounts, last-4 digits, card brand, billing details) is sensitive customer and financial data you should protect accordingly. Whether it changes your PCI scope depends on how you store and use it, so confirm with your QSA.

Can I exclude customer PII from the PostgreSQL sync?

Yes. In the column configuration step you can exclude a column (it is dropped before the write to PostgreSQL) or mask it (hashed, redacted or partially masked before the value is written). Stripe's list endpoints return full objects, so exclusion and masking happen in rsync.ai's processing layer, not in the Stripe request. Fields such as `email`, `phone`, `name` and `address` on the Customer object are good candidates to exclude.

Can I run rsync.ai on my own infrastructure?

rsync.ai Cloud is live today at app.rsync.ai — nothing to deploy. You can self-host the full stack today — one command (`curl -sSL https://raw.githubusercontent.com/rsync-ai/rsync.ai/main/install.sh | bash`) brings it up inside your own VPC — the Stripe connector, the PostgreSQL writer, the control plane, and the Workspace UI all in your environment — so your Stripe restricted API key and PostgreSQL credentials never leave your network. rsync.ai is source-available under the rsync.ai Source-Available License: self-hosting is free for your company's own internal use, while reselling it or hosting it for others as a service needs a commercial license.

How does rsync.ai pricing compare to Fivetran or Zapier for Stripe → PostgreSQL?

Fivetran prices on Monthly Active Rows and Zapier on tasks, so their cost follows how many rows or events change. rsync.ai has no per-row or per-MAR fees: Cloud starts free (the first 10 GB of data moved), then bills by GB moved, and pipelines pause at your cap. The Stripe connector is in preview. You can also self-host rsync.ai, which is source-available under the rsync.ai Source-Available License and free for your company's own internal use, and pay only for the compute you run it on.

Run your first Stripe to PostgreSQL pipeline free

The first 10 GB of data moved is free. Describe the sync in plain English and review the plan before anything runs. The Stripe connector is in preview.

Start free