mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 1 | // 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 | |
mad | 4527193 | 2017-04-13 16:07:38 | [diff] [blame] | 7 | #include <algorithm> |
anthonyvd | 0116ce33 | 2017-03-21 21:29:01 | [diff] [blame] | 8 | #include <set> |
mad | 4527193 | 2017-04-13 16:07:38 | [diff] [blame] | 9 | #include <utility> |
anthonyvd | 0116ce33 | 2017-03-21 21:29:01 | [diff] [blame] | 10 | |
Sebastien Marchand | 53801a3 | 2019-01-25 16:26:11 | [diff] [blame] | 11 | #include "base/bind.h" |
gogerald | 8189d52 | 2017-09-15 17:52:18 | [diff] [blame] | 12 | #include "base/feature_list.h" |
Sahel Sharify | 6efdfb3 | 2019-07-02 16:12:16 | [diff] [blame] | 13 | #include "base/metrics/histogram_functions.h" |
sebsg | ad86bd00 | 2017-03-29 16:39:12 | [diff] [blame] | 14 | #include "base/strings/utf_string_conversions.h" |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 15 | #include "components/autofill/core/browser/autofill_data_util.h" |
Dominic Battre | aed20f9f | 2019-05-10 19:09:52 | [diff] [blame] | 16 | #include "components/autofill/core/browser/data_model/autofill_profile.h" |
| 17 | #include "components/autofill/core/browser/data_model/credit_card.h" |
Dominic Battre | dd73d26 | 2019-05-15 20:10:38 | [diff] [blame] | 18 | #include "components/autofill/core/browser/geo/autofill_country.h" |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 19 | #include "components/autofill/core/browser/personal_data_manager.h" |
Sahel Sharify | 6efdfb3 | 2019-07-02 16:12:16 | [diff] [blame] | 20 | #include "components/autofill/core/browser/validation.h" |
Rouslan Solomakhin | 2039a34 | 2020-05-21 19:21:04 | [diff] [blame] | 21 | #include "components/payments/content/autofill_payment_app.h" |
Rouslan Solomakhin | 6d4c1c27 | 2019-11-22 17:09:27 | [diff] [blame] | 22 | #include "components/payments/content/autofill_payment_app_factory.h" |
Rouslan Solomakhin | 4eea9bc2 | 2017-10-10 15:18:51 | [diff] [blame] | 23 | #include "components/payments/content/content_payment_request_delegate.h" |
Rouslan Solomakhin | 2039a34 | 2020-05-21 19:21:04 | [diff] [blame] | 24 | #include "components/payments/content/payment_app.h" |
Rouslan Solomakhin | 6d4c1c27 | 2019-11-22 17:09:27 | [diff] [blame] | 25 | #include "components/payments/content/payment_app_service.h" |
| 26 | #include "components/payments/content/payment_app_service_factory.h" |
Rouslan Solomakhin | 4eea9bc2 | 2017-10-10 15:18:51 | [diff] [blame] | 27 | #include "components/payments/content/payment_manifest_web_data_service.h" |
sebsg | ad86bd00 | 2017-03-29 16:39:12 | [diff] [blame] | 28 | #include "components/payments/content/payment_response_helper.h" |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 29 | #include "components/payments/content/service_worker_payment_app.h" |
Sahel Sharify | 13331e8 | 2019-07-12 01:00:30 | [diff] [blame] | 30 | #include "components/payments/core/autofill_card_validation.h" |
Rouslan Solomakhin | 1dca2a92 | 2019-09-06 22:25:07 | [diff] [blame] | 31 | #include "components/payments/core/error_strings.h" |
Mathieu Perreault | 157f399 | 2018-06-29 18:48:06 | [diff] [blame] | 32 | #include "components/payments/core/features.h" |
Rouslan Solomakhin | 85b10da | 2019-11-05 20:03:17 | [diff] [blame] | 33 | #include "components/payments/core/method_strings.h" |
tmartino | 01c3eb8 | 2017-04-29 15:18:39 | [diff] [blame] | 34 | #include "components/payments/core/payment_request_data_util.h" |
Danyao Wang | 761739b | 2019-06-27 23:59:32 | [diff] [blame] | 35 | #include "components/payments/core/payments_experimental_features.h" |
Danyao Wang | 4f2ba63 | 2020-03-11 13:56:54 | [diff] [blame] | 36 | #include "content/public/browser/render_frame_host.h" |
Rouslan Solomakhin | a4a9b8c | 2020-10-15 21:16:24 | [diff] [blame^] | 37 | #include "content/public/browser/render_process_host.h" |
gogerald | 8189d52 | 2017-09-15 17:52:18 | [diff] [blame] | 38 | #include "content/public/common/content_features.h" |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 39 | |
| 40 | namespace payments { |
Rouslan Solomakhin | 1dca2a92 | 2019-09-06 22:25:07 | [diff] [blame] | 41 | namespace { |
| 42 | |
Rouslan Solomakhin | 1dca2a92 | 2019-09-06 22:25:07 | [diff] [blame] | 43 | // Invokes the |callback| with |status|. |
| 44 | void CallStatusCallback(PaymentRequestState::StatusCallback callback, |
| 45 | bool status) { |
| 46 | std::move(callback).Run(status); |
| 47 | } |
| 48 | |
| 49 | // Posts the |callback| to be invoked with |status| asynchronously. |
| 50 | void PostStatusCallback(PaymentRequestState::StatusCallback callback, |
| 51 | bool status) { |
| 52 | base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 53 | FROM_HERE, |
| 54 | base::BindOnce(&CallStatusCallback, std::move(callback), status)); |
| 55 | } |
| 56 | |
| 57 | } // namespace |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 58 | |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 59 | PaymentRequestState::PaymentRequestState( |
Danyao Wang | 4f2ba63 | 2020-03-11 13:56:54 | [diff] [blame] | 60 | content::RenderFrameHost* initiator_render_frame_host, |
gogerald | 7a0cc3e | 2017-09-19 03:35:48 | [diff] [blame] | 61 | const GURL& top_level_origin, |
| 62 | const GURL& frame_origin, |
Rouslan Solomakhin | c71cca62 | 2020-01-31 22:15:35 | [diff] [blame] | 63 | const url::Origin& frame_security_origin, |
DongJun Kim | 54690d5 | 2020-09-26 12:07:54 | [diff] [blame] | 64 | base::WeakPtr<PaymentRequestSpec> spec, |
Kyungsun Lee | cdbdade | 2020-08-25 18:06:12 | [diff] [blame] | 65 | base::WeakPtr<Delegate> delegate, |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 66 | const std::string& app_locale, |
anthonyvd | d23ed70 | 2017-04-05 15:29:00 | [diff] [blame] | 67 | autofill::PersonalDataManager* personal_data_manager, |
Rouslan Solomakhin | 4eea9bc2 | 2017-10-10 15:18:51 | [diff] [blame] | 68 | ContentPaymentRequestDelegate* payment_request_delegate, |
sebsg | c6719b3 | 2017-07-05 19:54:47 | [diff] [blame] | 69 | JourneyLogger* journey_logger) |
Rouslan Solomakhin | a4a9b8c | 2020-10-15 21:16:24 | [diff] [blame^] | 70 | : frame_routing_id_(content::GlobalFrameRoutingId( |
| 71 | initiator_render_frame_host->GetProcess()->GetID(), |
| 72 | initiator_render_frame_host->GetRoutingID())), |
Rouslan Solomakhin | 6d4c1c27 | 2019-11-22 17:09:27 | [diff] [blame] | 73 | top_origin_(top_level_origin), |
| 74 | frame_origin_(frame_origin), |
Rouslan Solomakhin | c71cca62 | 2020-01-31 22:15:35 | [diff] [blame] | 75 | frame_security_origin_(frame_security_origin), |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 76 | app_locale_(app_locale), |
DongJun Kim | 54690d5 | 2020-09-26 12:07:54 | [diff] [blame] | 77 | spec_(spec), |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 78 | delegate_(delegate), |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 79 | personal_data_manager_(personal_data_manager), |
sebsg | c6719b3 | 2017-07-05 19:54:47 | [diff] [blame] | 80 | journey_logger_(journey_logger), |
Rouslan Solomakhin | d2cae95a | 2018-08-09 00:16:10 | [diff] [blame] | 81 | are_requested_methods_supported_( |
| 82 | !spec_->supported_card_networks().empty()), |
tmartino | 01c3eb8 | 2017-04-29 15:18:39 | [diff] [blame] | 83 | payment_request_delegate_(payment_request_delegate), |
Jeremy Roman | 5c341f6d | 2019-07-15 15:56:10 | [diff] [blame] | 84 | profile_comparator_(app_locale, *spec) { |
Rouslan Solomakhin | 6d4c1c27 | 2019-11-22 17:09:27 | [diff] [blame] | 85 | PopulateProfileCache(); |
Danyao Wang | 761739b | 2019-06-27 23:59:32 | [diff] [blame] | 86 | |
Danyao Wang | e865a30 | 2020-04-01 18:35:14 | [diff] [blame] | 87 | PaymentAppService* service = PaymentAppServiceFactory::GetForContext( |
Rouslan Solomakhin | a4a9b8c | 2020-10-15 21:16:24 | [diff] [blame^] | 88 | initiator_render_frame_host->GetBrowserContext()); |
Danyao Wang | e865a30 | 2020-04-01 18:35:14 | [diff] [blame] | 89 | number_of_payment_app_factories_ = service->GetNumberOfFactories(); |
| 90 | service->Create(weak_ptr_factory_.GetWeakPtr()); |
Rouslan Solomakhin | 6d4c1c27 | 2019-11-22 17:09:27 | [diff] [blame] | 91 | |
sebsg | 7e61913 | 2017-04-27 16:07:10 | [diff] [blame] | 92 | spec_->AddObserver(this); |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 93 | } |
Rouslan Solomakhin | 4eea9bc2 | 2017-10-10 15:18:51 | [diff] [blame] | 94 | |
mathp | 151bd31 | 2017-04-03 21:07:24 | [diff] [blame] | 95 | PaymentRequestState::~PaymentRequestState() {} |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 96 | |
Rouslan Solomakhin | 6d4c1c27 | 2019-11-22 17:09:27 | [diff] [blame] | 97 | content::WebContents* PaymentRequestState::GetWebContents() { |
Rouslan Solomakhin | a4a9b8c | 2020-10-15 21:16:24 | [diff] [blame^] | 98 | auto* rfh = content::RenderFrameHost::FromID(frame_routing_id_); |
| 99 | return rfh && rfh->IsCurrent() |
| 100 | ? content::WebContents::FromRenderFrameHost(rfh) |
| 101 | : nullptr; |
gogerald | ac15d236 | 2017-11-15 01:04:19 | [diff] [blame] | 102 | } |
| 103 | |
Danyao Wang | aed5b0a9 | 2020-04-01 22:43:14 | [diff] [blame] | 104 | ContentPaymentRequestDelegate* PaymentRequestState::GetPaymentRequestDelegate() |
| 105 | const { |
Rouslan Solomakhin | 6d4c1c27 | 2019-11-22 17:09:27 | [diff] [blame] | 106 | return payment_request_delegate_; |
| 107 | } |
Rouslan Solomakhin | 1dca2a92 | 2019-09-06 22:25:07 | [diff] [blame] | 108 | |
Rouslan Solomakhin | 535fe30 | 2020-06-02 20:17:39 | [diff] [blame] | 109 | void PaymentRequestState::ShowProcessingSpinner() { |
| 110 | GetPaymentRequestDelegate()->ShowProcessingSpinner(); |
| 111 | } |
| 112 | |
DongJun Kim | 54690d5 | 2020-09-26 12:07:54 | [diff] [blame] | 113 | base::WeakPtr<PaymentRequestSpec> PaymentRequestState::GetSpec() const { |
| 114 | return spec_; |
Rouslan Solomakhin | 6d4c1c27 | 2019-11-22 17:09:27 | [diff] [blame] | 115 | } |
gogerald | ac15d236 | 2017-11-15 01:04:19 | [diff] [blame] | 116 | |
Rouslan Solomakhin | cbdeef9 | 2020-08-15 12:39:30 | [diff] [blame] | 117 | std::string PaymentRequestState::GetTwaPackageName() const { |
| 118 | return GetPaymentRequestDelegate()->GetTwaPackageName(); |
| 119 | } |
| 120 | |
Rouslan Solomakhin | 6d4c1c27 | 2019-11-22 17:09:27 | [diff] [blame] | 121 | const GURL& PaymentRequestState::GetTopOrigin() { |
| 122 | return top_origin_; |
| 123 | } |
| 124 | |
| 125 | const GURL& PaymentRequestState::GetFrameOrigin() { |
| 126 | return frame_origin_; |
| 127 | } |
| 128 | |
Rouslan Solomakhin | c71cca62 | 2020-01-31 22:15:35 | [diff] [blame] | 129 | const url::Origin& PaymentRequestState::GetFrameSecurityOrigin() { |
| 130 | return frame_security_origin_; |
| 131 | } |
| 132 | |
Danyao Wang | 4f2ba63 | 2020-03-11 13:56:54 | [diff] [blame] | 133 | content::RenderFrameHost* PaymentRequestState::GetInitiatorRenderFrameHost() |
| 134 | const { |
Rouslan Solomakhin | a4a9b8c | 2020-10-15 21:16:24 | [diff] [blame^] | 135 | return content::RenderFrameHost::FromID(frame_routing_id_); |
Danyao Wang | 4f2ba63 | 2020-03-11 13:56:54 | [diff] [blame] | 136 | } |
| 137 | |
Danyao Wang | aed5b0a9 | 2020-04-01 22:43:14 | [diff] [blame] | 138 | const std::vector<mojom::PaymentMethodDataPtr>& |
| 139 | PaymentRequestState::GetMethodData() const { |
Rouslan Solomakhin | 75450a4 | 2020-09-24 18:44:22 | [diff] [blame] | 140 | DCHECK(GetSpec()); |
Danyao Wang | aed5b0a9 | 2020-04-01 22:43:14 | [diff] [blame] | 141 | return GetSpec()->method_data(); |
| 142 | } |
| 143 | |
Rouslan Solomakhin | 914686c5 | 2020-08-21 15:15:41 | [diff] [blame] | 144 | std::unique_ptr<autofill::InternalAuthenticator> |
| 145 | PaymentRequestState::CreateInternalAuthenticator() const { |
Rouslan Solomakhin | 54e0d1e | 2020-08-30 20:23:31 | [diff] [blame] | 146 | return GetPaymentRequestDelegate()->CreateInternalAuthenticator(); |
Rouslan Solomakhin | 914686c5 | 2020-08-21 15:15:41 | [diff] [blame] | 147 | } |
| 148 | |
Danyao Wang | aed5b0a9 | 2020-04-01 22:43:14 | [diff] [blame] | 149 | scoped_refptr<PaymentManifestWebDataService> |
| 150 | PaymentRequestState::GetPaymentManifestWebDataService() const { |
| 151 | return GetPaymentRequestDelegate()->GetPaymentManifestWebDataService(); |
| 152 | } |
| 153 | |
Rouslan Solomakhin | 6d4c1c27 | 2019-11-22 17:09:27 | [diff] [blame] | 154 | const std::vector<autofill::AutofillProfile*>& |
| 155 | PaymentRequestState::GetBillingProfiles() { |
| 156 | return shipping_profiles_; |
| 157 | } |
| 158 | |
| 159 | bool PaymentRequestState::IsRequestedAutofillDataAvailable() { |
| 160 | return is_requested_autofill_data_available_; |
| 161 | } |
| 162 | |
| 163 | bool PaymentRequestState::MayCrawlForInstallablePaymentApps() { |
| 164 | return PaymentsExperimentalFeatures::IsEnabled( |
| 165 | features::kAlwaysAllowJustInTimePaymentApp) || |
Rouslan Solomakhin | 75450a4 | 2020-09-24 18:44:22 | [diff] [blame] | 166 | !spec_ || !spec_->supports_basic_card(); |
Rouslan Solomakhin | 6d4c1c27 | 2019-11-22 17:09:27 | [diff] [blame] | 167 | } |
| 168 | |
Rouslan Solomakhin | 535fe30 | 2020-06-02 20:17:39 | [diff] [blame] | 169 | bool PaymentRequestState::IsOffTheRecord() const { |
| 170 | return GetPaymentRequestDelegate()->IsOffTheRecord(); |
| 171 | } |
| 172 | |
Rouslan Solomakhin | 6d4c1c27 | 2019-11-22 17:09:27 | [diff] [blame] | 173 | void PaymentRequestState::OnPaymentAppCreated(std::unique_ptr<PaymentApp> app) { |
| 174 | if (app->type() == PaymentApp::Type::AUTOFILL) { |
| 175 | journey_logger_->SetEventOccurred( |
| 176 | JourneyLogger::EVENT_AVAILABLE_METHOD_BASIC_CARD); |
| 177 | } else if (base::Contains(app->GetAppMethodNames(), methods::kGooglePay) || |
| 178 | base::Contains(app->GetAppMethodNames(), methods::kAndroidPay)) { |
Danyao Wang | 25f72dc | 2019-10-18 05:11:32 | [diff] [blame] | 179 | journey_logger_->SetEventOccurred( |
| 180 | JourneyLogger::EVENT_AVAILABLE_METHOD_GOOGLE); |
| 181 | } else { |
| 182 | journey_logger_->SetEventOccurred( |
| 183 | JourneyLogger::EVENT_AVAILABLE_METHOD_OTHER); |
| 184 | } |
Rouslan Solomakhin | 6d4c1c27 | 2019-11-22 17:09:27 | [diff] [blame] | 185 | available_apps_.emplace_back(std::move(app)); |
gogerald | ac15d236 | 2017-11-15 01:04:19 | [diff] [blame] | 186 | } |
| 187 | |
Rouslan Solomakhin | 6d4c1c27 | 2019-11-22 17:09:27 | [diff] [blame] | 188 | void PaymentRequestState::OnPaymentAppCreationError( |
| 189 | const std::string& error_message) { |
| 190 | get_all_payment_apps_error_ = error_message; |
| 191 | } |
| 192 | |
Danyao Wang | aed5b0a9 | 2020-04-01 22:43:14 | [diff] [blame] | 193 | bool PaymentRequestState::SkipCreatingNativePaymentApps() const { |
| 194 | return false; |
| 195 | } |
| 196 | |
Rouslan Solomakhin | 6d4c1c27 | 2019-11-22 17:09:27 | [diff] [blame] | 197 | void PaymentRequestState::OnDoneCreatingPaymentApps() { |
| 198 | DCHECK_NE(0U, number_of_payment_app_factories_); |
| 199 | if (--number_of_payment_app_factories_ > 0U) |
| 200 | return; |
| 201 | |
Nick Burris | fca09083 | 2020-07-28 00:17:42 | [diff] [blame] | 202 | if (IsInTwa()) { |
| 203 | // If a preferred payment app is present (e.g. Play Billing within a TWA), |
| 204 | // all other payment apps are ignored. |
| 205 | bool has_preferred_app = |
| 206 | std::any_of(available_apps_.begin(), available_apps_.end(), |
| 207 | [](const auto& app) { return app->IsPreferred(); }); |
| 208 | if (has_preferred_app) { |
| 209 | available_apps_.erase( |
| 210 | std::remove_if(available_apps_.begin(), available_apps_.end(), |
| 211 | [](const auto& app) { return !app->IsPreferred(); }), |
| 212 | available_apps_.end()); |
| 213 | |
| 214 | // By design, only one payment app can be preferred. |
| 215 | DCHECK_EQ(available_apps_.size(), 1u); |
| 216 | if (available_apps_.size() > 1) |
| 217 | available_apps_.resize(1); |
| 218 | } |
| 219 | } |
| 220 | |
gogerald | 8189d52 | 2017-09-15 17:52:18 | [diff] [blame] | 221 | SetDefaultProfileSelections(); |
| 222 | |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 223 | get_all_apps_finished_ = true; |
Danyao Wang | 5a14e98 | 2020-02-12 21:34:09 | [diff] [blame] | 224 | has_enrolled_instrument_ = |
| 225 | std::any_of(available_apps_.begin(), available_apps_.end(), |
| 226 | [](const auto& app) { return app->HasEnrolledInstrument(); }); |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 227 | are_requested_methods_supported_ |= !available_apps_.empty(); |
| 228 | NotifyOnGetAllPaymentAppsFinished(); |
Rouslan Solomakhin | 9788d4b | 2019-04-09 13:10:23 | [diff] [blame] | 229 | NotifyInitialized(); |
gogerald | 8189d52 | 2017-09-15 17:52:18 | [diff] [blame] | 230 | |
Danyao Wang | 4bc0606a | 2018-12-27 16:54:53 | [diff] [blame] | 231 | // Fulfill the pending CanMakePayment call. |
Rouslan Solomakhin | 1dca2a92 | 2019-09-06 22:25:07 | [diff] [blame] | 232 | if (can_make_payment_callback_) |
Rouslan Solomakhin | ebf9f16 | 2020-08-27 15:28:13 | [diff] [blame] | 233 | std::move(can_make_payment_callback_).Run(GetCanMakePaymentValue()); |
Danyao Wang | 4bc0606a | 2018-12-27 16:54:53 | [diff] [blame] | 234 | |
Danyao Wang | ce175bf | 2018-12-21 22:35:58 | [diff] [blame] | 235 | // Fulfill the pending HasEnrolledInstrument call. |
| 236 | if (has_enrolled_instrument_callback_) |
Rouslan Solomakhin | ebf9f16 | 2020-08-27 15:28:13 | [diff] [blame] | 237 | std::move(has_enrolled_instrument_callback_) |
| 238 | .Run(GetHasEnrolledInstrumentValue()); |
gogerald | 0a7ee6c | 2017-11-13 18:23:19 | [diff] [blame] | 239 | |
Danyao Wang | ce175bf | 2018-12-21 22:35:58 | [diff] [blame] | 240 | // Fulfill the pending AreRequestedMethodsSupported call. |
gogerald | 0a7ee6c | 2017-11-13 18:23:19 | [diff] [blame] | 241 | if (are_requested_methods_supported_callback_) |
| 242 | CheckRequestedMethodsSupported( |
| 243 | std::move(are_requested_methods_supported_callback_)); |
gogerald | 8189d52 | 2017-09-15 17:52:18 | [diff] [blame] | 244 | } |
| 245 | |
Rouslan Solomakhin | ebf9f16 | 2020-08-27 15:28:13 | [diff] [blame] | 246 | void PaymentRequestState::SetCanMakePaymentEvenWithoutApps() { |
| 247 | can_make_payment_even_without_apps_ = true; |
| 248 | } |
| 249 | |
sebsg | 695799a | 2017-04-11 16:29:06 | [diff] [blame] | 250 | void PaymentRequestState::OnPaymentResponseReady( |
| 251 | mojom::PaymentResponsePtr payment_response) { |
Kyungsun Lee | cdbdade | 2020-08-25 18:06:12 | [diff] [blame] | 252 | if (!delegate_) |
| 253 | return; |
| 254 | |
sebsg | 695799a | 2017-04-11 16:29:06 | [diff] [blame] | 255 | delegate_->OnPaymentResponseAvailable(std::move(payment_response)); |
| 256 | } |
| 257 | |
Rouslan Solomakhin | 68429b7 | 2019-06-27 15:12:39 | [diff] [blame] | 258 | void PaymentRequestState::OnPaymentResponseError( |
| 259 | const std::string& error_message) { |
Kyungsun Lee | cdbdade | 2020-08-25 18:06:12 | [diff] [blame] | 260 | if (!delegate_) |
| 261 | return; |
| 262 | |
Rouslan Solomakhin | 68429b7 | 2019-06-27 15:12:39 | [diff] [blame] | 263 | delegate_->OnPaymentResponseError(error_message); |
| 264 | } |
| 265 | |
sebsg | 7e61913 | 2017-04-27 16:07:10 | [diff] [blame] | 266 | void PaymentRequestState::OnSpecUpdated() { |
Rouslan Solomakhin | 75450a4 | 2020-09-24 18:44:22 | [diff] [blame] | 267 | if (!spec_) |
| 268 | return; |
| 269 | |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 270 | autofill::AutofillProfile* selected_shipping_profile = |
| 271 | selected_shipping_profile_; |
| 272 | autofill::AutofillProfile* selected_contact_profile = |
| 273 | selected_contact_profile_; |
| 274 | |
| 275 | if (spec_->current_update_reason() == |
| 276 | PaymentRequestSpec::UpdateReason::RETRY) { |
| 277 | if (spec_->has_shipping_address_error() && selected_shipping_profile) { |
| 278 | invalid_shipping_profile_ = selected_shipping_profile; |
| 279 | selected_shipping_profile_ = nullptr; |
| 280 | } |
Jinho Bang | 092e716 | 2018-09-06 23:41:19 | [diff] [blame] | 281 | |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 282 | if (spec_->has_payer_error() && selected_contact_profile) { |
| 283 | invalid_contact_profile_ = selected_contact_profile; |
| 284 | selected_contact_profile_ = nullptr; |
| 285 | } |
| 286 | } |
| 287 | |
Mathieu Perreault | 04b4c66 | 2017-06-02 13:35:13 | [diff] [blame] | 288 | if (spec_->selected_shipping_option_error().empty()) { |
| 289 | selected_shipping_option_error_profile_ = nullptr; |
| 290 | } else { |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 291 | selected_shipping_option_error_profile_ = selected_shipping_profile; |
Mathieu Perreault | 04b4c66 | 2017-06-02 13:35:13 | [diff] [blame] | 292 | selected_shipping_profile_ = nullptr; |
Jinho Bang | 092e716 | 2018-09-06 23:41:19 | [diff] [blame] | 293 | if (spec_->has_shipping_address_error() && selected_shipping_profile) { |
| 294 | invalid_shipping_profile_ = selected_shipping_profile; |
| 295 | } |
Mathieu Perreault | 04b4c66 | 2017-06-02 13:35:13 | [diff] [blame] | 296 | } |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 297 | |
sebsg | 7e61913 | 2017-04-27 16:07:10 | [diff] [blame] | 298 | is_waiting_for_merchant_validation_ = false; |
| 299 | UpdateIsReadyToPayAndNotifyObservers(); |
| 300 | } |
| 301 | |
Danyao Wang | 03a4cbd | 2019-08-15 23:47:11 | [diff] [blame] | 302 | void PaymentRequestState::CanMakePayment(StatusCallback callback) { |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 303 | if (!get_all_apps_finished_) { |
Danyao Wang | 4bc0606a | 2018-12-27 16:54:53 | [diff] [blame] | 304 | DCHECK(!can_make_payment_callback_); |
| 305 | can_make_payment_callback_ = std::move(callback); |
| 306 | return; |
| 307 | } |
| 308 | |
Rouslan Solomakhin | 159e513 | 2020-08-29 21:05:02 | [diff] [blame] | 309 | PostStatusCallback(std::move(callback), GetCanMakePaymentValue()); |
Danyao Wang | ce175bf | 2018-12-21 22:35:58 | [diff] [blame] | 310 | } |
| 311 | |
| 312 | void PaymentRequestState::HasEnrolledInstrument(StatusCallback callback) { |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 313 | if (!get_all_apps_finished_) { |
Danyao Wang | 4bc0606a | 2018-12-27 16:54:53 | [diff] [blame] | 314 | DCHECK(!has_enrolled_instrument_callback_); |
Danyao Wang | ce175bf | 2018-12-21 22:35:58 | [diff] [blame] | 315 | has_enrolled_instrument_callback_ = std::move(callback); |
gogerald | 8189d52 | 2017-09-15 17:52:18 | [diff] [blame] | 316 | return; |
| 317 | } |
| 318 | |
Rouslan Solomakhin | ebf9f16 | 2020-08-27 15:28:13 | [diff] [blame] | 319 | PostStatusCallback(std::move(callback), GetHasEnrolledInstrumentValue()); |
mathp | 1a5be4f | 2017-03-24 18:09:19 | [diff] [blame] | 320 | } |
| 321 | |
gogerald | 0a7ee6c | 2017-11-13 18:23:19 | [diff] [blame] | 322 | void PaymentRequestState::AreRequestedMethodsSupported( |
Rouslan Solomakhin | d5dcc32 | 2019-07-11 21:47:20 | [diff] [blame] | 323 | MethodsSupportedCallback callback) { |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 324 | if (!get_all_apps_finished_) { |
gogerald | 0a7ee6c | 2017-11-13 18:23:19 | [diff] [blame] | 325 | are_requested_methods_supported_callback_ = std::move(callback); |
| 326 | return; |
| 327 | } |
| 328 | |
| 329 | base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 330 | FROM_HERE, |
| 331 | base::BindOnce(&PaymentRequestState::CheckRequestedMethodsSupported, |
| 332 | weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| 333 | } |
| 334 | |
Sahel Sharify | d341822 | 2020-02-19 21:50:02 | [diff] [blame] | 335 | void PaymentRequestState::OnAbort() { |
| 336 | // Reset supported method callback when the merchant calls abort before |
| 337 | // OnDoneCreatingPaymentApps(). |
| 338 | if (are_requested_methods_supported_callback_) |
| 339 | are_requested_methods_supported_callback_.Reset(); |
| 340 | } |
| 341 | |
gogerald | 0a7ee6c | 2017-11-13 18:23:19 | [diff] [blame] | 342 | void PaymentRequestState::CheckRequestedMethodsSupported( |
Rouslan Solomakhin | d5dcc32 | 2019-07-11 21:47:20 | [diff] [blame] | 343 | MethodsSupportedCallback callback) { |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 344 | DCHECK(get_all_apps_finished_); |
gogerald | 0a7ee6c | 2017-11-13 18:23:19 | [diff] [blame] | 345 | |
Rouslan Solomakhin | 75450a4 | 2020-09-24 18:44:22 | [diff] [blame] | 346 | if (!spec_) |
| 347 | return; |
| 348 | |
Rouslan Solomakhin | 1dca2a92 | 2019-09-06 22:25:07 | [diff] [blame] | 349 | // Don't modify the value of |are_requested_methods_supported_|, because it's |
| 350 | // used for canMakePayment(). |
| 351 | bool supported = are_requested_methods_supported_; |
| 352 | if (supported && is_show_user_gesture_ && |
Rouslan Solomakhin | 85b10da | 2019-11-05 20:03:17 | [diff] [blame] | 353 | base::Contains(spec_->payment_method_identifiers_set(), |
| 354 | methods::kBasicCard) && |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 355 | !has_non_autofill_app_ && !has_enrolled_instrument_ && |
Rouslan Solomakhin | 1dca2a92 | 2019-09-06 22:25:07 | [diff] [blame] | 356 | PaymentsExperimentalFeatures::IsEnabled( |
| 357 | features::kStrictHasEnrolledAutofillInstrument)) { |
| 358 | supported = false; |
| 359 | get_all_payment_apps_error_ = errors::kStrictBasicCardShowReject; |
| 360 | } |
| 361 | |
Liquan (Max) Gu | a3db8c07 | 2020-06-22 16:24:21 | [diff] [blame] | 362 | if (!supported && get_all_payment_apps_error_.empty() && |
| 363 | base::Contains(spec_->payment_method_identifiers_set(), |
Rouslan Solomakhin | a1ff8150 | 2020-06-26 00:56:00 | [diff] [blame] | 364 | methods::kGooglePlayBilling) && |
Nick Burris | fca09083 | 2020-07-28 00:17:42 | [diff] [blame] | 365 | !IsInTwa()) { |
Liquan (Max) Gu | a3db8c07 | 2020-06-22 16:24:21 | [diff] [blame] | 366 | get_all_payment_apps_error_ = errors::kAppStoreMethodOnlySupportedInTwa; |
| 367 | } |
| 368 | |
Rouslan Solomakhin | 1dca2a92 | 2019-09-06 22:25:07 | [diff] [blame] | 369 | std::move(callback).Run(supported, get_all_payment_apps_error_); |
rouslan | 6e3cf7c6 | 2017-04-17 21:23:28 | [diff] [blame] | 370 | } |
| 371 | |
anthonyvd | 6a43b93 | 2017-05-11 18:39:27 | [diff] [blame] | 372 | std::string PaymentRequestState::GetAuthenticatedEmail() const { |
| 373 | return payment_request_delegate_->GetAuthenticatedEmail(); |
| 374 | } |
| 375 | |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 376 | void PaymentRequestState::AddObserver(Observer* observer) { |
| 377 | CHECK(observer); |
| 378 | observers_.AddObserver(observer); |
| 379 | } |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 380 | |
| 381 | void PaymentRequestState::RemoveObserver(Observer* observer) { |
| 382 | observers_.RemoveObserver(observer); |
| 383 | } |
| 384 | |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 385 | void PaymentRequestState::GeneratePaymentResponse() { |
mathp | 363735b | 2017-03-16 18:08:05 | [diff] [blame] | 386 | DCHECK(is_ready_to_pay()); |
sebsg | 695799a | 2017-04-11 16:29:06 | [diff] [blame] | 387 | |
Rouslan Solomakhin | 75450a4 | 2020-09-24 18:44:22 | [diff] [blame] | 388 | if (!spec_) |
| 389 | return; |
| 390 | |
sebsg | 695799a | 2017-04-11 16:29:06 | [diff] [blame] | 391 | // Once the response is ready, will call back into OnPaymentResponseReady. |
Rouslan Solomakhin | 4eea9bc2 | 2017-10-10 15:18:51 | [diff] [blame] | 392 | response_helper_ = std::make_unique<PaymentResponseHelper>( |
DongJun Kim | 54690d5 | 2020-09-26 12:07:54 | [diff] [blame] | 393 | app_locale_, spec_, selected_app_, payment_request_delegate_, |
| 394 | selected_shipping_profile_, selected_contact_profile_, |
| 395 | weak_ptr_factory_.GetWeakPtr()); |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 396 | } |
| 397 | |
Rouslan Solomakhin | 761d65eb | 2019-04-29 20:08:01 | [diff] [blame] | 398 | void PaymentRequestState::OnPaymentAppWindowClosed() { |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 399 | DCHECK(selected_app_); |
Rouslan Solomakhin | 761d65eb | 2019-04-29 20:08:01 | [diff] [blame] | 400 | response_helper_.reset(); |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 401 | selected_app_->OnPaymentAppWindowClosed(); |
Rouslan Solomakhin | 761d65eb | 2019-04-29 20:08:01 | [diff] [blame] | 402 | } |
| 403 | |
sebsg | 8a93b27 | 2017-05-11 19:30:22 | [diff] [blame] | 404 | void PaymentRequestState::RecordUseStats() { |
Sahel Sharify | fef3d92 | 2019-09-11 01:41:22 | [diff] [blame] | 405 | if (ShouldShowShippingSection()) { |
sebsg | 8a93b27 | 2017-05-11 19:30:22 | [diff] [blame] | 406 | DCHECK(selected_shipping_profile_); |
| 407 | personal_data_manager_->RecordUseOf(*selected_shipping_profile_); |
| 408 | } |
| 409 | |
Sahel Sharify | fef3d92 | 2019-09-11 01:41:22 | [diff] [blame] | 410 | if (ShouldShowContactSection()) { |
sebsg | 8a93b27 | 2017-05-11 19:30:22 | [diff] [blame] | 411 | DCHECK(selected_contact_profile_); |
| 412 | |
| 413 | // If the same address was used for both contact and shipping, the stats |
| 414 | // should only be updated once. |
Sahel Sharify | fef3d92 | 2019-09-11 01:41:22 | [diff] [blame] | 415 | if (!ShouldShowShippingSection() || (selected_shipping_profile_->guid() != |
| 416 | selected_contact_profile_->guid())) { |
sebsg | 8a93b27 | 2017-05-11 19:30:22 | [diff] [blame] | 417 | personal_data_manager_->RecordUseOf(*selected_contact_profile_); |
| 418 | } |
| 419 | } |
| 420 | |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 421 | selected_app_->RecordUse(); |
sebsg | 8a93b27 | 2017-05-11 19:30:22 | [diff] [blame] | 422 | } |
| 423 | |
Sahel Sharify | cf4e213 | 2020-01-24 23:59:08 | [diff] [blame] | 424 | void PaymentRequestState::SetAvailablePaymentAppForRetry() { |
| 425 | DCHECK(selected_app_); |
| 426 | base::EraseIf(available_apps_, [this](const auto& payment_app) { |
| 427 | // Remove the app if it is not selected. |
| 428 | return payment_app.get() != selected_app_; |
| 429 | }); |
| 430 | is_retry_called_ = true; |
| 431 | } |
| 432 | |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 433 | void PaymentRequestState::AddAutofillPaymentApp( |
mathp | 24ce4cd | 2017-04-12 20:56:42 | [diff] [blame] | 434 | bool selected, |
| 435 | const autofill::CreditCard& card) { |
Rouslan Solomakhin | 6d4c1c27 | 2019-11-22 17:09:27 | [diff] [blame] | 436 | auto app = |
| 437 | AutofillPaymentAppFactory::ConvertCardToPaymentAppIfSupportedNetwork( |
| 438 | card, weak_ptr_factory_.GetWeakPtr()); |
| 439 | if (!app) |
mathp | 24ce4cd | 2017-04-12 20:56:42 | [diff] [blame] | 440 | return; |
Rouslan Solomakhin | 25d708b | 2017-06-23 17:12:03 | [diff] [blame] | 441 | |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 442 | available_apps_.push_back(std::move(app)); |
Danyao Wang | 25f72dc | 2019-10-18 05:11:32 | [diff] [blame] | 443 | journey_logger_->SetEventOccurred( |
| 444 | JourneyLogger::EVENT_AVAILABLE_METHOD_BASIC_CARD); |
mathp | 24ce4cd | 2017-04-12 20:56:42 | [diff] [blame] | 445 | |
Sahel Sharify | bc4173f | 2019-05-09 21:03:57 | [diff] [blame] | 446 | if (selected) { |
Danyao Wang | 46e7d94 | 2020-09-25 15:45:18 | [diff] [blame] | 447 | SetSelectedApp(available_apps_.back().get()); |
Sahel Sharify | bc4173f | 2019-05-09 21:03:57 | [diff] [blame] | 448 | } |
mathp | 24ce4cd | 2017-04-12 20:56:42 | [diff] [blame] | 449 | } |
| 450 | |
mad | f9904ea | 2017-04-25 18:39:12 | [diff] [blame] | 451 | void PaymentRequestState::AddAutofillShippingProfile( |
| 452 | bool selected, |
| 453 | const autofill::AutofillProfile& profile) { |
| 454 | profile_cache_.push_back( |
Rouslan Solomakhin | 4eea9bc2 | 2017-10-10 15:18:51 | [diff] [blame] | 455 | std::make_unique<autofill::AutofillProfile>(profile)); |
mad | f9904ea | 2017-04-25 18:39:12 | [diff] [blame] | 456 | // TODO(tmartino): Implement deduplication rules specific to shipping |
| 457 | // profiles. |
| 458 | autofill::AutofillProfile* new_cached_profile = profile_cache_.back().get(); |
| 459 | shipping_profiles_.push_back(new_cached_profile); |
| 460 | |
Sahel Sharify | bc4173f | 2019-05-09 21:03:57 | [diff] [blame] | 461 | if (selected) { |
Danyao Wang | 46e7d94 | 2020-09-25 15:45:18 | [diff] [blame] | 462 | SetSelectedShippingProfile(new_cached_profile); |
Sahel Sharify | bc4173f | 2019-05-09 21:03:57 | [diff] [blame] | 463 | } |
mad | f9904ea | 2017-04-25 18:39:12 | [diff] [blame] | 464 | } |
| 465 | |
Anthony Vallee-Dubois | f1e88b4 | 2017-05-15 15:09:23 | [diff] [blame] | 466 | void PaymentRequestState::AddAutofillContactProfile( |
| 467 | bool selected, |
| 468 | const autofill::AutofillProfile& profile) { |
| 469 | profile_cache_.push_back( |
Rouslan Solomakhin | 4eea9bc2 | 2017-10-10 15:18:51 | [diff] [blame] | 470 | std::make_unique<autofill::AutofillProfile>(profile)); |
Anthony Vallee-Dubois | f1e88b4 | 2017-05-15 15:09:23 | [diff] [blame] | 471 | autofill::AutofillProfile* new_cached_profile = profile_cache_.back().get(); |
| 472 | contact_profiles_.push_back(new_cached_profile); |
| 473 | |
Sahel Sharify | bc4173f | 2019-05-09 21:03:57 | [diff] [blame] | 474 | if (selected) { |
Danyao Wang | 46e7d94 | 2020-09-25 15:45:18 | [diff] [blame] | 475 | SetSelectedContactProfile(new_cached_profile); |
Sahel Sharify | bc4173f | 2019-05-09 21:03:57 | [diff] [blame] | 476 | } |
Anthony Vallee-Dubois | f1e88b4 | 2017-05-15 15:09:23 | [diff] [blame] | 477 | } |
| 478 | |
anthonyvd | 0116ce33 | 2017-03-21 21:29:01 | [diff] [blame] | 479 | void PaymentRequestState::SetSelectedShippingOption( |
mathp | 151bd31 | 2017-04-03 21:07:24 | [diff] [blame] | 480 | const std::string& shipping_option_id) { |
Rouslan Solomakhin | 75450a4 | 2020-09-24 18:44:22 | [diff] [blame] | 481 | if (!spec_) |
| 482 | return; |
| 483 | |
anthonyvd | 2f30baa1 | 2017-04-13 22:30:50 | [diff] [blame] | 484 | spec_->StartWaitingForUpdateWith( |
| 485 | PaymentRequestSpec::UpdateReason::SHIPPING_OPTION); |
Kyungsun Lee | cdbdade | 2020-08-25 18:06:12 | [diff] [blame] | 486 | if (delegate_) { |
| 487 | // This will inform the merchant and will lead to them calling updateWith |
| 488 | // with new PaymentDetails. |
| 489 | delegate_->OnShippingOptionIdSelected(shipping_option_id); |
| 490 | } |
anthonyvd | 0116ce33 | 2017-03-21 21:29:01 | [diff] [blame] | 491 | } |
| 492 | |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 493 | void PaymentRequestState::SetSelectedShippingProfile( |
Danyao Wang | 46e7d94 | 2020-09-25 15:45:18 | [diff] [blame] | 494 | autofill::AutofillProfile* profile) { |
Rouslan Solomakhin | 75450a4 | 2020-09-24 18:44:22 | [diff] [blame] | 495 | if (!spec_) |
| 496 | return; |
| 497 | |
anthonyvd | 2f30baa1 | 2017-04-13 22:30:50 | [diff] [blame] | 498 | spec_->StartWaitingForUpdateWith( |
| 499 | PaymentRequestSpec::UpdateReason::SHIPPING_ADDRESS); |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 500 | selected_shipping_profile_ = profile; |
sebsg | 7e61913 | 2017-04-27 16:07:10 | [diff] [blame] | 501 | |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 502 | // Changing the shipping address clears shipping address validation errors |
| 503 | // from retry(). |
| 504 | invalid_shipping_profile_ = nullptr; |
| 505 | |
sebsg | 7e61913 | 2017-04-27 16:07:10 | [diff] [blame] | 506 | // The user should not be able to click on pay until the callback from the |
| 507 | // merchant. |
| 508 | is_waiting_for_merchant_validation_ = true; |
sebsg | 7e61913 | 2017-04-27 16:07:10 | [diff] [blame] | 509 | |
| 510 | // Start the normalization of the shipping address. |
Mathieu Perreault | c94700f | 2017-10-23 20:28:39 | [diff] [blame] | 511 | payment_request_delegate_->GetAddressNormalizer()->NormalizeAddressAsync( |
Mathieu Perreault | 9b40d510 | 2017-11-21 20:51:29 | [diff] [blame] | 512 | *selected_shipping_profile_, /*timeout_seconds=*/2, |
Mathieu Perreault | 17c1ae9 | 2017-10-20 17:16:00 | [diff] [blame] | 513 | base::BindOnce(&PaymentRequestState::OnAddressNormalized, |
| 514 | weak_ptr_factory_.GetWeakPtr())); |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 515 | } |
| 516 | |
| 517 | void PaymentRequestState::SetSelectedContactProfile( |
Danyao Wang | 46e7d94 | 2020-09-25 15:45:18 | [diff] [blame] | 518 | autofill::AutofillProfile* profile) { |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 519 | selected_contact_profile_ = profile; |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 520 | |
| 521 | // Changing the contact information clears contact information validation |
| 522 | // errors from retry(). |
| 523 | invalid_contact_profile_ = nullptr; |
| 524 | |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 525 | UpdateIsReadyToPayAndNotifyObservers(); |
Jinho Bang | bb17815 | 2018-09-13 09:44:43 | [diff] [blame] | 526 | |
Kyungsun Lee | cdbdade | 2020-08-25 18:06:12 | [diff] [blame] | 527 | if (IsPaymentAppInvoked() && delegate_) { |
Jinho Bang | 21d6be9 | 2018-12-18 15:30:31 | [diff] [blame] | 528 | delegate_->OnPayerInfoSelected( |
| 529 | response_helper_->GeneratePayerDetail(profile)); |
Jinho Bang | bb17815 | 2018-09-13 09:44:43 | [diff] [blame] | 530 | } |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 531 | } |
| 532 | |
Danyao Wang | 46e7d94 | 2020-09-25 15:45:18 | [diff] [blame] | 533 | void PaymentRequestState::SetSelectedApp(PaymentApp* app) { |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 534 | selected_app_ = app; |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 535 | UpdateIsReadyToPayAndNotifyObservers(); |
| 536 | } |
| 537 | |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 538 | const std::string& PaymentRequestState::GetApplicationLocale() { |
| 539 | return app_locale_; |
| 540 | } |
| 541 | |
| 542 | autofill::PersonalDataManager* PaymentRequestState::GetPersonalDataManager() { |
| 543 | return personal_data_manager_; |
| 544 | } |
| 545 | |
mad | 763ed2b | 2017-04-24 20:28:47 | [diff] [blame] | 546 | autofill::RegionDataLoader* PaymentRequestState::GetRegionDataLoader() { |
| 547 | return payment_request_delegate_->GetRegionDataLoader(); |
mad | 4527193 | 2017-04-13 16:07:38 | [diff] [blame] | 548 | } |
| 549 | |
Anthony Vallee-Dubois | 6813c144 | 2017-05-17 19:32:56 | [diff] [blame] | 550 | bool PaymentRequestState::IsPaymentAppInvoked() const { |
| 551 | return !!response_helper_; |
| 552 | } |
| 553 | |
Mathieu Perreault | eea046d1 | 2017-09-28 15:51:21 | [diff] [blame] | 554 | autofill::AddressNormalizer* PaymentRequestState::GetAddressNormalizer() { |
Anthony Vallee-Dubois | 71bf34946 | 2017-07-20 23:56:45 | [diff] [blame] | 555 | return payment_request_delegate_->GetAddressNormalizer(); |
| 556 | } |
| 557 | |
Rouslan Solomakhin | 48fd6e87 | 2019-02-22 17:23:10 | [diff] [blame] | 558 | bool PaymentRequestState::IsInitialized() const { |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 559 | return get_all_apps_finished_; |
Rouslan Solomakhin | 48fd6e87 | 2019-02-22 17:23:10 | [diff] [blame] | 560 | } |
| 561 | |
Rouslan Solomakhin | 9788d4b | 2019-04-09 13:10:23 | [diff] [blame] | 562 | void PaymentRequestState::SelectDefaultShippingAddressAndNotifyObservers() { |
| 563 | // Only pre-select an address if the merchant provided at least one selected |
| 564 | // shipping option, and the top profile is complete. Assumes that profiles |
| 565 | // have already been sorted for completeness and frecency. |
Rouslan Solomakhin | 75450a4 | 2020-09-24 18:44:22 | [diff] [blame] | 566 | if (!shipping_profiles().empty() && spec_ && |
| 567 | spec_->selected_shipping_option() && |
Rouslan Solomakhin | 9788d4b | 2019-04-09 13:10:23 | [diff] [blame] | 568 | profile_comparator()->IsShippingComplete(shipping_profiles_[0])) { |
| 569 | selected_shipping_profile_ = shipping_profiles()[0]; |
| 570 | } |
Sahel Sharify | 6efdfb3 | 2019-07-02 16:12:16 | [diff] [blame] | 571 | // Record the missing required fields (if any) of the most complete shipping |
| 572 | // profile. |
| 573 | profile_comparator()->RecordMissingFieldsOfShippingProfile( |
| 574 | shipping_profiles().empty() ? nullptr : shipping_profiles()[0]); |
Rouslan Solomakhin | 9788d4b | 2019-04-09 13:10:23 | [diff] [blame] | 575 | UpdateIsReadyToPayAndNotifyObservers(); |
| 576 | } |
| 577 | |
Sahel Sharify | fef3d92 | 2019-09-11 01:41:22 | [diff] [blame] | 578 | bool PaymentRequestState::ShouldShowShippingSection() const { |
Rouslan Solomakhin | 75450a4 | 2020-09-24 18:44:22 | [diff] [blame] | 579 | if (!spec_ || !spec_->request_shipping()) |
Sahel Sharify | fef3d92 | 2019-09-11 01:41:22 | [diff] [blame] | 580 | return false; |
| 581 | |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 582 | return selected_app_ ? !selected_app_->HandlesShippingAddress() : true; |
Sahel Sharify | fef3d92 | 2019-09-11 01:41:22 | [diff] [blame] | 583 | } |
| 584 | |
| 585 | bool PaymentRequestState::ShouldShowContactSection() const { |
Rouslan Solomakhin | 75450a4 | 2020-09-24 18:44:22 | [diff] [blame] | 586 | if (!spec_) |
| 587 | return false; |
| 588 | |
Sahel Sharify | fef3d92 | 2019-09-11 01:41:22 | [diff] [blame] | 589 | if (spec_->request_payer_name() && |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 590 | (!selected_app_ || !selected_app_->HandlesPayerName())) { |
Sahel Sharify | fef3d92 | 2019-09-11 01:41:22 | [diff] [blame] | 591 | return true; |
| 592 | } |
| 593 | if (spec_->request_payer_email() && |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 594 | (!selected_app_ || !selected_app_->HandlesPayerEmail())) { |
Sahel Sharify | fef3d92 | 2019-09-11 01:41:22 | [diff] [blame] | 595 | return true; |
| 596 | } |
| 597 | if (spec_->request_payer_phone() && |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 598 | (!selected_app_ || !selected_app_->HandlesPayerPhone())) { |
Sahel Sharify | fef3d92 | 2019-09-11 01:41:22 | [diff] [blame] | 599 | return true; |
| 600 | } |
| 601 | |
| 602 | return false; |
| 603 | } |
| 604 | |
Rouslan Solomakhin | 6555229 | 2019-08-29 17:28:21 | [diff] [blame] | 605 | base::WeakPtr<PaymentRequestState> PaymentRequestState::AsWeakPtr() { |
| 606 | return weak_ptr_factory_.GetWeakPtr(); |
| 607 | } |
| 608 | |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 609 | void PaymentRequestState::PopulateProfileCache() { |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 610 | std::vector<autofill::AutofillProfile*> profiles = |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 611 | personal_data_manager_->GetProfilesToSuggest(); |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 612 | |
tmartino | cd131b3 | 2017-05-24 19:40:59 | [diff] [blame] | 613 | std::vector<autofill::AutofillProfile*> raw_profiles_for_filtering; |
| 614 | raw_profiles_for_filtering.reserve(profiles.size()); |
| 615 | |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 616 | // PaymentRequest may outlive the Profiles returned by the Data Manager. |
| 617 | // Thus, we store copies, and return a vector of pointers to these copies |
mathp | f14c1e3 | 2017-05-12 16:37:30 | [diff] [blame] | 618 | // whenever Profiles are requested. |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 619 | for (size_t i = 0; i < profiles.size(); i++) { |
| 620 | profile_cache_.push_back( |
Rouslan Solomakhin | 4eea9bc2 | 2017-10-10 15:18:51 | [diff] [blame] | 621 | std::make_unique<autofill::AutofillProfile>(*profiles[i])); |
tmartino | cd131b3 | 2017-05-24 19:40:59 | [diff] [blame] | 622 | raw_profiles_for_filtering.push_back(profile_cache_.back().get()); |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 623 | } |
| 624 | |
tmartino | 01c3eb8 | 2017-04-29 15:18:39 | [diff] [blame] | 625 | contact_profiles_ = profile_comparator()->FilterProfilesForContact( |
| 626 | raw_profiles_for_filtering); |
tmartino | cd131b3 | 2017-05-24 19:40:59 | [diff] [blame] | 627 | shipping_profiles_ = profile_comparator()->FilterProfilesForShipping( |
| 628 | raw_profiles_for_filtering); |
tmartino | a6eb22f | 2017-04-06 20:16:24 | [diff] [blame] | 629 | |
sebsg | c6719b3 | 2017-07-05 19:54:47 | [diff] [blame] | 630 | // Set the number of suggestions shown for the sections requested by the |
| 631 | // merchant. |
Sahel Sharify | fef3d92 | 2019-09-11 01:41:22 | [diff] [blame] | 632 | if (ShouldShowContactSection()) { |
sebsg | ce700484d | 2017-07-19 23:25:38 | [diff] [blame] | 633 | bool has_complete_contact = |
| 634 | contact_profiles_.empty() |
| 635 | ? false |
| 636 | : profile_comparator()->IsContactInfoComplete(contact_profiles_[0]); |
Rouslan Solomakhin | cb29c4f | 2019-08-16 22:49:39 | [diff] [blame] | 637 | is_requested_autofill_data_available_ &= has_complete_contact; |
sebsg | c6719b3 | 2017-07-05 19:54:47 | [diff] [blame] | 638 | journey_logger_->SetNumberOfSuggestionsShown( |
sebsg | ce700484d | 2017-07-19 23:25:38 | [diff] [blame] | 639 | JourneyLogger::Section::SECTION_CONTACT_INFO, contact_profiles_.size(), |
| 640 | has_complete_contact); |
sebsg | c6719b3 | 2017-07-05 19:54:47 | [diff] [blame] | 641 | } |
Sahel Sharify | fef3d92 | 2019-09-11 01:41:22 | [diff] [blame] | 642 | if (ShouldShowShippingSection()) { |
sebsg | ce700484d | 2017-07-19 23:25:38 | [diff] [blame] | 643 | bool has_complete_shipping = |
| 644 | shipping_profiles_.empty() |
| 645 | ? false |
| 646 | : profile_comparator()->IsShippingComplete(shipping_profiles_[0]); |
Rouslan Solomakhin | cb29c4f | 2019-08-16 22:49:39 | [diff] [blame] | 647 | is_requested_autofill_data_available_ &= has_complete_shipping; |
sebsg | c6719b3 | 2017-07-05 19:54:47 | [diff] [blame] | 648 | journey_logger_->SetNumberOfSuggestionsShown( |
| 649 | JourneyLogger::Section::SECTION_SHIPPING_ADDRESS, |
sebsg | ce700484d | 2017-07-19 23:25:38 | [diff] [blame] | 650 | shipping_profiles_.size(), has_complete_shipping); |
sebsg | c6719b3 | 2017-07-05 19:54:47 | [diff] [blame] | 651 | } |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 652 | } |
| 653 | |
| 654 | void PaymentRequestState::SetDefaultProfileSelections() { |
mathp | f14c1e3 | 2017-05-12 16:37:30 | [diff] [blame] | 655 | // Contact profiles were ordered by completeness in addition to frecency; |
| 656 | // the first one is the best default selection. |
tmartino | cd131b3 | 2017-05-24 19:40:59 | [diff] [blame] | 657 | if (!contact_profiles().empty() && |
| 658 | profile_comparator()->IsContactInfoComplete(contact_profiles_[0])) |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 659 | selected_contact_profile_ = contact_profiles()[0]; |
| 660 | |
Sahel Sharify | 6efdfb3 | 2019-07-02 16:12:16 | [diff] [blame] | 661 | // Record the missing required fields (if any) of the most complete contact |
| 662 | // profile. |
| 663 | profile_comparator()->RecordMissingFieldsOfContactProfile( |
| 664 | contact_profiles().empty() ? nullptr : contact_profiles()[0]); |
| 665 | |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 666 | // Sort apps. |
| 667 | PaymentApp::SortApps(&available_apps_); |
Sahel Sharify | 13331e8 | 2019-07-12 01:00:30 | [diff] [blame] | 668 | |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 669 | selected_app_ = nullptr; |
Sahel Sharify | 9030787 | 2019-12-02 17:28:14 | [diff] [blame] | 670 | if (!available_apps_.empty() && available_apps_[0]->CanPreselect()) { |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 671 | selected_app_ = available_apps_[0].get(); |
Sahel Sharify | 9be7b29 | 2020-03-13 17:37:46 | [diff] [blame] | 672 | UpdateIsReadyToPayAndNotifyObservers(); |
Sahel Sharify | 13331e8 | 2019-07-12 01:00:30 | [diff] [blame] | 673 | } |
Rouslan Solomakhin | 9788d4b | 2019-04-09 13:10:23 | [diff] [blame] | 674 | |
Sahel Sharify | 6efdfb3 | 2019-07-02 16:12:16 | [diff] [blame] | 675 | // Record the missing required payment fields when no complete payment |
| 676 | // info exists. |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 677 | if (available_apps_.empty()) { |
Rouslan Solomakhin | 75450a4 | 2020-09-24 18:44:22 | [diff] [blame] | 678 | if (spec_ && spec_->supports_basic_card()) { |
Sahel Sharify | 6efdfb3 | 2019-07-02 16:12:16 | [diff] [blame] | 679 | // All fields are missing when basic-card is requested but no card exits. |
| 680 | base::UmaHistogramSparse("PaymentRequest.MissingPaymentFields", |
Sahel Sharify | 13331e8 | 2019-07-12 01:00:30 | [diff] [blame] | 681 | CREDIT_CARD_EXPIRED | CREDIT_CARD_NO_CARDHOLDER | |
| 682 | CREDIT_CARD_NO_NUMBER | |
| 683 | CREDIT_CARD_NO_BILLING_ADDRESS); |
Sahel Sharify | 6efdfb3 | 2019-07-02 16:12:16 | [diff] [blame] | 684 | } |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 685 | } else if (available_apps_[0]->type() == PaymentApp::Type::AUTOFILL) { |
| 686 | // Record the missing fields (if any) of the most complete app when |
| 687 | // it's autofill based. SW based apps are always complete. |
| 688 | static_cast<const AutofillPaymentApp*>(available_apps_[0].get()) |
| 689 | ->RecordMissingFieldsForApp(); |
Sahel Sharify | 6efdfb3 | 2019-07-02 16:12:16 | [diff] [blame] | 690 | } |
gogerald | 8189d52 | 2017-09-15 17:52:18 | [diff] [blame] | 691 | |
Sahel Sharify | 6efdfb3 | 2019-07-02 16:12:16 | [diff] [blame] | 692 | SelectDefaultShippingAddressAndNotifyObservers(); |
gogerald | 8189d52 | 2017-09-15 17:52:18 | [diff] [blame] | 693 | |
| 694 | journey_logger_->SetNumberOfSuggestionsShown( |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 695 | JourneyLogger::Section::SECTION_PAYMENT_METHOD, available_apps().size(), |
| 696 | selected_app_); |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 697 | } |
| 698 | |
| 699 | void PaymentRequestState::UpdateIsReadyToPayAndNotifyObservers() { |
| 700 | is_ready_to_pay_ = |
| 701 | ArePaymentDetailsSatisfied() && ArePaymentOptionsSatisfied(); |
| 702 | NotifyOnSelectedInformationChanged(); |
| 703 | } |
| 704 | |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 705 | void PaymentRequestState::NotifyOnGetAllPaymentAppsFinished() { |
gogerald | 8189d52 | 2017-09-15 17:52:18 | [diff] [blame] | 706 | for (auto& observer : observers_) |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 707 | observer.OnGetAllPaymentAppsFinished(); |
gogerald | 8189d52 | 2017-09-15 17:52:18 | [diff] [blame] | 708 | } |
| 709 | |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 710 | void PaymentRequestState::NotifyOnSelectedInformationChanged() { |
| 711 | for (auto& observer : observers_) |
| 712 | observer.OnSelectedInformationChanged(); |
| 713 | } |
| 714 | |
| 715 | bool PaymentRequestState::ArePaymentDetailsSatisfied() { |
mathp | 363735b | 2017-03-16 18:08:05 | [diff] [blame] | 716 | // There is no need to check for supported networks, because only supported |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 717 | // apps are listed/created in the flow. |
| 718 | return selected_app_ != nullptr && selected_app_->IsCompleteForPayment(); |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 719 | } |
| 720 | |
| 721 | bool PaymentRequestState::ArePaymentOptionsSatisfied() { |
Rouslan Solomakhin | 75450a4 | 2020-09-24 18:44:22 | [diff] [blame] | 722 | if (is_waiting_for_merchant_validation_ || !spec_) |
sebsg | 7e61913 | 2017-04-27 16:07:10 | [diff] [blame] | 723 | return false; |
| 724 | |
Sahel Sharify | fef3d92 | 2019-09-11 01:41:22 | [diff] [blame] | 725 | if (ShouldShowShippingSection() && |
| 726 | (!spec_->selected_shipping_option() || |
| 727 | !profile_comparator()->IsShippingComplete(selected_shipping_profile_))) { |
tmartino | 01c3eb8 | 2017-04-29 15:18:39 | [diff] [blame] | 728 | return false; |
Sahel Sharify | fef3d92 | 2019-09-11 01:41:22 | [diff] [blame] | 729 | } |
tmartino | 01c3eb8 | 2017-04-29 15:18:39 | [diff] [blame] | 730 | |
Sahel Sharify | fef3d92 | 2019-09-11 01:41:22 | [diff] [blame] | 731 | if (ShouldShowContactSection() && |
| 732 | !profile_comparator()->IsContactInfoComplete(selected_contact_profile_)) { |
Anthony Vallee-Dubois | a881467 | 2017-06-01 18:43:20 | [diff] [blame] | 733 | return false; |
Sahel Sharify | fef3d92 | 2019-09-11 01:41:22 | [diff] [blame] | 734 | } |
Anthony Vallee-Dubois | a881467 | 2017-06-01 18:43:20 | [diff] [blame] | 735 | |
Sahel Sharify | fef3d92 | 2019-09-11 01:41:22 | [diff] [blame] | 736 | return true; |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 737 | } |
| 738 | |
Mathieu Perreault | 17c1ae9 | 2017-10-20 17:16:00 | [diff] [blame] | 739 | void PaymentRequestState::OnAddressNormalized( |
| 740 | bool success, |
| 741 | const autofill::AutofillProfile& normalized_profile) { |
Kyungsun Lee | cdbdade | 2020-08-25 18:06:12 | [diff] [blame] | 742 | if (!delegate_) |
| 743 | return; |
| 744 | |
Mathieu Perreault | 17c1ae9 | 2017-10-20 17:16:00 | [diff] [blame] | 745 | delegate_->OnShippingAddressSelected( |
Tommy Martino | 21d415f | 2018-01-12 20:08:22 | [diff] [blame] | 746 | data_util::GetPaymentAddressFromAutofillProfile(normalized_profile, |
| 747 | app_locale_)); |
Mathieu Perreault | 17c1ae9 | 2017-10-20 17:16:00 | [diff] [blame] | 748 | } |
| 749 | |
Nick Burris | fca09083 | 2020-07-28 00:17:42 | [diff] [blame] | 750 | bool PaymentRequestState::IsInTwa() const { |
| 751 | return !payment_request_delegate_->GetTwaPackageName().empty(); |
| 752 | } |
| 753 | |
Rouslan Solomakhin | ebf9f16 | 2020-08-27 15:28:13 | [diff] [blame] | 754 | bool PaymentRequestState::GetCanMakePaymentValue() const { |
| 755 | return are_requested_methods_supported_ || |
| 756 | can_make_payment_even_without_apps_; |
| 757 | } |
| 758 | |
| 759 | bool PaymentRequestState::GetHasEnrolledInstrumentValue() const { |
| 760 | return has_enrolled_instrument_ || can_make_payment_even_without_apps_; |
| 761 | } |
| 762 | |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 763 | } // namespace payments |