Tom Sailors
· Refreshed
Brief · Anonymized case study

US & Canada Split with Unified Customers

Split a single store into region-specific frontends by syncing customers bidirectionally, bridging inventory from one central source to both store locations, routing customers to the correct region at checkout based on their address, and funneling all orders back to a unified log. The merchant's customers see one account across both stores, inventory stays in sync, and fulfillment teams work from a single order stream.

A DTC merchant operating on a single Shopify store needed to split operations into separate US and Canadian storefronts while maintaining a unified customer identity, synchronized inventory across both regions, and smart checkout routing based on shipping address. The challenge was preventing customer friction, inventory oversell, and order routing complexity across the two stores.
Four pieces
B2B / Wholesale

Unified Customer Sync

Keeps one customer record synced across both US and Canadian stores so they stay logged in and their order history is visible everywhere.

Custom Shopify app + Storefront API
Admin GraphQL explorer graphql
# Admin GraphQL - Sync customer to secondary store
mutation SyncCustomerAcrossStores($input: CustomerInput!) {
  customerUpdate(input: $input) {
    customer {
      id
      email
      firstName
      lastName
      defaultAddress {
        countryCode
        provinceCode
      }
      metafield(namespace: "sync", key: "paired_store_id") {
        value
      }
    }
    userErrors {
      field
      message
    }
  }
}

# Use this mutation to apply the same email/name to the paired store
# and set a metafield linking them
# Variables:
# {
#   "input": {
#     "id": "gid://shopify/Customer/123456",
#     "metafields": [
#       {
#         "namespace": "sync",
#         "key": "paired_store_id",
#         "type": "single_line_text",
#         "value": "us-store-id"
#       }
#     ]
#   }
# }
Run this on both stores to link paired accounts; a background job watches for new signups and auto-mirrors them to the secondary store.
Inventory

Shared Inventory Bridge

Reads stock from one central source and pushes the same quantities to both stores so products never oversell across regions.

Heroku backend + inventory sync service
Admin GraphQL explorer (run once per store location) graphql
# Admin GraphQL - Adjust inventory on both stores after central sync
mutation AdjustInventoryBothStores($input: InventoryAdjustQuantitiesInput!) {
  inventoryAdjustQuantities(input: $input) {
    inventoryAdjustmentGroup {
      id
      reason
      changes {
        delta
        quantityAfterChange
        item {
          id
          sku
        }
        location {
          id
          name
        }
      }
    }
    userErrors {
      field
      message
    }
  }
}

# Call this mutation twice — once for US store locations, once for Canadian
# Variables example for US location:
# {
#   "input": {
#     "name": "Sync from warehouse",
#     "reason": "central_stock_source",
#     "changes": [
#       {
#         "inventoryItemId": "gid://shopify/InventoryItem/456",
#         "locationId": "gid://shopify/Location/us-warehouse",
#         "delta": 42
#       }
#     ]
#   }
# }
The backend pulls from your warehouse system on schedule and calls this twice to sync US and CA locations in lockstep.
Storefront

Checkout Region Router

Detects a customer's shipping address at checkout and automatically redirects them to the correct store if they're in the wrong one.

Theme app extension + Checkout UI
theme/snippets/region-router.liquid, then include from theme.liquid liquid
{% comment %}
  Place in theme/snippets/region-router.liquid
  Called from checkout.liquid or cart drawer
{% endcomment %}

{% if customer %}
  {% assign shipping_country = customer.default_address.country %}
  {% assign current_store_region = shop.metafields.region.code | default: 'us' %}
  
  {% if shipping_country == 'US' and current_store_region == 'ca' %}
    <div class="region-notice">
      <p>You're shipping to the US. Redirecting you to our US store...</p>
      <script>
        window.location.href = 'https://us-store.myshopify.com' + window.location.pathname;
      </script>
    </div>
  {% elsif shipping_country == 'CA' and current_store_region == 'us' %}
    <div class="region-notice">
      <p>You're shipping to Canada. Redirecting you to our Canadian store...</p>
      <script>
        window.location.href = 'https://ca-store.myshopify.com' + window.location.pathname;
      </script>
    </div>
  {% endif %}
{% endif %}
Set shop metafield 'region.code' to 'us' or 'ca' on each store so the snippet knows which store it is.
Operations

Post-Purchase Event Hub

Sends every order from both stores to a central log so email, fulfillment, and BI tools see one unified order stream.

Shopify Flow + webhook dispatcher
Shopify Flow editor: When → Then flow
Trigger: Order Created (fires on both US and CA stores)

Condition: Always (no filter needed)

Actions:
  1. Send HTTP POST to central event hub
     URL: https://your-backend.herokuapp.com/orders/dispatch
     Body: Include order.id, order.customer.id, order.name, order.billing_address.country_code
     
  2. Send to Klaviyo (or your email platform)
     Event: "order_placed"
     Properties: order number, customer email, store region
     
  3. Log to data warehouse (or Airtable)
     Create record with: Order ID, Store Region, Customer ID, Total

Result: Every order lands in one place regardless of which store it came from.
Set up one flow on each store with the same HTTP endpoint; the backend dedupes by order ID.

Got a similar problem?

Sketch your build in 30 seconds — voice, type, or attach a screenshot.

Sketch the build →