ERP solution

ERP solutions from One Stop Software connect the operational core of your business – inventory, orders, finance, purchasing – and integrate it with everything around it. We work with NetSuite, Microsoft Dynamics, and the accounting and ERP platforms mid-sized businesses actually run.

Integration Over Replacement

Ripping out an ERP is a last resort – expensive, disruptive, and risky. Far more often the win is integration and configuration: making the ERP you have talk to your CRM, your ecommerce, and your operational tools so data stops being rekeyed and reports stop being assembled by hand. We will tell you honestly when integration is enough and when it genuinely is not.

  • ERP integration with CRM, ecommerce, and operational systems – see CRM and ERP integration
  • Configuration and customization to match your workflows
  • Data migration and reconciliation, validated before go-live
  • Reporting and dashboards over ERP data that leaders will actually use
  • Automation of the order-to-cash and procure-to-pay steps done manually today

Tell us your ERP and what it does not connect to – we will scope the integration or improvement that removes the manual work.

What ERP Integration Actually Involves

ERP integration services get described as connecting systems, which undersells where the effort goes. Moving a record between two systems is the small part. The work is agreeing what a customer is in both places, deciding which fields are authoritative on each side, handling the records that already exist twice, and defining what happens when the receiving system rejects something overnight.

Budget your attention for master data and error handling. The connection itself is rarely the hard part. When a vendor describes a connector as a short configuration task, ask what it does with a customer that exists in both systems under slightly different names.

Master Data Is the Project

Before any ERP and CRM integration is built, these need answers in writing.

  • The customer: which system creates one, and what happens to the other system’s copy
  • The item or service: whether the CRM quotes from the ERP catalog or maintains its own list
  • Pricing: one source, or a documented rule for what happens when they differ
  • GL and cost codes: whether operational categories map cleanly onto the finance chart of accounts
  • The key: a stable identifier present in both systems, owned by one of them, and never re-used

Signs Integration Is Enough, and Signs It Is Not

Integration is the right call when the ERP holds your financial history, your people know how to use it, and the complaint is about rekeying, reporting, or a missing connection to another tool. Those are solvable at the seams without putting the general ledger at risk.

Replacement earns a serious hearing when the version you run has left vendor support, when the data model cannot represent something central to how you now do business, when the customization keeping it alive has become the reason you cannot upgrade, or when the vendor has ended the product line. Those are structural limits, and no amount of integration fixes a system that cannot hold the record you need.

Ask the Vendor About the API Before the Demo Ends

Whether you are keeping your ERP or choosing a new one, the integration surface decides how much of the next few years gets spent working around it. The general questions, documentation you can read without a login, sandboxes, rate limits, deprecation policy and full data export, sit on the Platforms page and apply to any system you buy. The ERP-specific ones are narrower and get asked less often.

A vendor who treats these as unusual questions has told you something useful, and the same questions apply to the CRM on the other side of the integration.

  • Can the API post transactions, or only read them, and which document types are excluded
  • What happens to a call that lands in a closed accounting period
  • Can a test environment be refreshed with real balances, and who is permitted to do it
  • Are there batch windows or month-end locks when integrations are expected to stand down
  • Which fields are validated by the API, and which are validated only in the user interface
  • What is the audit trail for a record created by an integration rather than by a person

Cutover, Parallel Running and the Reconciliation Nobody Plans

Go-live is a data event before it is a software event. Balances have to tie, open orders have to land in the right state, and somebody has to sign off that the numbers in the new system match the numbers in the old one. Decide who reconciles, against what, and what the threshold is for proceeding. Plan the fallback too, including how long the old system stays readable and who keeps that access.

Order-to-cash and procure-to-pay are where manual work hides: the order retyped from an email, the purchase order raised in a spreadsheet, the invoice assembled by hand from a job sheet. Those steps are where an integration or an automation shows up in someone’s actual week, and they make a better starting point than the module nobody has complained about.

What the Build Needs From You Before It Starts

The scoping conversation is about systems. The build is about access and answers. A connector can be specified in a week and then sit for a month because nobody can log in to the test instance, or because the question of which side wins on a price field has no owner who will answer it in writing.

Test data is the requirement people underestimate. Synthetic records pass because they were written to pass. The useful test set is a period that has already closed, run end to end and reconciled against what the ERP reported for it at the time, because that period contains the records nobody would have invented: the credit note against a canceled order, the invoice paid in two parts, the customer created twice in one afternoon by two different people.

The rest is a short list, but the items on it are hard to substitute:

  • A named person per object who can settle which system owns which field, available while the mapping is being written rather than at sign-off
  • Credentials for a dedicated integration account in each system, scoped to the permissions the job actually needs, with a rotation policy that will not expire the account without warning
  • A non-production instance to build against, or an explicit decision that there will not be one and the first passes run against production with a read-only account
  • Access to whatever the record passes through before it reaches the ERP: the ecommerce platform, the CRM, the field service app, the mailbox an order arrives in as an attachment
  • Booked time from finance during the reconciliation window, since that work cannot be staffed by the integration team alone

Error Handling Is a Design Decision, Not a Log File

A rejected record has to end up somewhere a person will look. The common failure is not that an integration lacks error handling. It is that the error handling writes to a log file on a server nobody opens, and the first sign of trouble is a customer asking where their order went.

Decide, per object, whether a failure stops the batch or is set aside so the rest continues. Stopping is right for journal entries, where a partial posting is worse than a late one. Continuing is usually right for sales orders, where twelve good orders should not wait behind one carrying a bad ship-to address. Either way, the set-aside records need a queue with a state on each row, so a person can see what failed, why, and whether it was retried, and so a corrected record can be resubmitted without anyone hand-editing the target system.

Retries need a limit and a backoff. An integration that retries a permanently invalid record every five minutes across a weekend generates thousands of identical alerts and trains everyone to ignore the channel they arrive in. Separate the two kinds of failure at the point of the error: a 5xx response or a dropped connection is worth retrying because the system was unavailable, while a 4xx validation rejection is not, because it will fail identically forever until the data itself changes.

The Duplicate Nobody Meant to Create

Idempotency is the property that submitting the same request twice has the same effect as submitting it once, and most ERP APIs do not give it to you for free. If the API assigns the document number on receipt, a second POST of the same invoice produces a second invoice. The way to get idempotency is to carry your own key: write the source system's identifier into a field on the ERP document and check for it before posting rather than after.

The case this protects against is a write that succeeded while the response was lost. The connector posts, the gateway times out or the connection resets, and the job has no way to distinguish a failed post from a successful post it never heard about. Retrying blindly is a common source of duplicate financial records created by an integration. A pre-check on the external key turns that ambiguity into a lookup.

That same key is what makes the numbers answerable later. When a total in the ERP does not match the total in the source system, the first question is which records are in one and not the other. It is a minute of work if every integrated document carries the identifier of the record that created it, and a research project if it does not.

Testing on Data That Behaves Like Production

Volume is the part of production a test instance usually does not reproduce. A job that handles two hundred orders in a demo can time out at four thousand, not because the logic is wrong but because a default page size, a per-record round trip, or a synchronous posting loop that was invisible at small numbers becomes the entire runtime. Test at month-end peak, inside the window the job will actually be given.

The other gap is data that is legal but strange. Production holds an address line longer than the target field, a customer name with an ampersand or a non-Latin character that breaks a query built by string concatenation, a quantity of zero, a line discount of one hundred percent, or a code that was deactivated after the record was created. None of these are error cases in the source system. All of them are error cases at the boundary.

Before go-live, the test set worth insisting on is a short list of specific situations rather than a count of records that passed:

  • The target system taken down mid-run on purpose and then brought back, to prove the job resumes without re-posting what already landed
  • The same record submitted twice, to confirm the second attempt is recognized rather than creating a second document
  • A reversal, meaning a credit note, a return, or a cancellation, which often follows a different document path than the original and gets tested last if at all
  • A record created just before midnight in one time zone and checked against the timestamp the ERP stored it under, since a job filtering on modified date against a server in another zone will silently skip or repeat a day
  • A run started while the previous run is still going, since a schedule that overlaps itself is a routine way a job that worked for months starts producing doubles

When This Is Not the Work You Need

Some requests that arrive as integration requests are answered better elsewhere, and it is cheaper to find that out before a connector exists to be maintained.

Two cases come up often. When the actual complaint is that nobody can see a number, the ERP often already holds the data and the work is a report, not a connector. And when the volume is genuinely low, a person handling twenty records a week costs less than a connector that has to be monitored, re-authenticated, and re-tested after every vendor update on both sides. The threshold is not the record count, it is what an error in one record costs: twenty invoices a week justify a level of care that twenty newsletter signups do not.

The shape of the data also decides which service fits. If what needs to move is documents rather than transactions, the quotes, signed orders and delivery notes attached to a job, that is document management work sitting alongside the ERP rather than a field-level sync. If technicians are working from printouts while the ERP holds the job record, the fix lives in field service. And if the goal is that an approval given in email lands against the right ERP record without a second pass, the connection point is often Microsoft 365 rather than the ERP API.

Frequently Asked Questions

What does ERP integration work exclude?

It is integration work rather than an ERP replacement project. A connector does not re-implement a module the ERP already has, rewrite the customizations sitting inside it, or change your license and support relationship with the ERP vendor, and upgrades to the ERP product itself arrive on the vendor's schedule. What a connector can add is a custom field or record on the ERP side to receive data the standard model does not carry. What it cannot do is make the ERP treat that field as part of its own logic, because posting rules, approvals and standard reports will not know it exists.

What has to already exist before an integration can be built?

A usable interface on both sides: a documented API, a supported file exchange, or a vendor-sanctioned database view, with credentials someone is actually able to issue. If the ERP is an on-premise version whose only integration path is writing directly to its tables, raise that in the first conversation, because direct table writes bypass the validation and posting logic the application applies and are the kind of change a vendor will decline to support afterward. Missing credentials and an unavailable decision maker are both able to hold up a build that is otherwise ready to proceed.

Does the ERP have to be cloud-hosted for this to work?

No. An on-premise ERP is normally integrated through a component that runs inside the same network and makes outbound calls, so the firewall change is permitted egress rather than an inbound port opened to the internet. What you need to supply is a host for that component that stays powered on and gets patched, and is not somebody's desktop, plus a decision about where its credentials are stored. A site-to-site VPN or a private link is the alternative when the cloud side has to initiate the connection.

Does data move in real time or on a schedule?

Usually on a schedule, and that is normally the right answer. Real time in the strict sense means the source emits an event and the connector reacts, which requires the source to support webhooks or a message queue and requires the ERP to accept a write at any moment, including during a close. Scheduled runs pull records changed since a stored watermark, which is easier to restart and easier to reason about when something goes wrong. Ask what the business actually needs, because "before the warehouse picks in the morning" is a schedule, not a latency requirement.

Should fields sync in both directions?

Rarely, and only where a real workflow demands it. One-way flow means one system is right and the other displays a copy, which is much cheaper to debug because a wrong value has only one place it could have come from. A two-way field needs a written tiebreaker for the case where both sides changed since the last run, and last-write-wins by timestamp is acceptable for a description and wrong for a quantity or a price. Where two-way is genuinely required, it is usually one or two fields rather than a whole object.

Do we need to upgrade the ERP before integrating it?

Sometimes, and it is worth checking before anything is scoped. The API surface differs by version: endpoints, filters and bulk operations get added over releases, so an older version may not expose the document type you need, or may expose it only through an older protocol with different authentication. A heavily customized instance is the other case, because customization can change validation behind an endpoint so the API stops behaving the way the vendor documentation describes. Read the documentation for the version you actually run, not the current one on the vendor's site.

What do we have to decide, as opposed to provide?

The error policy, which is the decision a developer cannot make correctly on your behalf. For each object, choose whether a record arriving without a required code is rejected and queued for a person, or accepted with a default and corrected later. Rejection keeps the ledger clean and creates a queue somebody has to work every day; a default keeps records flowing and puts approximate numbers in front of finance until someone fixes them. It is reasonable to answer that differently for a sales order than for a journal entry.