Customer Look up Logic using enterpriseSettings in EIMP
- Purpose: Customize how customers are identified based on merchant-specific requirements
- Configuration Location: In merchant configuration under
enterprise_settings(stored asorderedCustomerSearchCriteriain theMerchantentity) - Key Components:
OrderedCustomerSearchCriteriawrapsCustomerSearchCriterialists 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()duringfindOrCreateCustomer(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
| Property | Type | Description | Example |
|---|---|---|---|
merchantSearchKey | String | JSONPath expression to extract values from the CustomerRequest object | $.metadata.patientId |
merchantMetadataKey | String | Key to extract values from metadata in the customer request; also used as the storage key in merchant_customer_metadata during wallet upgrade | patientId |
enterpriseSearchKey | String | Dot-notation path to locate data in the EIMP identity response; becomes the key in the IdentitySearchRequest | identifiers.rx_patientId |
enterpriseValueKey | String | Property name placed into the value map of the IdentitySearchRequest; the extracted merchant value is set under this key | patientId |
value | Map<String, String> | Additional context fields (e.g., sourceCode, type) merged into the IdentitySearchRequest value alongside the extracted merchant value | {"sourceCode": "EEMS"} |
required | boolean | If 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 |
enterpriseResponseSearchPath | String | JSONPath expression for extracting values from the EIMP response during Wallet Upgrade. Not used during the initial EIMP search | $.[*].identifiers.payer_memberId[*]['subscriberId'] |
precedence (inner) | int | Order within a criteria set — used for CCG DB query ordering for performance optimization | 1, 2 |
precedence (outer) | int | Order of criteria sets — controls the sequence of EIMP queries (lowest value tried first) | 1, 2 |
- Inner
precedence(insidecustomerSearchCriteria): Controls the order of criteria processing within a single set, primarily for CCG database query optimization - Outer
precedence(onOrderedCustomerSearchCriteria): Controls which criteria set is sent to EIMP first. The system sorts sets by ascendingprecedenceand 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 aList<CustomerSearchCriteria>and aprecedencevalue (used for ordering EIMP queries)CustomerSearchCriteria: Defines a single matching criterion with all properties aboveMerchant.orderedCustomerSearchCriteria: The parent field stored in theenterprise_settingsJSON 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:
-
Retrieve the merchant's
orderedCustomerSearchCriteria- Load the
Merchantentity usingmerchantRepository.findByMerchantId()with theX-Merchant-Idheader value - If
orderedCustomerSearchCriteriais empty or null, skip metadata-based identity lookup
- Load the
-
Sort and process each
OrderedCustomerSearchCriteriaset by precedence- Sort sets by ascending
precedencevalue usingComparator.comparing(OrderedCustomerSearchCriteria::getPrecedence) - Iterate through each set as a
Flux
- Sort sets by ascending
-
For each criterion in the set, build an
IdentitySearchRequest:- Extract the merchant value from the
CustomerRequestusingJsonUtil.getJsonPathValue(customerRequest, merchantSearchKey) - Filter out optional criteria: If the extracted value is empty and
requiredisfalse, the criterion is excluded from the EIMP query entirely - If the criterion's
valuemap is present (e.g.,{"sourceCode": "EEMS"}), merge the extracted value into it under theenterpriseValueKeyand use the combined map as theIdentitySearchRequest.value - If no
valuemap is configured, use the raw extracted value directly - Set
IdentitySearchRequest.keytoenterpriseSearchKey
- Extract the merchant value from the
-
Send batch request to EIMP:
- All
IdentitySearchRequestobjects for the criteria set are sent as a single batch viaidentityClient.searchUser(IdentitySearchRequest[]) - EIMP returns an
Optional<User>golden record if a single match is found
- All
-
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
enterpriseIdnorhsidwas provided, throwNoValidCustomerRequestException("Customer Identifier is Missing") - Otherwise, return
Optional.empty()(the caller will handle local wallet creation)
- If neither
- If a golden record is found (
🔧 Technical Detail — Activity Diagram
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"
}
}
merchantSearchKeyspecifies a JSONPath expression to locate and retrieve merchant customer identifier from the incoming customer request- The data retrieval workflow:
- Parse the incoming customer request into a structured JSON object
- Apply the JSONPath expression to pinpoint the target value
- 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 valueFor 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:
enterpriseSearchKey: Defines a path to locate the specific object within the enterprise identity data structureenterpriseValueKey: Specifies which property within that object should be extracted for comparison
Extraction Process
-
enterpriseSearchKeyNavigation:- The
enterpriseSearchKeyis 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
- The
-
enterpriseValueKeyRetrieval:- Once the target object is located using
enterpriseSearchKey - The
enterpriseValueKeyspecifies which property within that object to extract - If
enterpriseValueKeyis not provided, the entire object atenterpriseSearchKeyis used
- Once the target object is located using
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):
- Both values are normalized for comparison (trimming whitespace, standardizing case if needed)
- Values are compared for equality
- If values match, the criterion is satisfied
- 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:
- Extract the patient ID from the request using
$.metadata.patientId - Look in the enterprise identity under
identifiers.rx_patientIdobject - Extract the value of the
patientIdfield from that object - Compare the two values
- 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:
- All criteria within this set must match (all are required)
- Process in order of precedence (lowest number first)
- 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:
- 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
- If identification fails with the primary set, system moves to the fallback set (precedence: 2)
- Process continues until a match is found or all criteria sets are exhausted
- 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
-
System extracts values from the customer request using each criterion's
merchantSearchKey:$.metadata.dependentCode→ "01"$.metadata.subscriberId→ "101417920"$.dateOfBirth→ "1972-06-24"
-
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"
}
]
- EIMP searches for matching records using these criteria
- If all required criteria match a record, customer is successfully identified
- 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:
-
Extract values for the fallback criteria:
$.metadata.healthInsuranceExchangeId→ "0005886061"$.zip5→ "12345"
-
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"
}
}
]
- EIMP searches for matching records using these fallback criteria
- 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:
- The patientId is mandatory in customer request
- 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:
- All requests are sent to the identity service in a single batch
- The system validates that matching records satisfy all the required criteria
- 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):
- Try the first criteria set (
precedence: 1) - If EIMP returns no match (or multiple ambiguous matches), try the next set (
precedence: 2) - Continue until a golden record is found or all sets are exhausted
- When all search criteria sets are exhausted, the system falls back to local wallet creation
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.