Complete guide for stripe-sync-engine in one skill. Use when the user wants to "sync stripe to database," "stripe-sync-engine," "stripe postgres sync," or needs a quick all-in-one reference.
Stripe Sync Engine - Complete Guide
You are an expert in stripe-sync-engine. This skill covers setup, migrations, webhooks, backfill, and querying in one place.
1. Installation
npm install stripe-sync-engine stripe pg
2. Environment Variables
DATABASE_URL=postgresql://user:password@host:5432/database
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
3. Create StripeSync Utility
// lib/stripeSync.ts
import { StripeSync } from "stripe-sync-engine";
export const stripeSync = new StripeSync({
stripe: { apiKey: process.env.STRIPE_SECRET_KEY! },
webhookSecret: process.env.STRIPE_WEBHOOK_SECRET!,
databaseUrl: process.env.DATABASE_URL!,
});
4. Run Migrations
// scripts/run-migrations.ts
import { stripeSync } from "../lib/stripeSync";
async function main() {
await stripeSync.runMigrations();
console.log("Migrations complete");
process.exit(0);
}
main();
npx tsx scripts/run-migrations.ts
5. Webhook Handler
Next.js App Router:
// app/api/webhooks/stripe/route.ts
import { NextResponse } from "next/server";
import { stripeSync } from "@/lib/stripeSync";
export async function POST(request: Request) {
const signature = request.headers.get("stripe-signature") ?? undefined;
const payload = Buffer.from(await request.arrayBuffer());
await stripeSync.processWebhook(payload, signature);
return NextResponse.json({ received: true });
}
Hono:
app.post("/webhooks/stripe", async (c) => {
const signature = c.req.header("stripe-signature");
const payload = await c.req.text();
await stripeSync.processWebhook(payload, signature);
return c.json({ received: true });
});
6. Backfill Historical Data
// Backfill all data types
await stripeSync.syncBackfill();
// Backfill specific types
await stripeSync.syncBackfill({
objectTypes: ["customer", "subscription", "invoice"],
});
// Backfill with date range
await stripeSync.syncBackfill({
created: { gte: Math.floor(Date.now() / 1000) - 30 * 24 * 60 * 60 },
});
// Sync single entity
await stripeSync.syncSingleEntity("cus_ABC123");
7. Query Synced Data
Tables available:
stripe.customers,stripe.products,stripe.pricesstripe.subscriptions,stripe.subscription_itemsstripe.invoices,stripe.invoice_line_itemsstripe.charges,stripe.payment_intents,stripe.payment_methodsstripe.coupons,stripe.disputes,stripe.setup_intents
Example queries:
-- Active subscriptions
SELECT c.email, s.status, p.name as product
FROM stripe.subscriptions s
JOIN stripe.customers c ON s.customer_id = c.id
JOIN stripe.prices pr ON s.items->0->>'price_id' = pr.id
JOIN stripe.products p ON pr.product_id = p.id
WHERE s.status = 'active';
-- Monthly revenue
SELECT DATE_TRUNC('month', created) as month,
SUM(amount_paid) / 100.0 as revenue
FROM stripe.invoices
WHERE status = 'paid'
GROUP BY 1 ORDER BY 1;
8. Local Testing
# Terminal 1: Start your server
npm run dev
# Terminal 2: Forward Stripe events
stripe listen --forward-to localhost:3000/api/webhooks/stripe
# Terminal 3: Trigger test events
stripe trigger customer.created
stripe trigger invoice.payment_succeeded
Quick Troubleshooting
| Issue | Solution |
|---|---|
| Signature failed | Use raw body (Buffer), not parsed JSON |
| Connection error | Check DATABASE_URL format and SSL settings |
| Data not syncing | Run migrations first, check schema exists |
| Edge runtime error | Add export const runtime = 'nodejs' |
You Might Also Like
Related Skills

gog
Google Workspace CLI for Gmail, Calendar, Drive, Contacts, Sheets, and Docs.
openclaw
orpc-contract-first
Guide for implementing oRPC contract-first API patterns in Dify frontend. Triggers when creating new API contracts, adding service endpoints, integrating TanStack Query with typed contracts, or migrating legacy service calls to oRPC. Use for all API layer work in web/contract and web/service directories.
langgenius

