# Customers

### Overview

Customer data synchronization is **bidirectional**:

* **Omnium → Flow:** When an order arrives from Omnium and the customer doesn't exist in Flow, the customer is fetched from Omnium and created in Flow.
* **Flow → Omnium:** When a customer is created or updated in Flow POS, the change is pushed to Omnium in real-time.

Both **private customers** (B2C/persons) and **business customers** (B2B/companies) are supported.

### Customer types

| Omnium type       | Flow type         | Omnium API interface        |
| ----------------- | ----------------- | --------------------------- |
| Private customer  | `PERSON`          | `IPrivateCustomerExporter`  |
| Business customer | `COMPANY` / `B2B` | `IBusinessCustomerExporter` |

### Flow → Omnium (customer create/update)

When a customer is created or updated in Flow, the integration pushes the data to Omnium. The behavior depends on whether the customer has an `externalId`:

* **No external ID** → Create new customer in Omnium
* **Has external ID** → Update existing customer in Omnium

#### Private customer field mapping (Flow → Omnium)

| Omnium field          | Flow source               | Notes                             |
| --------------------- | ------------------------- | --------------------------------- |
| `customerId`          | `customer.Uid`            | Unique identifier                 |
| `firstName`           | `customer.FirstName`      | —                                 |
| `lastName`            | `customer.LastName`       | —                                 |
| `fullName`            | `customer.DisplayName`    | —                                 |
| `email`               | `customer.Email`          | —                                 |
| `phone`               | `customer.Mobile`         | —                                 |
| `address.line1`       | `customer.Address`        | —                                 |
| `address.city`        | `customer.City`           | —                                 |
| `address.postalCode`  | `customer.Postalcode`     | —                                 |
| `address.countryCode` | `tenant.Country.Code`     | Tenant's country code             |
| `customerNumber`      | `customer.LoyaltyId`      | Loyalty program ID                |
| `marketGroupId`       | Extension parameter       | `OMNIUM_CUSTOMER_MARKET_GROUP_ID` |
| `created`             | `customer.CreatedAt`      | —                                 |
| `modified`            | `customer.LastModifiedAt` | —                                 |
| `modifiedBy`          | `customer.LastModifiedBy` | —                                 |

#### Business customer field mapping (Flow → Omnium)

| Omnium field          | Flow source               | Notes                             |
| --------------------- | ------------------------- | --------------------------------- |
| `customerId`          | `customer.Uid`            | Unique identifier                 |
| `name`                | `customer.CompanyName`    | Company name                      |
| `email`               | `customer.Email`          | —                                 |
| `phone`               | `customer.Mobile`         | —                                 |
| `taxId`               | `customer.VatNumber`      | Organization/VAT number           |
| `address.line1`       | `customer.Address`        | —                                 |
| `address.city`        | `customer.City`           | —                                 |
| `address.postalCode`  | `customer.Postalcode`     | —                                 |
| `address.countryCode` | `customer.CountryCode`    | —                                 |
| `address.name`        | `customer.CompanyName`    | —                                 |
| `customerNumber`      | `customer.LoyaltyId`      | Loyalty program ID                |
| `marketGroupId`       | Extension parameter       | `OMNIUM_CUSTOMER_MARKET_GROUP_ID` |
| `customerRelations`   | `customer.CustomerParent` | Parent company relationship       |
| `contacts`            | `customer.Contacts`       | Contact persons                   |
| `addresses`           | `customer.Addresses`      | Additional addresses              |

#### Business customer contacts

For B2B customers, Flow syncs contact persons to Omnium:

| Omnium field        | Flow source         |
| ------------------- | ------------------- |
| `id`                | `contact.Uid`       |
| `firstName`         | `contact.FirstName` |
| `lastName`          | `contact.LastName`  |
| `email`             | `contact.Email`     |
| `phone`             | `contact.Mobile`    |
| `privateCustomerId` | `customer.Uid`      |

#### Parent-child company relationships

B2B customers can have parent-child relationships (e.g., a company with departments). When a customer's parent is changed:

1. The new parent's `customerRelations` are updated to include the child
2. The old parent's `customerRelations` are updated to remove the child
3. The `Parent company` property is set to `true`/`false` accordingly

Relationship types:

* `Parent` — The customer has a parent company
* `SubDepartment` — The customer is a sub-department of a parent

### Omnium → Flow (customer from order)

When an order arrives from Omnium and the customer doesn't exist in Flow, the integration fetches the customer from Omnium and creates it in Flow.

#### Private customer field mapping (Omnium → Flow)

| Flow field     | Omnium source         | Notes                         |
| -------------- | --------------------- | ----------------------------- |
| `uid`          | `customerId`          | Used as Flow UID              |
| `customerType` | —                     | Always `PERSON`               |
| `firstName`    | `firstName`           | Defaults to `"-"` if empty    |
| `lastName`     | `lastName`            | Defaults to `"-"` if empty    |
| `email`        | `email`               | —                             |
| `mobile`       | `phone`               | —                             |
| `address`      | `address.line1`       | —                             |
| `city`         | `address.city`        | —                             |
| `postalCode`   | `address.postalCode`  | —                             |
| `countryCode`  | `address.countryCode` | —                             |
| `loyaltyId`    | External IDs          | See loyalty integration below |

#### Business customer field mapping (Omnium → Flow)

| Flow field     | Omnium source              | Notes                         |
| -------------- | -------------------------- | ----------------------------- |
| `uid`          | `customerId`               | Used as Flow UID              |
| `customerType` | —                          | Always `COMPANY`              |
| `companyName`  | `name`                     | —                             |
| `email`        | `address.email` or `email` | Address email takes priority  |
| `mobile`       | `address.phone` or `phone` | Address phone takes priority  |
| `vatNumber`    | `taxId`                    | —                             |
| `address`      | `address.line1`            | —                             |
| `city`         | `address.city`             | —                             |
| `postalCode`   | `address.postalCode`       | —                             |
| `countryCode`  | `address.countryCode`      | —                             |
| `loyaltyId`    | External IDs               | See loyalty integration below |

### Loyalty integration

The integration supports mapping loyalty IDs (e.g., from Voyado) to Flow's `loyaltyId` field. The loyalty ID is resolved from the customer's external IDs using a configurable property key.

The key is configured via the extension parameter `OMNIUM_CUSTOMER_LOYALTY_ID_PROPERTY_KEY`.

For Omnium's built-in export to Flow, the lookup order is:

1. External ID with key `"Voyado"`
2. External ID with key `"VoyadoContactId"`
3. External ID with key `"{marketGroupId}_VoyadoContactId"`

### Limitations

* Customer club/membership data cannot be synced
* The same customer ID cannot represent both a private and business customer in Flow


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.flowretail.com/docs/integrations/order-management/omnium-oms-integration/customers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
