Skip to content

Self-Serve ERP Onboarding + Open-Source Connector Strategy

Status: Draft / planning groundwork Author: David Boone (research-assisted) Date: 2026-06-14 Source: 3-pass deep-research (NetSuite/BC/Epicor/legacy OSS code inventory + onboarding-pattern survey), adversarially verified. Findings mirrored in agent memory at project_erp_integration_expansion_research_2026_06_14.


Two linked objectives:

  1. Learn from open-source ERP integration code so we can build connectors for ERPs we don’t have sandbox access to β€” weighted NetSuite β†’ Business Central β†’ Epicor Kinetic, plus Aptean and legacy/on-prem (AS/400, greenscreen).
  2. Design a self-serve ERP onboarding path as smooth as our existing Gmail OAuth flow, covering both the connection/auth mechanics and the end-to-end product UX.

Scope: full quote-to-cash lifecycle β€” read reference data out (customers, pricing tiers, inventory, item masters) and write orders / POs / invoices in. We already own the WhereFour integration; this expands the pattern.


2. The onboarding pattern (what every leader converged on)

Section titled β€œ2. The onboarding pattern (what every leader converged on)”

Merge Link, Airbyte Embedded, Paragon Connect Portal, and Nango Connect UI all implement the same architecture β€” and it’s the same handoff shape as our Gmail OAuth flow:

  1. Embeddable, vendor-hosted UI component dropped into the app. It generates the right credential form per provider (OAuth popup / API-key form / token fields / custom) β€” the app never hand-rolls per-ERP flows.
  2. Backend mints a short-lived session token (e.g. Merge link_token, Nango createConnectSession β†’ 30-min token). The frontend uses it to open the component.
  3. End user authorizes β†’ vendor stores credentials server-side β†’ backend receives a stable long-lived connection ID for subsequent calls. Credentials never touch our codebase (aligns with our β€œnever write secrets to files” rule).
  4. Connection test/validation is built into the component. Field mapping is a separate, later step β€” most ERP connectors lead with auth and defer mapping.
Customer in Ordermatic app ──"Connect your ERP"──▢ Embeddable Connect UI
(select ERP Β· capture creds)
β”‚
Ordermatic backend
(session token Β· server-side creds)
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
Cloud-API route Legacy / on-prem route
(OAuth / TBA token) (outbound tunnel agent)
β”‚ β”‚
NetSuite Β· BC Β· Epicor On-prem ERP (AS/400)
(direct REST / SOAP) (behind firewall Β· no inbound)

The connection layer (Connect UI + session-token handoff + encrypted creds) is where we decide adopt Nango vs. build. The read/write layer (orders/POs/invoices/pricing) is ours regardless, seeded from the OSS inventory in Β§5.


Recommendation: adopt the pattern, prototype with Nango, keep the ERP logic ours.

Nango is the only live, adoptable open-source building block (Supaglue is MIT but dead/archived since Mar 2024; Merge/Codat/Rutter/Fivetran/Airbyte-Embedded are SaaS-only; Paragon’s engine is closed).

What Nango gives us:

  • 800+ APIs incl. dedicated NetSuite + Microsoft Business Central auth pages.
  • Named Connect UI (nango.openConnectUI()), driven by a 30-min Connect Session token; white-labelable.
  • AES-256-GCM credential encryption at rest (NANGO_ENCRYPTION_KEY).
  • Self-hostable: documented 5-Node-service Docker architecture; managed OAuth + token refresh + authenticated proxy.

Three caveats that decide the call:

  1. License = Elastic License 2.0 (source-available, self-host freely, no reselling as a managed service). Their β€œfully open source” marketing is inaccurate. Fine for internal product use; confirm with counsel given we’re a SaaS.
  2. Free self-host tier = Auth + Proxy only. The Functions primitive (custom integration logic), webhooks, branding, SSO require paid Enterprise self-hosting.
  3. For NetSuite/BC, Nango provides AUTH only β€” NO pre-built read/write syncs. Order/PO/invoice/pricing logic is still custom (built from Β§5).

Decision path: run a self-hosted Nango spike (free Auth+Proxy tier) to validate the NetSuite + BC auth UX end-to-end. Then decide adopt-vs-build. If ELv2 or the Enterprise-gated Functions tier is a dealbreaker, we now have the exact blueprint (session-token handoff, AES-256-GCM at-rest, per-provider form generation) to build a thin in-house equivalent on top of our existing Gmail OAuth machinery.


4. Per-ERP credential models (the forms the wizard renders)

Section titled β€œ4. Per-ERP credential models (the forms the wizard renders)”
ERPAuthFields to capture
NetSuiteToken-Based Auth (OAuth 1.0a / HMAC-SHA256)account/realm + consumer key/secret + token id/secret (5 fields). Email/password not supported. Optional OAuth 2.0 client-credentials β†’ Bearer.
Business CentralOAuth 2.0Client ID / Secret / Tenant ID / Environment URL, against OData/REST.
Epicor KineticBearer tokenPOST /TokenResource.svc β†’ bearer, then REST over Erp.Bo.*.
Legacy / AS-400n/a (no public API)On-prem agent path (Β§6).

The 5-field NetSuite TBA model is corroborated by four independent codebases β€” it’s the canonical form to design around.


5. Open-source connector code inventory (seed code for the read/write layer)

Section titled β€œ5. Open-source connector code inventory (seed code for the read/write layer)”

License legend: βœ… permissive & safe to adapt Β· ⚠️ stated-but-unconfirmed or stale Β· ❌ no license (reference-only) Β· 🚫 copyleft (study-only).

RepoLifecycleLicenseMaintainedWorth learning
fylein/netsuite-sdk-pyWrite + pricingβœ… MITβœ… active (v3.1.2, Dec 2025)Strongest write ref. Per-record-type classes that create invoices/vendor bills/journal entries/customers w/ typed records, sublist + RecordRef field-mapping. Read/write capability-gating (post() only where writable). SOAP/zeep (transport doesn’t transfer to REST).
jacobsvante/netsuiteWriteβœ… MITβœ… low-velocity (2025)One client over SOAP + REST + RESTlet behind one Config; generic add/update/upsert/upsertList + REST post/put/patch. Best for TBA passport + multi-protocol packaging.
Petercw94/restsuiteWriteβœ… MIT⚠️ stale (2023)Cleanest REST write mechanics; OAuth 1.0a HMAC-SHA256 + the load-bearing Prefer: transient header.
vinikira/netsuite-generic-restletWriteβœ… MIT⚠️ stale (2022)Generic SuiteScript RESTlet β†’ N/record CRUD; dynamic-vs-standard sublist line-item write paths (needed for orders).
julbrs/netsuite-api-clientWrite⚠️ MIT (unconfirmed)βœ… active (v1.1.0, Jun 2026)Modern TS transport: OAuth-1.0a/TBA signing + generic request() + SuiteQL pagination/streaming; auto-sets prefer: transient.
ehmad11/netsuite-restReadβœ… MIT⚠️ archived Jan 2026SuiteQL POST-query + TBA signing + HATEOAS + metadata-catalog browsing to discover record shapes at runtime (good for reading price-level/item tables).
dturton/netsuite-nodejs-api-clientReadβœ… MIT⚠️ ~stalePaginate async-generator following links[rel=next]; streams large price-level SuiteQL sets.
kslater3/suitepyWrite❌ none⚠️ staleMinimal single-file REST CRUD; confirms endpoint/verb conventions only.
bernsteinmatt/netsuite-utilitiesRead UIβœ… MITβœ… activeSuiteQL editor w/ schema-cached autocomplete over the record catalog. Read-UI pattern.
Airbyte source-netsuiteRead🚫 ELv2community/alphaProduction-grade OAuth1/TBA HttpStream authenticator. Read-only; ELv2-restricted β€” structural template, not copy.

Pricing reads are thin in OSS: only fylein has confirmed pricing code. Practical path = SuiteQL SELECT against PriceLevel/item-price tables (patterns in ehmad11/dturton).

RepoLifecycleLicenseWorth learning
microsoft/ALAppExtensions β€” APIV2 Sales Orders pageWriteβœ… MITBest BC β€œwrite orders IN” ref. Models quote-to-cash transitions as server-side OData bound actions (ShipAndInvoice) rather than raw field writes. Note: active BC app code is migrating to microsoft/BCApps (also MIT).
RepoLifecycleLicenseWorth learning
TAIT-Towers/epicor-erp-apiWrite⚠️ MIT (unconfirmed)salesOrder.js + purchaseOrder.js create via the canonical GetNewβ†’mutateβ†’Update dataset idiom (server-side defaults/pricing populate). Best Epicor write ref. Confirm license.
Kopachris/EpycorWriteβœ… BSD-3Dynamic-dispatch over REST + BAQ + EFX; verb-by-method-name routing; documented GetNew/Update create flow.
bconner/Epicor-Rest-PostmanSamplesWrite❌ noneCanonical worked example: token auth + POST /Erp.Bo.SalesOrderSvc/SalesOrders then /OrderDtls. Reference shapes only.
dltHub Epicor sourceReadβœ… Apache-2.0 (dlt)Config-driven OData/REST over Erp.Bo.*. AI-generated scaffolding, not a maintained package.
RepoRoleLicenseWorth learning
cloudflare/cloudflaredTransportβœ… Apache-2.0Outbound-only reverse-tunnel agent; zero inbound ports. Already in our VMS prod stack.
fatedier/frpTransportβœ… Apache-2.0Battle-tested reverse-tunnel relay; STCP preshared-key tunnels, default TLS, token/OIDC auth.
timmo001/iseries-apiBridge mechanicsβœ… MIT (archived)node-jt400 bridge to DB2-for-i + parameterized batch write + native PGM (RPG/CL) invocation. Take mechanics, discard architecture (wrong security posture).
tn5250jPattern🚫 GPL-2.05250 terminal-emulation for true greenscreen IBM i with no API. Study-only.
MS on-prem data gateway docsBlueprintdocsOutbound-only polling, Azure Relay bridging, TLS 1.2, cloud-encrypted creds decrypted locally. Reference design for our gateway agent.

Aptean / Wherefour: No meaningful OSS connector code. We own Wherefour already; for Aptean’s acquired products, expect the legacy/on-prem agent path + per-product REST/SOAP discovery rather than reusable OSS.


This is the existing WSO2 gateway initiative (Smith Corona/Kroy class, Justin’s M4 REST middleware, VMS POC). Research de-risks the transport choice:

  • Standardize on cloudflared as the gateway transport (already in our stack for the VMS LAN: epmsdb.vmsinc.com:1433).
  • Build a thin REST/JDBC bridge agent behind the tunnel β€” integration mechanics from iseries-api (node-jt400), security model from the MS gateway docs (outbound-only, creds decrypted on-prem at connection time, no inbound ports).
  • For true greenscreen with no data API, fall back to 5250 emulation (tn5250j pattern, study-only due to GPL).

  1. Nango self-host spike (free Auth+Proxy tier) β€” validate NetSuite + BC auth UX end-to-end; surface the adopt-vs-build decision.
  2. NetSuite connector first β€” richest OSS coverage, cleanest 5-field credential model. Seed write logic from fylein; pricing reads via SuiteQL.
  3. Business Central β€” Microsoft’s own MIT reference (ALAppExtensions/BCApps), bound-action lifecycle model.
  4. Epicor Kinetic — thinner but real; GetNew→Update from TAIT-Towers/Epycor/bconner.
  5. Legacy/AS-400 β€” cloudflared gateway + REST/JDBC bridge agent (WSO2 initiative).

  • Nango licensing: ELv2 + Enterprise-gated Functions β€” counsel sign-off + a feature-table re-check before committing (it drifts; the Functions exclusion is decision-critical).
  • Unconfirmed licenses: julbrs, TAIT-Towers stated MIT but not independently verified; bconner, suitepy have no license β†’ reference-only. Confirm before lifting code.
  • Field-mapping / first-sync UX is lightly covered vs. auth β€” most ERP connectors defer mapping past auth, so lower priority for v1, but design the post-connection screens with a dedicated look.
  • Write-in coverage is mostly generic primitives, not order-shaped helpers (fylein is the exception) β€” expect to assemble SalesOrder/Invoice payloads ourselves.

Findings adversarially verified across 3 research passes (~263 agents). Vendor-doc claims describe what vendors say β€” re-verify Nango’s tier table and the ⚠️ licenses before relying on them. Canonical home for this doc is Coda (Implementation Tracker); this worktree markdown is the authoring surface.