Back to Blog
IntegrationsArchitectureEnterprise

Enterprise Integrations at Scale: 10+ Systems, Zero Downtime

Deep dive into integrating NetSuite, Checkout.com, HubSpot, Ziwo, and 8+ other enterprise systems into a unified platform — without breaking production.

BA
Bilal Adhi
Technical Manager
October 15, 2024
6 min read

Integrating enterprise software is one of those things that looks simple until you're three months in and realizing that every system has a different opinion about what a "customer" is.

At eZhire, we've integrated 10+ enterprise systems into a unified platform. Some integrations went smoothly. Several didn't. This is what we learned.

The Integration Landscape

Here's what we integrated, and why:

SystemCategoryWhy
Oracle NetSuiteERP / FinanceAccounting, revenue recognition, financial reporting
Checkout.comPaymentsCard processing, refunds, payment links
ZATCATax ComplianceUAE tax authority compliance
HubSpotCRMLead management, pipeline, sales automation
CrispLive ChatWebsite and in-app chat
BotSpaceWhatsAppWhatsApp Business API automation
ZiwoCall CenterTelephony, IVR, call recording
AswatVoice AnalyticsCall transcription and analytics
FirebaseMobilePush notifications, mobile backend
SlackNotificationsInternal alerting and notifications
ClearGridCollectionsDebt collection workflow automation

Eleven systems. Different APIs. Different authentication patterns. Different data models. Different failure modes.

Principle 1: Async Is Your Friend

The biggest mistake teams make with integrations is treating them as synchronous operations.

User books a car → sync to NetSuite → return success.

This works until NetSuite is having a bad day. Then your booking API starts timing out, customers can't complete bookings, and your on-call engineer is getting paged at 2am.

The correct pattern for almost all third-party integrations is:

  1. Record the event in your own system (fast, reliable)
  2. Return success to the user
  3. Asynchronously sync to the third-party system
  4. Retry failures with exponential backoff
  5. Alert on persistent failures for manual intervention

We implemented this pattern across all our integrations after learning the hard way with our initial NetSuite sync implementation.

Principle 2: Own the Data Model

Every integration wants you to adopt its data model. NetSuite wants customers to be NetSuite customers. HubSpot wants leads to be HubSpot contacts. Checkout.com wants transactions to be Checkout.com charges.

Don't do this.

Your canonical data model should live in your system. Third-party systems get their own representation of your data, synchronized from your canonical store.

This means:

  • A customer in our system has a netsuite_customer_id, a hubspot_contact_id, and a checkout_customer_id
  • When we look up a customer, we look in our database — not NetSuite
  • When we sync to NetSuite, we transform our customer model into NetSuite's model

This sounds like extra work. It is. But it means that when you switch CRM providers (and you will, eventually), you're changing one sync adapter, not your entire data model.

Principle 3: Build Idempotent Sync

Network failures happen. Servers restart. Webhooks are delivered multiple times. Your sync logic will run more than once for the same event.

If your sync logic isn't idempotent — meaning it produces the same result whether it runs once or a hundred times — you'll create duplicate data, double-charged customers, or corrupted financial records.

Every sync operation should:

  1. Check if the target already has this data
  2. If yes, compare and update if changed
  3. If no, create

Simple in principle. Surprisingly hard to implement correctly when dealing with complex nested data structures across different system schemas.

The NetSuite Integration: Our Hardest

NetSuite integration is a rite of passage for enterprise software teams. It's comprehensive, flexible, and genuinely complex.

Our NetSuite integration handles:

  • Customer records (created/updated on booking)
  • Invoice generation (rental period, extensions, late fees)
  • Payment recording (from Checkout.com webhooks)
  • Revenue recognition (rental period-based)
  • Credit notes (refunds, adjustments)
  • Collection records (overdue account status)

The hardest part was revenue recognition. A car rental spans multiple days. Revenue needs to be recognized daily, not at booking time. This required building a nightly job that creates journal entries in NetSuite for each active rental day.

Getting this right required 3 months of parallel running — our system and the old manual process running simultaneously — before finance was confident enough to switch over.

Checkout.com: Payment Webhooks Are Lies

Webhook reliability is a known problem in the industry. Checkout.com's documentation says webhooks are reliable. In practice, they're delivered at-least-once, sometimes delayed, and occasionally dropped.

Our payment processing is built around a polling fallback:

  1. Record payment initiation
  2. Receive webhook if/when it arrives
  3. Every 15 minutes, poll for any payments that are in "pending" state for more than 10 minutes
  4. Reconcile the payment status from the Checkout.com API directly

This redundancy means we have a brief window where a payment might appear pending, but we never miss a successful payment.

HubSpot + BotSpace + Crisp: The Lead Chaos Problem

Three different systems, all generating leads. A customer might:

  • Fill out the website form (HubSpot)
  • Chat on the website (Crisp)
  • Message on WhatsApp (BotSpace)

Without integration, you get three records in three systems for the same person.

We built a lead unification layer that:

  1. Captures leads from all three sources
  2. Deduplicates by phone number and email
  3. Creates a canonical lead record in our ERP
  4. Syncs back to HubSpot as the system of record for sales
  5. Links the Crisp and BotSpace conversation IDs to the lead record

The deduplication logic is the hard part. Phone numbers come in different formats. Emails are sometimes missing. Names are sometimes different. We use fuzzy matching with manual review queues for ambiguous cases.

Monitoring Integrations

Every integration should have:

  • Sync queue depth — how many events are waiting to sync?
  • Sync error rate — what percentage of syncs are failing?
  • Sync latency — how long does it take from event to sync?
  • Last successful sync — when did each integration last successfully process an event?

We built a simple integration health dashboard that shows these metrics for each of our 11 integrations. When something goes red, we know about it before a customer or executive notices.

What I'd Do Differently

Design the failure handling before the happy path. It's tempting to build the integration that works and then add error handling. Do it the other way around. Start with "what happens when the third-party system is down?" and build from there.

Be paranoid about data loss. Every event that enters your sync queue should be durably stored before you attempt to sync it. If your sync process dies mid-flight, you need to be able to replay from the durable store.

Version your integration contracts. External APIs change. Build your integration adapters to be versioned, so you can upgrade to a new API version while maintaining the old one during transition.


Enterprise integration is unglamorous work. Nobody writes blog posts celebrating a clean NetSuite sync. But it's the foundation that makes everything else work — and getting it right separates platforms that scale from platforms that constantly break.