Skip to content

Documentation · Integrations

Setting up Stripe Connect

10 min read · Integrations · Updated 2026-05-14

Integrations10 minShare
Documentation sections

Payments in LiteHQ flow through Stripe Connect. You — the operator — own the Connect account; we orchestrate the platform. Funds settle straight into your bank; Stripe is the only party handling card data; we never touch it.

This guide walks the end-to-end setup: why Connect (not Charges, not Direct), the onboarding flow, configuring webhook secrets, payout schedules, and the five most common Connect errors with resolutions.

Test mode is free. You can run the entire onboarding flow with Stripe test keys (sk_test_) without any real money moving. Switch to sk_live_when you're ready.

Section 1

Why Stripe Connect (not Charges)

Operator owns funds · LiteHQ is a payment processor on behalf of you

The simplest Stripe shape is Charges: customers pay a single Stripe account, you settle later. That works for one-operator setups but collapses for multi-tenant SaaS — and LiteHQ is multi-tenant by definition.

Three reasons we picked Connect

  1. Direct settlement. Tenant payments land in your bank — not ours. We never custody your money. This is a legal + tax simplification.
  2. Per-operator dispute handling.Chargebacks, refunds, and disputes go to your Connect dashboard. You don't need to wait for us to triage.
  3. Multi-currency without a per-currency platform account.Each operator picks their settlement currency at onboarding. We don't need to be in every market they are.

Section 2

Onboarding flow walkthrough

~10 min · operator-attended · KYC + bank account + verification

Onboarding happens at signup time (or later if you skipped it). You're redirected to a Stripe-hosted page, fill in business + verification details, and come back to your LiteHQ dashboard with a connected account.

The full sequence

  1. In Settings → Payments, click Connect Stripe. We create a Stripe account in your jurisdiction and generate an AccountLink.
  2. The AccountLink redirects to Stripe's hosted onboarding. Fill in: business name, tax id (ABN / NZBN / EIN / VAT), bank account, owner ID verification.
  3. Stripe returns to our callback at /v2/preview/onboarding (see step 7 of the onboarding flow).
  4. We auto-create two webhook secrets and register both endpoints with Stripe. You see them surfaced in Settings → Webhooks.
  5. We mark your operator account stripe_status='active'. From this point your public booking URL accepts paid bookings.
The Stripe-hosted onboarding handoff — your operator dashboard pauses here until Stripe redirects back.
The Stripe-hosted onboarding handoff — your operator dashboard pauses here until Stripe redirects back.

Section 3

Configuring webhook secret(s)

Two secrets · platform + connect · dual-secret verification

LiteHQ's Stripe webhook endpoint accepts events from both your platform account and your connected account. The endpoint verifies the signature against both secrets — whichever matches wins, neither matching fails the request.

The two secrets

  • STRIPE_WEBHOOK_SECRET. Platform-level events. Things like account.updated on your Connect account.
  • STRIPE_WEBHOOK_SECRET_CONNECT. Connected-account events. charge.succeeded, payment_intent.succeeded, refunds.
webhook_handler.example.ts
typescript
// Both secrets are tried — the first that verifies wins.
// We never reveal which one matched to the caller (timing leak).

async function POST(req: Request): Promise<Response> {
  const sig = req.headers.get('stripe-signature') ?? ''
  const body = await req.text()

  let event: Stripe.Event | null = null

  for (const secret of [
    process.env.STRIPE_WEBHOOK_SECRET!,
    process.env.STRIPE_WEBHOOK_SECRET_CONNECT!,
  ]) {
    try {
      event = stripe.webhooks.constructEvent(body, sig, secret)
      break
    } catch {
      // try the next secret
    }
  }

  if (!event) return new Response('invalid signature', { status: 400 })
  await processEvent(event)
  return new Response('ok')
}

Section 4

Payout schedule and bank linking

Daily/weekly/monthly · per-currency settlement · per-operator override

Stripe sweeps funds from your connected account to your linked bank on a schedule you choose. We default to daily for operators with steady volume and weekly for smaller operators (fewer wire fees on the receiving bank).

Setting the schedule

  1. In your Stripe dashboard → Settings → Payouts, choose Daily / Weekly / Monthly. Stripe applies a rolling 2-business-day hold for cards (configurable).
  2. Link a bank account. Stripe requires a 1-cent test deposit + confirmation for ACH accounts; instant for AU/NZ via PayTo/POLi.
  3. Multi-currency operators can add additional payout currencies — each currency gets its own bank.

Reconciling payouts in Xero

Stripe payouts arrive in your bank as a single batched line. We map each payout to its underlying invoices via the cron-xero-syncedge function, which writes a Bank Transaction in Xero and matches it against the payout's individual charges.

Reference

Troubleshooting common Connect errors

Five errors that cover 80% of support tickets

These five errors are the most common Stripe Connect issues we see in support. Each includes the underlying cause and the exact resolution.

  • account.requirements.disabled_reason
    Connect account stuck in 'pending'

    Cause. Stripe needs ID/ownership verification that hasn't been submitted. The onboarding link was abandoned mid-flow.

    Fix. Re-issue the AccountLink in your dashboard (Settings → Stripe → Resume onboarding). The new link is valid for 7 days.

  • platform_account_required
    Webhook secret missing on a connected account event

    Cause. The connected-account webhook (STRIPE_WEBHOOK_SECRET_CONNECT) wasn't generated or was rotated without updating the env.

    Fix. Regenerate from the Connect dashboard, copy the new whsec_…, update the env var, redeploy. Old + new both validate for 24h after rotation.

  • balance.insufficient_funds_for_payout
    Scheduled payout failed

    Cause. Stripe couldn't fund the payout — usually because of a recent refund that hit a too-thin balance.

    Fix. Top up via Stripe dashboard or wait for the next batch of charges to land. We retry the payout automatically next business day.

  • verification_directors_required
    Connect onboarding blocked on director details

    Cause. Your jurisdiction requires director KYC and the form has more than one required field unfilled.

    Fix. Open the Stripe-hosted re-verification link. We send the operator-owner an email when this fires — check spam.

  • payment_intent.amount_capturable_amount_changed
    Refund larger than available balance

    Cause. You tried to refund more than has settled on the connected account.

    Fix. Wait for the funds to settle (T+2 for cards, T+1 for bank-funded payments) and re-try the refund.