Stripe Connect → automatic GL posting (Stripe Clearing & Payment Processing Fees)
When Stripe is connected and a charge clears on your connected account, Turtini auto-posts the right journal entries to your general ledger. No manual reconciliation, no end-of-month "what was that fee" hunt — your books match Stripe's BT model exactly.
How the books move (per charge):
1. Charge succeeds for $100 with a $3.20 Stripe fee
• DR 1050 Stripe Clearing 96.80
• DR 6250 Payment Processing Fees 3.20
• CR 4900 Other Revenue 100.00
2. Stripe pays out $96.80 to your bank ~2 business days later
• DR 1010 Checking Account 96.80
• CR 1050 Stripe Clearing 96.80
Why two stages: Stripe holds funds for ~2 days before depositing them. Posting straight to Cash on charge would misstate your bank balance. The Stripe Clearing (1050) account mirrors your actual Stripe balance — net of fees, less refunds — and zeroes out as payouts land. This is exactly how accountants want it.
Refunds:
• DR 4900 Other Revenue (gross)
• CR 1050 Stripe Clearing (net of fee returned)
• CR 6250 Payment Processing Fees (the fee Stripe gave back, when applicable)
Refunds are detected per refund-event, so partial and multiple refunds on the same charge each post their own JE.
Accounts created automatically:
The first time auto-posting fires, two accounts are added to your Chart of Accounts (marked isSystem so you can't accidentally delete them):
• 1050 — Stripe Clearing (Current Asset)
• 6250 — Payment Processing Fees (Operating Expense)
You can rename them in Accounting → Chart of Accounts; the codes stay the same.
Revenue account mapping:
Default revenue code is 4900 ("Other Revenue"). To route a specific charge to a different revenue account, set metadata.glRevenueCode on the PaymentIntent or Charge before it succeeds (e.g. "4000" for Sales Revenue, "4500" for Services Revenue). Common pattern: set this from your checkout integration based on what was sold.
Module flows that already post their own JEs (auto-post is skipped):
• Marketplace purchases — module fees, partner payouts, +15% chargeback all post via marketplace-specific code
• Ticket resale — buyer fee + seller payout split posts via ticketResale.ts
• Retail / restaurant / lodging orders — point-of-sale flows write their own GL via the Hospitality posting layer
• Dues — member payment + treasurer fee split posts via dues.ts
Behind the scenes these flows set metadata.skipStripeGlPosting='1' on the PaymentIntent so the auto-poster knows to stay out of their way.
Idempotency:
Every JE is keyed on the Stripe object id (Charge id, Refund id, Payout id). If the webhook fires twice (Stripe retries delivery), the JE is posted exactly once. You'll never see duplicate revenue or duplicate fees from the auto-poster.
Reconciling at month-end:
1. Pull the Stripe payout report for the month
2. Sum the gross / fees / refunds — should match 4900 / 6250 / refund reversals exactly
3. The 1050 Stripe Clearing balance at month-end should equal your in-flight Stripe balance (charges done, payout not yet landed)
4. Anomaly detection (Wally's accounting tools) will flag any mismatch automatically — show "Stripe Clearing diverges from expected" if the running total ever drifts
Disabling per-charge:
Pass metadata.skipStripeGlPosting='1' on a PaymentIntent to opt out of auto-posting (e.g. for a charge you'll book manually). The webhook will skip GL entirely for that event.
Disabling globally:
Disconnecting Stripe stops auto-posting going forward. Existing JEs stay where they are — they're real history, not synthetic. Re-connecting Stripe resumes posting on the next event.
Platform-direct charges (Turtini's own billing):
Charges to Turtini itself (your monthly platform fees, marketplace +15% chargeback) post via the platform's chargeback ledger, not your org GL. Those show up under Account → Billing rather than in your books.