node-red-contrib-tdn-sts-gen2 1.1.0

Node-RED nodes for cloud POS transaction and reporting APIs: PKCE OAuth2 token, closed-check pollers, menu and tender reference tables

npm install node-red-contrib-tdn-sts-gen2

node-red-contrib-tdn-sts-gen2

Node-RED nodes for working with a cloud POS transaction API:

  • sts-oidc-token — authenticates against an OpenID Connect provider using the OAuth2 Authorization Code Flow with PKCE
  • sts-gen2-poller — watches enabled locations and revenue centres for newly closed (paid) checks and emits each one exactly once
  • bi-reference — builds menu item and tender name lookup tables from the reporting API's dimensions endpoints
  • bi-checks-poller — polls the reporting API for closed guest checks, resolving names from those tables

Both pollers emit the same message shape, so one downstream formatter serves either source.

Install

From your Node-RED user directory (typically ~/.node-red):

npm install node-red-contrib-tdn-sts-gen2

Both nodes appear in your palette after install and a restart of Node-RED.

Token node (sts-oidc-token)

The token node performs the full six-step authentication flow on each incoming message:

  1. Generates a PKCE code verifier + SHA-256 challenge
  2. GET /oidc-provider/v1/oauth2/authorize — captures session cookies
  3. Replays the cookies to POST /oidc-provider/v1/oauth2/signin with your API account credentials
  4. Extracts the authorization code from the returned redirectUrl
  5. POST /oidc-provider/v1/oauth2/token with the code + verifier
  6. Caches the token in node context and reuses it until expiry — repeated messages do not re-authenticate while the cached token is valid

Usage

Send a message with a msg.credentials object:

msg.credentials = {
    authHost:     "https://<your-auth-host>",  // OIDC provider host only, no path
    clientId:     "<client-id>",
    username:     "<api-account-username>",
    password:     "<api-account-password>",
    orgShortName: "<org-short-name>"
};
return msg;

All five fields are required; the node reports a specific error and status for any missing field.

On success the message passes through with the token attached:

msg.tokenOut = {
    access_token:  "...",
    id_token:      "...",   // typically used as the Bearer token for API calls
    refresh_token: "...",
    expires_in:    "...",
    token_type:    "Bearer"
}

Use msg.tokenOut.id_token in the Authorization: Bearer header for downstream API requests.

Node status

The node shows its exact state in the editor: validating input, requesting token, cookies stored, token stored, token valid, token expired, or a specific error state.

Poller node (sts-gen2-poller)

The poller node runs its own non-overlapping poll loop (default every 15 s) and queries the checks endpoint once per enabled (location, revenue centre) pair, capped at a configurable number of parallel requests. It emits only closed checks, exactly once each — checks without payment tenders or line items are held back so no partial receipt is ever dispatched downstream.

It is driven entirely from global context:

global.set("cfg", { apiBase: "https://<api-host>/api", orgShortName: "..." });
global.set("locations", [
  { locRef: "loc1", name: "Site 1", enabled: true,
    rvcRefs: [ { rvcRef: 101, name: "Bar", enabled: true } ] }
]);

The work list is rebuilt from locations on every cycle, so enabling or disabling a location or revenue centre takes effect on the next poll without a redeploy.

Token handling: wire the token node's output into the poller's input — any message carrying msg.tokenOut is consumed as a token push. The poller can also fall back to a configurable global context key. On a 401/403 it drops the cached token, emits a token-kind error, and keeps polling with backoff.

Outputs (4): status, closed checks, open checks (off by default), errors. Closed-check messages carry msg.payload (full check), msg.summary (flat record with location/revenue-centre refs, totals, and tenders), and msg.topic = locRef/rvcRef for routing.

Input commands (msg.topic or string payload): poll, start, stop, reset.

Why closed-only polling works: the API's sinceTime filter matches check creation time, so every check created inside the configurable lookback window (default 240 min) reappears in each poll until it ages out. Whenever it closes, the next poll sees the closed status and emits it. Set the lookback longer than the longest-lived open check.

Reporting API nodes (bi-reference, bi-checks-poller)

The reporting API is an alternative source for closed checks. It differs from the transaction API in two ways that matter:

  • its change filter matches modification time, so a check that opens at 09:00 and closes at 10:00 reappears when it closes — no large lookback window is needed
  • its check detail lines carry only numbers (menu item number, tender number), never names

bi-reference solves the second point: it loads menu item and tender name tables per location and stores them in global context, keyed by number, so a lookup is a direct index. Run it once at startup (menus change rarely). The dimensions endpoints return no prices, so the poller computes each unit price from the transaction itself (line total ÷ quantity) and can write those learned prices back into the table.

bi-checks-poller then polls closed guest checks per enabled location, filters to enabled revenue centres, resolves names from the tables, and emits each newly closed check exactly once — normalised to the same msg.summary and msg.payload.menuItems shape as the transaction poller. Because the API requires a business date and venues roll over well after midnight, it queries the last two business dates each cycle by default.

global.set("cfg", {
    biBase: "https://<reporting-host>",
    apiBase: "https://<api-host>/api",
    orgShortName: "..."
});

Notes

  • Credentials should come from context or a secure store — never hard-code them in a flow.
  • Some providers expire API account passwords on a fixed schedule and lock the account temporarily after repeated failed sign-ins — handle credential rotation accordingly.
  • The token is cached per node instance (node context) and re-requested only after expires_in elapses.

License

MIT

Node Info

Version: 1.1.0
Updated 3 days ago
License: MIT
Rating: not yet rated

Categories

Actions

Rate:

Downloads

12 in the last week

Nodes

  • sts-oidc-token
  • sts-gen2-poller
  • bi-reference
  • bi-checks-poller

Keywords

  • node-red

Maintainers