- Client
- Coastline Apparel (demonstration build)
- Industry
- Retail & e-commerce
- Services
- Integration architecture, Apex & Platform Events, Change Data Capture & Pub/Sub, Off-platform middleware (Node/TypeScript)
- Orders land in Salesforce in real time, verified and idempotent
- Loyalty changes sync back to Shopify automatically
- A reconciliation job backstops any missed event
- Every event logged both ways for a single source of truth
Coastline Apparel is a fictional retail brand. We built this engagement against a real Shopify store and a real Salesforce org to show the integration side of our work: two systems kept in sync in real time, built so a dropped message never means a lost order. Only the brand is invented.
The brief was the one every growing store hits. Sales happen in Shopify. The customer relationship lives in Salesforce. Keeping the two in step by hand does not scale, and a nightly export is too slow and too brittle to trust.
The challenge
A storefront and a CRM disagree the moment they stop talking. An order placed at checkout needs to be a record in Salesforce within seconds, not the next morning. A loyalty tier the team sets in the CRM needs to show up on the customer in Shopify without anyone re-keying it.
The hard part is not the happy path. It is what happens when a webhook is delivered twice, or arrives out of order, or the network drops mid-send. Get that wrong and you get duplicate orders, stale data, and a team that stops believing the numbers. So the real requirement was reliability: every event accounted for, nothing silently lost, and a way to see exactly what crossed between the systems.
The approach
We treated the seam between the two systems as the thing to design first, before any code. We wrote a contract: which system owns which data, what each message looks like, and how every failure is handled. Salesforce owns the customer relationship. Shopify owns the order. Each direction has one clear job.
Inbound, an order placed in Shopify is sent to Salesforce as a signed webhook. We verify that signature before trusting a single byte, so only genuine Shopify traffic is ever processed. The order becomes an opportunity with its line items, and the write is idempotent: if the same order arrives twice, it updates in place instead of creating a duplicate.
Outbound, a change to a customer in Salesforce is picked up through Change Data Capture and streamed out over the Pub/Sub API. A piece of middleware maps it to the Shopify customer and pushes it. The loyalty tier a rep sets in the CRM lands on the customer in Shopify on its own.
The middleware itself runs off-platform, in Node and TypeScript. Some integration work does not belong inside Salesforce, and forcing it there just to keep everything in one place is a mistake. Keeping it outside let us build it properly, with its own tests and its own failure handling, and keep the Salesforce org clean.
What we built
A verified inbound path. Shopify orders arrive as signed webhooks, get checked, and become opportunities with their line items. The order total always matches the sum of its lines, because that invariant is enforced on every write.
A real-time outbound path. CRM changes flow out through Change Data Capture and the Pub/Sub API to the store, so the loyalty tier set in Salesforce shows up on the Shopify customer without a manual step.
A reconciliation backstop. Real integrations drop messages eventually. A job runs every few hours, pulls recent orders straight from Shopify, and re-ingests anything Salesforce missed. Each order is handled in its own savepoint, so one bad record can never poison the rest of the batch.
A single source of truth for what happened. Every event in either direction writes an Integration Log record: direction, status, latency, and a reference back to the record it touched. No personal data is ever logged. When failures cross a threshold, the team gets an alert instead of finding out from a customer.
How it runs
A customer checks out on the store. Within seconds the order is a verified opportunity in Salesforce, line items and all. Nobody re-keys anything.
A rep updates a customer’s loyalty tier in the CRM. The change flows out to Shopify on its own, so the storefront reflects it without a second system to update.
Every few hours, the reconciliation job sweeps recent orders and fills any gap before it matters. And the whole time, both directions are writing to the integration log, so there is always one place to answer the question “did this go through?”
The result
A storefront and a CRM that stay in sync in real time, built so the failure cases are handled rather than hoped against. Orders are verified and idempotent. Loyalty syncs itself back. A reconciliation job catches the rest, and every event is visible on both sides.
To prove it, we ran a signed order end to end and watched it become the right opportunity in Salesforce, then changed a customer in the CRM and watched the loyalty tag appear in Shopify. We seeded the log with traffic in both directions, including deliberate failures, so the dashboard and the alerting run on real movement.
This is the integration work we bring when two systems have to behave like one: a designed contract, real-time sync both ways, and the reliability engineering that keeps it honest under load. If your storefront and your CRM are drifting apart, let’s talk.