Configuring Enterprise Settings for a Merchant
This guide explains how to configure the enterpriseSettings for a merchant to enable customer identification through EIMP and CCG database lookups.
- Familiarity with the Enterprise Settings Logic β how merchant search criteria drive EIMP lookups
- Familiarity with the CCG DB Lookup Logic β how the same configuration drives database-level lookups
- Access to the merchant event pipeline (Kafka) or direct database access for configuration updates
How Enterprise Settings Are Storedβ
The configuration is stored as a JSONB column named enterprise_settings on the merchant table. At the application level, it maps to the orderedCustomerSearchCriteria field on the Merchant entity:
Java Entity Mapping
@JdbcTypeCode(SqlTypes.JSON)
@Column(name = "enterprise_settings")
private List<OrderedCustomerSearchCriteria> orderedCustomerSearchCriteria;
How It Gets Into the Databaseβ
Enterprise settings are not configured through a REST API. They arrive via Kafka events:
| Event | Trigger |
|---|---|
merchant-created-event | New merchant onboarded β creates the merchant record with enterprise settings |
merchant-updated-event | Merchant configuration changed β updates the existing enterprise settings |
The MerchantConsumer listens for these events, and MerchantConsumerMapper maps merchantPayload.enterpriseSettings β Merchant.orderedCustomerSearchCriteria.
For ad-hoc configuration changes or initial setup in lower environments, you can update the enterprise_settings column directly via SQL:
UPDATE merchant
SET enterprise_settings = '<JSON>'::jsonb
WHERE wallet_merchant_id = '<merchant-uuid>';
Configuration Schemaβ
Schema Reference & Field Definitions
The enterpriseSettings JSON is an array of OrderedCustomerSearchCriteria objects. Each contains a precedence and a list of CustomerSearchCriteria:
[
{
"precedence": <outer_precedence>,
"customerSearchCriteria": [
{
"merchantSearchKey": "<JSONPath>",
"enterpriseSearchKey": "<EIMP_key>",
"enterpriseValueKey": "<value_map_key>",
"merchantMetadataKey": "<metadata_key>",
"enterpriseResponseSearchPath": "<JSONPath_or_null>",
"value": { "<context_key>": "<context_value>" },
"precedence": <inner_precedence>,
"required": true | false
}
]
}
]
Field Referenceβ
Outer Level β OrderedCustomerSearchCriteriaβ
| Field | Type | Required | Description |
|---|---|---|---|
precedence | int | Yes | Controls the order in which criteria sets are tried. Lower value = tried first. If the first set fails to identify a customer, the next set is tried. |
customerSearchCriteria | Array | Yes | List of individual search criteria within this set. All required criteria must match for the set to succeed. |
Inner Level β CustomerSearchCriteriaβ
| Field | Type | Default | Used By | Description |
|---|---|---|---|---|
merchantSearchKey | String | null | EIMP | JSONPath expression to extract a value from the incoming CustomerRequest. E.g., $.metadata.subscriberId |
enterpriseSearchKey | String | null | EIMP | Dot-notation key sent to EIMP as the key field in the IdentitySearchRequest. E.g., identifiers.payer_memberId |
enterpriseValueKey | String | null | EIMP | Property name in the value map where the extracted merchant value is placed. E.g., subscriberId |
merchantMetadataKey | String | null | CCG DB, Upgrade | Key for matching against metadata in the customer request (CCG DB lookup), and for storing values in merchant_customer_metadata during wallet upgrade |
enterpriseResponseSearchPath | String | null | Upgrade | JSONPath expression to extract values from the EIMP golden record response during wallet upgrade. Not used during initial search. |
value | Map<String,String> | null | EIMP | Template map with context fields (e.g., sourceCode, type). The extracted merchant value is merged into this map under enterpriseValueKey. If null, the raw extracted value is sent directly. |
precedence | int | 0 | Both | Order within a criteria set. Lower = processed first. Affects EIMP query order and CCG DB query nesting. |
required | boolean | false | Both | If true, this criterion must have a value in the request. If false and the value is empty, the criterion is silently skipped. |
There is no JSON schema validation on the enterprise_settings column. Invalid configurations will only surface at runtime during customer identification. Always test configurations in a lower environment first.
- Missing fields default to Java defaults:
nullfor objects,0for int,falsefor boolean - Extra/unknown fields are silently ignored (
@JsonIgnoreProperties(ignoreUnknown = true)) - Malformed JSON that cannot be deserialized will cause a Hibernate-level error when the merchant is loaded
Step-by-Step Configuration Guideβ
Step 1: Identify Your Matching Strategyβ
Determine which fields from the customer request should be used to identify a customer in EIMP. Common strategies:
| Strategy | Request Fields | EIMP Target |
|---|---|---|
| Subscriber ID matching | metadata.subscriberId | identifiers.payer_memberId |
| Patient ID matching | metadata.patientId | identifiers.rx_patientId |
| Health exchange ID | metadata.healthInsuranceExchangeId | identifiers.other_ids |
| DOB matching | dateOfBirth | birthDate |
| Name matching | firstName, lastName | givenName, familyName |
Step 2: Design Your Criteria Setsβ
Decide how many fallback strategies you need. Each OrderedCustomerSearchCriteria is an independent identification strategy tried in ascending precedence order.
Best practices:
- Primary set (
precedence: 1): Use your most specific/reliable identifiers (e.g., subscriber ID + dependent code) - Fallback set (
precedence: 2): Use alternative identifiers (e.g., health insurance exchange ID + zip code) - Mark primary identifiers as
required: true, supplementary ones asrequired: false
Step 3: Map Each Fieldβ
Field Mapping Paths (Technical Detail)
For each criterion, you need to configure four interconnected paths:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Customer Request β
β { "metadata": { "subscriberId": "ABC123" } } β
β β β
β merchantSearchKey: "$.metadata.subscriberId" ββββ extracts ββββΊ β
β β "ABC123" β
β merchantMetadataKey: "subscriberId" ββββ filters ββββΊ β
β β metadata map for β
β β CCG DB lookup β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β EIMP IdentitySearchRequest β β
β β { β β
β β "key": "identifiers.payer_memberId", βββ enterpriseSearchKeyβ
β β "value": { β β
β β "subscriberId": "ABC123", βββ enterpriseValueKey + β β
β β "sourceCode": "EEMS" extracted value + value β β
β β } map context β β
β β } β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Step 4: Configure for Wallet Upgrade (Optional)β
Wallet Upgrade Configuration (Optional)
If you need wallet upgrade support (migrating local wallets to enterprise), add enterpriseResponseSearchPath and merchantMetadataKey:
enterpriseResponseSearchPath: JSONPath to extract the matching value from the EIMP golden record responsemerchantMetadataKey: The key under which the value is stored inmerchant_customer_metadata
Common patterns:
{
"merchantMetadataKey": "subscriberId",
"enterpriseResponseSearchPath": "$.[*].identifiers.payer_memberId[*]['subscriberId']"
}
{
"merchantMetadataKey": "dependentCode",
"enterpriseResponseSearchPath": "$.[*].identifiers.payer_memberId[*]['dependentCode']"
}
{
"merchantMetadataKey": "healthInsuranceExchangeId",
"enterpriseResponseSearchPath": "$.[*].identifiers.other_ids[*][?(@.type=='HealthInsuranceExchangeId')]['value']"
}
Configuration Examplesβ
Example 1: Simple Single-Criterion Lookup
Use case: Identify customers by pharmacy patient ID only.
[
{
"precedence": 1,
"customerSearchCriteria": [
{
"value": { "patientId": "xxxxxx" },
"merchantSearchKey": "$.metadata.patientId",
"enterpriseSearchKey": "identifiers.rx_patientId",
"enterpriseValueKey": "patientId",
"merchantMetadataKey": "patientId",
"enterpriseResponseSearchPath": null,
"precedence": 1,
"required": true
}
]
}
]
What happens:
- Extracts
patientIdfrom$.metadata.patientIdin the request - Sends EIMP request:
{ "key": "identifiers.rx_patientId", "value": { "patientId": "<extracted>" } } - If EIMP returns a golden record β customer identified
- CCG DB: queries
merchant_customer_metadatawheremetadata_key = 'patientId'andmetadata_value = '<extracted>'
Example 2: Multi-Criterion with Required and Optional Fields
Use case: Identify by subscriber ID (required) with DOB and last name as optional strengthening criteria.
[
{
"precedence": 1,
"customerSearchCriteria": [
{
"value": { "sourceCode": "EEMS", "subscriberId": "xxxx" },
"merchantSearchKey": "$.metadata.subscriberId",
"enterpriseSearchKey": "identifiers.payer_memberId",
"enterpriseValueKey": "subscriberId",
"merchantMetadataKey": "subscriberId",
"enterpriseResponseSearchPath": "$.[*].identifiers.payer_memberId[*]['subscriberId']",
"precedence": 1,
"required": true
},
{
"value": null,
"merchantSearchKey": "$.dateOfBirth",
"enterpriseSearchKey": "birthDate",
"enterpriseValueKey": null,
"merchantMetadataKey": null,
"enterpriseResponseSearchPath": null,
"precedence": 2,
"required": false
},
{
"value": null,
"merchantSearchKey": "$.lastName",
"enterpriseSearchKey": "familyName",
"enterpriseValueKey": null,
"merchantMetadataKey": null,
"enterpriseResponseSearchPath": null,
"precedence": 3,
"required": false
}
]
}
]
Behavior:
subscriberIdis required β if missing from the request, this entire set is skippeddateOfBirthandlastNameare optional β included in the EIMP query only if present in the request, omitted otherwise- All three are sent in a single batch to EIMP when present
Example 3: Multiple Criteria Sets with Fallback
Use case: Try subscriber ID + dependent code first. If that fails, fall back to health insurance exchange ID + zip code.
[
{
"precedence": 1,
"customerSearchCriteria": [
{
"value": { "sourceCode": "CSP_Facets", "dependentCode": "xxxx" },
"merchantSearchKey": "$.metadata.dependentCode",
"enterpriseSearchKey": "identifiers.payer_memberId",
"enterpriseValueKey": "dependentCode",
"merchantMetadataKey": "dependentCode",
"enterpriseResponseSearchPath": "$.[*].identifiers.payer_memberId[*]['dependentCode']",
"precedence": 1,
"required": true
},
{
"value": { "sourceCode": "EEMS", "subscriberId": "xxxx" },
"merchantSearchKey": "$.metadata.subscriberId",
"enterpriseSearchKey": "identifiers.payer_memberId",
"enterpriseValueKey": "subscriberId",
"merchantMetadataKey": "subscriberId",
"enterpriseResponseSearchPath": "$.[*].identifiers.payer_memberId[*]['subscriberId']",
"precedence": 2,
"required": true
},
{
"value": null,
"merchantSearchKey": "$.dateOfBirth",
"enterpriseSearchKey": "birthDate",
"enterpriseValueKey": null,
"merchantMetadataKey": null,
"enterpriseResponseSearchPath": null,
"precedence": 0,
"required": false
}
]
},
{
"precedence": 2,
"customerSearchCriteria": [
{
"value": { "type": "HealthInsuranceExchangeId", "sourceCode": "CSP_Facets" },
"merchantSearchKey": "$.metadata.healthInsuranceExchangeId",
"enterpriseSearchKey": "identifiers.other_ids",
"enterpriseValueKey": "value",
"merchantMetadataKey": "healthInsuranceExchangeId",
"enterpriseResponseSearchPath": "$.[*].identifiers.other_ids[*][?(@.type=='HealthInsuranceExchangeId')]['value']",
"precedence": 1,
"required": true
},
{
"value": { "zipPostalCode": "xxxx" },
"merchantSearchKey": "$.zip5",
"enterpriseSearchKey": "contacts.postalAddresses",
"enterpriseValueKey": "zipPostalCode",
"merchantMetadataKey": null,
"enterpriseResponseSearchPath": null,
"precedence": 2,
"required": true
}
]
}
]
Flow:
- Set 1 (
precedence: 1): Send dependent code + subscriber ID + optional DOB to EIMP- If golden record found β done
- If no match β proceed to Set 2
- Set 2 (
precedence: 2): Send health insurance exchange ID + zip code to EIMP- If golden record found β done
- If no match β create local wallet
Example 4: Direct Property Matching (No Value Map)
Use case: Simple DOB or name matching where no additional context is needed.
{
"value": null,
"merchantSearchKey": "$.dateOfBirth",
"enterpriseSearchKey": "birthDate",
"enterpriseValueKey": null,
"merchantMetadataKey": null,
"enterpriseResponseSearchPath": null,
"precedence": 1,
"required": false
}
When value is null and enterpriseValueKey is null, the extracted value is sent directly to EIMP:
{
"key": "birthDate",
"value": "1980-01-01"
}
vs. when value has a template map:
{
"key": "identifiers.payer_memberId",
"value": {
"subscriberId": "ABC123",
"sourceCode": "EEMS"
}
}
Applying Configuration via SQLβ
SQL Scripts
Insert a New Enterprise Settings Configurationβ
UPDATE merchant
SET enterprise_settings = '[
{
"precedence": 1,
"customerSearchCriteria": [
{
"value": {"sourceCode": "EEMS", "subscriberId": "xxxx"},
"merchantSearchKey": "$.metadata.subscriberId",
"enterpriseSearchKey": "identifiers.payer_memberId",
"enterpriseValueKey": "subscriberId",
"merchantMetadataKey": "subscriberId",
"enterpriseResponseSearchPath": "$.[*].identifiers.payer_memberId[*][''subscriberId'']",
"precedence": 1,
"required": true
}
]
}
]'::jsonb
WHERE wallet_merchant_id = '<your-merchant-uuid>';
Verify Current Configurationβ
SELECT wallet_merchant_id, name,
jsonb_pretty(enterprise_settings) AS enterprise_settings
FROM merchant
WHERE wallet_merchant_id = '<your-merchant-uuid>';
Check All Merchants in a Groupβ
SELECT m.wallet_merchant_id, m.name,
jsonb_pretty(m.enterprise_settings) AS enterprise_settings
FROM merchant m
WHERE m.merchant_group_id = (
SELECT merchant_group_id FROM merchant
WHERE wallet_merchant_id = '<your-merchant-uuid>'
);
Configuration Checklistβ
Before deploying a new enterprise settings configuration, verify:
| # | Check | Details |
|---|---|---|
| 1 | Valid JSON | Ensure the JSON is syntactically valid and can be cast to jsonb |
| 2 | Precedence values set | Both outer (criteria set) and inner (individual criterion) precedence values should be explicitly set |
| 3 | Required fields marked | At least one criterion per set should be required: true for meaningful identification |
| 4 | merchantSearchKey paths valid | JSONPath expressions must match the actual structure of incoming customer requests |
| 5 | enterpriseSearchKey values valid | Dot-notation keys must match the EIMP identity data model |
| 6 | merchantMetadataKey set for CCG DB | If you need CCG DB lookup support, ensure merchantMetadataKey is set on criteria |
| 7 | enterpriseResponseSearchPath set for upgrade | If you need wallet upgrade support, ensure both enterpriseResponseSearchPath and merchantMetadataKey are configured |
| 8 | Merchant group consistency | If merchants share a group, ensure their configurations are compatible β CCG DB lookups search across all group members |
| 9 | Value map template correct | If using value map, ensure the placeholder key matches enterpriseValueKey |
| 10 | Test in lower environment | No schema validation exists β test with actual customer requests before production deployment |
Common Mistakesβ
Common Mistakes & How to Fix Them
Missing merchantMetadataKeyβ
// β Wrong β CCG DB lookup and wallet upgrade won't work
{
"merchantSearchKey": "$.metadata.subscriberId",
"enterpriseSearchKey": "identifiers.payer_memberId",
"enterpriseValueKey": "subscriberId",
"required": true
}
// β
Correct β enables all three lookup paths
{
"merchantSearchKey": "$.metadata.subscriberId",
"enterpriseSearchKey": "identifiers.payer_memberId",
"enterpriseValueKey": "subscriberId",
"merchantMetadataKey": "subscriberId",
"required": true
}
Mismatched enterpriseValueKey and value Mapβ
// β Wrong β "subId" doesn't match the placeholder "xxxx" key "subscriberId"
{
"value": { "sourceCode": "EEMS", "subscriberId": "xxxx" },
"enterpriseValueKey": "subId",
...
}
// β
Correct β enterpriseValueKey matches the placeholder key in value map
{
"value": { "sourceCode": "EEMS", "subscriberId": "xxxx" },
"enterpriseValueKey": "subscriberId",
...
}
All Criteria Optional in a Setβ
// β Risky β if all optional criteria have empty values, no EIMP query is sent
{
"customerSearchCriteria": [
{ "required": false, "merchantSearchKey": "$.dateOfBirth", ... },
{ "required": false, "merchantSearchKey": "$.lastName", ... }
]
}
// β
Better β at least one required criterion ensures the set has substance
{
"customerSearchCriteria": [
{ "required": true, "merchantSearchKey": "$.metadata.subscriberId", ... },
{ "required": false, "merchantSearchKey": "$.dateOfBirth", ... }
]
}
Duplicate Precedence Valuesβ
// β Ambiguous β two sets with same precedence, order is not deterministic
[
{ "precedence": 1, "customerSearchCriteria": [...] },
{ "precedence": 1, "customerSearchCriteria": [...] }
]
// β
Correct β unique precedence values ensure deterministic ordering
[
{ "precedence": 1, "customerSearchCriteria": [...] },
{ "precedence": 2, "customerSearchCriteria": [...] }
]
Related Documentationβ
- Enterprise Settings Logic (EIMP Lookup) β How the configuration drives EIMP identity lookups
- CCG DB Lookup Logic β How the same configuration drives database-level lookups
- Customer Creation β End-to-end customer creation flow