Skip to content
Build 6ff80cd

Gladly Customer Lookup

When a customer emails PopSockets support (or an agent opens their conversation), Gladly — the customer-support CRM — asks our integration layer who the customer is and what they ordered, so the agent sees order context inline. The lookup is read-only against OMS and crosses three Camel services: cm-ext-service-expcm-order-prccm-osor-sys → OMS.

Verified current state — 22 July 2026

Traced against the master branches of cm-ext-service-exp, cm-order-prc, and cm-osor-sys, the served Config Server values, and production logs. The flow replaced the equivalent Mule flow (fulfill-exp POST /osor/details) and went to production on 11 March 2026; the entry-point contract was carried over unchanged, so Gladly only needed a URL and credential repoint at cutover.

Production lookups are failing — as of 22 July 2026

Every production lookup — roughly 1,500 per day, all real traffic — is rejected with 401 at cm-ext-service-exp's Basic Auth check, and has been for at least the full 15-day log retention window. The credential file has not changed since the March go-live, which points at the Gladly-side stored credential. Whether to fix or sunset is tied to the pending proposal to replace Gladly with Richpanel (PAP-6704).

To re-check: Datadog query service:popint-cm-ext-service-exp-int-prod "AUTH FAILURE" — the healthy signal is "Received Gladly request to exp layer".

Lookup sequence

sequenceDiagram
    participant Gladly as Gladly CRM<br/>lookup adapter
    participant APIM as Azure APIM<br/>API gateway
    participant Exp as cm-ext-service-exp<br/>Camel HTTP ingress
    participant Prc as cm-order-prc<br/>lookup branch and mapping
    participant Sys as cm-osor-sys<br/>OMS adapter
    participant OMS as OMS<br/>order system (Rails)

    Note over Gladly: fires when a customer emails support<br/>or an agent opens a conversation
    Gladly->>APIM: POST /{env}/cm-ext-service-exp/osor/details<br/>subscription key + Basic Auth
    APIM->>Exp: forward
    Note over Exp: Basic Auth validated in-app<br/>(prod: rejecting since at least 7 Jul 2026)
    Exp->>Prc: POST /gladly/order-details<br/>body forwarded unchanged

    alt lookupLevel = basic
        Prc->>Sys: POST /order/gladly-order-details-basic<br/>email
        Sys->>OMS: GET /api/v3/customers?email=...
        OMS-->>Sys: matching customer profiles
    else any other lookupLevel (treated as detailed)
        Prc->>Sys: POST /order/gladly-order-details-detailed<br/>customer_id, email, from, to
        Note over Sys: customer_id is not forwarded —<br/>the query keeps order_id, email, from, to
        Sys->>OMS: GET /api/v3/osor_order/orders?email=...&from=...&to=...
        OMS-->>Sys: orders in the 90-day window
    end

    Sys-->>Prc: raw OMS JSON
    Note over Prc: reshape into Gladly's results[] contract
    Prc-->>Exp: Gladly-format response
    Exp-->>Gladly: results[]
    Note over Gladly: customer and order context<br/>appear on the agent's screen

Every hop between Camel services goes out through APIM and back in — public gateway URL with a per-hop subscription key — not cluster-internal DNS.

The two lookup levels

Basic (lookupLevel: "basic") answers who is this customer? Gladly sends an email address; OMS returns matching customer profiles (id, name, billing address, email), one Gladly result per match.

Detailed (any other lookupLevel) answers what did they order? The window is fixed at the last 90 days (from/to computed in cm-order-prc). OMS returns the customer's orders, which cm-order-prc reshapes into Gladly transactions[] — order number, status, total, tracking number and URL, and line items with SKUs and image URLs.

Service responsibilities

Service Endpoint Role
cm-ext-service-exp POST /osor/details Entry point. Spring Basic Auth validated in-app (users-{env}.xml); forwards the body unchanged to cm-order-prc
cm-order-prc POST /gladly/order-details Branches on lookupLevel, builds the OMS query parameters, and owns all response mapping from OMS shapes to Gladly's results[] contract
cm-osor-sys POST /order/gladly-order-details-basic · POST /order/gladly-order-details-detailed Converts the parameters into a URL-encoded GET query and calls OMS with the X-USER-TOKEN service token
OMS GET /api/v3/customers · GET /api/v3/osor_order/orders Source of truth for customers and orders

Per-environment hosts for the OMS endpoints are in the OMS endpoint map.

Configuration

All URLs come from the Config Server (no hardcoded hosts):

Key Consumed by Points at
order-prc.gladly.order-details cm-ext-service-exp cm-order-prc /gladly/order-details via APIM
osor-sys.gladly.order-details-basic / -detailed cm-order-prc the two cm-osor-sys endpoints via APIM
oms.gladlyFetchOrdersBasic / oms.gladlyFetchOrdersDetailed cm-osor-sys the two OMS endpoints
oms.accessToken cm-osor-sys OMS X-USER-TOKEN value

Gladly itself holds two credentials: an APIM subscription key and a Basic Auth user that must match an entry in cm-ext-service-exp's users-{env}.xml. Gladly also signs each request with its own HMAC header (gladly-authorization), which we do not verify.

Sharp edges

These are all verified in current master code:

  • customer_id is silently dropped. cm-order-prc sends it for detailed lookups, but cm-osor-sys only forwards order_id, email, from, to — so detailed lookups effectively match by email and date window only.
  • A detailed lookup without an email returns 500 — the mapping code takes the first email unconditionally.
  • Only one email is searched. If Gladly sends several emails, the parameter map keeps the last one.
  • Unknown lookupLevel values take the detailed branch — the check is basic/else, not basic/detailed/reject.
  • Cross-order product bleed. Each transaction's fulfillments[0].productIds lists product ids from all returned orders, not just that order's.
  • Constants: every transaction has note: "Note" and an empty customerOrderUrl; the 90-day lookback is a hardcoded constant evaluated in the pod's timezone.

History

  • Aug–Sep 2024 — Gladly replaces Zendesk company-wide.
  • Nov 2024 – Jan 2025 — Mule build: fulfill-exp exposes POST /osor/details backed by osor-gladly-basic-search-impl / osor-gladly-details-search-impl, calling the same OMS endpoints (AD-939 and satellites; OMS side OS-1842/OS-1845).
  • Feb–Mar 2026 — Camel rebuild (CI-259, CI-260, CI-261, CI-263). cm-ext-service-exp was created for this flow — the Gladly entry point was its first responsibility, before it grew the Cirro webhook and fulfillment surfaces.
  • 11 March 2026 — Production release: cm-ext-service-exp 1.0.0, cm-order-prc 1.2.0, cm-osor-sys 1.1.0.
  • July 2026 — PAP-6704 proposes replacing Gladly with Richpanel; production lookups found failing (see warning above).

Running it locally

The onboarding track covers this flow end-to-end: 5A · Gladly Local Setup boots the entry service alone; 5B · Complete Gladly Local Flow runs all three services against sandbox OMS with the inter-service URLs pinned to localhost.