Complete Stripe billing and payments integration for nself. Syncs all Stripe data to PostgreSQL with real-time webhook support.
The Stripe plugin provides complete synchronization of your Stripe account data to a local PostgreSQL database. It supports:
# Install the plugin
nself plugin install stripe
# Configure environment
echo "STRIPE_API_KEY=sk_live_xxx" >> .env
echo "STRIPE_WEBHOOK_SECRET=whsec_xxx" >> .env
echo "DATABASE_URL=postgresql://user:pass@localhost:5432/nself" >> .env
# Initialize database schema
nself plugin stripe init
# Sync all data
nself plugin stripe sync
# Start webhook server
nself plugin stripe server --port 3001| Variable | Required | Default | Description |
|---|---|---|---|
DATABASE_URL | Yes | - | PostgreSQL connection string |
STRIPE_API_KEY | Yes | - | Stripe secret API key (sk_live_xxx or sk_test_xxx) |
STRIPE_WEBHOOK_SECRET | No | - | Webhook endpoint signing secret (whsec_xxx) |
STRIPE_API_VERSION | No | 2024-12-18 | Stripe API version to use |
PORT | No | 3001 | HTTP server port |
LOG_LEVEL | No | info | Logging level (debug, info, warn, error) |
Your Stripe API key needs read access to all resources you want to sync. Write access is not required (plugin is read-only). For production, use a restricted key with only read permissions.
# Initialize database schema
nself plugin stripe init
# Check plugin status
nself plugin stripe status
# View sync statistics
nself plugin stripe stats# Full sync (all resources)
nself plugin stripe sync
# Sync specific resources
nself plugin stripe sync customers
nself plugin stripe sync subscriptions
nself plugin stripe sync invoices
nself plugin stripe sync products
nself plugin stripe sync prices
nself plugin stripe sync charges
nself plugin stripe sync payouts
# Incremental sync (only changed data)
nself plugin stripe sync --incremental
# Sync with date filter
nself plugin stripe sync --since 2024-01-01# List all customers
nself plugin stripe customers list
# List with pagination
nself plugin stripe customers list --limit 50 --offset 100
# Get customer by ID
nself plugin stripe customers get cus_ABC123
# Search customers by email
nself plugin stripe customers search john@example.com
# List customers by creation date
nself plugin stripe customers list --since 2024-01-01
# Export customers to CSV
nself plugin stripe customers list --format csv > customers.csv# List active subscriptions
nself plugin stripe subscriptions list
# List all subscriptions (including canceled)
nself plugin stripe subscriptions list --all
# Get subscription details
nself plugin stripe subscriptions get sub_ABC123
# List subscriptions by status
nself plugin stripe subscriptions list --status active
nself plugin stripe subscriptions list --status canceled
nself plugin stripe subscriptions list --status past_due
# View subscription statistics
nself plugin stripe subscriptions stats# List all invoices
nself plugin stripe invoices list
# List by status
nself plugin stripe invoices list --status paid
nself plugin stripe invoices list --status open
nself plugin stripe invoices list --status uncollectible
# View failed payments
nself plugin stripe invoices failed
# Get invoice details
nself plugin stripe invoices get in_ABC123# List payment intents
nself plugin stripe payments list
# List successful payments
nself plugin stripe payments list --status succeeded
# List failed payments
nself plugin stripe payments list --status failed
# Get payment details
nself plugin stripe payments get pi_ABC123
# List charges
nself plugin stripe charges list
# List refunds
nself plugin stripe refunds list# Check webhook configuration
nself plugin stripe webhook status
# List recent webhook events
nself plugin stripe webhook events
# List events by type
nself plugin stripe webhook events --type customer.created
# View failed events
nself plugin stripe webhook events --failed
# Retry a failed event
nself plugin stripe webhook retry evt_ABC123# Start HTTP server
nself plugin stripe server
# Start on custom port
nself plugin stripe server --port 3001
# Start with specific host
nself plugin stripe server --host 0.0.0.0 --port 3001https://your-domain.com/webhooks/stripecustomer.created, customer.updatedsubscription.created, subscription.updated, subscription.deletedinvoice.paid, invoice.payment_failedpayment_intent.succeeded, payment_intent.payment_failedSTRIPE_WEBHOOK_SECRETstripe listen --forward-to localhost/webhooks/stripeThe Stripe CLI is the easiest way to test webhooks locally. It automatically provides a webhook secret and forwards events to your local server.
| Resource | Description | Table |
|---|---|---|
| Customers | Customer profiles with metadata | stripe_customers |
| Products | Product catalog | stripe_products |
| Prices | Pricing information | stripe_prices |
| Subscriptions | Active and past subscriptions | stripe_subscriptions |
| Subscription Items | Individual subscription line items | stripe_subscription_items |
| Invoices | All invoices | stripe_invoices |
| Invoice Items | Individual invoice line items | stripe_invoice_items |
| Payment Intents | Payment attempts | stripe_payment_intents |
| Payment Methods | Saved payment methods | stripe_payment_methods |
| Charges | Completed charges | stripe_charges |
| Refunds | Refund records | stripe_refunds |
| Disputes | Chargebacks and disputes | stripe_disputes |
| Balance Transactions | Account balance history | stripe_balance_transactions |
| Payouts | Payout records | stripe_payouts |
| Coupons | Discount coupons | stripe_coupons |
| Promotion Codes | Promo codes | stripe_promotion_codes |
| Tax Rates | Tax rate definitions | stripe_tax_rates |
| Setup Intents | Payment method setup attempts | stripe_setup_intents |
| Checkout Sessions | Checkout session records | stripe_checkout_sessions |
| Events | Stripe event log | stripe_events |
| Webhook Events | Received webhook events | stripe_webhook_events |
| View | Description |
|---|---|
stripe_active_subscriptions | Active subscriptions with customer details |
stripe_mrr | Monthly recurring revenue calculation |
stripe_failed_payments | Recent failed payment attempts |
stripe_revenue_by_month | Revenue aggregated by month |
stripe_customer_lifetime_value | Customer lifetime value calculation |
stripe_subscription_churn | Subscription churn metrics |
-- Monthly recurring revenue from Stripe
SELECT
DATE_TRUNC('month', created_at) AS month,
SUM(amount / 100.0) AS mrr
FROM stripe_subscriptions
WHERE status = 'active'
GROUP BY month
ORDER BY month DESC;
-- Find customers at risk of churn
SELECT
c.email,
c.name,
s.current_period_end,
s.cancel_at_period_end,
i.amount / 100.0 AS last_invoice_amount,
i.status AS last_invoice_status
FROM stripe_customers c
JOIN stripe_subscriptions s ON c.id = s.customer_id
LEFT JOIN stripe_invoices i ON s.latest_invoice = i.id
WHERE s.status = 'active'
AND (
s.cancel_at_period_end = TRUE
OR i.status IN ('open', 'uncollectible')
OR s.current_period_end < NOW() + INTERVAL '7 days'
)
ORDER BY s.current_period_end;
-- Revenue report by product
SELECT
pr.name AS product_name,
p.nickname AS price_name,
p.unit_amount / 100.0 AS price,
p.currency,
COUNT(DISTINCT s.id) AS active_subscriptions,
SUM(p.unit_amount) / 100.0 AS total_mrr
FROM stripe_products pr
JOIN stripe_prices p ON pr.id = p.product_id
JOIN stripe_subscription_items si ON p.id = si.price_id
JOIN stripe_subscriptions s ON si.subscription_id = s.id
WHERE s.status = 'active'
GROUP BY pr.name, p.nickname, p.unit_amount, p.currency
ORDER BY total_mrr DESC;All Stripe tables are automatically tracked in Hasura:
query GetCustomerSubscriptions {
stripe_customers(limit: 10) {
id
email
name
stripe_subscriptions {
id
status
current_period_end
stripe_price {
unit_amount
stripe_product {
name
}
}
}
}
}ENV=dev
STRIPE_API_KEY=sk_test_xxxxxUses test customers, no real charges.
ENV=prod
STRIPE_API_KEY=sk_live_xxxxxReal customer data and charges.
Never use live API keys in development. Always use test keys (sk_test_*) for local development and staging environments.
# Remove plugin and data
nself plugin remove stripe
# Keep database tables
nself plugin remove stripe --keep-dataError: Invalid API Key providedCheck that STRIPE_API_KEY is set correctly. Ensure you are using the correct key for your environment (test vs live).
# Verify key format
echo $STRIPE_API_KEY | head -c 10
# Should show: sk_live_xx or sk_test_xxError: Webhook signature verification failedSolutions:
STRIPE_WEBHOOK_SECRET matches the endpoint in Stripe DashboardError: Rate limit exceededThe plugin has built-in rate limiting, but if you are hitting limits:
Error: Connection refusedSolutions:
DATABASE_URL format# Test connection
psql $DATABASE_URL -c "SELECT 1"Enable debug logging for detailed troubleshooting:
LOG_LEVEL=debug nself plugin stripe sync# Check plugin status
nself plugin stripe status
# Check database connectivity
curl http://localhost:3001/health
# Check sync status
curl http://localhost:3001/api/status-- Create a view to join app users with Stripe customers
CREATE VIEW user_billing AS
SELECT
u.id AS user_id,
u.email,
sc.id AS stripe_customer_id,
sc.created AS customer_since,
(SELECT COUNT(*) FROM stripe_subscriptions ss
WHERE ss.customer_id = sc.id AND ss.status = 'active') AS active_subscriptions
FROM users u
LEFT JOIN stripe_customers sc ON u.email = sc.email;// Check if user has active subscription
async function hasActiveSubscription(userEmail: string): Promise<boolean> {
const result = await hasura.query({
query: `
query CheckSubscription($email: String!) {
stripe_customers(where: { email: { _eq: $email } }) {
stripe_subscriptions(where: { status: { _eq: "active" } }) {
id
}
}
}
`,
variables: { email: userEmail }
});
return result.stripe_customers[0]?.stripe_subscriptions?.length > 0;
}Last Updated: January 2026 | Plugin Version 1.0.0 | Stripe API Version 2024-12-18