npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

n8n-nodes-morning

v0.1.10

Published

n8n community node for Morning (Green Invoice) — Israeli accounting and invoicing API

Downloads

1,616

Readme

n8n-nodes-morning

npm version License: MIT

n8n community node for Morning (formerly Green Invoice / חשבונית ירוקה) — the Israeli accounting and invoicing API.

Full coverage of the API surfaces a real workflow needs: documents, clients, suppliers, items, expenses, accounting classifications, business profile, and the hosted-checkout payment flow with auto-issued tax invoice + receipt. Includes a trigger node that receives Morning's notifyUrl webhooks.

Built against the live sandbox API (verified 2026-05-31).

What's included

Credentials: Morning (Green Invoice) API

  • API Key ID + Secret + Environment (sandbox / production)
  • Auto-fetches an OAuth access token via POST /idp/v1/oauth/token on the auth host (api.morning.co / api.sandbox.morning.dev) using grant_type=client_credentials — refreshed on demand via n8n's expirable token field
  • Credential test pings GET /businesses/me

Node: Morning (action)

| Resource | Operations | |---|---| | Document | Create · Get · Search · Email · Preview · Close · Open · Get Download Links · Get Info | | Client | Create · Get · Update · Search · Delete (tax ID validated client-side via mod-10) | | Supplier | Create · Get · Update · Search · Delete (tax ID validated client-side via mod-10) | | Item (Catalog) | Create · Get · Update · Search · Delete | | Expense | Create · Get · Search · Close · Open · Delete · Search Drafts · Get Statuses | | Payment | Create Payment Form · Search Links · Get Link · Search Saved Tokens · Charge Token · Create Token Link | | Transaction (עסקה) | Search · Get · Cancel · Refund · Count | | Recurring Payment (הוראת קבע) | Create · Get · Update · Delete · Search · Count · Get Jobs · Recharge · Unsuspend · Approve · Distribute · Search Failed Jobs · Export | | Retainer (ריטיינר) | Create · Get · Update · Delete · Search · Count · Get Jobs · Process Job | | Accounting | Get Classifications Map | | Business | Get Me · Get Numbering · Get Footer · Get Business Types |

65 operations across 11 resources.

Recurring Payment and Retainer wrap Morning's recurring-income features (הכנסות קבועות). A Recurring Payment (/payments/recurrings) auto-charges a saved credit-card token on a schedule; a Retainer (/retainers) auto-issues a recurring document/payment-request to a client. These two endpoint families are not in Morning's official (Apiary) API reference — paths, verbs, bodies and enums were taken verbatim from Morning's own web-app client (and confirmed against a live recurring-payment response).

Note the two resources use different interval encodings: Recurring Payment is 1 / 2 / 3 / 12 (months); Retainer is 1m / 2m / 3m / 6m / 1y. Status filters are numeric: recurring 5/10/20/30/50/60/70 (pending/created/started/finished/canceled/suspended/expired), retainer 1/2/3/10/20 (created/started/finished/paused/deleted).

The retainer create/update body is nested (from the web app's buildData()): { startDate, endDate, interval, doc: { …document fields, type }, data: { paymentTerms, description } }, built via dotted properties (doc.*, data.*). paymentTerms is a number (Immediate -1, or Net 10/15/30/45/60/75/90/120); data.description is a token (my = month-year, pmy = previous-month-year) or free text.

Transaction (/payments/transactions) reads and reverses the actual charge records behind payment forms, token charges and recurring runs — the counterpart to Payment, which creates the checkout links/forms/tokens. Search takes { documentId, from, to, page, pageSize } (dates YYYY-MM-DD) and returns a paged items[] with aggregations; Get additionally returns the full paymentData (card number/expiry/token) that Search omits. Cancel (/cancel, no body) fully voids a still-cancellable charge; Refund (/refund, body { amount } — omit for a full refund) returns money on a settled one. Both produce a new, linked reversal transaction (type: 25, negative amount, relatedTransactionId → the original). Only rows with cancellable: true can be voided. Paths/verbs were taken verbatim from Morning's own web-app payment service.

Document → Create's "Enable Online Payment" attaches an online payment link (credit card / Bit / Apple Pay / Google Pay) directly to the document being created — the same one-call flow Morning's own web app uses when you toggle online payment on a Tax Invoice. It sends paymentRequestData: { plugins: [{ id: pluginId, type: 12200, group }, ...], maxPayments } in the same POST /documents body (not a separate /payments/form call); the response carries a paymentRequestId, and once the customer pays, Morning auto-issues a linked receipt and closes the document. This is distinct from Payment → Create Payment Form, which always creates a brand-new combo document (320/400/405) from scratch rather than attaching a payment link to an existing/being-created document. Undocumented in Morning's Apiary reference — reverse-engineered from a live sandbox request captured from the web app's network traffic.

Trigger: Morning Trigger

  • Receives the form-urlencoded webhook Morning POSTs to notifyUrl after a payment
  • Optional ?token= query-param verification (Morning does not sign webhooks, so this is the recommended guard)
  • Output: parsed (camelCase normalized) or raw

Built-in helpers (so you don't trip on Morning's gotchas)

  • Israeli mod-10 (Luhn-variant) checksum validates taxId on client/supplier create before the request goes out. Rejects "123456789" with a clear error instead of waiting for Morning's Hebrew rejection. Test value 000000018 passes.
  • VAT math auto-compute (Payment → Create Payment Form): toggle "Auto-Compute Amount from Income" and the node calculates amount from income[] × vatRate per the chosen vatType. No more קיים חוסר התאמה בין סכום התקבולים לסכום התשלומים errors.

Install

Community Nodes panel (easiest — self-hosted n8n)

  1. In n8n: Settings → Community Nodes → Install.
  2. Enter the package name n8n-nodes-morning and confirm.
  3. The Morning and Morning Trigger nodes appear in the node panel.

Requires self-hosted n8n with community packages enabled (N8N_COMMUNITY_PACKAGES_ENABLED=true, which is the default). n8n Cloud only lists verified community nodes in the panel.

npm (Docker / manual)

cd ~/.n8n/custom        # mkdir -p ~/.n8n/custom first if it doesn't exist
npm install n8n-nodes-morning
# restart n8n

From source (development)

git clone https://github.com/shirser121/n8n-nodes-morning.git
cd n8n-nodes-morning
npm install
npm run build
cd ~/.n8n/custom && npm install /absolute/path/to/n8n-nodes-morning
# restart n8n

The Morning node and Morning Trigger appear in the node panel.

Getting started

  1. Generate API keys at app.greeninvoice.co.il → המשתמש שלי → כלי מפתחים → API Keys (separate tabs for sandbox vs production).
  2. Create the credential in n8n: paste id, secret, pick environment. Hit "Test" — it should green-check against /businesses/me.
  3. Discover your pluginId — drop a Morning node, Resource: Document, Operation: Get Info, Type: 320. The response contains paymentPlugins[0].id — that's your pluginId for any payment-form call.
  4. Build the payment flow:
    • Morning node → Resource: Payment → Op: Create Payment Form. Paste the pluginId. Set notifyUrl to the URL of your Morning Trigger node.
    • Morning Trigger node → set a verification token, append ?token=<value> to the URL you paste into notifyUrl.
    • Customer redirected to response.url from Create Payment Form → pays → Morning issues a tax invoice + receipt → webhook fires → workflow continues.

Gotchas built into the node (so you don't trip on them)

  • Field naming is non-obvious. The node uses Morning's exact names: income (not items), payment singular (not payments), emails always array (not email), lang (not language), remarks (not notes).
  • VAT mathamount must match income[] based on vatType. The Auto-Compute toggle on payment-form does this for you. Manual math also works — the VAT-type dropdown spells out which mode means what.
  • Documents are immutable — there is no Update operation on Document, because Morning returns 405. To fix an issued doc, create a credit note (type 330) with linkedDocumentIds, then issue a new one.
  • Clients/suppliers with docs/expenses can't be deleted — set active: false instead (via Update).
  • taxId must pass Israeli mod-10 checksum. The node validates this client-side. Test value: 000000018.
  • Expense documentType — use the supplier's invoice kind (305/320/400), NOT 10 (quote). The dropdown only shows valid options.
  • Expense number — must be ≥5 numeric digits. "INV-001" and "1001" are both rejected.
  • accountingClassification — pass the UUID id from /accounting/classifications/map, not the code or key. Use Resource: Accounting → Get Classifications Map to discover.
  • Rate limit ~3 req/s — n8n batches don't throttle by default. For high-volume workflows, add a Wait node.

Webhook security

Morning does not sign webhooks. Anything that knows your notifyUrl can forge a "paid" callback. Two guards:

  1. Use the trigger's "Verification Token (Query Param)" — append ?token=<long-random> to the URL you give Morning. The node rejects anything without a match.
  2. The trigger output's documentId is Morning's UUID. After receiving, use a Morning action node with Op: Get Document to fetch the canonical document — if the doc id is bogus, it 404s and you abort.

Notes for production

  • The session token is cached for ~50 minutes (TTL is 60). The expirable: true flag on the credential's session token field tells n8n to re-call preAuthentication when needed.
  • The notifyUrl callback comes from AWS eu-west-1 (34.255.212.236 observed) with User-Agent: GreenInvoice/2.1.
  • Body is application/x-www-form-urlencoded — n8n parses it automatically into req.body.
  • Be idempotent on documentId — Morning may retry on 5xx/timeout.
  • Return 2xx fast (≤5s). Do heavy work async via a follow-on workflow.

Project structure

n8n-nodes-morning/
├── credentials/
│   └── MorningApi.credentials.ts         JWT flow with auto-refresh
├── nodes/
│   ├── Morning/
│   │   ├── Morning.node.ts               Declarative node wiring 8 resources
│   │   ├── helpers.ts                    mod-10 checksum + VAT math + preSend hooks
│   │   ├── morning.svg                   Icon (sunrise / "Morning" branding)
│   │   └── descriptions/                 One file per resource
│   │       ├── DocumentDescription.ts
│   │       ├── ClientDescription.ts
│   │       ├── SupplierDescription.ts
│   │       ├── ItemDescription.ts
│   │       ├── ExpenseDescription.ts
│   │       ├── PaymentDescription.ts
│   │       ├── TransactionDescription.ts
│   │       ├── RecurringPaymentDescription.ts
│   │       ├── RetainerDescription.ts
│   │       ├── AccountingDescription.ts
│   │       └── index.ts
│   └── MorningTrigger/
│       ├── MorningTrigger.node.ts        Webhook receiver for notifyUrl
│       └── morning.svg
├── package.json
├── tsconfig.json
└── README.md

Development

npm install        # dev deps: n8n-workflow, typescript, eslint
npm run typecheck  # tsc --noEmit
npm run lint       # eslint
npm run build      # compile to dist/ + copy icons

dist/ is git-ignored and produced at build/publish time. Cutting a GitHub Release publishes the package to npm automatically (see .github/workflows/publish.yml).

For the n8n verified community-node badge, switch linting over to eslint-plugin-n8n-nodes-base (see the note in .eslintrc.js) and clear its findings before submitting to n8n.

License

MIT — see LICENSE.