# Stripe Integration

> Payment processing via Stripe Connect with automatic journal entries.

- **Category:** Integrations
- HTML version: https://www.ondayzero.com/docs/guides/stripe
- All guides: https://www.ondayzero.com/docs/guides/index.md
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

# Stripe Integration

DayZero integrates with Stripe Connect for multi-tenant payment processing. Each business connects its own Stripe account so customers can pay DayZero invoices online, and the resulting payments, fees and payouts are booked automatically.

> The `/api/v1/stripe/*` endpoints below work with an API token but are not part of the public API Reference — they back DayZero's own Integrations page and may change. The results show up through the public [Invoices](/docs/guides/invoices) and [Journal Entries](/docs/guides/journal-entries) endpoints, which is where integrations should read from.

## Connect Stripe

The simplest path is the **Integrations** page in the DayZero dashboard, which starts the Stripe Connect OAuth flow. Programmatically, request the connect URL:

```bash
curl "https://api.ondayzero.com/api/v1/stripe/connect-url" \
  -H "Authorization: Bearer dz_your_token_here" \
  -H "x-business-id: YOUR_BUSINESS_ID"
```

The response's `oauth_url` sends the user to Stripe to authorize; after the callback the business's `stripe_account_id` (visible on `GET /api/v1/businesses/{business_id}`) is stored automatically. The connect URL is bound to the browser that requested it via a cookie, so it must be opened in the same browser session — it is not something to hand to a headless client.

Check the connection with:

```bash
curl "https://api.ondayzero.com/api/v1/stripe/account-status" \
  -H "Authorization: Bearer dz_your_token_here" \
  -H "x-business-id: YOUR_BUSINESS_ID"
```

`data.status` is `connected`, `not_connected` or `connected_but_error` (with `error` / `message` explaining why), alongside the `stripe_account_id`. If the account exists but Stripe onboarding was never finished, `GET /api/v1/stripe/onboarding-link` returns a link to complete it. `POST /api/v1/stripe/dashboard-link` returns a link into the business's own Stripe dashboard (a one-time login link for Express accounts, the plain dashboard URL for Standard accounts).

## Invoice Payments

When an invoice is finalized for a business with Stripe connected, DayZero mirrors it to Stripe and the invoice gains `stripe_invoice_id` and `hosted_invoice_url` — Stripe's hosted payment page. Customers pay there; the confirmation arrives via webhook and automatically:

1. Updates the invoice `status` to `stripe_paid` and records the payment on the invoice
2. Creates the payment journal entry, net of fees
3. Records the Stripe processing fee (and any platform fee) as an expense

No webhook configuration is needed on your side — DayZero receives Stripe's events for every connected account. See [Invoices](/docs/guides/invoices) for the invoice lifecycle and how to read payments back.

## Automatic Journal Entries

| Stripe event | Journal entry |
|-------------|---------------|
| `invoice.finalized` | No new entry — the AR / revenue entry was posted when the invoice was finalized in DayZero. The webhook only verifies that entry matches what Stripe recorded. |
| `invoice.paid` | Debit *Stripe Merchant Account* (amount paid less fees) and *Merchant Fees Expense* (fees) / Credit *Accounts Receivable* (amount paid). Payments marked paid out-of-band in Stripe set the invoice to `manual_paid` instead and post no Stripe entry. |
| `invoice.voided` | No new entry — the void entry was posted when the invoice was voided in DayZero; the webhook verifies it. |
| `payout.paid` | Debit *Transfers Between Accounts* / Credit *Stripe Merchant Account* for the payout amount. When the deposit shows up in a connected bank feed, DayZero matches it by amount and arrival window and books the bank line against *Transfers Between Accounts*, completing the move into the bank ledger. |
| `payout.failed` / `payout.canceled` | Updates the stored payout status; no entry |

*Stripe Merchant Account* is a clearing ledger: it fills as invoices are paid and drains as payouts land, so its balance should hover near the amount Stripe is still holding. Each posted payout is also stored with its gross, fee and invoice breakdown; `POST /api/v1/stripe/payouts/{stripe_payout_id}/resync` re-fetches the balance transactions from Stripe and rebuilds that breakdown if it looks wrong.

## Disconnect

```bash
curl -X DELETE "https://api.ondayzero.com/api/v1/stripe/disconnect" \
  -H "Authorization: Bearer dz_your_token_here" \
  -H "x-business-id: YOUR_BUSINESS_ID"
```

Removes the connection from the business. Existing invoices keep their payment history; new invoices are no longer mirrored to Stripe and have no `hosted_invoice_url`.
