| 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 |