OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/payments/content/payment_response_helper.h" | 5 #include "components/payments/content/payment_response_helper.h" |
6 | 6 |
7 #include "base/strings/string_split.h" | 7 #include "base/strings/string_split.h" |
8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
9 #include "components/autofill/core/browser/autofill_country.h" | 9 #include "components/autofill/core/browser/autofill_profile.h" |
10 #include "components/autofill/core/browser/autofill_data_util.h" | |
11 #include "components/autofill/core/browser/autofill_type.h" | 10 #include "components/autofill/core/browser/autofill_type.h" |
12 #include "components/payments/content/payment_request_spec.h" | 11 #include "components/payments/content/payment_request_spec.h" |
13 #include "components/payments/core/payment_request_data_util.h" | 12 #include "third_party/libphonenumber/phonenumber_api.h" |
14 #include "components/payments/core/payment_request_delegate.h" | |
15 | 13 |
16 namespace payments { | 14 namespace payments { |
17 | 15 |
| 16 namespace { |
| 17 |
| 18 using ::i18n::phonenumbers::PhoneNumberUtil; |
| 19 |
| 20 } // namespace |
| 21 |
18 PaymentResponseHelper::PaymentResponseHelper( | 22 PaymentResponseHelper::PaymentResponseHelper( |
19 const std::string& app_locale, | 23 const std::string& app_locale, |
20 PaymentRequestSpec* spec, | 24 PaymentRequestSpec* spec, |
21 PaymentInstrument* selected_instrument, | 25 PaymentInstrument* selected_instrument, |
22 PaymentRequestDelegate* payment_request_delegate, | |
23 autofill::AutofillProfile* selected_shipping_profile, | 26 autofill::AutofillProfile* selected_shipping_profile, |
24 autofill::AutofillProfile* selected_contact_profile, | 27 autofill::AutofillProfile* selected_contact_profile, |
25 Delegate* delegate) | 28 Delegate* delegate) |
26 : app_locale_(app_locale), | 29 : app_locale_(app_locale), |
27 is_waiting_for_shipping_address_normalization_(false), | |
28 is_waiting_for_instrument_details_(false), | |
29 spec_(spec), | 30 spec_(spec), |
30 delegate_(delegate), | 31 delegate_(delegate), |
31 selected_instrument_(selected_instrument), | 32 selected_instrument_(selected_instrument), |
32 payment_request_delegate_(payment_request_delegate), | 33 selected_shipping_profile_(selected_shipping_profile), |
33 selected_contact_profile_(selected_contact_profile) { | 34 selected_contact_profile_(selected_contact_profile) { |
34 DCHECK(spec_); | 35 DCHECK(spec_); |
35 DCHECK(selected_instrument_); | 36 DCHECK(selected_instrument_); |
36 DCHECK(delegate_); | 37 DCHECK(delegate_); |
37 | 38 |
38 is_waiting_for_instrument_details_ = true; | |
39 | |
40 // Start to normalize the shipping address, if necessary. | |
41 if (spec_->request_shipping()) { | |
42 DCHECK(selected_shipping_profile); | |
43 DCHECK(spec_->selected_shipping_option()); | |
44 | |
45 is_waiting_for_shipping_address_normalization_ = true; | |
46 | |
47 // Use the country code from the profile if it is set, otherwise infer it | |
48 // from the |app_locale_|. | |
49 std::string country_code = base::UTF16ToUTF8( | |
50 selected_shipping_profile->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY)); | |
51 if (!autofill::data_util::IsValidCountryCode(country_code)) { | |
52 country_code = | |
53 autofill::AutofillCountry::CountryCodeForLocale(app_locale_); | |
54 } | |
55 | |
56 payment_request_delegate_->GetAddressNormalizer() | |
57 ->StartAddressNormalization(*selected_shipping_profile, country_code, | |
58 /*timeout_seconds=*/5, this); | |
59 } | |
60 | |
61 // Start to get the instrument details. Will call back into | 39 // Start to get the instrument details. Will call back into |
62 // OnInstrumentDetailsReady. | 40 // OnInstrumentDetailsReady. |
63 selected_instrument_->InvokePaymentApp(this); | 41 selected_instrument_->InvokePaymentApp(this); |
64 }; | 42 }; |
65 | 43 |
66 PaymentResponseHelper::~PaymentResponseHelper(){}; | 44 PaymentResponseHelper::~PaymentResponseHelper(){}; |
67 | 45 |
68 // static | 46 // static |
69 mojom::PaymentAddressPtr | 47 mojom::PaymentAddressPtr |
70 PaymentResponseHelper::GetMojomPaymentAddressFromAutofillProfile( | 48 PaymentResponseHelper::GetMojomPaymentAddressFromAutofillProfile( |
(...skipping 27 matching lines...) Expand all Loading... |
98 // TODO(crbug.com/705945): Format phone number according to spec. | 76 // TODO(crbug.com/705945): Format phone number according to spec. |
99 payment_address->phone = | 77 payment_address->phone = |
100 base::UTF16ToUTF8(profile->GetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER)); | 78 base::UTF16ToUTF8(profile->GetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER)); |
101 | 79 |
102 return payment_address; | 80 return payment_address; |
103 } | 81 } |
104 | 82 |
105 void PaymentResponseHelper::OnInstrumentDetailsReady( | 83 void PaymentResponseHelper::OnInstrumentDetailsReady( |
106 const std::string& method_name, | 84 const std::string& method_name, |
107 const std::string& stringified_details) { | 85 const std::string& stringified_details) { |
108 method_name_ = method_name; | |
109 stringified_details_ = stringified_details; | |
110 is_waiting_for_instrument_details_ = false; | |
111 | |
112 if (!is_waiting_for_shipping_address_normalization_) | |
113 GeneratePaymentResponse(); | |
114 } | |
115 | |
116 void PaymentResponseHelper::OnAddressNormalized( | |
117 const autofill::AutofillProfile& normalized_profile) { | |
118 if (is_waiting_for_shipping_address_normalization_) { | |
119 shipping_address_ = normalized_profile; | |
120 is_waiting_for_shipping_address_normalization_ = false; | |
121 | |
122 if (!is_waiting_for_instrument_details_) | |
123 GeneratePaymentResponse(); | |
124 } | |
125 } | |
126 | |
127 void PaymentResponseHelper::OnCouldNotNormalize( | |
128 const autofill::AutofillProfile& profile) { | |
129 // Since the phone number is formatted in either case, this profile should be | |
130 // used. | |
131 OnAddressNormalized(profile); | |
132 } | |
133 | |
134 void PaymentResponseHelper::GeneratePaymentResponse() { | |
135 DCHECK(!is_waiting_for_instrument_details_); | |
136 DCHECK(!is_waiting_for_shipping_address_normalization_); | |
137 | |
138 mojom::PaymentResponsePtr payment_response = mojom::PaymentResponse::New(); | 86 mojom::PaymentResponsePtr payment_response = mojom::PaymentResponse::New(); |
139 | 87 |
140 // Make sure that we return the method name that the merchant specified for | 88 // Make sure that we return the method name that the merchant specified for |
141 // this instrument: cards can be either specified through their name (e.g., | 89 // this instrument: cards can be either specified through their name (e.g., |
142 // "visa") or through basic-card's supportedNetworks. | 90 // "visa") or through basic-card's supportedNetworks. |
143 payment_response->method_name = | 91 payment_response->method_name = |
144 spec_->IsMethodSupportedThroughBasicCard(method_name_) | 92 spec_->IsMethodSupportedThroughBasicCard(method_name) |
145 ? kBasicCardMethodName | 93 ? kBasicCardMethodName |
146 : method_name_; | 94 : method_name; |
147 payment_response->stringified_details = stringified_details_; | 95 payment_response->stringified_details = stringified_details; |
148 | 96 |
149 // Shipping Address section | 97 // Shipping Address section |
150 if (spec_->request_shipping()) { | 98 if (spec_->request_shipping()) { |
| 99 DCHECK(selected_shipping_profile_); |
151 payment_response->shipping_address = | 100 payment_response->shipping_address = |
152 GetMojomPaymentAddressFromAutofillProfile(&shipping_address_, | 101 GetMojomPaymentAddressFromAutofillProfile(selected_shipping_profile_, |
153 app_locale_); | 102 app_locale_); |
| 103 |
| 104 DCHECK(spec_->selected_shipping_option()); |
154 payment_response->shipping_option = spec_->selected_shipping_option()->id; | 105 payment_response->shipping_option = spec_->selected_shipping_option()->id; |
155 } | 106 } |
156 | 107 |
157 // Contact Details section. | 108 // Contact Details section. |
158 if (spec_->request_payer_name()) { | 109 if (spec_->request_payer_name()) { |
159 DCHECK(selected_contact_profile_); | 110 DCHECK(selected_contact_profile_); |
160 payment_response->payer_name = | 111 payment_response->payer_name = |
161 base::UTF16ToUTF8(selected_contact_profile_->GetInfo( | 112 base::UTF16ToUTF8(selected_contact_profile_->GetInfo( |
162 autofill::AutofillType(autofill::NAME_FULL), app_locale_)); | 113 autofill::AutofillType(autofill::NAME_FULL), app_locale_)); |
163 } | 114 } |
164 if (spec_->request_payer_email()) { | 115 if (spec_->request_payer_email()) { |
165 DCHECK(selected_contact_profile_); | 116 DCHECK(selected_contact_profile_); |
166 payment_response->payer_email = base::UTF16ToUTF8( | 117 payment_response->payer_email = base::UTF16ToUTF8( |
167 selected_contact_profile_->GetRawInfo(autofill::EMAIL_ADDRESS)); | 118 selected_contact_profile_->GetRawInfo(autofill::EMAIL_ADDRESS)); |
168 } | 119 } |
169 if (spec_->request_payer_phone()) { | 120 if (spec_->request_payer_phone()) { |
170 DCHECK(selected_contact_profile_); | 121 DCHECK(selected_contact_profile_); |
171 | 122 |
172 // Try to format the phone number to the E.164 format to send in the Payment | 123 // Try to format the phone number to the E.164 format to send in the Payment |
173 // Response, as defined in the Payment Request spec. If it's not possible, | 124 // Response, as defined in the Payment Request spec. If it's not possible, |
174 // send the original. More info at: | 125 // send the original. More info at: |
175 // https://w3c.github.io/browser-payment-api/#paymentrequest-updated-algorit
hm | 126 // https://w3c.github.io/browser-payment-api/#paymentrequest-updated-algorit
hm |
| 127 // TODO(sebsg): Move this code to a reusable location. |
176 const std::string original_number = | 128 const std::string original_number = |
177 base::UTF16ToUTF8(selected_contact_profile_->GetInfo( | 129 base::UTF16ToUTF8(selected_contact_profile_->GetInfo( |
178 autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER), | 130 autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER), |
179 app_locale_)); | 131 app_locale_)); |
180 | 132 i18n::phonenumbers::PhoneNumber parsed_number; |
181 const std::string default_region_code = | 133 PhoneNumberUtil* phone_number_util = PhoneNumberUtil::GetInstance(); |
182 autofill::AutofillCountry::CountryCodeForLocale(app_locale_); | 134 if (phone_number_util->Parse(original_number, "US", &parsed_number) == |
183 payment_response->payer_phone = | 135 ::i18n::phonenumbers::PhoneNumberUtil::NO_PARSING_ERROR) { |
184 data_util::FormatPhoneForResponse(original_number, default_region_code); | 136 std::string formatted_number; |
| 137 phone_number_util->Format(parsed_number, |
| 138 PhoneNumberUtil::PhoneNumberFormat::E164, |
| 139 &formatted_number); |
| 140 payment_response->payer_phone = formatted_number; |
| 141 } else { |
| 142 payment_response->payer_phone = original_number; |
| 143 } |
185 } | 144 } |
186 | 145 |
187 delegate_->OnPaymentResponseReady(std::move(payment_response)); | 146 delegate_->OnPaymentResponseReady(std::move(payment_response)); |
188 } | 147 } |
189 | 148 |
190 } // namespace payments | 149 } // namespace payments |
OLD | NEW |