FrancodesystemsFran<code>systems
EcommerceCustom integration

Holded Shopify integration

Shopify invoicing, stock and returns pushed to Holded in real time.

HoldedHolded
Shopify

Implementation time · 5-10 días laborables

Diagnosis

The problem

A Shopify store with 200+ orders a month loses 6 to 10 hours a week generating invoices by hand from the dashboard. The admin team copies order numbers, amounts, tax details and line items into Holded one by one, and any slip turns into a sales ledger that the accountant sends back with corrections. In parallel, stock between Shopify and the ERP is always out of sync: you sell products you do not have, you stop selling what you do have, and you handle complaints that damage your reputation. Free plugins or one-off paid modules solve none of this once the store grows: they break with theme changes, they do not handle intra-EU VAT well, they do not account for partial returns and they leave orders with line-level discounts orphaned.

Proposal

The solution

Every Shopify order automatically generates the matching invoice in Holded, with its customer, its numbering series, its VAT type and its payment method. Stock is synced two-way between both platforms with timestamp-based conflict resolution. Returns and refunds trigger corrective invoices in Holded and adjust stock only for the units actually sent back. The whole operation is idempotent: if Shopify retries a webhook, we never duplicate anything.

Scope

What we automate

  • Shopify order to customer plus invoice in Holded with the correct series (B2C, B2B, intra-EU, export)
  • New Shopify customer to Holded contact with tax ID validated against VIES where applicable
  • Shopify product synced with Holded product (SKU, price, VAT, category)
  • Two-way stock with timestamp-based conflict resolution
  • Shopify refund to Holded corrective invoice plus partial stock adjustment
  • Multi-currency with the EUR equivalent recorded at the order's own exchange rate
  • Multi-VAT: automatic detection of EU B2C (IOSS), intra-EU B2B (0% with VIES), export (0%)
  • Line-level discounts, shipping costs, taxes and tips mapped to Holded line items
  • Shopify POS orders tagged with their physical store for per-channel reporting
Who uses it

Real use cases

These are the profiles that most ask us for the HoldedShopify integration and what they get in the end.

Case 01

DTC store with 500 orders/month

Before: The admin team spent 2 full days at month-end reconciling Shopify orders against Holded invoices and matching returns.

After: Month-end close in a single morning. Zero discrepancies between Shopify, Holded and the bank. The accountant stops sending corrections.

Case 02

Brand running B2B and B2C in the same store

Before: They mixed invoices with and without VAT depending on the customer, and issuing intra-EU invoices meant reviewing every order by hand.

After: Automatic detection of valid intra-EU tax IDs against VIES and the correct invoicing series with no human intervention.

Case 03

Multi-store Shopify plus Shopify POS

Before: Three channels (online, physical store, marketplace) generating three uncoordinated accounting streams and stock that was always outdated.

After: Unified inventory, invoices with their source channel identified and clean per-store reporting in Holded.

Before / After

What changes exactly

Without the integration

  • 6-10 h/week copying orders into Holded by hand
  • Stock lagging 24-48 h and sales of out-of-stock products
  • Partial returns mis-booked or left pending close
  • Intra-EU VAT reviewed order by order
  • The accountant sends the close back with corrections every month

With the integration

  • Invoices generated within seconds of the order, no manual work
  • Unified stock updated in real time across channels
  • Automatic corrective invoices with precise partial stock adjustment
  • VIES and the VAT matrix applied by the buyer's country and tax ID
  • A clean month-end close: the accountant has nothing to fix
Architecture

How we build it

We connect through Shopify webhooks (orders/create, orders/updated, refunds/create, inventory_levels/update) that flow into a BullMQ queue backed by Redis. The workers are idempotent, deduping by X-Shopify-Webhook-Id, they call the Holded REST API with exponential backoff and they record every operation in auditable structured logs. If Holded or Shopify are down, jobs retry for 24 hours and, if they ultimately fail, they alert the team for manual resolution without losing any data. The service runs outside Shopify (on a dedicated VPS or on your own infrastructure) so it does not break with every theme or Shopify app update.

flow.ts
webhook shopify.event
queue.enqueue(jobId)
worker.handle() // idempotent
holded.api.call() // retries with backoff
log.emit({ status: 'ok' })
FAQ

Frequently asked questions

What happens with partial returns?

We generate a corrective invoice in Holded for the exact quantity returned and adjust stock only for the units sent back, not the whole order. If Shopify issues several partial refunds against the same order, each one produces its own corrective invoice, numbered correctly.

Does it support multi-currency?

Yes. We take the exchange rate from the Shopify order itself (not the day's rate) and record it in Holded in the sale currency with its EUR equivalent. This avoids discrepancies with the actual payment received in your gateway.

How do you handle intra-EU VAT?

We detect the buyer's country and, if they have an intra-EU tax ID, we validate it in VIES at the moment of the order. We apply 0% with a valid B2B tax ID, IOSS for EU B2C under 150 euros, local rates for B2C via your branch and 0% on non-EU exports. The corresponding tax records are logged.

What if Shopify or Holded are down?

The queue holds the webhooks and retries with exponential backoff for 24 h. If it is still failing after that, it alerts the team by email or Slack for manual resolution. No order is ever lost: the queue is persisted.

Do I have to install an app in Shopify?

No. We work with native webhooks and the standard Admin API. That means your theme, your current apps and your checkout keep working exactly the same. Zero footprint on the store.

Does it work with Shopify Plus, multi-store and Markets?

Yes. Each store or market can go to its own invoicing series in Holded, with its own per-country VAT mappings. It is the typical setup we build for brands with an international presence.

Shall we talk about your Shopify integration?

A 30-minute call, no strings. You leave with scope and a price.