blob: cb0941cf9423ca405f01cf702c92ca32ae6b4295 [file] [log] [blame]
mathpf1a7a3752017-03-15 11:23:371// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "components/payments/content/payment_request_state.h"
6
mad45271932017-04-13 16:07:387#include <algorithm>
anthonyvd0116ce332017-03-21 21:29:018#include <set>
mad45271932017-04-13 16:07:389#include <utility>
anthonyvd0116ce332017-03-21 21:29:0110
gogerald8189d522017-09-15 17:52:1811#include "base/feature_list.h"
sebsgad86bd002017-03-29 16:39:1212#include "base/strings/utf_string_conversions.h"
sebsg7e619132017-04-27 16:07:1013#include "components/autofill/core/browser/autofill_country.h"
mathpf1a7a3752017-03-15 11:23:3714#include "components/autofill/core/browser/autofill_data_util.h"
15#include "components/autofill/core/browser/autofill_profile.h"
16#include "components/autofill/core/browser/credit_card.h"
mathpc0d616a2017-03-15 14:09:3317#include "components/autofill/core/browser/personal_data_manager.h"
Rouslan Solomakhin4eea9bc22017-10-10 15:18:5118#include "components/payments/content/content_payment_request_delegate.h"
Rouslan Solomakhin4eea9bc22017-10-10 15:18:5119#include "components/payments/content/payment_manifest_web_data_service.h"
sebsgad86bd002017-03-29 16:39:1220#include "components/payments/content/payment_response_helper.h"
gogerald8189d522017-09-15 17:52:1821#include "components/payments/content/service_worker_payment_instrument.h"
mathpf1a7a3752017-03-15 11:23:3722#include "components/payments/core/autofill_payment_instrument.h"
Mathieu Perreault157f3992018-06-29 18:48:0623#include "components/payments/core/features.h"
sebsgc6719b32017-07-05 19:54:4724#include "components/payments/core/journey_logger.h"
sebsg695799a2017-04-11 16:29:0625#include "components/payments/core/payment_instrument.h"
tmartino01c3eb82017-04-29 15:18:3926#include "components/payments/core/payment_request_data_util.h"
gogerald8189d522017-09-15 17:52:1827#include "content/public/common/content_features.h"
mathpf1a7a3752017-03-15 11:23:3728
29namespace payments {
30
mathpc0d616a2017-03-15 14:09:3331PaymentRequestState::PaymentRequestState(
Rouslan Solomakhindbf593d92017-11-21 19:20:5732 content::WebContents* web_contents,
gogerald7a0cc3e2017-09-19 03:35:4833 const GURL& top_level_origin,
34 const GURL& frame_origin,
mathpc0d616a2017-03-15 14:09:3335 PaymentRequestSpec* spec,
36 Delegate* delegate,
37 const std::string& app_locale,
anthonyvdd23ed702017-04-05 15:29:0038 autofill::PersonalDataManager* personal_data_manager,
Rouslan Solomakhin4eea9bc22017-10-10 15:18:5139 ContentPaymentRequestDelegate* payment_request_delegate,
sebsgc6719b32017-07-05 19:54:4740 JourneyLogger* journey_logger)
mathpf1a7a3752017-03-15 11:23:3741 : is_ready_to_pay_(false),
gogerald8189d522017-09-15 17:52:1842 get_all_instruments_finished_(true),
sebsg7e619132017-04-27 16:07:1043 is_waiting_for_merchant_validation_(false),
mathpc0d616a2017-03-15 14:09:3344 app_locale_(app_locale),
mathpf1a7a3752017-03-15 11:23:3745 spec_(spec),
46 delegate_(delegate),
mathpc0d616a2017-03-15 14:09:3347 personal_data_manager_(personal_data_manager),
sebsgc6719b32017-07-05 19:54:4748 journey_logger_(journey_logger),
mathpf1a7a3752017-03-15 11:23:3749 selected_shipping_profile_(nullptr),
Mathieu Perreault04b4c662017-06-02 13:35:1350 selected_shipping_option_error_profile_(nullptr),
mathpf1a7a3752017-03-15 11:23:3751 selected_contact_profile_(nullptr),
anthonyvdd23ed702017-04-05 15:29:0052 selected_instrument_(nullptr),
gogeraldac15d2362017-11-15 01:04:1953 number_of_pending_sw_payment_instruments_(0),
tmartino01c3eb82017-04-29 15:18:3954 payment_request_delegate_(payment_request_delegate),
gogerald8189d522017-09-15 17:52:1855 profile_comparator_(app_locale, *spec),
56 weak_ptr_factory_(this) {
Mathieu Perreault157f3992018-06-29 18:48:0657 if (base::FeatureList::IsEnabled(::features::kServiceWorkerPaymentApps)) {
gogerald8189d522017-09-15 17:52:1858 get_all_instruments_finished_ = false;
gogerald97e1b3312017-11-21 23:31:1059 ServiceWorkerPaymentAppFactory::GetInstance()->GetAllPaymentApps(
Rouslan Solomakhindbf593d92017-11-21 19:20:5760 web_contents,
Rouslan Solomakhin438d8c92017-10-26 21:33:1861 payment_request_delegate_->GetPaymentManifestWebDataService(),
Rouslan Solomakhin06df42d2017-11-14 20:35:1162 spec_->method_data(),
Rouslan Solomakhine36f41f2018-03-19 16:27:0963 /*may_crawl_for_installable_payment_apps=*/
64 !spec_->supports_basic_card(),
Rouslan Solomakhin438d8c92017-10-26 21:33:1865 base::BindOnce(&PaymentRequestState::GetAllPaymentAppsCallback,
gogerald3f1cabf2018-02-08 14:19:1866 weak_ptr_factory_.GetWeakPtr(), web_contents,
67 top_level_origin, frame_origin),
gogerald97e1b3312017-11-21 23:31:1068 base::BindOnce([]() {
69 /* Nothing needs to be done after writing cache. This callback is used
70 * only in tests. */
71 }));
gogerald8189d522017-09-15 17:52:1872 } else {
73 PopulateProfileCache();
74 SetDefaultProfileSelections();
75 }
sebsg7e619132017-04-27 16:07:1076 spec_->AddObserver(this);
mathpf1a7a3752017-03-15 11:23:3777}
Rouslan Solomakhin4eea9bc22017-10-10 15:18:5178
mathp151bd312017-04-03 21:07:2479PaymentRequestState::~PaymentRequestState() {}
mathpf1a7a3752017-03-15 11:23:3780
gogerald8189d522017-09-15 17:52:1881void PaymentRequestState::GetAllPaymentAppsCallback(
gogerald3f1cabf2018-02-08 14:19:1882 content::WebContents* web_contents,
gogerald7a0cc3e2017-09-19 03:35:4883 const GURL& top_level_origin,
84 const GURL& frame_origin,
gogerald84ae6262018-02-06 06:21:4685 content::PaymentAppProvider::PaymentApps apps,
86 ServiceWorkerPaymentAppFactory::InstallablePaymentApps installable_apps) {
gogerald3f1cabf2018-02-08 14:19:1887 number_of_pending_sw_payment_instruments_ =
88 apps.size() + installable_apps.size();
gogeraldac15d2362017-11-15 01:04:1989 if (number_of_pending_sw_payment_instruments_ == 0U) {
90 FinishedGetAllSWPaymentInstruments();
91 return;
gogerald8189d522017-09-15 17:52:1892 }
93
gogeraldac15d2362017-11-15 01:04:1994 for (auto& app : apps) {
95 std::unique_ptr<ServiceWorkerPaymentInstrument> instrument =
96 std::make_unique<ServiceWorkerPaymentInstrument>(
gogerald3f1cabf2018-02-08 14:19:1897 web_contents->GetBrowserContext(), top_level_origin, frame_origin,
98 spec_, std::move(app.second), payment_request_delegate_);
99 instrument->ValidateCanMakePayment(
100 base::BindOnce(&PaymentRequestState::OnSWPaymentInstrumentValidated,
101 weak_ptr_factory_.GetWeakPtr()));
102 available_instruments_.push_back(std::move(instrument));
103 }
104
105 for (auto& installable_app : installable_apps) {
106 std::unique_ptr<ServiceWorkerPaymentInstrument> instrument =
107 std::make_unique<ServiceWorkerPaymentInstrument>(
108 web_contents, top_level_origin, frame_origin, spec_,
109 std::move(installable_app.second), installable_app.first.spec(),
110 payment_request_delegate_);
gogeraldac15d2362017-11-15 01:04:19111 instrument->ValidateCanMakePayment(
112 base::BindOnce(&PaymentRequestState::OnSWPaymentInstrumentValidated,
113 weak_ptr_factory_.GetWeakPtr()));
114 available_instruments_.push_back(std::move(instrument));
115 }
116}
117
118void PaymentRequestState::OnSWPaymentInstrumentValidated(
119 ServiceWorkerPaymentInstrument* instrument,
120 bool result) {
121 // Remove service worker payment instruments failed on validation.
122 if (!result) {
123 for (size_t i = 0; i < available_instruments_.size(); i++) {
124 if (available_instruments_[i].get() == instrument) {
125 available_instruments_.erase(available_instruments_.begin() + i);
126 break;
127 }
128 }
129 }
130
131 if (--number_of_pending_sw_payment_instruments_ > 0)
132 return;
133
134 FinishedGetAllSWPaymentInstruments();
135}
136
137void PaymentRequestState::FinishedGetAllSWPaymentInstruments() {
gogerald8189d522017-09-15 17:52:18138 PopulateProfileCache();
139 SetDefaultProfileSelections();
140
141 get_all_instruments_finished_ = true;
142 NotifyOnGetAllPaymentInstrumentsFinished();
143
gogerald0a7ee6c2017-11-13 18:23:19144 // Fullfill the pending CanMakePayment call.
gogerald8189d522017-09-15 17:52:18145 if (can_make_payment_callback_)
146 CheckCanMakePayment(std::move(can_make_payment_callback_));
gogerald0a7ee6c2017-11-13 18:23:19147
148 // Fullfill the pending AreRequestedMethodsSupported call.
149 if (are_requested_methods_supported_callback_)
150 CheckRequestedMethodsSupported(
151 std::move(are_requested_methods_supported_callback_));
gogerald8189d522017-09-15 17:52:18152}
153
sebsg695799a2017-04-11 16:29:06154void PaymentRequestState::OnPaymentResponseReady(
155 mojom::PaymentResponsePtr payment_response) {
156 delegate_->OnPaymentResponseAvailable(std::move(payment_response));
157}
158
sebsg7e619132017-04-27 16:07:10159void PaymentRequestState::OnSpecUpdated() {
Mathieu Perreault04b4c662017-06-02 13:35:13160 if (spec_->selected_shipping_option_error().empty()) {
161 selected_shipping_option_error_profile_ = nullptr;
162 } else {
163 selected_shipping_option_error_profile_ = selected_shipping_profile_;
164 selected_shipping_profile_ = nullptr;
165 }
sebsg7e619132017-04-27 16:07:10166 is_waiting_for_merchant_validation_ = false;
167 UpdateIsReadyToPayAndNotifyObservers();
168}
169
gogerald0a7ee6c2017-11-13 18:23:19170void PaymentRequestState::CanMakePayment(StatusCallback callback) {
gogerald8189d522017-09-15 17:52:18171 if (!get_all_instruments_finished_) {
172 can_make_payment_callback_ = std::move(callback);
173 return;
174 }
175
176 base::ThreadTaskRunnerHandle::Get()->PostTask(
177 FROM_HERE,
178 base::BindOnce(&PaymentRequestState::CheckCanMakePayment,
179 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
180}
181
gogerald0a7ee6c2017-11-13 18:23:19182void PaymentRequestState::CheckCanMakePayment(StatusCallback callback) {
gogerald8189d522017-09-15 17:52:18183 bool can_make_payment_value = false;
Rouslan Solomakhin25d708b2017-06-23 17:12:03184 for (const auto& instrument : available_instruments_) {
rouslan6e3cf7c62017-04-17 21:23:28185 if (instrument->IsValidForCanMakePayment()) {
gogerald8189d522017-09-15 17:52:18186 can_make_payment_value = true;
187 break;
mathp1a5be4f2017-03-24 18:09:19188 }
189 }
gogerald8189d522017-09-15 17:52:18190 std::move(callback).Run(can_make_payment_value);
mathp1a5be4f2017-03-24 18:09:19191}
192
gogerald0a7ee6c2017-11-13 18:23:19193void PaymentRequestState::AreRequestedMethodsSupported(
194 StatusCallback callback) {
195 if (!get_all_instruments_finished_) {
196 are_requested_methods_supported_callback_ = std::move(callback);
197 return;
198 }
199
200 base::ThreadTaskRunnerHandle::Get()->PostTask(
201 FROM_HERE,
202 base::BindOnce(&PaymentRequestState::CheckRequestedMethodsSupported,
203 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
204}
205
206void PaymentRequestState::CheckRequestedMethodsSupported(
207 StatusCallback callback) {
208 DCHECK(get_all_instruments_finished_);
209
210 std::move(callback).Run(!spec_->supported_card_networks().empty() ||
211 !available_instruments_.empty());
rouslan6e3cf7c62017-04-17 21:23:28212}
213
anthonyvd6a43b932017-05-11 18:39:27214std::string PaymentRequestState::GetAuthenticatedEmail() const {
215 return payment_request_delegate_->GetAuthenticatedEmail();
216}
217
mathpf1a7a3752017-03-15 11:23:37218void PaymentRequestState::AddObserver(Observer* observer) {
219 CHECK(observer);
220 observers_.AddObserver(observer);
221}
mathpf1a7a3752017-03-15 11:23:37222
223void PaymentRequestState::RemoveObserver(Observer* observer) {
224 observers_.RemoveObserver(observer);
225}
226
mathpf1a7a3752017-03-15 11:23:37227void PaymentRequestState::GeneratePaymentResponse() {
mathp363735b2017-03-16 18:08:05228 DCHECK(is_ready_to_pay());
sebsg695799a2017-04-11 16:29:06229
230 // Once the response is ready, will call back into OnPaymentResponseReady.
Rouslan Solomakhin4eea9bc22017-10-10 15:18:51231 response_helper_ = std::make_unique<PaymentResponseHelper>(
sebsg8a9c2342017-04-21 17:05:15232 app_locale_, spec_, selected_instrument_, payment_request_delegate_,
233 selected_shipping_profile_, selected_contact_profile_, this);
mathpf1a7a3752017-03-15 11:23:37234}
235
sebsg8a93b272017-05-11 19:30:22236void PaymentRequestState::RecordUseStats() {
237 if (spec_->request_shipping()) {
238 DCHECK(selected_shipping_profile_);
239 personal_data_manager_->RecordUseOf(*selected_shipping_profile_);
240 }
241
242 if (spec_->request_payer_name() || spec_->request_payer_email() ||
243 spec_->request_payer_phone()) {
244 DCHECK(selected_contact_profile_);
245
246 // If the same address was used for both contact and shipping, the stats
247 // should only be updated once.
248 if (!spec_->request_shipping() || (selected_shipping_profile_->guid() !=
249 selected_contact_profile_->guid())) {
250 personal_data_manager_->RecordUseOf(*selected_contact_profile_);
251 }
252 }
253
254 selected_instrument_->RecordUse();
255}
256
mathp24ce4cd2017-04-12 20:56:42257void PaymentRequestState::AddAutofillPaymentInstrument(
258 bool selected,
259 const autofill::CreditCard& card) {
260 std::string basic_card_network =
rouslan4e981bd32017-05-01 17:49:16261 autofill::data_util::GetPaymentRequestData(card.network())
262 .basic_card_issuer_network;
Rouslan Solomakhin25d708b2017-06-23 17:12:03263 if (!spec_->supported_card_networks_set().count(basic_card_network) ||
264 !spec_->supported_card_types_set().count(card.card_type())) {
mathp24ce4cd2017-04-12 20:56:42265 return;
Rouslan Solomakhin25d708b2017-06-23 17:12:03266 }
267
268 // The total number of card types: credit, debit, prepaid, unknown.
269 constexpr size_t kTotalNumberOfCardTypes = 4U;
270
271 // Whether the card type (credit, debit, prepaid) matches thetype that the
272 // merchant has requested exactly. This should be false for unknown card
273 // types, if the merchant cannot accept some card types.
274 bool matches_merchant_card_type_exactly =
275 card.card_type() != autofill::CreditCard::CARD_TYPE_UNKNOWN ||
276 spec_->supported_card_types_set().size() == kTotalNumberOfCardTypes;
mathp24ce4cd2017-04-12 20:56:42277
278 // AutofillPaymentInstrument makes a copy of |card| so it is effectively
279 // owned by this object.
Rouslan Solomakhin4eea9bc22017-10-10 15:18:51280 auto instrument = std::make_unique<AutofillPaymentInstrument>(
Rouslan Solomakhin25d708b2017-06-23 17:12:03281 basic_card_network, card, matches_merchant_card_type_exactly,
282 shipping_profiles_, app_locale_, payment_request_delegate_);
mathp24ce4cd2017-04-12 20:56:42283 available_instruments_.push_back(std::move(instrument));
284
285 if (selected)
286 SetSelectedInstrument(available_instruments_.back().get());
287}
288
madf9904ea2017-04-25 18:39:12289void PaymentRequestState::AddAutofillShippingProfile(
290 bool selected,
291 const autofill::AutofillProfile& profile) {
292 profile_cache_.push_back(
Rouslan Solomakhin4eea9bc22017-10-10 15:18:51293 std::make_unique<autofill::AutofillProfile>(profile));
madf9904ea2017-04-25 18:39:12294 // TODO(tmartino): Implement deduplication rules specific to shipping
295 // profiles.
296 autofill::AutofillProfile* new_cached_profile = profile_cache_.back().get();
297 shipping_profiles_.push_back(new_cached_profile);
298
299 if (selected)
300 SetSelectedShippingProfile(new_cached_profile);
301}
302
Anthony Vallee-Duboisf1e88b42017-05-15 15:09:23303void PaymentRequestState::AddAutofillContactProfile(
304 bool selected,
305 const autofill::AutofillProfile& profile) {
306 profile_cache_.push_back(
Rouslan Solomakhin4eea9bc22017-10-10 15:18:51307 std::make_unique<autofill::AutofillProfile>(profile));
Anthony Vallee-Duboisf1e88b42017-05-15 15:09:23308 autofill::AutofillProfile* new_cached_profile = profile_cache_.back().get();
309 contact_profiles_.push_back(new_cached_profile);
310
311 if (selected)
312 SetSelectedContactProfile(new_cached_profile);
313}
314
anthonyvd0116ce332017-03-21 21:29:01315void PaymentRequestState::SetSelectedShippingOption(
mathp151bd312017-04-03 21:07:24316 const std::string& shipping_option_id) {
anthonyvd2f30baa12017-04-13 22:30:50317 spec_->StartWaitingForUpdateWith(
318 PaymentRequestSpec::UpdateReason::SHIPPING_OPTION);
mathp151bd312017-04-03 21:07:24319 // This will inform the merchant and will lead to them calling updateWith with
320 // new PaymentDetails.
321 delegate_->OnShippingOptionIdSelected(shipping_option_id);
anthonyvd0116ce332017-03-21 21:29:01322}
323
mathpf1a7a3752017-03-15 11:23:37324void PaymentRequestState::SetSelectedShippingProfile(
325 autofill::AutofillProfile* profile) {
anthonyvd2f30baa12017-04-13 22:30:50326 spec_->StartWaitingForUpdateWith(
327 PaymentRequestSpec::UpdateReason::SHIPPING_ADDRESS);
mathpf1a7a3752017-03-15 11:23:37328 selected_shipping_profile_ = profile;
sebsg7e619132017-04-27 16:07:10329
330 // The user should not be able to click on pay until the callback from the
331 // merchant.
332 is_waiting_for_merchant_validation_ = true;
sebsg7e619132017-04-27 16:07:10333
334 // Start the normalization of the shipping address.
Mathieu Perreaultc94700f2017-10-23 20:28:39335 payment_request_delegate_->GetAddressNormalizer()->NormalizeAddressAsync(
Mathieu Perreault9b40d5102017-11-21 20:51:29336 *selected_shipping_profile_, /*timeout_seconds=*/2,
Mathieu Perreault17c1ae92017-10-20 17:16:00337 base::BindOnce(&PaymentRequestState::OnAddressNormalized,
338 weak_ptr_factory_.GetWeakPtr()));
mathpf1a7a3752017-03-15 11:23:37339}
340
341void PaymentRequestState::SetSelectedContactProfile(
342 autofill::AutofillProfile* profile) {
343 selected_contact_profile_ = profile;
344 UpdateIsReadyToPayAndNotifyObservers();
345}
346
mathp363735b2017-03-16 18:08:05347void PaymentRequestState::SetSelectedInstrument(PaymentInstrument* instrument) {
348 selected_instrument_ = instrument;
mathpf1a7a3752017-03-15 11:23:37349 UpdateIsReadyToPayAndNotifyObservers();
350}
351
mathpc0d616a2017-03-15 14:09:33352const std::string& PaymentRequestState::GetApplicationLocale() {
353 return app_locale_;
354}
355
356autofill::PersonalDataManager* PaymentRequestState::GetPersonalDataManager() {
357 return personal_data_manager_;
358}
359
mad763ed2b2017-04-24 20:28:47360autofill::RegionDataLoader* PaymentRequestState::GetRegionDataLoader() {
361 return payment_request_delegate_->GetRegionDataLoader();
mad45271932017-04-13 16:07:38362}
363
Anthony Vallee-Dubois6813c1442017-05-17 19:32:56364bool PaymentRequestState::IsPaymentAppInvoked() const {
365 return !!response_helper_;
366}
367
Mathieu Perreaulteea046d12017-09-28 15:51:21368autofill::AddressNormalizer* PaymentRequestState::GetAddressNormalizer() {
Anthony Vallee-Dubois71bf349462017-07-20 23:56:45369 return payment_request_delegate_->GetAddressNormalizer();
370}
371
mathpf1a7a3752017-03-15 11:23:37372void PaymentRequestState::PopulateProfileCache() {
mathpf1a7a3752017-03-15 11:23:37373 std::vector<autofill::AutofillProfile*> profiles =
mathpc0d616a2017-03-15 14:09:33374 personal_data_manager_->GetProfilesToSuggest();
mathpf1a7a3752017-03-15 11:23:37375
tmartinocd131b32017-05-24 19:40:59376 std::vector<autofill::AutofillProfile*> raw_profiles_for_filtering;
377 raw_profiles_for_filtering.reserve(profiles.size());
378
mathpf1a7a3752017-03-15 11:23:37379 // PaymentRequest may outlive the Profiles returned by the Data Manager.
380 // Thus, we store copies, and return a vector of pointers to these copies
mathpf14c1e32017-05-12 16:37:30381 // whenever Profiles are requested.
mathpf1a7a3752017-03-15 11:23:37382 for (size_t i = 0; i < profiles.size(); i++) {
383 profile_cache_.push_back(
Rouslan Solomakhin4eea9bc22017-10-10 15:18:51384 std::make_unique<autofill::AutofillProfile>(*profiles[i]));
tmartinocd131b32017-05-24 19:40:59385 raw_profiles_for_filtering.push_back(profile_cache_.back().get());
mathpf1a7a3752017-03-15 11:23:37386 }
387
tmartino01c3eb82017-04-29 15:18:39388 contact_profiles_ = profile_comparator()->FilterProfilesForContact(
389 raw_profiles_for_filtering);
tmartinocd131b32017-05-24 19:40:59390 shipping_profiles_ = profile_comparator()->FilterProfilesForShipping(
391 raw_profiles_for_filtering);
tmartinoa6eb22f2017-04-06 20:16:24392
sebsgc6719b32017-07-05 19:54:47393 // Set the number of suggestions shown for the sections requested by the
394 // merchant.
395 if (spec_->request_payer_name() || spec_->request_payer_phone() ||
396 spec_->request_payer_email()) {
sebsgce700484d2017-07-19 23:25:38397 bool has_complete_contact =
398 contact_profiles_.empty()
399 ? false
400 : profile_comparator()->IsContactInfoComplete(contact_profiles_[0]);
sebsgc6719b32017-07-05 19:54:47401 journey_logger_->SetNumberOfSuggestionsShown(
sebsgce700484d2017-07-19 23:25:38402 JourneyLogger::Section::SECTION_CONTACT_INFO, contact_profiles_.size(),
403 has_complete_contact);
sebsgc6719b32017-07-05 19:54:47404 }
405 if (spec_->request_shipping()) {
sebsgce700484d2017-07-19 23:25:38406 bool has_complete_shipping =
407 shipping_profiles_.empty()
408 ? false
409 : profile_comparator()->IsShippingComplete(shipping_profiles_[0]);
sebsgc6719b32017-07-05 19:54:47410 journey_logger_->SetNumberOfSuggestionsShown(
411 JourneyLogger::Section::SECTION_SHIPPING_ADDRESS,
sebsgce700484d2017-07-19 23:25:38412 shipping_profiles_.size(), has_complete_shipping);
sebsgc6719b32017-07-05 19:54:47413 }
414
mathpf14c1e32017-05-12 16:37:30415 // Create the list of available instruments. A copy of each card will be made
416 // by their respective AutofillPaymentInstrument.
mathpf1a7a3752017-03-15 11:23:37417 const std::vector<autofill::CreditCard*>& cards =
Amirhossein Simjourd3b7ba4a2018-05-07 15:27:21418 personal_data_manager_->GetCreditCardsToSuggest(
Mathieu Perreault157f3992018-06-29 18:48:06419 /*include_server_cards=*/base::FeatureList::IsEnabled(
420 payments::features::kReturnGooglePayInBasicCard));
mathp24ce4cd2017-04-12 20:56:42421 for (autofill::CreditCard* card : cards)
422 AddAutofillPaymentInstrument(/*selected=*/false, *card);
mathpf1a7a3752017-03-15 11:23:37423}
424
425void PaymentRequestState::SetDefaultProfileSelections() {
mathp151bd312017-04-03 21:07:24426 // Only pre-select an address if the merchant provided at least one selected
tmartinocd131b32017-05-24 19:40:59427 // shipping option, and the top profile is complete. Assumes that profiles
428 // have already been sorted for completeness and frecency.
429 if (!shipping_profiles().empty() && spec_->selected_shipping_option() &&
430 profile_comparator()->IsShippingComplete(shipping_profiles_[0])) {
431 selected_shipping_profile_ = shipping_profiles()[0];
mathpf14c1e32017-05-12 16:37:30432 }
mathpf1a7a3752017-03-15 11:23:37433
mathpf14c1e32017-05-12 16:37:30434 // Contact profiles were ordered by completeness in addition to frecency;
435 // the first one is the best default selection.
tmartinocd131b32017-05-24 19:40:59436 if (!contact_profiles().empty() &&
437 profile_comparator()->IsContactInfoComplete(contact_profiles_[0]))
mathpf1a7a3752017-03-15 11:23:37438 selected_contact_profile_ = contact_profiles()[0];
439
mathp363735b2017-03-16 18:08:05440 // TODO(crbug.com/702063): Change this code to prioritize instruments by use
441 // count and other means, and implement a way to modify this function's return
442 // value.
443 const std::vector<std::unique_ptr<PaymentInstrument>>& instruments =
444 available_instruments();
445 auto first_complete_instrument =
446 std::find_if(instruments.begin(), instruments.end(),
447 [](const std::unique_ptr<PaymentInstrument>& instrument) {
Rouslan Solomakhin25d708b2017-06-23 17:12:03448 return instrument->IsCompleteForPayment() &&
449 instrument->IsExactlyMatchingMerchantRequest();
mathp363735b2017-03-16 18:08:05450 });
mathp363735b2017-03-16 18:08:05451 selected_instrument_ = first_complete_instrument == instruments.end()
452 ? nullptr
453 : first_complete_instrument->get();
mathpf1a7a3752017-03-15 11:23:37454 UpdateIsReadyToPayAndNotifyObservers();
gogerald8189d522017-09-15 17:52:18455
456 bool has_complete_instrument =
457 available_instruments().empty()
458 ? false
459 : available_instruments()[0]->IsCompleteForPayment();
460
461 journey_logger_->SetNumberOfSuggestionsShown(
462 JourneyLogger::Section::SECTION_PAYMENT_METHOD,
463 available_instruments().size(), has_complete_instrument);
mathpf1a7a3752017-03-15 11:23:37464}
465
466void PaymentRequestState::UpdateIsReadyToPayAndNotifyObservers() {
467 is_ready_to_pay_ =
468 ArePaymentDetailsSatisfied() && ArePaymentOptionsSatisfied();
469 NotifyOnSelectedInformationChanged();
470}
471
gogerald8189d522017-09-15 17:52:18472void PaymentRequestState::NotifyOnGetAllPaymentInstrumentsFinished() {
473 for (auto& observer : observers_)
474 observer.OnGetAllPaymentInstrumentsFinished();
475}
476
mathpf1a7a3752017-03-15 11:23:37477void PaymentRequestState::NotifyOnSelectedInformationChanged() {
478 for (auto& observer : observers_)
479 observer.OnSelectedInformationChanged();
480}
481
482bool PaymentRequestState::ArePaymentDetailsSatisfied() {
mathp363735b2017-03-16 18:08:05483 // There is no need to check for supported networks, because only supported
484 // instruments are listed/created in the flow.
mathp4baea332017-04-10 21:42:29485 return selected_instrument_ != nullptr &&
486 selected_instrument_->IsCompleteForPayment();
mathpf1a7a3752017-03-15 11:23:37487}
488
489bool PaymentRequestState::ArePaymentOptionsSatisfied() {
sebsg7e619132017-04-27 16:07:10490 if (is_waiting_for_merchant_validation_)
491 return false;
492
tmartino01c3eb82017-04-29 15:18:39493 if (!profile_comparator()->IsShippingComplete(selected_shipping_profile_))
494 return false;
495
Anthony Vallee-Duboisa8814672017-06-01 18:43:20496 if (spec_->request_shipping() && !spec_->selected_shipping_option())
497 return false;
498
tmartino01c3eb82017-04-29 15:18:39499 return profile_comparator()->IsContactInfoComplete(selected_contact_profile_);
mathpf1a7a3752017-03-15 11:23:37500}
501
Mathieu Perreault17c1ae92017-10-20 17:16:00502void PaymentRequestState::OnAddressNormalized(
503 bool success,
504 const autofill::AutofillProfile& normalized_profile) {
505 delegate_->OnShippingAddressSelected(
Tommy Martino21d415f2018-01-12 20:08:22506 data_util::GetPaymentAddressFromAutofillProfile(normalized_profile,
507 app_locale_));
Mathieu Perreault17c1ae92017-10-20 17:16:00508}
509
mathpf1a7a3752017-03-15 11:23:37510} // namespace payments