New to Kestra?
Use blueprints to kickstart your first workflows.
Sync Stripe payments and customers into a PostgreSQL CRM table daily with Kestra. Enriched records, upserts with deduplication, Slack alerts.
Pull Stripe charges and customer profiles, merge them into enriched payment records, and upsert the result into a PostgreSQL CRM table every day. This blueprint replaces manual Stripe CSV exports and ad hoc scripts with a scheduled, idempotent pipeline that builds a queryable payment history for sales reporting, MRR and churn analytics, customer LTV models, and downstream CRM automation. It combines the Stripe REST API, Kestra KV store for incremental state, a Python enrichment step, a PostgreSQL upsert, and a Slack confirmation message into a single declarative YAML flow.
io.kestra.plugin.core.kv.Get reads the stripe_crm_last_sync_ts key from the KV store so the run knows when the previous sync finished.io.kestra.plugin.core.http.Request calls https://api.stripe.com/v1/charges with a created[gte] filter derived from the lookback_hours input, authenticated with the STRIPE_SECRET_KEY secret.io.kestra.plugin.core.http.Request fetches https://api.stripe.com/v1/customers for the same window.io.kestra.plugin.scripts.python.Script (merge_and_enrich) builds a customer lookup map, joins each charge to its customer, and emits enriched records with payment_id, customer_email, amount, currency, status, and metadata.io.kestra.plugin.scripts.python.Script (upsert_to_postgres) creates the crm_payments table if missing and runs INSERT ... ON CONFLICT (payment_id) DO UPDATE via psycopg2 so reruns stay idempotent.io.kestra.plugin.core.kv.Set writes the new stripe_crm_last_sync_ts value.io.kestra.plugin.slack.notifications.SlackIncomingWebhook posts the record count to Slack.io.kestra.plugin.core.trigger.Schedule (daily_sync) runs the whole flow at 0 6 * * * (06:00 UTC).crm_payments PostgreSQL table with one row per Stripe charge, kept fresh with upserts.lookback_hours input for backfills or catch up runs.Stripe does not ship a scheduler, an enrichment runtime, or a Postgres loader. Kestra fills that gap with a declarative YAML flow, native KV state, retries, alerting, full execution lineage, and event or schedule triggers. The same flow can be promoted across dev, staging, and prod without rewriting glue code, and every run produces auditable logs and outputs you can replay.
crm_payments.Configure these as Kestra secrets before the first run:
STRIPE_SECRET_KEY (Stripe REST API bearer token)POSTGRES_HOSTPOSTGRES_DBPOSTGRES_USERPOSTGRES_PASSWORDSLACK_WEBHOOK_URLnamespace if needed.crm_payments table on first run).lookback_hours: 168 to backfill the last week, then let the daily schedule take over.SELECT count(*) FROM crm_payments; to confirm.