| 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 "ios/chrome/browser/payments/payment_request.h" | 5 #include "ios/chrome/browser/payments/payment_request.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/containers/adapters.h" | 9 #include "base/containers/adapters.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 new autofill::ChromeMetadataSource(I18N_ADDRESS_VALIDATION_DATA_URL, | 44 new autofill::ChromeMetadataSource(I18N_ADDRESS_VALIDATION_DATA_URL, |
| 45 url_context_getter)); | 45 url_context_getter)); |
| 46 } | 46 } |
| 47 | 47 |
| 48 std::unique_ptr<::i18n::addressinput::Storage> GetAddressInputStorage() { | 48 std::unique_ptr<::i18n::addressinput::Storage> GetAddressInputStorage() { |
| 49 return autofill::ValidationRulesStorageFactory::CreateStorage(); | 49 return autofill::ValidationRulesStorageFactory::CreateStorage(); |
| 50 } | 50 } |
| 51 | 51 |
| 52 } // namespace | 52 } // namespace |
| 53 | 53 |
| 54 namespace payments { |
| 55 |
| 54 PaymentRequest::PaymentRequest( | 56 PaymentRequest::PaymentRequest( |
| 55 const web::PaymentRequest& web_payment_request, | 57 const web::PaymentRequest& web_payment_request, |
| 56 ios::ChromeBrowserState* browser_state, | 58 ios::ChromeBrowserState* browser_state, |
| 57 autofill::PersonalDataManager* personal_data_manager, | 59 autofill::PersonalDataManager* personal_data_manager, |
| 58 id<PaymentRequestUIDelegate> payment_request_ui_delegate) | 60 id<PaymentRequestUIDelegate> payment_request_ui_delegate) |
| 59 : web_payment_request_(web_payment_request), | 61 : web_payment_request_(web_payment_request), |
| 60 browser_state_(browser_state), | 62 browser_state_(browser_state), |
| 61 personal_data_manager_(personal_data_manager), | 63 personal_data_manager_(personal_data_manager), |
| 62 payment_request_ui_delegate_(payment_request_ui_delegate), | 64 payment_request_ui_delegate_(payment_request_ui_delegate), |
| 63 address_normalizer_(new payments::AddressNormalizerImpl( | 65 address_normalizer_(new AddressNormalizerImpl( |
| 64 GetAddressInputSource( | 66 GetAddressInputSource( |
| 65 personal_data_manager_->GetURLRequestContextGetter()), | 67 personal_data_manager_->GetURLRequestContextGetter()), |
| 66 GetAddressInputStorage())), | 68 GetAddressInputStorage())), |
| 67 selected_shipping_profile_(nullptr), | 69 selected_shipping_profile_(nullptr), |
| 68 selected_contact_profile_(nullptr), | 70 selected_contact_profile_(nullptr), |
| 69 selected_payment_method_(nullptr), | 71 selected_payment_method_(nullptr), |
| 70 selected_shipping_option_(nullptr), | 72 selected_shipping_option_(nullptr), |
| 71 profile_comparator_(GetApplicationContext()->GetApplicationLocale(), | 73 profile_comparator_(GetApplicationContext()->GetApplicationLocale(), |
| 72 *this) { | 74 *this) { |
| 73 PopulateAvailableShippingOptions(); | 75 PopulateAvailableShippingOptions(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 93 if (!contact_profiles_.empty() && | 95 if (!contact_profiles_.empty() && |
| 94 profile_comparator_.IsContactInfoComplete(contact_profiles_[0])) { | 96 profile_comparator_.IsContactInfoComplete(contact_profiles_[0])) { |
| 95 selected_contact_profile_ = contact_profiles_[0]; | 97 selected_contact_profile_ = contact_profiles_[0]; |
| 96 } | 98 } |
| 97 } | 99 } |
| 98 | 100 |
| 99 // TODO(crbug.com/702063): Change this code to prioritize payment methods by | 101 // TODO(crbug.com/702063): Change this code to prioritize payment methods by |
| 100 // use count and other means. | 102 // use count and other means. |
| 101 auto first_complete_payment_method = | 103 auto first_complete_payment_method = |
| 102 std::find_if(payment_methods_.begin(), payment_methods_.end(), | 104 std::find_if(payment_methods_.begin(), payment_methods_.end(), |
| 103 [this](payments::PaymentInstrument* payment_method) { | 105 [this](PaymentInstrument* payment_method) { |
| 104 return payment_method->IsCompleteForPayment(); | 106 return payment_method->IsCompleteForPayment(); |
| 105 }); | 107 }); |
| 106 if (first_complete_payment_method != payment_methods_.end()) | 108 if (first_complete_payment_method != payment_methods_.end()) |
| 107 selected_payment_method_ = *first_complete_payment_method; | 109 selected_payment_method_ = *first_complete_payment_method; |
| 108 } | 110 } |
| 109 | 111 |
| 110 PaymentRequest::~PaymentRequest() {} | 112 PaymentRequest::~PaymentRequest() {} |
| 111 | 113 |
| 112 autofill::PersonalDataManager* PaymentRequest::GetPersonalDataManager() { | 114 autofill::PersonalDataManager* PaymentRequest::GetPersonalDataManager() { |
| 113 return personal_data_manager_; | 115 return personal_data_manager_; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 132 } | 134 } |
| 133 | 135 |
| 134 void PaymentRequest::DoFullCardRequest( | 136 void PaymentRequest::DoFullCardRequest( |
| 135 const autofill::CreditCard& credit_card, | 137 const autofill::CreditCard& credit_card, |
| 136 base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate> | 138 base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate> |
| 137 result_delegate) { | 139 result_delegate) { |
| 138 [payment_request_ui_delegate_ requestFullCreditCard:credit_card | 140 [payment_request_ui_delegate_ requestFullCreditCard:credit_card |
| 139 resultDelegate:result_delegate]; | 141 resultDelegate:result_delegate]; |
| 140 } | 142 } |
| 141 | 143 |
| 142 payments::AddressNormalizer* PaymentRequest::GetAddressNormalizer() { | 144 AddressNormalizer* PaymentRequest::GetAddressNormalizer() { |
| 143 return address_normalizer_; | 145 return address_normalizer_; |
| 144 } | 146 } |
| 145 | 147 |
| 146 autofill::RegionDataLoader* PaymentRequest::GetRegionDataLoader() { | 148 autofill::RegionDataLoader* PaymentRequest::GetRegionDataLoader() { |
| 147 return new autofill::RegionDataLoaderImpl( | 149 return new autofill::RegionDataLoaderImpl( |
| 148 GetAddressInputSource( | 150 GetAddressInputSource( |
| 149 personal_data_manager_->GetURLRequestContextGetter()) | 151 personal_data_manager_->GetURLRequestContextGetter()) |
| 150 .release(), | 152 .release(), |
| 151 GetAddressInputStorage().release(), | 153 GetAddressInputStorage().release(), |
| 152 GetApplicationContext()->GetApplicationLocale()); | 154 GetApplicationContext()->GetApplicationLocale()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 } | 186 } |
| 185 | 187 |
| 186 bool PaymentRequest::request_payer_phone() const { | 188 bool PaymentRequest::request_payer_phone() const { |
| 187 return web_payment_request_.options.request_payer_phone; | 189 return web_payment_request_.options.request_payer_phone; |
| 188 } | 190 } |
| 189 | 191 |
| 190 bool PaymentRequest::request_payer_email() const { | 192 bool PaymentRequest::request_payer_email() const { |
| 191 return web_payment_request_.options.request_payer_email; | 193 return web_payment_request_.options.request_payer_email; |
| 192 } | 194 } |
| 193 | 195 |
| 194 payments::PaymentShippingType PaymentRequest::shipping_type() const { | 196 PaymentShippingType PaymentRequest::shipping_type() const { |
| 195 return web_payment_request_.options.shipping_type; | 197 return web_payment_request_.options.shipping_type; |
| 196 } | 198 } |
| 197 | 199 |
| 198 payments::CurrencyFormatter* PaymentRequest::GetOrCreateCurrencyFormatter() { | 200 CurrencyFormatter* PaymentRequest::GetOrCreateCurrencyFormatter() { |
| 199 if (!currency_formatter_) { | 201 if (!currency_formatter_) { |
| 200 currency_formatter_.reset(new payments::CurrencyFormatter( | 202 currency_formatter_.reset(new CurrencyFormatter( |
| 201 base::UTF16ToASCII(web_payment_request_.details.total.amount.currency), | 203 base::UTF16ToASCII(web_payment_request_.details.total.amount.currency), |
| 202 base::UTF16ToASCII( | 204 base::UTF16ToASCII( |
| 203 web_payment_request_.details.total.amount.currency_system), | 205 web_payment_request_.details.total.amount.currency_system), |
| 204 GetApplicationContext()->GetApplicationLocale())); | 206 GetApplicationContext()->GetApplicationLocale())); |
| 205 } | 207 } |
| 206 return currency_formatter_.get(); | 208 return currency_formatter_.get(); |
| 207 } | 209 } |
| 208 | 210 |
| 209 autofill::AutofillProfile* PaymentRequest::AddAutofillProfile( | 211 autofill::AutofillProfile* PaymentRequest::AddAutofillProfile( |
| 210 const autofill::AutofillProfile& profile) { | 212 const autofill::AutofillProfile& profile) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 | 246 |
| 245 // Contact profiles are deduped and ordered by completeness. | 247 // Contact profiles are deduped and ordered by completeness. |
| 246 contact_profiles_ = | 248 contact_profiles_ = |
| 247 profile_comparator_.FilterProfilesForContact(raw_profiles_for_filtering); | 249 profile_comparator_.FilterProfilesForContact(raw_profiles_for_filtering); |
| 248 | 250 |
| 249 // Shipping profiles are ordered by completeness. | 251 // Shipping profiles are ordered by completeness. |
| 250 shipping_profiles_ = | 252 shipping_profiles_ = |
| 251 profile_comparator_.FilterProfilesForShipping(raw_profiles_for_filtering); | 253 profile_comparator_.FilterProfilesForShipping(raw_profiles_for_filtering); |
| 252 } | 254 } |
| 253 | 255 |
| 254 payments::AutofillPaymentInstrument* | 256 AutofillPaymentInstrument* PaymentRequest::AddAutofillPaymentInstrument( |
| 255 PaymentRequest::AddAutofillPaymentInstrument( | |
| 256 const autofill::CreditCard& credit_card) { | 257 const autofill::CreditCard& credit_card) { |
| 257 std::string basic_card_issuer_network = | 258 std::string basic_card_issuer_network = |
| 258 autofill::data_util::GetPaymentRequestData(credit_card.network()) | 259 autofill::data_util::GetPaymentRequestData(credit_card.network()) |
| 259 .basic_card_issuer_network; | 260 .basic_card_issuer_network; |
| 260 | 261 |
| 261 if (!base::ContainsValue(supported_card_networks_, | 262 if (!base::ContainsValue(supported_card_networks_, |
| 262 basic_card_issuer_network) || | 263 basic_card_issuer_network) || |
| 263 !supported_card_types_set_.count(credit_card.card_type())) { | 264 !supported_card_types_set_.count(credit_card.card_type())) { |
| 264 return nullptr; | 265 return nullptr; |
| 265 } | 266 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 277 | 278 |
| 278 // Whether the card type (credit, debit, prepaid) matches the type that the | 279 // Whether the card type (credit, debit, prepaid) matches the type that the |
| 279 // merchant has requested exactly. This should be false for unknown card | 280 // merchant has requested exactly. This should be false for unknown card |
| 280 // types, if the merchant cannot accept some card types. | 281 // types, if the merchant cannot accept some card types. |
| 281 bool matches_merchant_card_type_exactly = | 282 bool matches_merchant_card_type_exactly = |
| 282 credit_card.card_type() != autofill::CreditCard::CARD_TYPE_UNKNOWN || | 283 credit_card.card_type() != autofill::CreditCard::CARD_TYPE_UNKNOWN || |
| 283 supported_card_types_set_.size() == kTotalNumberOfCardTypes; | 284 supported_card_types_set_.size() == kTotalNumberOfCardTypes; |
| 284 | 285 |
| 285 // AutofillPaymentInstrument makes a copy of |credit_card| so it is | 286 // AutofillPaymentInstrument makes a copy of |credit_card| so it is |
| 286 // effectively owned by this object. | 287 // effectively owned by this object. |
| 287 payment_method_cache_.push_back( | 288 payment_method_cache_.push_back(base::MakeUnique<AutofillPaymentInstrument>( |
| 288 base::MakeUnique<payments::AutofillPaymentInstrument>( | 289 method_name, credit_card, matches_merchant_card_type_exactly, |
| 289 method_name, credit_card, matches_merchant_card_type_exactly, | 290 billing_profiles(), GetApplicationContext()->GetApplicationLocale(), |
| 290 billing_profiles(), GetApplicationContext()->GetApplicationLocale(), | 291 this)); |
| 291 this)); | |
| 292 | 292 |
| 293 PopulateAvailablePaymentMethods(); | 293 PopulateAvailablePaymentMethods(); |
| 294 | 294 |
| 295 return static_cast<payments::AutofillPaymentInstrument*>( | 295 return static_cast<AutofillPaymentInstrument*>( |
| 296 payment_method_cache_.back().get()); | 296 payment_method_cache_.back().get()); |
| 297 } | 297 } |
| 298 | 298 |
| 299 payments::PaymentsProfileComparator* PaymentRequest::profile_comparator() { | 299 PaymentsProfileComparator* PaymentRequest::profile_comparator() { |
| 300 return &profile_comparator_; | 300 return &profile_comparator_; |
| 301 } | 301 } |
| 302 | 302 |
| 303 bool PaymentRequest::CanMakePayment() const { | 303 bool PaymentRequest::CanMakePayment() const { |
| 304 for (payments::PaymentInstrument* payment_method : payment_methods_) { | 304 for (PaymentInstrument* payment_method : payment_methods_) { |
| 305 if (payment_method->IsValidForCanMakePayment()) { | 305 if (payment_method->IsValidForCanMakePayment()) { |
| 306 return true; | 306 return true; |
| 307 } | 307 } |
| 308 } | 308 } |
| 309 return false; | 309 return false; |
| 310 } | 310 } |
| 311 | 311 |
| 312 void PaymentRequest::RecordUseStats() { | 312 void PaymentRequest::RecordUseStats() { |
| 313 if (request_shipping()) { | 313 if (request_shipping()) { |
| 314 DCHECK(selected_shipping_profile_); | 314 DCHECK(selected_shipping_profile_); |
| 315 personal_data_manager_->RecordUseOf(*selected_shipping_profile_); | 315 personal_data_manager_->RecordUseOf(*selected_shipping_profile_); |
| 316 } | 316 } |
| 317 | 317 |
| 318 if (request_payer_name() || request_payer_email() || request_payer_phone()) { | 318 if (request_payer_name() || request_payer_email() || request_payer_phone()) { |
| 319 DCHECK(selected_contact_profile_); | 319 DCHECK(selected_contact_profile_); |
| 320 // If the same address was used for both contact and shipping, the stats | 320 // If the same address was used for both contact and shipping, the stats |
| 321 // should be updated only once. | 321 // should be updated only once. |
| 322 if (!request_shipping() || (selected_shipping_profile_->guid() != | 322 if (!request_shipping() || (selected_shipping_profile_->guid() != |
| 323 selected_contact_profile_->guid())) { | 323 selected_contact_profile_->guid())) { |
| 324 personal_data_manager_->RecordUseOf(*selected_contact_profile_); | 324 personal_data_manager_->RecordUseOf(*selected_contact_profile_); |
| 325 } | 325 } |
| 326 } | 326 } |
| 327 | 327 |
| 328 selected_payment_method_->RecordUse(); | 328 selected_payment_method_->RecordUse(); |
| 329 } | 329 } |
| 330 | 330 |
| 331 void PaymentRequest::PopulatePaymentMethodCache() { | 331 void PaymentRequest::PopulatePaymentMethodCache() { |
| 332 for (const payments::PaymentMethodData& method_data_entry : | 332 for (const PaymentMethodData& method_data_entry : |
| 333 web_payment_request_.method_data) { | 333 web_payment_request_.method_data) { |
| 334 for (const std::string& method : method_data_entry.supported_methods) { | 334 for (const std::string& method : method_data_entry.supported_methods) { |
| 335 stringified_method_data_[method].insert(method_data_entry.data); | 335 stringified_method_data_[method].insert(method_data_entry.data); |
| 336 } | 336 } |
| 337 } | 337 } |
| 338 | 338 |
| 339 // TODO(crbug.com/709036): Validate method data. | 339 // TODO(crbug.com/709036): Validate method data. |
| 340 payments::data_util::ParseBasicCardSupportedNetworks( | 340 data_util::ParseBasicCardSupportedNetworks(web_payment_request_.method_data, |
| 341 web_payment_request_.method_data, &supported_card_networks_, | 341 &supported_card_networks_, |
| 342 &basic_card_specified_networks_); | 342 &basic_card_specified_networks_); |
| 343 | 343 |
| 344 payments::data_util::ParseSupportedCardTypes(web_payment_request_.method_data, | 344 data_util::ParseSupportedCardTypes(web_payment_request_.method_data, |
| 345 &supported_card_types_set_); | 345 &supported_card_types_set_); |
| 346 | 346 |
| 347 const std::vector<autofill::CreditCard*>& credit_cards_to_suggest = | 347 const std::vector<autofill::CreditCard*>& credit_cards_to_suggest = |
| 348 personal_data_manager_->GetCreditCardsToSuggest(); | 348 personal_data_manager_->GetCreditCardsToSuggest(); |
| 349 // Return early if the user has no stored credit cards. | 349 // Return early if the user has no stored credit cards. |
| 350 if (credit_cards_to_suggest.empty()) | 350 if (credit_cards_to_suggest.empty()) |
| 351 return; | 351 return; |
| 352 | 352 |
| 353 // TODO(crbug.com/602666): Determine number of possible payments so | 353 // TODO(crbug.com/602666): Determine number of possible payments so |
| 354 // that we can appropriate reserve space in the following vector. | 354 // that we can appropriate reserve space in the following vector. |
| 355 | 355 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 void PaymentRequest::SetSelectedShippingOption() { | 388 void PaymentRequest::SetSelectedShippingOption() { |
| 389 // If more than one option has |selected| set, the last one in the sequence | 389 // If more than one option has |selected| set, the last one in the sequence |
| 390 // should be treated as the selected item. | 390 // should be treated as the selected item. |
| 391 for (auto* shipping_option : base::Reversed(shipping_options_)) { | 391 for (auto* shipping_option : base::Reversed(shipping_options_)) { |
| 392 if (shipping_option->selected) { | 392 if (shipping_option->selected) { |
| 393 selected_shipping_option_ = shipping_option; | 393 selected_shipping_option_ = shipping_option; |
| 394 break; | 394 break; |
| 395 } | 395 } |
| 396 } | 396 } |
| 397 } | 397 } |
| 398 |
| 399 } // namespace payments |
| OLD | NEW |