How customers are matched
How the shop decides which customer an order belongs to: your customer ID, the shop's customer number, a verified email, or a new customer.
The rule in short
For every order, the shop determines the customer in this order:
- The shop’s customer number (
customer.customer_id), if you send it. - Your customer ID (
customer.external_id), if it was used before with your access. - The email address, only if the operator has enabled it for your access and you send
"email_verified": true. - Otherwise, a new customer is created.
After steps 3 and 4, your customer ID is linked to the customer. From then on, step 2 finds the customer directly.
Your customer ID
customer.external_id is your app’s ID for the customer, up to 191 characters. Once the shop has seen it with your access, every order with that ID goes to the same customer.
- The ID is compared exactly, including upper and lower case.
u-1andU-1are two customers. - Leading and trailing spaces are removed.
- The link belongs to your access. The same ID sent with a key of a different access is a different customer.
- If the linked customer was deleted in the shop, the next order with that ID is treated like a first order: matched by email if enabled, otherwise a new customer is created. The ID is then linked to that customer.
Use an ID that never changes for a customer in your app, for example your internal user ID, not the email address.
The shop’s customer number
Each order response contains customer_id, the shop’s customer number. The shop operator can also give you the number of an existing customer. You can send it instead of your own ID:
"customer": { "customer_id": 9021 }
"customer": { "id": 9021 } means the same. If you send both id and customer_id, they must match, otherwise the request fails with invalid_value.
This works for every active, registered customer of your shop. Guest customers, blocked or deleted customers and customers of other shops are rejected with 422 and the field code unknown_customer. If you send both customer_id and external_id, customer_id decides, and your customer ID is not linked to that customer. To find the customer later by your own ID, send an order with external_id, a verified email and email matching enabled, or keep the customer number in your app.
Matching by email
Matching by email connects an order to a customer who already exists in the shop, for example someone who registered in the online shop before using your app. It applies only if both conditions are met:
- The operator has enabled Match existing customers by email for your access. It is off by default.
- You send
"email_verified": true, which states that your app has confirmed the address, for example with a confirmation link.
The shop then looks for a customer with exactly this email address (not case-sensitive) who:
- belongs to the shop of your access
- has a registered customer account (guest customers are never matched)
- is active (locked customers are never matched)
If several customers qualify, the one with the lowest customer number is used. If none qualifies, a new customer is created.
Send email_verified: true only when the address is really confirmed. Otherwise an order could end up in a stranger’s customer account, with their order history and payment data.
If the customer found by email is already linked to a different customer ID of your app, the order is still assigned to that customer, and the response contains the warning customer_already_linked. Check your app for duplicate accounts in that case.
New customers
A new customer is created from email and billing, both required in that case. The customer:
- is created in the shop of your access, with the shop’s default customer class
- has no login for the online shop; the account lives in your app
- gets the billing address, and the delivery address if you send one, in the address book
Because these customers have no shop login, matching by email never finds them later. They are found through your customer ID.
Collective invoice
Whether an order may use the collective invoice depends on the customer the order is assigned to, following the rules above. For an existing customer, the customer’s own setting decides, otherwise the customer class. A new customer gets the shop’s default customer class, so that class must be approved for the collective invoice. The stored address of a new customer is taken from billing, so later orders with the same billing address run on the collective invoice. If an order’s billing address differs from the stored address, it is invoiced on its own and the response carries the warning collective_invoice_single_order.
Examples
A first order from a new app user, matching disabled:
"customer": {
"external_id": "u-55871",
"email": "jane.doe@example.com",
"billing": {
"first_name": "Jane",
"last_name": "Doe",
"street": "Example Street",
"house": "5",
"postcode": "10115",
"city": "Berlin",
"country": "DE"
}
}
Response: customer_created: true. The ID u-55871 is now linked.
A second order from the same user:
"customer": { "external_id": "u-55871" }
Response: customer_created: false, same customer_id.
A first order from a user who already has an account in the online shop, matching enabled, email confirmed in the app:
"customer": {
"external_id": "u-60112",
"email": "john.doe@example.com",
"email_verified": true,
"billing": { "...": "..." }
}
Response: customer_created: false, customer_id of the existing account. The ID u-60112 is now linked to it.
Reading and maintaining linked customers
Customers created or matched through your access can be read and maintained with the customer endpoints, using your customer ID in the path. See Maintain customers.
With matching by email and the scope customers.read, this includes the full record of an existing shop customer who was matched by email.