Shopify Integration

A comprehensive accounting-first integration for Shopify stores, providing revenue recognition, payout reconciliation, fee tracking, and financial reporting.

The /api/v1/shopify/* 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. Booked activity lands in the public Journal Entries, Inventory and Reports endpoints, which is where integrations should read from.

What Gets Synced

Data Description
Orders Pulled into the Shopify subledger; summarised into sales-recognition journal entries
Payouts Settlement journal entries that match the bank deposit 1:1
Products & inventory Synced into the product catalog for inventory and COGS tracking
Customers Customer records and balances
Refunds Netted into the daily / payout summaries
Gift cards Liability tracking
Disputes Reserve management

Connect Shopify

Option 1: OAuth (Recommended)

From the Integrations page in DayZero, enter your Shopify shop domain and click Connect Shopify. You'll be redirected to Shopify to authorize access.

Or via API:

bash
curl "https://api.ondayzero.com/api/v1/shopify/install-url?shop=your-store" \
  -H "Authorization: Bearer dz_your_token_here" \
  -H "x-business-id: YOUR_BUSINESS_ID"

The response includes an install_url. Redirect the merchant to that URL to begin the OAuth flow. After authorization, DayZero registers webhooks and queues the initial sync. (Merchants who installed from the Shopify App Store before creating a DayZero account are attached with POST /api/v1/shopify/finalize-pending-install?shop=your-store.)

Option 2: Manual Access Token

If you have a Shopify custom app access token:

bash
curl -X POST "https://api.ondayzero.com/api/v1/shopify/setup" \
  -H "Authorization: Bearer dz_your_token_here" \
  -H "x-business-id: YOUR_BUSINESS_ID" \
  -H "Content-Type: application/json" \
  -d '{"shop": "your-store.myshopify.com", "access_token": "shpat_..."}'

Automatic Accounting

DayZero never posts one journal entry per order — the general ledger only sees summaries. Orders, refunds, products and customers are pulled on a schedule into a subledger; webhooks are used only for payouts, disputes and app lifecycle. Two posting modes are available (GET/PATCH /api/v1/shopify/subledger/posting-config):

posting_mode Journal entries created
per_payout (default) One entry per Shopify payout. Debits: the net deposit (to the bank ledger, or to the Shopify Merchant Account clearing ledger when bank matching is on), processing fees, refunds, discounts and gift-card redemptions. Credits: product sales, shipping, tips, duties and sales tax payable (one ledger per jurisdiction). COGS / inventory lines are added when inventory is tracked. The entry total equals the bank deposit, so bank matching is exact.
daily_summary One sales-recognition entry per business-local day (Debit Shopify Merchant Account clearing / Credit revenue, tax payable, etc., plus COGS), and a separate settlement entry when each payout lands that moves cash from Clearing to Bank net of fees. Accrual-friendly.

Posting is idempotent per day / per payout, so re-syncing never double-books. Other posting-config fields: posting_start_date (ignore history before this date; clear_posting_start_date: true removes it), bank_match_enabled (auto-match payouts to bank transactions) and catalog_sync_hour / catalog_sync_timezone for the nightly product sync.

Payout Reconciliation

Shopify payouts are matched against bank deposits for reconciliation. Each payout includes a breakdown of orders, refunds, fees, and adjustments — GET /api/v1/shopify/subledger/payouts lists them (filter by status, start_date, end_date, posted), and GET /api/v1/shopify/subledger/payouts/{payout_id} shows the detail.

Browse the Subledger

Everything DayZero pulled from Shopify is queryable, which is useful for tying a journal entry back to the orders behind it:

Endpoint Returns
GET /api/v1/shopify/subledger/summary Record counts (orders, payouts, refunds, posted vs. unposted summaries), the clearing-account balance and the store's posting settings
GET /api/v1/shopify/subledger/orders Orders; filter by journal_entry_id, financial_status, date range
GET /api/v1/shopify/subledger/orders/{order_id}/line-items Line items for one order
GET /api/v1/shopify/subledger/daily Per-day sales summaries
GET /api/v1/shopify/subledger/customers Synced customers (search supported)
GET /api/v1/shopify/subledger/backlink/{journal_entry_id} The Shopify records that produced a journal entry

These list endpoints use limit/offset paging rather than cursors.

Sync Status

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

Returns connected, healthy, shop_domain, orders_synced, products_synced, last_sync, and the current bootstrap progress (sync_state, sync_stage, sync_started_at, sync_completed_at, sync_error). GET /api/v1/shopify/stores lists the connected stores.

Manual Import

To re-import products or pull all orders on demand:

bash
# Import products
curl -X PUT "https://api.ondayzero.com/api/v1/shopify/import" \
  -H "Authorization: Bearer dz_your_token_here" \
  -H "x-business-id: YOUR_BUSINESS_ID"

# Import orders
curl -X POST "https://api.ondayzero.com/api/v1/shopify/import-orders" \
  -H "Authorization: Bearer dz_your_token_here" \
  -H "x-business-id: YOUR_BUSINESS_ID"

POST /api/v1/shopify/bootstrap queues the full end-to-end catch-up (products, inventory, orders, payouts, balance transactions and summary posting). If payout or refund counts look wrong — typically because posting_start_date filtered out history on the original sync — POST /api/v1/shopify/resync wipes the subledger (journal entries and ledgers are untouched) and re-pulls the entire history. POST /api/v1/shopify/subledger/backfill with {"limit": 200} (default 50) queues posting for paid payouts and daily summaries that were pulled but never booked — GET /api/v1/shopify/subledger/summary shows how many are payouts_unposted / daily_summaries_unposted.

Disconnect

Preview the impact first with GET /api/v1/shopify/disconnect/preview, then choose how much to remove with purge_mode:

bash
curl -X DELETE "https://api.ondayzero.com/api/v1/shopify/disconnect?purge_mode=connection_only" \
  -H "Authorization: Bearer dz_your_token_here" \
  -H "x-business-id: YOUR_BUSINESS_ID"
purge_mode Effect
connection_only (default) Revokes the token, removes webhooks and clears credentials. Subledger and journal entries stay.
subledger Also deletes every synced Shopify record (orders, payouts, customers…). Journal entries stay intact.
full Subledger purge plus a reversing journal entry for every Shopify-sourced entry, and removal of any Shopify-managed ledger left empty. Requires confirm=WIPE; pass cutoff_date=YYYY-MM-DD to leave entries in closed periods alone.