The System Integration Playbook: Connecting CRM, Finance and Operations Without Breaking Them
How to connect the systems a business already runs so data stops being re-typed: map the records, pick one owner for each, design flows around business events, plan for failure and monitor every flow.

- Best for
- Operations, finance and IT leaders tired of re-typing data
- You will get
- 5 decisions to make, with a checklist
- Reading time
- 14 minutes
- Updated
- 13 October 2026
- 01Who this playbook is for
- 02Why integration is now the default problem
- 03The playbook at a glance
- 04Step 1: Map the records
- 05Step 2: Pick one source of truth per record
- 06Step 3: Design flows around business events
- 07Step 4: Plan for failure
- 08Step 5: Monitor every flow
- 09Step 6: Replace manual work one flow at a time
- 10Clean the data before you connect it
- 11The first load and the ongoing flow
- 12Testing integrations
- 13How to measure success
- 14When not to integrate
- 15Choosing the first flow
- 16Keeping integrations healthy after launch
- 17Integration platform or custom code?
- 18Security checklist
- 19Common mistakes
- 20Questions to ask an integration partner or tool vendor
- 21Checklist
- 22A worked example: order to invoice
- 23How we approach it at CodeWorx
How do you integrate business systems like CRM, finance and operations?
Decide which system owns each record, connect the systems through their APIs around business events, make every flow safe to retry so duplicates cannot create a second invoice or order, send failures to an exception queue a person can resolve, and monitor every flow. Replace manual exports one flow at a time, starting with the one that costs the most re-typing or causes the most errors.
01Who this playbook is for
Operations and finance leaders, and the engineers who support them, in businesses where the same customer, order or invoice is typed into two or three systems. If month-end involves reconciling spreadsheets, or a customer can be "active" in one system and "closed" in another, this is for you.
02Why integration is now the default problem
Businesses rarely run one system any more. Okta's Businesses at Work 2025 report puts the average at around 101 applications per company. Each was bought for a good reason. Together they leave people doing the integration by hand: exporting, re-typing and checking.
Good integration is not about connecting everything to everything. It is about deciding where each piece of information lives, and moving it reliably when something happens in the business.
03The playbook at a glance
| Step | Output |
|---|---|
| 1. Map the records | A one-page record map: what exists, where, who changes it |
| 2. One owner per record | A source-of-truth decision for each record type |
| 3. Flows around events | A named list of flows, each triggered by a business event |
| 4. Plan for failure | Retry, duplicate and exception handling for every flow |
| 5. Monitor | Volume, failures and delay per flow, with alerts |
| 6. Roll out one flow at a time | A rollout order, starting with the most expensive manual step |

04Step 1: Map the records
List the records that matter: customers, contacts, deals, jobs, orders, invoices, payments, products. For each one, note every system that holds a copy and who changes it.
| Record | Systems that hold it | Who changes it | Pain today |
|---|---|---|---|
| Customer | CRM, finance, support desk | Sales, accounts | Addresses differ between systems |
| Job | Job system, finance | Operations | Completed jobs invoiced late |
| Invoice | Finance, CRM | Accounts | Sales cannot see what is unpaid |
| Product and price | Spreadsheet, website, finance | Commercial team | Prices change in one place only |
This map is usually the most valuable page in the whole project. It turns "our systems don't talk" into a specific list of records that disagree.
05Step 2: Pick one source of truth per record
Each record type gets one owner system. The CRM might own customers and deals, the finance system invoices and payments, and the job system delivery. Every other copy becomes a reference that is updated from the owner and never edited by hand.
Most integration problems are ownership problems. Decide ownership first and the engineering becomes simpler.
Ownership can be split by field when it has to be. The CRM owns a customer's contacts and sales stage; finance owns their credit terms and billing address. Write the split down, field by field, for each shared record.
Why this is harder than it sounds
Melvin Conway observed in 1968 that organisations which design systems are constrained to produce designs that copy their own communication structures (How Do Committees Invent?). Sales, finance and operations each chose a tool for their own work. Agreeing ownership is a conversation between those teams, and it needs a decision-maker who can settle disputes.
06Step 3: Design flows around business events
Integrate around moments the business recognises, not around tables:
- A deal is won in the CRM
- A job is created in the operations system
- The job is completed and signed off
- An invoice is raised in finance
- The payment is recorded and the CRM is updated
Each event triggers one flow with a name, an owner and a clear definition of done. Small, named flows are easier to test, monitor and change than one large sync that copies everything every night.
Choosing how each flow is triggered
| Approach | How it works | Good for | Watch out for |
|---|---|---|---|
| Webhooks | The source system calls you when something changes | Near real-time flows from modern SaaS | Missed calls if you are down; verify signatures |
| Polling | You ask the source for changes on a schedule | Systems without webhooks | Delay and API limits |
| Event bus or queue | Events are published once and delivered to each consumer | Several systems reacting to one event | Needs monitoring and duplicate handling |
| Scheduled batch | Files or bulk API calls at set times | Large volumes, reporting, legacy systems | Data is only as fresh as the last run |
Most businesses use more than one. The choice is per flow, based on how fresh the data needs to be and what the systems support.
07Step 4: Plan for failure
Systems go down, events arrive twice or out of order, and data does not always match. Design for it from the first flow.
Make every flow safe to retry
If a flow fails halfway and runs again, it must not create a second invoice or a second order. Integration specialists call this idempotency. The Idempotent Receiver pattern describes a receiver that can safely get the same message more than once. Payment providers build it into their APIs: Stripe, for example, lets a client send an idempotency key so a retried request returns the original result instead of charging twice.
In practice: give every event a unique id, store the ids you have processed, and skip any you have seen.
Never write to two places and hope
A common bug: the job system saves a completed job, then calls finance to raise the invoice. If the second call fails, the job is complete and the invoice never exists. The transactional outbox pattern fixes this by saving the change and an "invoice needed" event in the same database transaction, then delivering the event separately until it succeeds. Either both happen or neither does.
Handle the rest explicitly
- Retries with back-off when a system is unavailable, with a limit.
- Ordering rules for events that can arrive out of sequence, such as a payment before its invoice.
- An exception queue where a person resolves what the rules cannot, with enough context to act.
- An audit trail of what moved, when and why, so disputes can be settled from facts.
08Step 5: Monitor every flow
Track three numbers for each flow:
| Measure | Why it matters | Alert when |
|---|---|---|
| Volume | Shows the flow is alive | It drops to zero during working hours |
| Failures | Shows data is not arriving | Failures exceed an agreed threshold |
| Delay | Shows how stale the target is | The oldest unprocessed event is older than agreed |
Alert the owning team, not a shared inbox. A weekly look at the exception queue shows where the process itself needs fixing, which is often more valuable than the alert.
09Step 6: Replace manual work one flow at a time
Start with the flow that costs the most re-typing or causes the most errors. Run it alongside the manual process until the numbers match for a full cycle, such as a month-end close. Then switch off the manual step and move to the next flow.
A worked example
A services business re-types every won deal from its CRM into its job system, and every completed job into its accounting system.
- Flow 1, deal won → job created. Owner: operations. Trigger: CRM webhook. Duplicate key: the CRM deal id. Exception: deals with no service address go to a queue for sales.
- Flow 2, job completed → invoice raised. Owner: finance. Trigger: outbox event from the job system. Duplicate key: job id. Exception: jobs with unpriced extras go to accounts.
- Flow 3, payment recorded → CRM updated. Owner: finance. Trigger: accounting webhook, with a nightly check for missed payments.
Each flow ships separately, runs in parallel with the manual process for one cycle, then replaces it.
10Clean the data before you connect it
Connecting two systems with bad data spreads the bad data faster. Before the first flow goes live:
- Match records across systems. Decide how a customer in the CRM is recognised in finance: a shared id if one exists, otherwise a matching rule such as company registration number or billing email. Record the match once and store each system's id against the other.
- Remove duplicates in the owner system first. Merging duplicates after they have been copied everywhere is much harder.
- Map reference values. Statuses, tax codes, currencies, units and product codes rarely match between systems. Put the mapping in one table that both people and the integration use.
- Decide what to do with history. Not every old record needs to move. Often only open and recent records do.
Mapping statuses: an example
| Job system status | Finance meaning | CRM stage |
|---|---|---|
| Scheduled | Nothing to invoice | Won, in delivery |
| Completed | Ready to invoice | Won, in delivery |
| Signed off | Invoice raised | Won, invoiced |
| Cancelled | Credit note if invoiced | Lost or cancelled |
When the mapping is written down, disagreements between teams surface in a meeting instead of in the month-end figures.
11The first load and the ongoing flow
Every integration has two parts: the initial load that brings systems into line, and the ongoing flow that keeps them there.
- Freeze the record map and the mappings.
- Load the history once, in a rehearsal environment, and reconcile totals and counts against the source.
- Repeat the rehearsal until the reconciliation is clean.
- Run the real load at a quiet time, then switch on the ongoing flow from that point.
- Run a reconciliation report daily for the first weeks: counts and totals by record type in each system.
12Testing integrations
- Use each vendor's sandbox or test environment, never production, for development.
- Keep a set of sample events, including awkward ones: duplicates, out-of-order events, missing fields, very large records.
- Replay those events on every change and check the target systems end up in the expected state.
- Test failure on purpose: switch a target off and confirm events wait, retry and then succeed without duplicates.
13How to measure success
Pick measures the business already cares about and record them before the first flow goes live:
| Measure | Before | Target |
|---|---|---|
| Hours per week spent re-typing or exporting | Measured by the team | Most of it removed for the flows built |
| Records that disagree between systems | From the reconciliation report | Close to zero, with exceptions worked daily |
| Days from job completion to invoice | From the finance system | Same day for standard jobs |
| Days to close the month | From finance | Shorter, with less manual reconciliation |
14When not to integrate
Sometimes the right answer is fewer systems, not more connections. If two tools hold the same records, serve the same team and one can do the other's job, retire one. Integrating them preserves a duplication nobody needs. The record map from step 1 usually makes these cases obvious.
15Choosing the first flow
Score the candidate flows and start with the highest total. Score each from 1 (low) to 3 (high).
| Flow | Hours saved per week | Cost of errors today | Ease (data clean, good API) | Total |
|---|---|---|---|---|
| Deal won → job created | 3 | 2 | 3 | 8 |
| Job completed → invoice | 3 | 3 | 2 | 8 |
| Payment → CRM status | 1 | 2 | 3 | 6 |
| Product prices → website | 2 | 3 | 1 | 6 |
Ties go to the flow that teaches the team the most about the systems involved. A first flow that ships quickly and visibly removes a weekly chore builds support for the rest.
16Keeping integrations healthy after launch
Integrations break most often when something changes around them, not when they are first built.
- Vendor API changes. SaaS providers version and retire APIs. Track the versions each flow uses and the vendors' deprecation notices, and test against new versions before the old ones are switched off.
- System upgrades and new fields. When a team adds a field or changes a status in its own tool, the mapping must change too. Make mapping changes part of the change process for each system.
- Ownership. Every flow has a named owner who receives its alerts and approves changes. When people move roles, ownership moves with a handover, not by default.
- Documentation. One page per flow: trigger, source, target, mapping, duplicate key, exception handling and owner. It takes an hour to write and saves days when something goes wrong.
17Integration platform or custom code?
Integration platforms and workflow tools work well for simple, low-volume flows between popular products. Custom integration code, or a small integration service, is better when flows carry business rules, need careful duplicate handling, run at volume or involve systems with no ready-made connector. Many businesses use both. Decide per flow, and make sure every flow, whatever it runs on, is monitored and has an owner.
18Security checklist
- Use a separate service account for each integration, with the narrowest permissions it needs.
- Keep API keys and tokens in a managed secrets store, never in code or spreadsheets.
- Verify webhook signatures.
- Log what moved without logging sensitive values in full.
- Review access when people or vendors change.
19Common mistakes
- Syncing everything, everywhere. A two-way sync of whole records between systems that both allow edits creates conflicts nobody can resolve. Decide ownership and move changes one way per field.
- Starting with the hardest flow. The flow with the messiest data and the weakest API is a poor first project. Start where the payoff is clear and the systems are cooperative.
- Treating the exception queue as optional. Without it, failures disappear into logs and the business quietly goes back to spreadsheets.
- Building on a personal account. Integrations that run under one employee's login stop when that person leaves or changes their password.
- No reconciliation. If nobody compares counts and totals between systems, small drifts become month-end surprises.
- Forgetting the people. Staff who used to re-type data need to know what changed, what they should now check, and who to tell when something looks wrong.
20Questions to ask an integration partner or tool vendor
- Which system will own each record, and how will you handle fields owned by different systems?
- What happens when the same event arrives twice, or arrives before the event it depends on?
- Where do failed records go, and who sees them?
- How will we know a flow has stopped, and how quickly?
- How do you handle the first load of historical data, and how will we reconcile it?
- What happens when one of our vendors changes or retires its API?
- Who will own each flow after launch, and what documentation will we receive?
21Checklist
- Records mapped and owners agreed, field by field where needed
- Flows named after business events, each with an owner
- Every flow safe to retry, with duplicate protection
- No dual writes: outbox or equivalent for changes that must reach another system
- Exception queue with a named person working it
- Monitoring and alerts per flow
- A rollout order, starting with the most expensive manual step
22A worked example: order to invoice
A wholesaler takes orders in its e-commerce platform, ships from a warehouse system and invoices from its accounting package. Following the playbook, the record map makes the platform the owner of orders, the warehouse the owner of shipments and accounting the owner of invoices. The first flow is "order shipped" to "invoice drafted", because unbilled shipments are the costliest gap. Each event carries an idempotency key so a retry cannot create a second invoice, failures go to a queue the finance team works each morning, and a daily check compares shipped orders with invoices raised. Only when that check stays clean for a month does the manual invoicing step stop.
23How we approach it at CodeWorx
Integration is most of what we do for operations-heavy clients. Our consistent finding: the record map and the ownership decisions take less time than the engineering and save more money. We build flows that can be retried safely from day one, because retrofitting duplicate protection after the first double invoice is always harder. See integration and automation and our blueprint for connecting CRM, finance and job systems.
Your next steps
- Map which system owns each kind of record before writing any integration. Most integration problems are ownership problems.
- Design each flow around a business event, such as a deal won or an invoice paid, not around a nightly sync of everything.
- Plan for failure from the start: retries, duplicate protection, out-of-order events and an exception queue a person can work.
- Never write to two systems and hope both succeed. Record the change and the event together, then deliver the event.
- Replace manual work one flow at a time, running old and new side by side until the numbers match.
References
- Enterprise Integration Patterns: Idempotent Receiver Gregor Hohpe and Bobby Woolf, enterpriseintegrationpatterns.com
- Idempotent requests Stripe API documentation
- Transactional outbox pattern AWS Prescriptive Guidance
- How Do Committees Invent? Melvin E. Conway, Datamation, April 1968
- Businesses at Work 2025 Okta, March 2025








