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.
1. Goal
Section titled β1. GoalβTwo linked objectives:
- 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).
- 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:
- 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.
- Backend mints a short-lived session token (e.g. Merge
link_token, NangocreateConnectSessionβ 30-min token). The frontend uses it to open the component. - 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).
- Connection test/validation is built into the component. Field mapping is a separate, later step β most ERP connectors lead with auth and defer mapping.
Recommended architecture
Section titled βRecommended architectureβ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.
3. Build vs. adopt: the connection layer
Section titled β3. Build vs. adopt: the connection layerβ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:
- 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.
- Free self-host tier = Auth + Proxy only. The Functions primitive (custom integration logic), webhooks, branding, SSO require paid Enterprise self-hosting.
- 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)β| ERP | Auth | Fields to capture |
|---|---|---|
| NetSuite | Token-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 Central | OAuth 2.0 | Client ID / Secret / Tenant ID / Environment URL, against OData/REST. |
| Epicor Kinetic | Bearer token | POST /TokenResource.svc β bearer, then REST over Erp.Bo.*. |
| Legacy / AS-400 | n/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).
NetSuite (richest coverage)
Section titled βNetSuite (richest coverage)β| Repo | Lifecycle | License | Maintained | Worth learning |
|---|---|---|---|---|
| fylein/netsuite-sdk-py | Write + 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/netsuite | Write | β 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/restsuite | Write | β MIT | β οΈ stale (2023) | Cleanest REST write mechanics; OAuth 1.0a HMAC-SHA256 + the load-bearing Prefer: transient header. |
| vinikira/netsuite-generic-restlet | Write | β MIT | β οΈ stale (2022) | Generic SuiteScript RESTlet β N/record CRUD; dynamic-vs-standard sublist line-item write paths (needed for orders). |
| julbrs/netsuite-api-client | Write | β οΈ 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-rest | Read | β MIT | β οΈ archived Jan 2026 | SuiteQL 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-client | Read | β MIT | β οΈ ~stale | Paginate async-generator following links[rel=next]; streams large price-level SuiteQL sets. |
| kslater3/suitepy | Write | β none | β οΈ stale | Minimal single-file REST CRUD; confirms endpoint/verb conventions only. |
| bernsteinmatt/netsuite-utilities | Read UI | β MIT | β active | SuiteQL editor w/ schema-cached autocomplete over the record catalog. Read-UI pattern. |
| Airbyte source-netsuite | Read | π« ELv2 | community/alpha | Production-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
SELECTagainst PriceLevel/item-price tables (patterns in ehmad11/dturton).
Microsoft Dynamics 365 Business Central
Section titled βMicrosoft Dynamics 365 Business Centralβ| Repo | Lifecycle | License | Worth learning |
|---|---|---|---|
| microsoft/ALAppExtensions β APIV2 Sales Orders page | Write | β MIT | Best 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). |
Epicor Kinetic
Section titled βEpicor Kineticβ| Repo | Lifecycle | License | Worth learning |
|---|---|---|---|
| TAIT-Towers/epicor-erp-api | Write | β οΈ 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/Epycor | Write | β BSD-3 | Dynamic-dispatch over REST + BAQ + EFX; verb-by-method-name routing; documented GetNew/Update create flow. |
| bconner/Epicor-Rest-PostmanSamples | Write | β none | Canonical worked example: token auth + POST /Erp.Bo.SalesOrderSvc/SalesOrders then /OrderDtls. Reference shapes only. |
| dltHub Epicor source | Read | β Apache-2.0 (dlt) | Config-driven OData/REST over Erp.Bo.*. AI-generated scaffolding, not a maintained package. |
Legacy / on-prem (AS-400, greenscreen)
Section titled βLegacy / on-prem (AS-400, greenscreen)β| Repo | Role | License | Worth learning |
|---|---|---|---|
| cloudflare/cloudflared | Transport | β Apache-2.0 | Outbound-only reverse-tunnel agent; zero inbound ports. Already in our VMS prod stack. |
| fatedier/frp | Transport | β Apache-2.0 | Battle-tested reverse-tunnel relay; STCP preshared-key tunnels, default TLS, token/OIDC auth. |
| timmo001/iseries-api | Bridge 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). |
| tn5250j | Pattern | π« GPL-2.0 | 5250 terminal-emulation for true greenscreen IBM i with no API. Study-only. |
| MS on-prem data gateway docs | Blueprint | docs | Outbound-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.
6. Legacy / on-prem agent path
Section titled β6. Legacy / on-prem agent pathβ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 (
tn5250jpattern, study-only due to GPL).
7. Recommended sequencing
Section titled β7. Recommended sequencingβ- Nango self-host spike (free Auth+Proxy tier) β validate NetSuite + BC auth UX end-to-end; surface the adopt-vs-build decision.
- NetSuite connector first β richest OSS coverage, cleanest 5-field credential model. Seed write logic from
fylein; pricing reads via SuiteQL. - Business Central β Microsoftβs own MIT reference (
ALAppExtensions/BCApps), bound-action lifecycle model. - Epicor Kinetic β thinner but real; GetNewβUpdate from
TAIT-Towers/Epycor/bconner. - Legacy/AS-400 β cloudflared gateway + REST/JDBC bridge agent (WSO2 initiative).
8. Open questions / gaps
Section titled β8. Open questions / gapsβ- 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-Towersstated MIT but not independently verified;bconner,suitepyhave 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.
9. Provenance
Section titled β9. Provenanceβ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.