Payment-request: Standardize phone number format

Created on 8 Nov 2017  ·  14Comments  ·  Source: w3c/payment-request

It would be good to require a standard format for phone number (e.g. E. 164). It's recommended right now, but not required.

  • [x] Chrome ✅
  • [x] Firefox ✅
  • [ ] Edge (Microsoft Wallet)
  • [x] Safari ❌
enhancement CR-Exit PaymentAddress

All 14 comments

A note for other implementers: Chrome asks the user to fix their phone number before payment if it's not valid. Chrome uses libphonenumber for both validation and formatting.

@mnoorenberghe, wdyt?

Firefox uses libphonenumber's data as well and we were aware of the previous discussion about E.164 so were planning to normalize according to it.

@molly26dalton, could you enquire within Microsoft for us?

@aestes, how do you handle this in Apple Pay?

I've proposed some language for this:
https://github.com/w3c/payment-request/pull/654/commits/ae41fb48792e7ae669bc216ea86b180625c98a75

In pr #654 I define what a structurally valid phone number is (as per E.164).

@marcoscaceres We don't do any phone number formatting in WebKit. We rely on the format that comes out of the Contacts database. Note that Contacts will enforce some formatting when inputting numbers -- for instance if I enter "408-123-4567" it will reformat it to "(408) 123-4567" (in the en_us locale). I don't what rules Contacts follows, though.

@michelle, all.... I spent the last few days researching if E.164 can be a "MUST" requirement in the spec. Sadly, short of standardizing Google's libphonenumber, it doesn't seem doable IMO. There is just too much variance and craziness in phone numbers. Thus, I think all we can do is continue to ask for a "SHOULD" here.

Longer... Consider the variance of the national conventions for phone numbers, to silly things, like some German phone numbers being 17 digits long, when E.164 says they should be 15 max 🤪

Then there is a bunch of interesting challenges around internationalized formats including the numbers themselves, the "(", ")" and "[", "]" and "-" and so on. Although those can all be stripped out, one still might end up with an oddball number that starts with multiple "00"s, so then you need to know if the zero should be dropped to put the country prefix on the front, etc. It gets a little scary for me from there, because you start changing the numbers themselves.

To cut a long story short, I think it's best to lobby directly here that implementers do phone numbers through libphonumber to try to get a E.164 number out (which both Google and Firefox will do, for instance).

However, despite the browser's best effort, developers might need to still deal with the possibility of a number not being in E.164 by checking if the first character is a "+", and if not, passing the number and the country to libphonenumber.

If others think this might be doable and want to discuss further, I'm happy to discuss further. It's a worthy goal to standardize this stuff, but it seems quite hard... so would require a few of us to do it.

I'm closing this - but we can reopen if others are willing to work on the problem together.

Thank you for the research, @marcoscaceres!

cc @anthonyvd @sebsg @mahmadi re: libphonenumber usage.

While I understand the issue with edge-cases in E.164, I'm concerned about the spec being so broad that the resulting numbers become unusable. The example from @aestes above has a US number with special formatting (no big deal) but also no country code (big deal!). The form in which a phone number is presented to a user has meaning in the context of their system's locale settings and the user's own knowledge of what country their phone number is for. If that same user-facing value is passed as-is to a merchant, without context, it may not be interpretable. Can we at least require numbers to include country code?

@asolove-stripe Good point. That would argue for SHOULD, not MUST.

@asolove-stripe wrote:

Can we at least require numbers to include country code?

As I said, the problem is that we can't really specify how to do the conversion without standardizing libphonenumber's parse algorithm.

What we might need is a .payerCountry attribute (or .payerPhoneCountry). Which can then be fed into libphonenumber (or similar lib), so that:

// given "(408) 123-4567", and "US"
const phone = phoneUtil.parse(response.payerPhone, response.payerCountry);
// Yields, for instance, "+14081234567"

Fixed typo above.

Reopening, so we can discuss more options....

I've not heard any alternatives approaches and no one has volunteered to do this work, so I'm inclined to close this issue.

If someone wants to have a go at proposing a workable solution, we should reopen.

Was this page helpful?
0 / 5 - 0 ratings