yallabuy

n8n community nodes for YallaBuy — the Public API v1 action node (orders, products, inventory, customers, returns, marketing, analytics) and the signed merchant-webhook trigger (16 event types, §3.1 HMAC verification).

Documentation

n8n-nodes-yallabuy

n8n community nodes for YallaBuy — the commerce & ERP
platform. Two nodes, one credential:

Node What it does
YallaBuy (action) Drives the YallaBuy Public API v1 — 19 resources across orders, products, inventory, customers, returns/refunds, coupons/promotions/bundles, analytics/finance, POS shifts, staff/branches, restaurant, search, activity/security and the storefront design engine.
YallaBuy Trigger Receives YallaBuy merchant webhooks — the 16 subscribable event types — with full §3.1 HMAC signature verification.

Install

n8n Cloud / self-hosted (Community Nodes UI): Settings → Community Nodes →
Install → enter n8n-nodes-yallabuy.

Self-hosted (manual):

cd ~/.n8n/nodes            # create it if it does not exist
npm init -y                # once
npm install n8n-nodes-yallabuy
restart n8n

Development (this repository):

cd packages/n8n-nodes
npm install
npm run build              # tsc + icon copy → dist/
# point a local install at it:  npm install <absolute path to this folder>

Credentials — YallaBuy API

  1. In YallaBuy: Dashboard → Settings → API — create an API credential.
    Copy the ybapi_… token once (it is hashed server-side and cannot be
    shown again).
  2. Grant only the scopes your workflow needs. Mutating orders/inventory and
    the other high-risk operations additionally require the credential's
    high-risk flag to be enabled in the dashboard — without it those calls
    answer 403 FORBIDDEN.
  3. In n8n, create the YallaBuy API credential:
    • Base URL — https://yallabuy.app (or your deployment / staging).
    • API Token — the ybapi_… token.
    • Webhook Signing Secret / Previous — only for the Trigger node (below).

Test connection: the credential test calls GET /api/v1, the platform's
auth echo. 200 = live, and the echo shows the credential's scopes and bound
stores. Note: YallaBuy ships its Public API behind a server-side kill switch —
if the deployment has not set PUBLIC_API_ENABLED=true, every request
(including a valid token) answers 503 API_DISABLED. That is the platform
policy, not a bad token.

How authorization works (worth knowing)

  • Requests are Authorization: Bearer ybapi_….
  • The store set is server-derived. No store/tenant id is ever sent: the
    credential's bound stores ∩ currently-owned ∩ ACTIVE, recomputed on every
    request. A store that is paused or transferred drops out immediately
    (403 NO_AUTHORIZED_STORE when none remain).
  • Rate limits are per credential (the 429 carries Retry-After):
    reads 60/min (heavy analytics 20/min), standard writes 20/min, high-risk
    writes 10/min, bulk 5/min.

YallaBuy (action node)

Resource → operation, with dynamic dropdowns for products, customers,
branches and dining tables (type in the dropdown to search), Return All
on every cursor-paginated list, and expression support everywhere.

Coverage

Resource Operations
Store Get Profile · Get Settings · Get Feature Flags · Get Setup Status · Get Builder Context · Get Design Context
Product Create · Get · Get Many · Update · Archive · Get Many Serials
Order Create · Get · Get Many · Update Status · Dispatch · Decide Cancellation Request · Advance Kitchen Status · Transfer Table · Release Table
Customer Create · Get 360 · Get Many · Update · Delete
Inventory Get Many · Get Overview · Get Item · Get Many Movements · Receive Stock · Adjust Inventory · Bulk Preview · Bulk Apply
Return Create · Get · Get Many · Get Many Requests · Review Request · Refund Approval · Refund Execution
Coupon Create · Get Many · Update · Delete
Promotion Create · Get Many · Get Performance · Update · Delete
Bundle Create · Update · Delete
Marketing Get Overview
Analytics Sales · Product Performance · Business Insights · Business Overview · Action Center · Profit & Loss · Get Many Expenses
Shift Get Many · Get
Staff Get Many · Get
Branch Get Many
Restaurant Get Floor Plan · Get KDS Board · Get Kitchen Config
Search Search Everything
Activity Get Many
Security Login History · Staff Activity · Security Activity
Store Design Get Design Context · Propose · Preview · Diff · Verify · Apply

Behaviors that mirror the platform's contracts

  • Idempotency. Order Create, Receive Stock, Adjust Inventory and Return
    Create are keyed writes: the node always sends an Idempotency-Key
    (UUID). Leave the field empty and a fresh key is generated per item —
    an accidental replay cannot double-place an order or double-book stock.
    Set an explicit key when you want deterministic retries.
  • Server-side repricing. Order Create sends product/variant ids only —
    the checkout authority reprices from the live catalog and enforces the
    WEBSITE channel (DELIVERY / TABLE / PICKUP). POS-channel orders are
    register-only by design and cannot be created from the API.
  • Stock only through the authorities. Product Update cannot change stock
    or replace variants — the platform deliberately refuses both; stock moves
    through Receive/Adjust so every change has a ledger movement.
  • Refunds are evidence-recorded. Refund Approval / Execution record the
    external reality (amount, method, External Reference — required); the
    platform enforces the caps (order total − Σ prior refunds; the approved
    amount) and books the drawer movement for CASH on an OPEN shift itself.
  • Promotion type is immutable after creation; deleting a promotion is a
    one-way archive; deleting a coupon archives it only when redemption
    history exists.
  • Grouped reads are not flattened. Inventory, inventory movements,
    customers, serials, branches, the security reads and the restaurant reads
    return the platform's grouped per-store shape as one item (they have no
    cursor). Cursor lists (products, orders, returns, return-requests,
    coupons, promotions, shifts, staff, activity, expenses) honor Return
    All
    by following pagination.next_cursor.
  • Errors are the API's own words. Failures surface the stable error code
    and request_id (e.g. YallaBuy API INVALID_STATE_TRANSITION — request_id: req_…) — quote the request id when contacting support.

A note on boolean list filters

The API's schemas declare boolean query filters (is_available, active),
but the current query transport coerces numbers only — sending them as query
strings answers 400 VALIDATION_ERROR today. The node therefore does not
expose those filters; filter after fetching (or use the search filters),
and they can be re-added once the transport coerces booleans.

YallaBuy Trigger

YallaBuy pushes at-least-once, signed webhook deliveries for 16 event
types:

order.created · order.status_changed · order.cancellation_requested ·
order.cancellation_decided · return.created · return.requested ·
return.request_decided · refund.executed · product.created ·
product.updated · product.deleted · inventory.received ·
inventory.adjusted · coupon.redeemed · kitchen.status_changed ·
shift.closed

(plus the non-subscribable ping test event from the dashboard's
"Send test event" button.)

Setup

  1. Add the trigger node and copy its production URL. YallaBuy dials only
    public HTTPS on port 443 or 8443 (no userinfo, no private/loopback
    hosts, redirect hops re-validated) — n8n Cloud URLs qualify; a
    self-hosted n8n must sit behind a public HTTPS front on an allowed port.
  2. In YallaBuy: Dashboard → Settings → Integrations → Webhooks → create
    an endpoint with that URL and the same event types you selected in the
    node. Copy the whsec_… secret — it is shown once.
  3. Paste the secret into the credential's Webhook Signing Secret. During
    a secret rotation, put the old value in Previous for the 24 h overlap.

Registration is manual by design: YallaBuy's webhook management API is
dashboard-session-authenticated only, so the node cannot create/unregister
endpoints itself. Events are generated only while the endpoint is ACTIVE,
and there is no backfill — enable the endpoint early.

What the node enforces

  • Signature verification (§3.1): webhook-signature: v1=<hex> must be
    HMAC-SHA256 over <timestamp>.<endpoint_id>.<event_id>.<delivery_id>.<body>
    with your whsec_ secret (current, then previous during rotation), within
    a ±300 s window, compared constant-time. Bad/missing/stale signatures
    answer 401 without starting the workflow.
  • Dedupe: deliveries are retried with backoff (at-least-once). The node
    remembers webhook-delivery-id for one hour per n8n instance — a redelivery
    answers 200 without re-triggering.
  • Event filter: an endpoint may be subscribed to more types than the node
    selects; filtered deliveries answer 200 but do not start the workflow.
  • Item shape: the item JSON is the platform envelope
    {id, type, api_version, tenant_id, data} — except the three first-generation
    events (order.created, order.status_changed, return.created) whose
    fields are flat next to the envelope. The delivery headers are echoed under
    webhook_event_type, webhook_delivery_id, webhook_event_id,
    webhook_endpoint_id. Payload size rules: 64 KB cap, items capped at 100
    (items_truncated), costs (COGS) are stripped platform-wide.

Test mode note: n8n's "Listen for test event" waits on the
/webhook-test/… URL, but YallaBuy dials the URL registered on the
endpoint. To exercise a real delivery, activate the workflow and press
Send test event in the dashboard (a ping arrives; with no subscribable
types selected it will not trigger a filtered node — use Listen to All, or
subscribe to a real type and make a small change in the dashboard).

Patterns

Order created → enrich → notify:
YallaBuy Trigger (order.created) → YallaBuy (Order → Get, id from
$json.data.order_id or the flat order_id) → your channel node.

Hourly reconcile (webhooks + polling):
Schedule Trigger → YallaBuy (Order → Get Many with
Updated Since = last run, Return All) → compare against your local store.
updated_since accepts any ISO instant with timezone; every mutating table
carries a server-maintained updated_at.

Approved cancellation auto-pilot:
YallaBuy Trigger (order.cancellation_requested) → IF requested_by = CUSTOMER and reason in a set → YallaBuy (Order → Decide Cancellation
Request, APPROVED) — the platform executes the cancellation atomically
(including stock reversal).

Files

packages/n8n-nodes/
├── credentials/YallaBuyApi.credentials.ts   Bearer ybapi_ credential + /api/v1 test + whsec_ fields
├── nodes/YallaBuy/
│   ├── YallaBuy.node.ts                     action node — the execute() switch over 19 resources
│   ├── YallaBuyTrigger.node.ts              webhook trigger — §3.1 HMAC verify, dedupe, event filter
│   ├── GenericFunctions.ts                  transport: auth, cursor pagination, error shaping, HMAC, catalogs
│   ├── descriptions/*.ts                    per-resource operation & field definitions
│   └── yallabuy.svg
├── index.ts
├── gulpfile.js                              icon copy for dist/
├── tsconfig.json                            strict, ES2019/commonjs → dist/
└── package.json                             n8n manifest (n8nNodesApiVersion 1)

License

MIT

Discussion