SAP Cloud for Customer Phone Number Parsing and Formatting
In the SAP Cloud for Customer solution each phone number is stored in two different representations.
There is the single field representation or formatted number where – as the name implies – the whole number is stored in a single field. The UI uses exclusively this representation.
There is also the structured representation of the GDT PhoneNumber consisting of the components
All message based communication, including replication to and from SAP OnPremise systems, uses this representation.
Naturally the existence of two different representations for the same entity necessitates program logic to parse the single field representation into the structured representation and reversely to format the structured representation into the single field representation. In this post I will try to describe the underlying logic behind both.
[Side note: All I am writing about phone numbers applies identically to fax numbers. For simplicity’s sake I will be talking about phone numbers only, though.]
Country Determination from the Postal Address
A fully parsed or formatted phone number contains the country information if at all possible. Hence whenever that information is not provided in the phone number itself, i.e. the country code in the structured representation is empty or invalid or the formatted representation does not start with ‘+’ and a valid international dialing code, the program logic tries to retrieve the country code from the related postal address. In case of an Account this is the main address, in case of a Contact this is the main address of the main Account. This country code will be added to both representations of the phone number.
NANPA or not?
The biggest distinction in both parsing or formatting is whether the phone number in question belongs to the North American Numbering Plan (NANPA) or not. The NANPA consists of the United States, Canada and eighteen other countries primarily in North America, including the Caribbean and the U.S. territories. Not all North American countries participate in the NANPA. They all have in common that they share the international dialing code ‘+1’.
Cloud for Customer considers a number to belong to NANPA if:
- The number is provided in the single field representation and starts with a ‘+1’
- The number is provided in structured representation and the Country Code belongs to a NANPA country
- The number is provided in a way that does not allow to determine the country but the country of the related postal address is a NANPA country.
Depending on whether the phone number belongs to a NANPA country or not the parsing and formatting logic differs significantly.
Non-NANPA numbers and the Trunk Prefix
Many countries outside NANPA have a so called trunk prefix, a single digit – often a ‘0’ – that needs to be prefixed to the phone number whenever a domestic call is made. For example in Germany the trunk prefix is ‘0’, so when calling SAP headquarters from within Germany you dial
06227 7 47474
while when calling from the United States you dial
01149 6227 7 47474
This implies that different structured representations can lead to the same formatted number, in the above example
CountryCode: DE AreaID: 06227 SubscriberID: 7 ExtensionID: 47474
CountryCode: DE AreaID: 6227 SubscriberID: 7 ExtensionID: 47474
both will result in the formatted number +49 (6227) 7-47474. Hence when parsing the formatted number a decision has to be made whether the resulting structured representation should include the trunk prefix in the area id or not.
In SAP Cloud for Customer the parsing routine will include the trunk prefix in the structured representation.
Phone Number Parsing
If a phone number is provided in single field representation it has to be parsed to the structured representation, potentially altering the single field representation as well.
As the first step all characters except digits, letters, ‘(‘, ‘)’, ‘/’ and ‘-‘ are removed from the number.
The next step is to determine the country code.
This country can only be determined if the phone number starts with a ‘+’. If the leading ‘+’ is missing the program has no way to tell whether the user merely omitted the ‘+’, whether the user entered an international dialing prefix instead of the ‘+’ or whether the user simply entered a domestic number only. For example a phone number starting with ‘01149’ could be a number dialed to call Germany from the United States, or it could be a domestic German phone number with the AreaID ‘01149’. Hence when a phone number in single field representation has no leading ‘+’ the program logic will always assume it is a domestic number and try to determine the country code from the related postal address.
If the phone number starts with a leading ‘+’ then the following digits are used to determine the country code from the international dialing code. For example a phone number starting with ‘+33’ will be considered French. In case multiple countries share the same international dialing code – like e.g. all NANPA countries or Finland and the Aaland Islands – the next digits, presumably the area id, are used to further narrow down the country code if possible.
Once the country code is determined the logic branches depending on whether the country belongs to NANPA or not.
In case of a NANPA phone number we make use of the fact that NANPA phone numbers follow a very rigid structure of AAA-CCC-NNNN. Hence the first three digits form the Area ID, while the next seven form the subscriber ID, with a ‘-‘ between the third and fourth. All special characters will be ignored and removed.
If the number has more than ten digits, everything after the tenth digit is considered an extension. The program logic tries to determine whether an extension prefix like ‘x’ or ‘ext:’ is provided. Everything but the extension prefix forms the Extension ID. The currently recognized extension prefixes (case insensitive) are ‘e’, ‘x’, ‘ext’, and ‘extension’, followed by an ‘:’ or not.
In case of phone numbers that do not belong to a NANPA country the phone number structure is not as rigid. For example in Germany the length of the Area ID can be 3, 4 or 5. Hence the parsing logic has to work with whatever information it can get from the user input. So it looks for separators.
A separator is one of the characters ‘(‘, ‘)’, ‘/’ or ‘-‘ that does not appear before the first digit. So a leading ‘(‘ is not considered a separator. Spaces are also not considered separators as in some countries it is a common notation to group phone number digits in groups of two even within the individual phone number elements.
Only the first two separators are relevant. The number is then distributed among Area ID, Subscriber ID and Extension ID according to the following logic:
- If no separator can be found, everything is put into the Subscriber ID
- If one separator is found that is not a ‘-‘ then the part before the separator becomes the Area ID and the part after the separator becomes the Subscriber ID.
- If one separator is found that is a ‘-‘ then the part before the separator becomes the Subscriber ID and the part after the separator becomes the Extension ID.
- If two or more separators are found then the part before the first separator becomes the Area ID, the part between first and second separator becomes the Subscriber ID and everything after the second separator becomes the Extension ID
Once the phone number has been parsed this way, the parsed result will then be formatted according to the formatting logic to replace the originally provided phone number. This is to ensure uniform formatting in the system.
|Initial Phone Number||Country Code||Area ID||Subscriber ID||Extension ID||Final Phone Number|
|+1 650-849-4000||US||650||849-4000||+1 650-849-4000|
|65084940005555||US||650||849-4000||5555||+1 650-849-4000 ext: 5555|
|+1 650-849-4000 x5555||US||650||849-4000||5555||+1 650-849-4000 ext: 5555|
|+1 650-849-4000 myext 5555||US||650||849-4000||MYEXT 5555||+1 650-849-4000 ext: MYEXT 5555|
|+49 (6227) 7-47474||DE||06227||7||47474||+49 (6227) 7-47474|
|06227 / 7-47474||DE||06227||7||47474||+49 (6227) 7-47474|
|+49 0 62 27 / 74 74 74||DE||0 62 27||74 74 74||+49 (62 27) 74 74 74|
|+49 62 – 27 – 74 – 74 – 74||DE||062||27||74 – 74 – 74||+49 (62) 27-74 – 74 – 74|
In the third example it is assumed that country code ‘US’ is maintained in the related address.
In the seventh example it is assumed that country code ‘DE’ is maintained in the related address.
Phone number formatting
If a phone number is provided in the structured representation it has to be formatted. During that process the structured representation might change as well.
The first step again is to remove all characters except digits, letters, ‘(‘, ‘)’, ‘/’ and ‘-‘ are removed from the number.
As the second step, if the Country Code is empty, it will be provided from the related postal address.
This determination of the Country Code from the postal address can be suppressed in the Business Configuration Scoping under Built-in Services and Support -> Business Environment -> Addresses and Languages -> Phone Number Country Defaulting.
From then on, again, the logic branches depending on whether the country belongs to NANPA or not.
For NANPA numbers the Area ID, Subscriber ID and Extension ID are concatenated into a single string. All characters except digits and letters are removed and the result is condensed. Then if applicaple a ‘-‘ is inserted between the third and fourth as well as between the sixth and seventh characters. If applicable an ‘ ext: ‘ is inserted between the tenth and eleventh character. Finally the end result is prefixed with a ‘+1’.
For non NANPA numbers a first draft is created in the form
+<international dialing code> (<Area ID>) Subscriber ID – Extension ID
That one is then parsed into structured form and formatted again for a second and final time, following the same above schema. The latter is to take care of cases where due to various reasons like incomplete or incorrect mapping rules the components were not entered into the correct fields initially during message inbound processing. The most frequent case for this is the whole phone number being maintained in the Subscriber ID field.
|Country Code||Area ID||Subscriber ID||Extension ID||Formatted Number||Final Country Code||Final Area ID||Final Subscriber ID||Final Extension ID|
|US||650||849-4000||5555||+1 650-849-4000 ext: 5555||US||650||849-4000||5555|
|US||65084940005555||+1 650-849-4000 ext: 5555||US||650||849-4000||5555|
|DE||06227||7||47474||+49 (6227) 7-47474||DE||06227||7||47474|
|DE||6227/7||47474||+49 (6227) 7-47474||DE||6227/7||47474|
|+49 6227/7-47474||+49 (6227) 7-47474||DE||06227||7||47474|
In the last example we assume that the country code ‘DE’ was maintained in the related postal address.
Since the structured representation is not relevant for the UI display of the phone number the database will only be updated with the final structured representation resulting from the formatting routine if that final representation differs from the original input in non cosmetic ways. If the difference is merely cosmetic the structured representation will be kept exactly as it was passed to the address.
This is to minimize the changes performed in a bidirectional replication scenario.
The delta is considered cosmetic if merely special characters were changed or digits were moved from one component field to another. As of C4C release 1902 the addition of the trunk prefix is also considered a cosmetic change. In the above table of examples the ones highlighted in yellow lead to a non cosmetic change.
Is it possible to have access in PDI to the phone number - without the country dialling code?
As of C4C 1805 only the formatted number is released for PDI. The reason for that is that it also is the only field that is currently maintainable on the UI.
We have an integration with ECC and C4C for accounts and contacts. When we maintain a phone number in C4C on an account or contact, the system prefixes the country code in the phone number field based on the country on the account or contact. Just as in the blog above.
However, when we maintain the phone number in ECC with country code 1, when the account replicates to C4C, C4C again puts a country code prefix.
For example. if we maintain 19209685357 on an account in ECC, when that account replicates to C4C, C4C adds the country code prefix again and thus the number on the account in C4C shows +1 1920968535 ext 7. This is impacting outbound calling as the system now tries to call the number +1 1920968535 which is not a valid number.
I then tried to maintain +19209685357 in ECC but the system does not allow me to maintain a + in the telephone number field.
Can you please advise?
the telephone number field in ECC does not correspond to the formatted number field in C4C but to a combination of AreaID and SubscriberID. ECC also has a separate field for the extension and for the country code. The latter is defaulted with the country of the postal address and only visible on the tabular detail view.
Hence when maintaining a telephone number in ECC you should do it with the structured representation above in mind. In your example maintain telephone number = ‘920-968-5357’ (omit the ‘-‘ if you want) for your US address and you should be fine.
Thank you much Andreas for your prompt response. Appreciate it.
Hi Andreas ...
In Ecuador, there are prefixes internally depending on the states that are called ... how can it be done so that when selecting the federal state, the phone also takes that prefix?
I am assuming that you are referring to the fact that in Ecuador the state determines the area id of all landline phone numbers within that state.
As a general design principle the phone number is not hard linked to the postal address. It is intentionally possible to maintain phone numbers at an address that even have a different country dialing code than the country of the postal address. This is even more rellevant in OnPremise solutions where it is possible to maintain multiple phone numbers for an address, but even in the C4C setup there are use cases where this makes sense, in particular when dealing with mobile numbers and/or the account is located close to a border.
Hence even with the country dialing code C4C only intervenes by offering a default if none is maintained. In case of the country dialing code that is easy to distinguish due to the leading '+' that does denote an international number. Note that C4C does intentionally not adjust the country dialing code just because the country of the postal address was changed.
For the state/area id link these problems are compounded. By the above design philosophy C4C can not just hard insert an area id for every Ecuadorian phone number. For one C4C would need access to the related reference data - basically a table of the Ecuadorian states and their related area ids - and then C4C would need a sure fire way to distinguish between an Ecuadorian phone number without area id and one that already has an area id maintained, just not one related to the currently maintained state. In the latter case, C4C must not adjust anything.
Hence I am afraid I can not help you with your request. You still will have to maintain the area ids manually.
Would it be possible to disable the NANPA formatting in C4C somehow? As our ECC cannot deal with it properly and we also do not have the need to save phone number in NANPA format.
Would this be a possibility, or do you see other solutions for this problem?
it is a common misconception that the 'Telephone' field in ECC corresponds to the 'Phone' field in C4C, while in fact it is only a combination of Area ID and Subscriber ID. The country dialing code does not belong into the Telephone field, there is a separate Country Code field that is only accessible in the Telephone detail popup.
That said even keeping this in mind the number +1 123-456-7891 ext 0 should be replicated to ECC as Telephone: 123-456-7891 Extension: 0. If that is not the case there is likely an error somehwere in the replication. If your problem still persists, please open a ticket for this, someone needs to have a look.
And to answer your initial question: No, currently it is not possible to deactivate/change the phone number formatting for NANPA numbers in C4C.
Hi Andreas Neumann ,
We are receiving phone number from third party system, with country code but without plus(+) sign.
C4C is saving this number again with country code with sign.
For example Third system sends - 44 32478418
C4C saves it +44 44 32478418
Is it possible to add plus sign on received number so system does not add the country code again?
Hello Nimisha Ray ,
that would have to be done in the inbound processing. The backend business object has no way of knowing whether just the leading '+' is missing or whether the number was provided without country dialing code.
See my other blog post https://blogs.sap.com/2017/03/20/sap-cloud-for-customer-always-prefix-your-phone-numbers-with-a/ on this topic.