Skip to main content
Version: v2

Customer Look up Logic using enterpriseSettings in EIMP

Legend: Class / Handler Method Field / Config Key Event API Endpoint DB Table / Column
Quick Reference
  • Purpose: Customize how customers are identified based on merchant-specific requirements
  • Configuration Location: In merchant configuration under enterprise_settings (stored as orderedCustomerSearchCriteria in the Merchant entity)
  • Key Components: OrderedCustomerSearchCriteria wraps CustomerSearchCriteria lists with precedence-based fallback
  • Pattern: Extract data from customer request → Build EIMP search payloads → Match against enterprise identity data
  • Matching Fields: Required fields must match; optional fields are excluded from the query if absent in the request
  • Invoked by: AbstractCustomerHandler.getIdentityUserBySearchId() during findOrCreateCustomer (POST /customers/find)

Overview

This document outlines the algorithm for identifying customers through the enterpriseSettings configuration in the merchant settings. The identification process involves matching customer request data with enterprise identity data using JSONPath expressions.

Key Benefits

  • Flexible Matching: Configure different identification strategies based on merchant requirements
  • Precedence-Based Fallbacks: Define primary and fallback identification methods
  • Granular Control: Mark criteria as required or optional to tune identification precision
  • Diverse Data Support: Match against various identifier types (patient IDs, subscriber IDs, etc.)

🔧 Technical Detail — Sequence Diagram: Component Interaction

This diagram illustrates the interaction between different components during the customer identification process, showing the exact sequence of API calls and data exchange.


EnterpriseSettings Structure

Configuration Structure and Properties

The enterpriseSettings configuration is stored in the enterprise_settings column of the merchant table. It is structured as an ordered list of criteria sets — each set represents one identification strategy, tried in ascending precedence order.

Key Configuration Properties

PropertyTypeDescriptionExample
merchantSearchKeyStringJSONPath expression to extract values from the CustomerRequest object$.metadata.patientId
merchantMetadataKeyStringKey to extract values from metadata in the customer request; also used as the storage key in merchant_customer_metadata during wallet upgradepatientId
enterpriseSearchKeyStringDot-notation path to locate data in the EIMP identity response; becomes the key in the IdentitySearchRequestidentifiers.rx_patientId
enterpriseValueKeyStringProperty name placed into the value map of the IdentitySearchRequest; the extracted merchant value is set under this keypatientId
valueMap<String, String>Additional context fields (e.g., sourceCode, type) merged into the IdentitySearchRequest value alongside the extracted merchant value{"sourceCode": "EEMS"}
requiredbooleanIf true, this criterion must have a matching value in the request. If false and the value is empty in the request, the criterion is excluded from the EIMP query entirely (not sent)true or false
enterpriseResponseSearchPathStringJSONPath expression for extracting values from the EIMP response during Wallet Upgrade. Not used during the initial EIMP search$.[*].identifiers.payer_memberId[*]['subscriberId']
precedence (inner)intOrder within a criteria set — used for CCG DB query ordering for performance optimization1, 2
precedence (outer)intOrder of criteria sets — controls the sequence of EIMP queries (lowest value tried first)1, 2
Precedence Clarification
  • Inner precedence (inside customerSearchCriteria): Controls the order of criteria processing within a single set, primarily for CCG database query optimization
  • Outer precedence (on OrderedCustomerSearchCriteria): Controls which criteria set is sent to EIMP first. The system sorts sets by ascending precedence and tries each until a golden record is found
🔧 Technical Detail — JSON Schema & Domain Model

The enterpriseSettings configuration maps to orderedCustomerSearchCriteria in the Merchant entity:

  • OrderedCustomerSearchCriteria: Contains a List<CustomerSearchCriteria> and a precedence value (used for ordering EIMP queries)
  • CustomerSearchCriteria: Defines a single matching criterion with all properties above
  • Merchant.orderedCustomerSearchCriteria: The parent field stored in the enterprise_settings JSON column
"enterpriseSettings": [
{
"customerSearchCriteria": [
{
"merchantSearchKey": "$.metadata.patientId",
"enterpriseSearchKey": "identifiers.rx_patientId",
"enterpriseValueKey": "patientId",
"merchantMetadataKey": "patientId",
"required": true,
"enterpriseResponseSearchPath": null,
"precedence": 1
}
],
"precedence": 1
}
]

Customer Lookup Process in EIMP

When a POST /customers/find request arrives, the system works through your configured criteria sets in precedence order, sending each as a batch query to EIMP. The first set that returns a single matching golden record wins — if all sets are exhausted without a match, a local wallet is created.

🔧 Technical Detail — Identification Algorithm (AbstractCustomerHandler.getIdentityUserBySearchId())

The identification algorithm is implemented in AbstractCustomerHandler.getIdentityUserBySearchId() and works as follows:

  1. Retrieve the merchant's orderedCustomerSearchCriteria

    • Load the Merchant entity using merchantRepository.findByMerchantId() with the X-Merchant-Id header value
    • If orderedCustomerSearchCriteria is empty or null, skip metadata-based identity lookup
  2. Sort and process each OrderedCustomerSearchCriteria set by precedence

    • Sort sets by ascending precedence value using Comparator.comparing(OrderedCustomerSearchCriteria::getPrecedence)
    • Iterate through each set as a Flux
  3. For each criterion in the set, build an IdentitySearchRequest:

    • Extract the merchant value from the CustomerRequest using JsonUtil.getJsonPathValue(customerRequest, merchantSearchKey)
    • Filter out optional criteria: If the extracted value is empty and required is false, the criterion is excluded from the EIMP query entirely
    • If the criterion's value map is present (e.g., {"sourceCode": "EEMS"}), merge the extracted value into it under the enterpriseValueKey and use the combined map as the IdentitySearchRequest.value
    • If no value map is configured, use the raw extracted value directly
    • Set IdentitySearchRequest.key to enterpriseSearchKey
  4. Send batch request to EIMP:

    • All IdentitySearchRequest objects for the criteria set are sent as a single batch via identityClient.searchUser(IdentitySearchRequest[])
    • EIMP returns an Optional<User> golden record if a single match is found
  5. Handle results:

    • If a golden record is found (Optional.isPresent()), stop iterating and return it
    • If no match or multiple matches, try the next criteria set based on precedence
    • If all sets are exhausted without a match:
      • If neither enterpriseId nor hsid was provided, throw NoValidCustomerRequestException("Customer Identifier is Missing")
      • Otherwise, return Optional.empty() (the caller will handle local wallet creation)
🔧 Technical Detail — Activity Diagram

CCG Database Lookup

The enterprise settings configuration is also used for CCG database lookups as a fallback when direct identifiers are unavailable. See the dedicated page: Customer Lookup in CCG Database


Data Extraction and Matching Process

Retrieving MCID from Customer Request via merchantSearchKey
Customer Request Example
{
"firstName": "John",
"lastName": "Doe",
"dateOfBirth": "1980-01-01",
"metadata": {
"patientId": "123456",
"subscriberId": "ABC789",
"dependentCode": "01"
}
}
  • merchantSearchKey specifies a JSONPath expression to locate and retrieve merchant customer identifier from the incoming customer request
  • The data retrieval workflow:
    1. Parse the incoming customer request into a structured JSON object
    2. Apply the JSONPath expression to pinpoint the target value
    3. Obtain the specified value for subsequent comparison operations

Common JSONPath expression patterns:

  • $.metadata.patientId - Locates and retrieves patientId from the metadata container

  • $.dateOfBirth - Accesses the dateOfBirth attribute directly

  • $.firstName - Obtains the firstName field value

    For the above request:

    • $.metadata.patientId → "123456"
    • $.dateOfBirth → "1980-01-01"
    • $.firstName → "John"
Retrieve values from enterprise identity using enterpriseSearchKey and enterpriseValueKey

The process of extracting values from the enterprise identity involves two key configuration properties:

  1. enterpriseSearchKey: Defines a path to locate the specific object within the enterprise identity data structure
  2. enterpriseValueKey: Specifies which property within that object should be extracted for comparison

Extraction Process

  1. enterpriseSearchKey Navigation:

    • The enterpriseSearchKey is a dot-notation path (not a JSONPath expression)
    • It navigates through the enterprise identity data structure
    • It often points to a specific nested object that contains identity information
  2. enterpriseValueKey Retrieval:

    • Once the target object is located using enterpriseSearchKey
    • The enterpriseValueKey specifies which property within that object to extract
    • If enterpriseValueKey is not provided, the entire object at enterpriseSearchKey is used

EIMP Response Structure

🔧 Technical Detail — Sample EIMP Response
 {
"links": null,
"identifiers": {
"identity_enterpriseId": [
{
"linking_authority": "weak",
"enterpriseID": "5183682010"
}
],
"cdb_id": [],
"finance_faroid": [],
"rx_cagmId": [],
"rx_patientId": [],
"payer_memberId": [
{
"linking_authority": "weak",
"memberId": null,
"policyNumber": null,
"subscriberId": "101417920",
"dependentCode": null,
"familyId": null,
"divisionCode": null,
"sourceCode": "EEMS",
"surrogateId": "2204187144",
"originatingSystemId": null
}
],
"hsid_identifiers": [],
"rally_identifiers": [],
"identity_personid": [],
"source_identifiers": [],
"optumCare_identifiers": [],
"other_ids": [
{
"linking_authority": "weak",
"type": "SubscriberId",
"value": "101417920",
"sourceCode": "EEMS"
},
{
"linking_authority": "weak",
"type": "SocialSecurityNumber",
"value": "702101676",
"sourceCode": "EEMS"
}
]
},
"id": "fa4bccdc-6706-494b-91fc-e589c7d3118b",
"familyName": "Flink",
"givenName": "Kristen",
"middleName": null,
"middleInitial": null,
"nameSuffix": null,
"deceasedDate": null,
"locale": null,
"chosenName": null,
"birthDate": "1972-06-24",
"gender": "F",
"createdAt": "2024-05-17 22:17:30",
"ireScore": null,
"apiIdentifier": "eyJlaWQiOiI1MTgzNjgyMDEwIiwiZmlkcyI6W10sImNyaWRzIjpbXSwiY21wc01ick51bSI6W10sImNtcHNJZHMiOltdLCJncHNJZHMiOltdLCJncHNJbmR2SWRzIjpbXSwiZGVudGFsSWRzIjpbXSwiZGVudGFsSWRzTmV3IjpbXSwiZGVudGFsQ29udHJLZXlzIjpbXSwidWhPbmVTYnNjcklkIjpbXSwiY3JNZW1iZXJTUksiOltdLCJjclNic2NySWQiOltdLCJwaG1kc0lkcyI6W10sInBwbEhsdGhNYnJJZHMiOltdLCJybWhwTWJySWRzIjpbXSwidWhPbmVNYnJJZHMiOltdLCJjc3BNYnJJZHMiOltdLCJjc3BTYnNjcklkIjpbXSwic3JjU3lzSWRzIjpbXSwic2llcnJhTWJySWRzIjpbXSwidmFzTWJySWRzIjpbXSwidmFzU2JzY3JJZCI6W10sInBobWRzU2JzY3JJZHMiOltdLCJjclNic2NySWRHcnAiOltdLCJuaWNlU2JzY3JJZEdycCI6W10sImNlc1Nic2NySWRHcnAiOltdLCJoaHNJZCI6bnVsbH0=",
"contacts": null,
"aliases": []
},
{
"links": null,
"identifiers": {
"identity_enterpriseId": [
{
"linking_authority": "weak",
"enterpriseID": "5181690299"
}
],
"cdb_id": [],
"finance_faroid": [],
"rx_cagmId": [],
"rx_patientId": [],
"payer_memberId": [
{
"linking_authority": "weak",
"memberId": null,
"policyNumber": null,
"subscriberId": "101652135",
"dependentCode": null,
"familyId": null,
"divisionCode": null,
"sourceCode": "EEMS",
"surrogateId": "2200644816",
"originatingSystemId": null
}
],
"hsid_identifiers": [],
"rally_identifiers": [],
"identity_personid": [],
"source_identifiers": [],
"optumCare_identifiers": [],
"other_ids": [
{
"linking_authority": "weak",
"type": "SubscriberId",
"value": "101652135",
"sourceCode": "EEMS"
},
{
"linking_authority": "weak",
"type": "SocialSecurityNumber",
"value": "703038534",
"sourceCode": "EEMS"
}
]
},
"id": "4b0c9c5a-74c5-43cc-8b96-353c95ef947e",
"familyName": "Struye De Swielande",
"givenName": "Shivangi",
"middleName": null,
"middleInitial": null,
"nameSuffix": null,
"deceasedDate": null,
"locale": null,
"chosenName": null,
"birthDate": "1972-06-24",
"gender": "F",
"createdAt": "2024-05-17 21:03:29",
"ireScore": null,
"apiIdentifier": "eyJlaWQiOiI1MTgxNjkwMjk5IiwiZmlkcyI6W10sImNyaWRzIjpbXSwiY21wc01ick51bSI6W10sImNtcHNJZHMiOltdLCJncHNJZHMiOltdLCJncHNJbmR2SWRzIjpbXSwiZGVudGFsSWRzIjpbXSwiZGVudGFsSWRzTmV3IjpbXSwiZGVudGFsQ29udHJLZXlzIjpbXSwidWhPbmVTYnNjcklkIjpbXSwiY3JNZW1iZXJTUksiOltdLCJjclNic2NySWQiOltdLCJwaG1kc0lkcyI6W10sInBwbEhsdGhNYnJJZHMiOltdLCJybWhwTWJySWRzIjpbXSwidWhPbmVNYnJJZHMiOltdLCJjc3BNYnJJZHMiOltdLCJjc3BTYnNjcklkIjpbXSwic3JjU3lzSWRzIjpbXSwic2llcnJhTWJySWRzIjpbXSwidmFzTWJySWRzIjpbXSwidmFzU2JzY3JJZCI6W10sInBobWRzU2JzY3JJZHMiOltdLCJjclNic2NySWRHcnAiOltdLCJuaWNlU2JzY3JJZEdycCI6W10sImNlc1Nic2NySWRHcnAiOltdLCJoaHNJZCI6bnVsbH0=",
"contacts": null,
"aliases": []
},
{
"links": null,
"identifiers": {
"identity_enterpriseId": [
{
"linking_authority": "weak",
"enterpriseID": "5183747532"
}
],
"cdb_id": [],
"finance_faroid": [],
"rx_cagmId": [],
"rx_patientId": [],
"payer_memberId": [
{
"linking_authority": "weak",
"memberId": null,
"policyNumber": null,
"subscriberId": "101410221",
"dependentCode": null,
"familyId": null,
"divisionCode": null,
"sourceCode": "EEMS",
"surrogateId": "2204330161",
"originatingSystemId": null
}
],
"hsid_identifiers": [],
"rally_identifiers": [],
"identity_personid": [],
"source_identifiers": [],
"optumCare_identifiers": [],
"other_ids": [
{
"linking_authority": "weak",
"type": "SocialSecurityNumber",
"value": "702070878",
"sourceCode": "EEMS"
},
{
"linking_authority": "weak",
"type": "SubscriberId",
"value": "101410221",
"sourceCode": "EEMS"
}
]
},
"id": "0c221b42-0bb6-4868-92b6-0fb5a79c4d72",
"familyName": "Peng",
"givenName": "Iqbal",
"middleName": null,
"middleInitial": null,
"nameSuffix": null,
"deceasedDate": null,
"locale": null,
"chosenName": null,
"birthDate": "1972-06-24",
"gender": "F",
"createdAt": "2024-05-17 22:15:03",
"ireScore": null,
"apiIdentifier": "eyJlaWQiOiI1MTgzNzQ3NTMyIiwiZmlkcyI6W10sImNyaWRzIjpbXSwiY21wc01ick51bSI6W10sImNtcHNJZHMiOltdLCJncHNJZHMiOltdLCJncHNJbmR2SWRzIjpbXSwiZGVudGFsSWRzIjpbXSwiZGVudGFsSWRzTmV3IjpbXSwiZGVudGFsQ29udHJLZXlzIjpbXSwidWhPbmVTYnNjcklkIjpbXSwiY3JNZW1iZXJTUksiOltdLCJjclNic2NySWRHcnAiOltdLCJuaWNlU2JzY3JJZEdycCI6W10sImNlc1Nic2NySWRHcnAiOltdLCJoaHNJZCI6bnVsbH0=",
"contacts": null,
"aliases": []
},
{
"links": null,
"identifiers": {
"identity_enterpriseId": [
{
"linking_authority": "weak",
"enterpriseID": "5180921055"
}
],
"cdb_id": [],
"finance_faroid": [],
"rx_cagmId": [],
"rx_patientId": [],
"payer_memberId": [
{
"linking_authority": "weak",
"memberId": null,
"policyNumber": null,
"subscriberId": "101503003",
"dependentCode": null,
"familyId": null,
"divisionCode": null,
"sourceCode": "EEMS",
"surrogateId": "2199489116",
"originatingSystemId": null
}
],
"hsid_identifiers": [],
"rally_identifiers": [],
"identity_personid": [],
"source_identifiers": [],
"optumCare_identifiers": [],
"other_ids": [
{
"linking_authority": "weak",
"type": "SocialSecurityNumber",
"value": "702442005",
"sourceCode": "EEMS"
},
{
"linking_authority": "weak",
"type": "SubscriberId",
"value": "101503003",
"sourceCode": "EEMS"
}
]
},
"id": "8c5cd775-2f1f-401f-b53c-7713fcbd9520",
"familyName": "McBrien",
"givenName": "Simone",
"middleName": null,
"middleInitial": null,
"nameSuffix": null,
"deceasedDate": null,
"locale": null,
"chosenName": null,
"birthDate": "1972-06-24",
"gender": "F",
"createdAt": "2024-05-17 21:44:30",
"ireScore": null,
"apiIdentifier": "eyJlaWQiOiI1MTgwOTIxMDU1IiwiZmlkcyI6W10sImNyaWRzIjpbXSwiY21wc01ick51bSI6W10sImNtcHNJZHMiOltdLCJncHNJZHMiOltdLCJncHNJbmR2SWRzIjpbXSwiZGVudGFsSWRzIjpbXSwiZGVudGFsSWRzTmV3IjpbXSwiZGVudGFsQ29udHJLZXlzIjpbXSwidWhPbmVTYnNjcklkIjpbXSwiY3JNZW1iZXJTUksiOltdLCJjclNic2NySWRHcnAiOltdLCJuaWNlU2JzY3JJZEdycCI6W10sImNlc1Nic2NySWRHcnAiOltdLCJoaHNJZCI6bnVsbH0=",
"contacts": null,
"aliases": []
}

Example Extraction Scenarios

Scenario 1: Simple property extraction

  • enterpriseSearchKey: "birthDate"
  • enterpriseValueKey: null (not needed for direct properties)
  • Result: "1980-01-01"

Scenario 2: Nested object property extraction

  • enterpriseSearchKey: "identifiers.rx_patientId"
  • enterpriseValueKey: "patientId"
  • Result: "123456"

Comparison Logic

Once values are extracted from both the customer request (via merchantSearchKey) and enterprise identity (via enterpriseSearchKey/enterpriseValueKey):

  1. Both values are normalized for comparison (trimming whitespace, standardizing case if needed)
  2. Values are compared for equality
  3. If values match, the criterion is satisfied
  4. If the criterion is marked required and doesn't match, the entire criteria set fails

Configuration Examples

🔧 Technical Detail — Single Criterion Configuration
Configuration
{
"customerSearchCriteria": [
{
"value": {
"patientId": "xxxxxx"
},
"merchantSearchKey": "$.metadata.patientId",
"enterpriseSearchKey": "identifiers.rx_patientId",
"enterpriseValueKey": "patientId",
"merchantMetadataKey": "patientId",
"enterpriseResponseSearchPath": null,
"precedence": 1,
"required": true
}
],
"precedence": 1
}

Logic interpretation:

  1. Extract the patient ID from the request using $.metadata.patientId
  2. Look in the enterprise identity under identifiers.rx_patientId object
  3. Extract the value of the patientId field from that object
  4. Compare the two values
  5. Since this criterion is marked as required: true, the identification fails if they don't match
🔧 Technical Detail — Multiple Criteria Configuration
Configuration
{
"customerSearchCriteria": [
{
"merchantSearchKey": "$.metadata.groupNumber",
"enterpriseSearchKey": "identifiers.payer_memberId",
"enterpriseValueKey": "policyNumber",
"required": true,
"precedence": 1
},
{
"merchantSearchKey": "$.dateOfBirth",
"enterpriseSearchKey": "birthDate",
"required": true,
"precedence": 2
}
// ...other criteria
]
}

Logic interpretation:

  1. All criteria within this set must match (all are required)
  2. Process in order of precedence (lowest number first)
  3. The customer is identified only if ALL required criteria match

Enterprise Settings Combinations and Request Payloads

Simple Direct Property Matching

Configuration:

{
"merchantSearchKey": "$.dateOfBirth",
"enterpriseSearchKey": "birthDate",
"enterpriseValueKey": null,
"enterpriseResponseSearchPath": null,
"required": true
}

Use Case: Matching simple properties at the root level of objects (DOB, names, etc.)
Behavior: Direct value equality comparison
Example: Match DOB "1980-01-01" from request with "1980-01-01" from enterprise identity

🔧 EIMP Payload — Simple Direct Property Matching
{
"key": "birthDate",
"value": "1980-01-01"
}
Nested Property Matching

Configuration:

{
"merchantSearchKey": "$.metadata.patientId",
"enterpriseSearchKey": "identifiers.rx_patientId",
"enterpriseValueKey": "patientId",
"enterpriseResponseSearchPath": null,
"required": true
}

Use Case: Matching values that are nested within objects
Behavior: Navigates to nested objects before comparison
Example: Extract "123456" from request metadata and match with pharmacy patient ID in enterprise identity

🔧 EIMP Payload — Nested Property Matching
{
"key": "identifiers.rx_patientId",
"value": {
"patientId": "123456"
}
}
Typed Identifier Matching with Context

Configuration:

{
"value": {
"type": "HealthInsuranceExchangeId",
"sourceCode": "CSP_Facets"
},
"merchantSearchKey": "$.metadata.healthInsuranceExchangeId",
"enterpriseSearchKey": "identifiers.other_ids",
"enterpriseValueKey": "value",
"enterpriseResponseSearchPath": null,
"required": true
}

Use Case: Matching identifiers that require type and source context
Behavior: Places extracted value into a predefined structure with type and source information
Example: Searching for health exchange ID in a collection of typed identifiers

🔧 EIMP Payload — Typed Identifier Matching
{
"key": "identifiers.other_ids",
"value": {
"type": "HealthInsuranceExchangeId",
"value": "0005886061",
"sourceCode": "CSP_Facets"
}
}
Multiple Criteria Sets with Fallback Mechanism

The enterprise settings configuration allows for multiple criteria sets with fallback logic. If the primary criteria set fails to identify a customer, the system automatically tries the next set based on precedence.

Fallback Logic Flow:

  1. System first tries to identify the customer using the primary criteria set (precedence: 1)
    • All required criteria in this set must match for successful identification
    • Optional criteria enhance matching confidence but are not mandatory
  2. If identification fails with the primary set, system moves to the fallback set (precedence: 2)
  3. Process continues until a match is found or all criteria sets are exhausted
  4. When all sets are exhausted without a match, system creates a local wallet
🔧 Technical Detail — Full Configuration JSON
"enterpriseSettings": [
{
"customerSearchCriteria": [
{
"value": {
"sourceCode": "CSP_Facets"
},
"merchantSearchKey": "$.metadata.dependentCode",
"enterpriseSearchKey": "identifiers.payer_memberId",
"enterpriseValueKey": "dependentCode",
"merchantMetadataKey": "dependentCode",
"enterpriseResponseSearchPath": null,
"precedence": 1,
"required": true
},
{
"value": {
"sourceCode": "EEMS"
},
"merchantSearchKey": "$.metadata.subscriberId",
"enterpriseSearchKey": "identifiers.payer_memberId",
"enterpriseValueKey": "subscriberId",
"merchantMetadataKey": "subscriberId",
"enterpriseResponseSearchPath": null,
"precedence": 2,
"required": true
},
{
"value": null,
"merchantSearchKey": "$.dateOfBirth",
"enterpriseSearchKey": "birthDate",
"enterpriseValueKey": null,
"merchantMetadataKey": null,
"enterpriseResponseSearchPath": null,
"precedence": 0,
"required": false
}
],
"precedence": 1 // Primary criteria set (tried first)
},
{
"customerSearchCriteria": [
{
"value": {
"type": "HealthInsuranceExchangeId",
"sourceCode": "CSP_Facets"
},
"merchantSearchKey": "$.metadata.healthInsuranceExchangeId",
"enterpriseSearchKey": "identifiers.other_ids",
"enterpriseValueKey": "value",
"merchantMetadataKey": "healthInsuranceExchangeId",
"enterpriseResponseSearchPath": null,
"precedence": 1,
"required": true
},
{
"value": {
"zipPostalCode": "xxxx"
},
"merchantSearchKey": "$.zip5",
"enterpriseSearchKey": "contacts.postalAddresses",
"enterpriseValueKey": "zipPostalCode",
"merchantMetadataKey": null,
"enterpriseResponseSearchPath": null,
"precedence": 2,
"required": true
}
],
"precedence": 2 // Fallback criteria set (tried if primary fails)
}
]
Customer Request Example
{
"firstName": "Kristen",
"lastName": "Flink",
"dateOfBirth": "1972-06-24",
"zip5": "12345",
"metadata": {
"subscriberId": "101417920",
"dependentCode": "01",
"healthInsuranceExchangeId": "0005886061"
}
}
🔧 EIMP Payload — Primary Criteria Set
  1. System extracts values from the customer request using each criterion's merchantSearchKey:

    • $.metadata.dependentCode → "01"
    • $.metadata.subscriberId → "101417920"
    • $.dateOfBirth → "1972-06-24"
  2. System generates EIMP request payloads for each criterion:

[
{
"key": "identifiers.payer_memberId",
"value": {
"dependentCode": "01",
"sourceCode": "CSP_Facets"
}
},
{
"key": "identifiers.payer_memberId",
"value": {
"subscriberId": "101417920",
"sourceCode": "EEMS"
}
},
{
"key": "birthDate",
"value": "1972-06-24"
}
]
  1. EIMP searches for matching records using these criteria
  2. If all required criteria match a record, customer is successfully identified
  3. If any required criterion fails to match, the entire criteria set fails
🔧 EIMP Payload — Fallback Criteria Set

If the primary criteria set fails, the system tries the fallback set:

  1. Extract values for the fallback criteria:

    • $.metadata.healthInsuranceExchangeId → "0005886061"
    • $.zip5 → "12345"
  2. Generate EIMP request payloads for the fallback criteria:

[
{
"key": "identifiers.other_ids",
"value": {
"type": "HealthInsuranceExchangeId",
"value": "0005886061",
"sourceCode": "CSP_Facets"
}
},
{
"key": "contacts.postalAddresses",
"value": {
"zipPostalCode": "12345"
}
}
]
  1. EIMP searches for matching records using these fallback criteria
  2. Customer is identified if all required criteria in this set match

Key Points:

  • Each criteria set functions as an independent identification strategy
  • Sets are tried in order of precedence (lowest number first)
  • Within a set, all required criteria must match for successful identification
  • If a set fails, the system automatically tries the next set
  • Optional criteria (required: false) provide additional matching confidence but aren't mandatory
  • All requests within a set are sent to EIMP in a single batch
Required and Optional Mixed Fields

Configuration:

{
"customerSearchCriteria": [
{
"merchantSearchKey": "$.metadata.patientId",
"enterpriseSearchKey": "identifiers.rx_patientId",
"enterpriseValueKey": "patientId",
"required": true,
"precedence": 1
},
{
"merchantSearchKey": "$.dateOfBirth",
"enterpriseSearchKey": "birthDate",
"required": false,
"precedence": 2
},
{
"merchantSearchKey": "$.lastName",
"enterpriseSearchKey": "familyName",
"required": false,
"precedence": 3
}
]
}

Behavior:

  1. The patientId is mandatory in customer request
  2. DOB and lastName are optional but provide stronger identity assurance if they match
🔧 EIMP Payload — Required & Optional Mixed Fields
[
{
"key": "identifiers.rx_patientId",
"value": {
"patientId": "123456"
}
},
{
"key": "birthDate",
"value": "1980-01-01"
},
{
"key": "familyName",
"value": "Doe"
}
]
Composite Match Identification

When a subscriber needs to be identified using multiple fields that must be matched together:

Configuration:

{
"customerSearchCriteria": [
{
"value": {
"sourceCode": "EEMS",
"subscriberId":"***"
},
"merchantSearchKey": "$.metadata.subscriberId",
"enterpriseSearchKey": "identifiers.payer_memberId",
"enterpriseValueKey": "subscriberId",
"required": true,
"precedence": 1
}
],
"precedence": 1
}
🔧 EIMP Payload — Composite Match
[
{
"key": "identifiers.payer_memberId",
"value": {
"subscriberId": "XYZ12345",
"sourceCode": "EEMS"
}
}
]

Processing Logic:

  1. All requests are sent to the identity service in a single batch
  2. The system validates that matching records satisfy all the required criteria
  3. Only records that match all required criteria will be returned as positive identifications

Fallback Mechanisms

If a merchant has multiple OrderedCustomerSearchCriteria sets, they are tried in order of their precedence value (ascending):

  1. Try the first criteria set (precedence: 1)
  2. If EIMP returns no match (or multiple ambiguous matches), try the next set (precedence: 2)
  3. Continue until a golden record is found or all sets are exhausted
  4. When all search criteria sets are exhausted, the system falls back to local wallet creation
Implementation Detail

In the code, AbstractCustomerHandler.getIdentityUserBySearchId() uses Flux.fromIterable() on the sorted list and calls .filter(Optional::isPresent).next() — meaning it short-circuits and returns the first criteria set that produces a golden record.