Skip to main content

Stripe Integration Architecture - How ERPClaw Connects to Stripe

Technical architecture of the ERPClaw Stripe connector. Direct API access from your machine. No middleware. Optional webhook receiver. 12 GL accounts, 67 actions, 17 tables.

This page explains what runs where, what data is held where, and why the design eliminates the typical “middleware syncs Stripe to QuickBooks” pattern.

Two components

The Stripe integration is simpler than the Shopify one. There are only two moving parts:

  1. Your ERPClaw. Holds the API key, talks to the Stripe API directly, writes journal entries to local SQLite.
  2. Stripe API at api.stripe.com. Source of truth for charges, refunds, payouts, customers, subscriptions.
  Your ERPClaw  <===Stripe API v2026-04===>  Stripe
  (SQLite on your machine)

Optional third component: your ERPClaw’s webhook receiver, if you want real-time sync. Stripe POSTs events to your receiver, your ERPClaw verifies the signature and posts journal entries within seconds. No third-party middleware, no message queues.

If you do not want to expose your ERPClaw to the internet, skip the webhook and rely on polling sync (default 5-minute interval).

What ERPClaw stores

Seventeen dedicated tables:

TableRecords
stripe_accountOne per Stripe account you connect
stripe_chargeEvery charge, success or failure
stripe_refundEvery refund, partial or full
stripe_disputeEvery dispute, including won/lost outcomes
stripe_payoutEvery payout to your bank
stripe_payout_transactionPer-transaction breakdown of each payout
stripe_customerEvery customer object
stripe_subscriptionEvery subscription with full lifecycle
stripe_invoiceSubscription and one-off invoices
stripe_invoice_line_itemPer-line-item detail
stripe_application_feeConnect application fees
stripe_transferConnect transfers to connected accounts
stripe_balance_transactionThe Stripe ledger view
stripe_webhook_eventWebhook deduplication + audit
stripe_sync_jobSync run history with timing
stripe_gl_ruleConfigurable routing rules per event type
stripe_reconciliation_runPer-payout reconciliation runs

Plus 12 dedicated GL accounts auto-created on connect:

  • stripe_clearing — funds Stripe holds before payout
  • stripe_revenue — gross revenue
  • stripe_fee — Stripe processing fees
  • stripe_refund — refund holding (offset)
  • stripe_chargeback — disputed charges
  • stripe_chargeback_fee — Stripe’s chargeback fee
  • stripe_deferred_revenue — ASC 606 liability
  • stripe_application_fee — Connect platform revenue
  • stripe_connect_transfer — Connect transfers held
  • stripe_reserve — Stripe reserves (rare)
  • stripe_dispute_reserve — held during dispute
  • stripe_bank — your bank account from payouts

Sync modes

Polling (default): a background daemon runs stripe-sync-charges, stripe-sync-refunds, and stripe-sync-payouts every 5 minutes. Catches everything within 5 minutes of when Stripe records it.

Webhook (real-time): register a webhook endpoint with stripe-register-webhook. Stripe posts events to your ERPClaw within seconds. Your ERPClaw verifies the signature with HMAC-SHA256 against the webhook secret, deduplicates by event ID, and posts journal entries.

Manual: trigger any sync command on demand from CLI or chat interface.

You can run all three modes simultaneously. Webhook events take precedence; polling fills any gaps; manual catches edge cases.

Webhook signature verification

When ERPClaw receives a webhook, it:

  1. Extracts the Stripe-Signature header
  2. Splits into timestamp + signatures
  3. Verifies the timestamp is within 5 minutes of now (replay protection)
  4. Concatenates timestamp.payload and HMAC-SHA256 with the webhook secret
  5. Constant-time compares to the signature
  6. Looks up the event ID in stripe_webhook_event; if present, returns 200 (deduplication); if not, processes and records

Standard Stripe pattern; we do not deviate.

API rate limits

Stripe rate-limits API calls per account: 100 read requests per second in live mode, 25 in test mode. Bursts above that get 429 responses. ERPClaw uses exponential backoff with jitter, capped at 60 seconds, for any 429.

For initial syncs of large accounts (millions of charges), the bulk import endpoints are used where available. A 10-million-charge sync typically completes in 30-90 minutes depending on Stripe’s response times.

Connect platforms

If you run a marketplace on Stripe Connect, ERPClaw handles the three standard patterns:

  • Direct charges with application_fee_amount
  • Destination charges with transfer_data.destination
  • Separate charges and transfers for full control

Each pattern posts journal entries to the correct combination of clearing, revenue, application_fee, and connect_transfer accounts. See Connect platform fees.

ASC 606 revenue recognition

If you sell subscriptions, ERPClaw can be configured to post charges to Deferred Revenue (a liability) instead of immediate revenue, then recognize revenue monthly over the subscription period. See ASC 606 reference.

Source