Syncing invoices to Zoho via the dedicated n8n node
Goal
Automatically create invoices (TD01) and credit notes (TD04) in Zoho Invoice or Zoho Books
from documents generated by POP, using the official npm package
n8n-nodes-pop-zoho on your own
self-hosted n8n instance.
This is a separate, distinct package from n8n-nodes-pop (which handles SdI/PEPPOL/VIES
and, via its Sync Document to Zoho operation, also a simpler native Zoho sync — see n8n)
— install both only if you need both capabilities, or prefer this path if you want the Zoho OAuth
connection to live inside n8n itself.
Installation note: this package is published on npm but is not approved/listed on n8n’s official Community Nodes registry — n8n’s Settings → Community Nodes → Install button will not find it. It must be installed manually (see below), and as a result it doesn’t work on n8n Cloud, only on a self-hosted instance.
Prerequisites
- A self-hosted n8n instance (v2+), Node.js 18+. Not available on n8n Cloud (see note above).
- A Zoho Invoice or Zoho Books account, with an OAuth2 application created in the Zoho API Console for your region, and tax rates configured in Zoho (one entry per percentage used in your POP payloads).
- A POP account with the n8n connector enabled and a webhook already registered in the Webhooks panel.
Steps
- Manual install (n8n’s “Community Nodes” installer won’t find this package):
git clone https://github.com/getpopapi/n8n-nodes-pop-zoho.git cd n8n-nodes-pop-zoho npm install npm run build ln -s $(pwd)/dist/nodes/PopZohoInvoice/PopZohoInvoice.node.js ~/.n8n/custom/PopZohoInvoice.node.js ln -s $(pwd)/dist/credentials/ZohoInvoiceOAuth2Api.credentials.js ~/.n8n/custom/ZohoInvoiceOAuth2Api.credentials.js ln -s $(pwd)/dist/nodes/PopZohoInvoice/pop-zoho-invoice.svg ~/.n8n/custom/pop-zoho-invoice.svg n8n start - On the Zoho API Console, create a Server-based Application with
redirect URI
https://<your-n8n-instance>/rest/oauth2-credential/callback. - In n8n, create a Zoho OAuth2 (Invoice / Books) credential: product, region, Organization ID (from Zoho → Settings → Organization Profile), Client ID/Secret from the app you just created. Click Connect to complete authorization.
- Build the workflow: Webhook node (Authentication:
None, Respond:Using 'Respond to Webhook' Node, pathwebhook/zoho) → POP → Zoho node → Respond to Webhook. - Copy the Webhook node’s production URL and register it in POP’s Webhooks panel, setting the Connector field to “n8n Connector — Zoho”.
- In the POP → Zoho node, set the License Key (always the account’s default key, from
popapi.io → Account → API → API Key (default)— never a platform-specific Shopify/WooCommerce key) and click the refresh button to fetch the RSA public key.
Verify
Send a request with environment: "sandbox" (or enable Dry Run on the node): the response includes
dry_run: true and the zoho_body that would have been sent to Zoho, without creating anything for
real and without consuming quota.
Good to know
- The node’s Invoice Status field controls the status of the invoice created in Zoho: if set to
Sent, the node automatically performs the status transition Zoho requires after creation, instead
of leaving the invoice in
draft.
Common errors
auth_error— the License Key in the node isn’t the default one: POP always signs with the default key regardless of which platform generated the document.tax_not_found— one of the tax rates used in your POP payloads isn’t configured in Zoho → Settings → Taxes: add it.contact_ambiguous— multiple Zoho contacts match the same VAT/email/name: resolve the duplicate in Zoho before retrying.unsupported_doc_type— onlyTD01(invoice) andTD04(credit note) are supported in v1.
Related configuration
For the generic routing mechanism this node relies on (the /connector/zoho route, HMAC+RSA signing,
POP-side error codes), see api/connectors. To choose between this path and
the other available channels, see
choosing-an-invoicing-integration.