Documentation Index
Fetch the complete documentation index at: https://docs.insforge.dev/llms.txt
Use this file to discover all available pages before exploring further.
Overview
InsForge Payments helps developers add Stripe payment flows to generated applications without putting Stripe secret keys in frontend code. Developers configure their own Stripe account, agents manage products and prices, and app frontends create Stripe Checkout and Billing Portal sessions through InsForge. Stripe remains the source of truth. InsForge mirrors Stripe catalog and runtime payment state into apayments schema so the dashboard, agents, and custom app logic can reason about products, prices, checkout sessions, subscriptions, refunds, and webhook processing.
InsForge does not decide what a successful payment means for your app. Use the payment projection tables to update your own app tables, such as
orders, credits, team_entitlements, or billing_status.Technology Stack
Core Model
InsForge uses the developer-owned Stripe account model. Each project can configure:| Environment | Secret key | Purpose |
|---|---|---|
test | STRIPE_TEST_SECRET_KEY | Development and agent implementation |
live | STRIPE_LIVE_SECRET_KEY | Production payments |
environment column instead of using separate test/live table sets.
Configuration Flow
Configure Stripe from the dashboard Payments settings, or through the CLI:Catalog Management
Products and prices are managed in Stripe first, then mirrored into InsForge.Data Model
Thepayments schema stores Stripe connection metadata, catalog mirrors, checkout attempts, subscriptions, payment history, and webhook processing state.
| Table | Purpose |
|---|---|
payments.stripe_connections | One row per environment with Stripe account, key, webhook, and sync status |
payments.products | Mirrored Stripe products |
payments.prices | Mirrored Stripe prices |
payments.checkout_sessions | Local Checkout Session attempts created by app frontends |
payments.customer_portal_sessions | Local Billing Portal Session attempts |
payments.stripe_customer_mappings | Maps app billing subjects to Stripe customers |
payments.subscriptions | Mirrored Stripe subscription state |
payments.subscription_items | Mirrored subscription item and price state |
payments.payment_history | One-time payments, subscription invoices, failed payments, and refunds |
payments.webhook_events | Stripe webhook deduplication and processing status |
Billing Subjects
A billing subject is the app-defined owner of a customer or subscription:subject_type and subject_id; your app decides what those values mean.
Runtime Checkout Flow
Use the TypeScript SDK from your app frontend:- InsForge inserts a row in
payments.checkout_sessionsusing the caller’s role and JWT context. - InsForge creates the Stripe Checkout Session. If Stripe succeeds, the local row becomes
openand stores the Stripe URL.
subject is optional. For subscription checkout, subject is required because ongoing access belongs to an app-defined billing owner.
Customer Portal Flow
Use Stripe Billing Portal when customers need to manage subscriptions, invoices, payment methods, or cancellation.payments.stripe_customer_mappings row for the subject. That mapping is usually created after a Checkout Session completes and Stripe returns a customer.
Webhook Projection Flow
Managed Stripe webhooks update InsForge’s payment projections. The webhook handler verifies Stripe signatures, deduplicates events, and records processing state inpayments.webhook_events.
InsForge listens for events that keep checkout, subscriptions, payment history, and refunds current:
| Event family | Examples | Projection |
|---|---|---|
| Checkout | checkout.session.completed, checkout.session.async_payment_succeeded, checkout.session.expired | checkout_sessions, customer mappings, one-time payment history |
| Invoices | invoice.paid, invoice.payment_failed | subscription invoice payment history |
| PaymentIntents | payment_intent.succeeded, payment_intent.payment_failed | payment history |
| Refunds | charge.refunded, refund.created, refund.updated, refund.failed | refund rows and original payment refund status |
| Subscriptions | customer.subscription.created, customer.subscription.updated, customer.subscription.deleted | subscriptions and subscription items |
Custom Fulfillment Logic
InsForge cannot know what a successful payment means for every app. Your agent should create app-specific tables, triggers, or jobs based on your product model. Treat thepayments schema as an internal projection layer, then copy the business result into your own public tables with RLS.
For example, a SaaS app might turn a paid subscription into public.team_billing_status, while a marketplace might turn a one-time payment into public.orders.status = 'paid'. The frontend should read those app-owned tables, not the admin payment projection tables.
If the frontend needs to be notified immediately, publish or subscribe from the app-owned table. For example, use Realtime on public.orders after the fulfillment trigger marks the order paid. Avoid subscribing end users directly to payments.payment_history.
Which Table Should Trigger Business Logic?
Use the most final payment projection available for the job:| Business need | Recommended source | Why |
|---|---|---|
| Mark a one-time order paid | payments.payment_history where type = 'one_time_payment' and status = 'succeeded' | Handles webhook confirmation and delayed payment methods |
| Apply refunds or reduce credits | payments.payment_history refund rows, or original rows with amount_refunded | Refunds can arrive separately from the original payment |
| Activate or revoke subscription access | payments.subscriptions status and period fields | Captures subscription lifecycle changes, renewals, cancellations, and sync repair |
| Record invoice/payment ledger entries | payments.payment_history where type = 'subscription_invoice' | Captures paid and failed recurring invoices |
| Track local checkout attempts | payments.checkout_sessions | Useful for metadata, idempotency, and debugging, but not the final fulfillment signal |
payments.checkout_sessions.status = 'completed'. Checkout completion is not always the same as money being available, especially with delayed payment methods. Use payment_history.status = 'succeeded' for one-time payment fulfillment and subscriptions.status for subscription access.
Typical app-owned tables include:
| Use case | App-owned table |
|---|---|
| Ecommerce orders | public.orders |
| Credit packs | public.credit_ledger |
| Paid content | public.user_entitlements |
| Team subscriptions | public.team_billing_status |
| Async side effects | public.fulfillment_jobs |
One-Time Checkout Fulfillment Example
Create your order before Checkout, pass the order ID in Checkout metadata, then fulfill from webhook-projected payment history. The trigger below is intentionally idempotent: repeated webhook deliveries or manual sync repairs update the same order and do not double-fulfill it.Subscription Entitlement Example
For subscriptions, update an app-owned entitlement or billing status table frompayments.subscriptions.
active and trialing as access-granting states, and treat canceled, unpaid, and incomplete_expired as access-revoking states. Stripe also recommends handling past_due deliberately: you might keep access during retry windows, show a billing warning, or restrict premium features based on your product policy.
Agent Fulfillment Checklist
When an agent integrates Payments into an app, it should:- Identify the app’s billing owner: user, team, organization, tenant, or anonymous order.
- Create app-owned read models such as
orders,credit_ledger, orteam_billing_status. - Add RLS to app-owned tables before exposing them in the frontend.
- Add RLS to
payments.checkout_sessionsandpayments.customer_portal_sessionswhen users can pass asubject. - Add idempotent triggers from
payments.payment_historyorpayments.subscriptionsinto the app-owned tables. - Use app-owned table updates or Realtime messages to notify the frontend.
- Use outbox rows or edge functions for emails, shipping, analytics, or other external side effects.
- Test with Stripe test mode, including success, failed payment, delayed payment, renewal, cancellation, and refund paths.
Session Authorization and RLS
The runtime payment routes insert intopayments.checkout_sessions and payments.customer_portal_sessions using the caller context. By default, the migration grants insert/select access for these session tables so apps can start quickly.
If users can pass a subject, add app-specific RLS policies before shipping subscription checkout or portal UI. For example, if subscriptions belong to teams, only team members should be able to create checkout or portal sessions for that team.
Runtime Payment State
The frontend SDK currently exposes creation flows only:insforge.payments.createCheckoutSession(...)insforge.payments.createCustomerPortalSession(...)
payments.subscriptions and payments.payment_history are not a generic end-user read surface. If your app needs users to see subscription status, order status, credits, or entitlements, create app-owned tables with RLS and populate them from payment projections.
Local Development
Stripe requires webhook endpoints to be publicly accessible. Localhost backend URLs cannot be registered as Stripe webhook endpoints from the dashboard or CLI. For local testing:- Configure the Stripe test key.
- Build checkout with
environment: 'test'. - Use the Stripe CLI to forward events to your local backend webhook endpoint.
- Confirm your app-owned fulfillment tables update from webhook-projected payment state.
Current Limitations
Payments private preview intentionally starts with a small, stable surface.
| Limitation | Details |
|---|---|
| Developer-owned Stripe accounts only | Connected Accounts, claimable sandboxes, and platform-managed onboarding are not part of this phase |
| No test-to-live publishing | Agents explicitly target test or live environments |
| No generic end-user read API | Build app-owned read models with RLS for entitlements and billing status |
| No full Stripe object mirror | Customers, invoices, charges, payment methods, and checkout line-item projections are intentionally limited |
| No default business fulfillment | Agents generate custom triggers/jobs based on your app schema |
Best Practices
Start in Test Mode
Build and verify checkout with Stripe test keys before touching live data.
Use Idempotency Keys
Use stable keys for product, price, and checkout creation to avoid duplicates during retries.
Fulfill from Webhooks
Use payment projection tables, not success redirects, to grant access or mark orders paid.
Own Your App State
Store user-facing status in app-owned tables with RLS.
Protect Billing Subjects
Add RLS before exposing team, organization, or subscription management flows.
Keep Secrets Server-Side
Never put Stripe secret keys in frontend code or public deployment variables.
Related Pages
Payments CLI
Configure Stripe keys, sync catalog state, manage products and prices, and inspect projections
TypeScript
Create Checkout Sessions and Billing Portal Sessions from web applications