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_spec.h" |
| 6 | |
| 7 | #include <utility> |
| 8 | |
Hans Wennborg | df87046c | 2020-04-28 11:06:24 | [diff] [blame] | 9 | #include "base/check.h" |
Mathieu Perreault | 51339b8 | 2017-07-20 17:06:05 | [diff] [blame] | 10 | #include "base/feature_list.h" |
Hans Wennborg | df87046c | 2020-04-28 11:06:24 | [diff] [blame] | 11 | #include "base/notreached.h" |
Rouslan Solomakhin | b26faa07 | 2019-08-19 14:42:28 | [diff] [blame] | 12 | #include "base/stl_util.h" |
| 13 | #include "base/strings/string_util.h" |
mathp | eb8892ff | 2017-05-04 18:42:55 | [diff] [blame] | 14 | #include "base/strings/utf_string_conversions.h" |
Rouslan Solomakhin | 2039a34 | 2020-05-21 19:21:04 | [diff] [blame] | 15 | #include "components/payments/content/payment_app.h" |
Mohamad Ahmadi | f5544bb | 2017-09-01 21:48:22 | [diff] [blame] | 16 | #include "components/payments/content/payment_request_converter.h" |
Mathieu Perreault | 51339b8 | 2017-07-20 17:06:05 | [diff] [blame] | 17 | #include "components/payments/core/features.h" |
Rouslan Solomakhin | 85b10da | 2019-11-05 20:03:17 | [diff] [blame] | 18 | #include "components/payments/core/method_strings.h" |
mathp | b65623a | 2017-04-06 02:01:54 | [diff] [blame] | 19 | #include "components/payments/core/payment_method_data.h" |
| 20 | #include "components/payments/core/payment_request_data_util.h" |
Rouslan Solomakhin | b26faa07 | 2019-08-19 14:42:28 | [diff] [blame] | 21 | #include "components/payments/core/payments_experimental_features.h" |
mathp | eb8892ff | 2017-05-04 18:42:55 | [diff] [blame] | 22 | #include "components/strings/grit/components_strings.h" |
| 23 | #include "ui/base/l10n/l10n_util.h" |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 24 | |
| 25 | namespace payments { |
| 26 | |
mathp | b65623a | 2017-04-06 02:01:54 | [diff] [blame] | 27 | namespace { |
| 28 | |
Rouslan Solomakhin | 4eea9bc2 | 2017-10-10 15:18:51 | [diff] [blame] | 29 | // Validates the |method_data| and fills the output parameters. |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 30 | void PopulateValidatedMethodData( |
| 31 | const std::vector<PaymentMethodData>& method_data_vector, |
| 32 | std::vector<std::string>* supported_card_networks, |
| 33 | std::set<std::string>* basic_card_specified_networks, |
| 34 | std::set<std::string>* supported_card_networks_set, |
Randall Raymond | 6a85ba0ab | 2017-08-04 23:11:54 | [diff] [blame] | 35 | std::vector<GURL>* url_payment_method_identifiers, |
Rouslan Solomakhin | 4eea9bc2 | 2017-10-10 15:18:51 | [diff] [blame] | 36 | std::set<std::string>* payment_method_identifiers_set, |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 37 | std::map<std::string, std::set<std::string>>* stringified_method_data) { |
Randall Raymond | ec4e085 | 2017-07-14 01:30:45 | [diff] [blame] | 38 | data_util::ParseSupportedMethods(method_data_vector, supported_card_networks, |
| 39 | basic_card_specified_networks, |
Rouslan Solomakhin | 4eea9bc2 | 2017-10-10 15:18:51 | [diff] [blame] | 40 | url_payment_method_identifiers, |
| 41 | payment_method_identifiers_set); |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 42 | supported_card_networks_set->insert(supported_card_networks->begin(), |
| 43 | supported_card_networks->end()); |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 44 | } |
| 45 | |
| 46 | void PopulateValidatedMethodData( |
| 47 | const std::vector<mojom::PaymentMethodDataPtr>& method_data_mojom, |
| 48 | std::vector<std::string>* supported_card_networks, |
| 49 | std::set<std::string>* basic_card_specified_networks, |
| 50 | std::set<std::string>* supported_card_networks_set, |
Randall Raymond | 6a85ba0ab | 2017-08-04 23:11:54 | [diff] [blame] | 51 | std::vector<GURL>* url_payment_method_identifiers, |
Rouslan Solomakhin | 4eea9bc2 | 2017-10-10 15:18:51 | [diff] [blame] | 52 | std::set<std::string>* payment_method_identifiers_set, |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 53 | std::map<std::string, std::set<std::string>>* stringified_method_data) { |
| 54 | std::vector<PaymentMethodData> method_data_vector; |
| 55 | method_data_vector.reserve(method_data_mojom.size()); |
| 56 | for (const mojom::PaymentMethodDataPtr& method_data_entry : |
| 57 | method_data_mojom) { |
Jinho Bang | d252ebf5b1 | 2018-07-18 00:00:59 | [diff] [blame] | 58 | (*stringified_method_data)[method_data_entry->supported_method].insert( |
| 59 | method_data_entry->stringified_data); |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 60 | |
Mohamad Ahmadi | f5544bb | 2017-09-01 21:48:22 | [diff] [blame] | 61 | method_data_vector.push_back(ConvertPaymentMethodData(method_data_entry)); |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 62 | } |
| 63 | |
| 64 | PopulateValidatedMethodData( |
| 65 | method_data_vector, supported_card_networks, |
| 66 | basic_card_specified_networks, supported_card_networks_set, |
Rouslan Solomakhin | 8aca664 | 2020-01-17 13:32:16 | [diff] [blame] | 67 | url_payment_method_identifiers, payment_method_identifiers_set, |
| 68 | stringified_method_data); |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 69 | } |
| 70 | |
Rouslan Solomakhin | b26faa07 | 2019-08-19 14:42:28 | [diff] [blame] | 71 | std::string ToString(bool value) { |
| 72 | return value ? "true" : "false"; |
| 73 | } |
| 74 | |
mathp | b65623a | 2017-04-06 02:01:54 | [diff] [blame] | 75 | } // namespace |
| 76 | |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 77 | PaymentRequestSpec::PaymentRequestSpec( |
| 78 | mojom::PaymentOptionsPtr options, |
| 79 | mojom::PaymentDetailsPtr details, |
| 80 | std::vector<mojom::PaymentMethodDataPtr> method_data, |
DongJun Kim | 54690d5 | 2020-09-26 12:07:54 | [diff] [blame] | 81 | base::WeakPtr<Observer> observer, |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 82 | const std::string& app_locale) |
| 83 | : options_(std::move(options)), |
| 84 | details_(std::move(details)), |
gogerald | 7a0cc3e | 2017-09-19 03:35:48 | [diff] [blame] | 85 | method_data_(std::move(method_data)), |
mathp | 151bd31 | 2017-04-03 21:07:24 | [diff] [blame] | 86 | app_locale_(app_locale), |
Rouslan Solomakhin | 9788d4b | 2019-04-09 13:10:23 | [diff] [blame] | 87 | selected_shipping_option_(nullptr), |
| 88 | current_update_reason_(UpdateReason::NONE) { |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 89 | if (observer) |
DongJun Kim | 54690d5 | 2020-09-26 12:07:54 | [diff] [blame] | 90 | AddObserver(observer.get()); |
Rouslan Solomakhin | e1a93542 | 2019-04-15 21:48:36 | [diff] [blame] | 91 | if (!details_->display_items) |
| 92 | details_->display_items = std::vector<mojom::PaymentItemPtr>(); |
Jinho Bang | 6f591c7 | 2018-12-05 09:26:43 | [diff] [blame] | 93 | if (!details_->shipping_options) |
| 94 | details_->shipping_options = std::vector<mojom::PaymentShippingOptionPtr>(); |
Rouslan Solomakhin | e1a93542 | 2019-04-15 21:48:36 | [diff] [blame] | 95 | if (!details_->modifiers) |
| 96 | details_->modifiers = std::vector<mojom::PaymentDetailsModifierPtr>(); |
mathp | b77b873 | 2017-05-11 15:26:42 | [diff] [blame] | 97 | UpdateSelectedShippingOption(/*after_update=*/false); |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 98 | PopulateValidatedMethodData( |
gogerald | 7a0cc3e | 2017-09-19 03:35:48 | [diff] [blame] | 99 | method_data_, &supported_card_networks_, &basic_card_specified_networks_, |
Rouslan Solomakhin | 8aca664 | 2020-01-17 13:32:16 | [diff] [blame] | 100 | &supported_card_networks_set_, &url_payment_method_identifiers_, |
| 101 | &payment_method_identifiers_set_, &stringified_method_data_); |
Rouslan Solomakhin | b26faa07 | 2019-08-19 14:42:28 | [diff] [blame] | 102 | |
| 103 | query_for_quota_ = stringified_method_data_; |
Rouslan Solomakhin | 85b10da | 2019-11-05 20:03:17 | [diff] [blame] | 104 | if (base::Contains(payment_method_identifiers_set_, methods::kBasicCard) && |
Rouslan Solomakhin | b26faa07 | 2019-08-19 14:42:28 | [diff] [blame] | 105 | PaymentsExperimentalFeatures::IsEnabled( |
| 106 | features::kStrictHasEnrolledAutofillInstrument)) { |
| 107 | query_for_quota_["basic-card-payment-options"] = { |
| 108 | base::ReplaceStringPlaceholders( |
| 109 | "{payerEmail:$1,payerName:$2,payerPhone:$3,shipping:$4}", |
| 110 | {ToString(request_payer_email()), ToString(request_payer_name()), |
| 111 | ToString(request_payer_phone()), ToString(request_shipping())}, |
| 112 | nullptr)}; |
| 113 | } |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 114 | } |
| 115 | PaymentRequestSpec::~PaymentRequestSpec() {} |
| 116 | |
mathp | 151bd31 | 2017-04-03 21:07:24 | [diff] [blame] | 117 | void PaymentRequestSpec::UpdateWith(mojom::PaymentDetailsPtr details) { |
Jinho Bang | 6f591c7 | 2018-12-05 09:26:43 | [diff] [blame] | 118 | DCHECK(details_); |
Rouslan Solomakhin | 9788d4b | 2019-04-09 13:10:23 | [diff] [blame] | 119 | DCHECK(details_->total || details->total); |
Jinho Bang | 6f591c7 | 2018-12-05 09:26:43 | [diff] [blame] | 120 | if (details->total) |
| 121 | details_->total = std::move(details->total); |
Rouslan Solomakhin | e1a93542 | 2019-04-15 21:48:36 | [diff] [blame] | 122 | if (details->display_items) |
Jinho Bang | 94ca2b10 | 2019-02-21 05:55:57 | [diff] [blame] | 123 | details_->display_items = std::move(details->display_items); |
Jinho Bang | 6f591c7 | 2018-12-05 09:26:43 | [diff] [blame] | 124 | if (details->shipping_options) |
| 125 | details_->shipping_options = std::move(details->shipping_options); |
Rouslan Solomakhin | e1a93542 | 2019-04-15 21:48:36 | [diff] [blame] | 126 | if (details->modifiers) |
Jinho Bang | 2a203518 | 2019-02-21 07:57:56 | [diff] [blame] | 127 | details_->modifiers = std::move(details->modifiers); |
Jinho Bang | 6f591c7 | 2018-12-05 09:26:43 | [diff] [blame] | 128 | details_->error = std::move(details->error); |
| 129 | if (details->shipping_address_errors) |
| 130 | details_->shipping_address_errors = |
| 131 | std::move(details->shipping_address_errors); |
| 132 | if (details->id) |
| 133 | details_->id = std::move(details->id); |
Rouslan Solomakhin | e1a93542 | 2019-04-15 21:48:36 | [diff] [blame] | 134 | DCHECK(details_->total); |
| 135 | DCHECK(details_->display_items); |
| 136 | DCHECK(details_->shipping_options); |
| 137 | DCHECK(details_->modifiers); |
Rouslan Solomakhin | a9ff928 | 2017-10-31 21:58:05 | [diff] [blame] | 138 | RecomputeSpecForDetails(); |
| 139 | } |
| 140 | |
Jinho Bang | 745898b | 2019-03-25 14:00:03 | [diff] [blame] | 141 | void PaymentRequestSpec::Retry( |
| 142 | mojom::PaymentValidationErrorsPtr validation_errors) { |
| 143 | if (!validation_errors) |
Jinho Bang | 092e716 | 2018-09-06 23:41:19 | [diff] [blame] | 144 | return; |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 145 | |
Jinho Bang | 745898b | 2019-03-25 14:00:03 | [diff] [blame] | 146 | retry_error_message_ = |
| 147 | validation_errors->error.empty() |
| 148 | ? l10n_util::GetStringUTF16(IDS_PAYMENTS_ERROR_MESSAGE) |
| 149 | : base::UTF8ToUTF16(std::move(validation_errors->error)); |
| 150 | details_->shipping_address_errors = |
| 151 | std::move(validation_errors->shipping_address); |
| 152 | payer_errors_ = std::move(validation_errors->payer); |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 153 | current_update_reason_ = UpdateReason::RETRY; |
| 154 | NotifyOnSpecUpdated(); |
| 155 | current_update_reason_ = UpdateReason::NONE; |
| 156 | } |
| 157 | |
| 158 | base::string16 PaymentRequestSpec::GetShippingAddressError( |
| 159 | autofill::ServerFieldType type) { |
Jinho Bang | 47531aa | 2018-12-14 10:43:55 | [diff] [blame] | 160 | if (!details_->shipping_address_errors) |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 161 | return base::string16(); |
| 162 | |
| 163 | if (type == autofill::ADDRESS_HOME_STREET_ADDRESS) |
Jinho Bang | 47531aa | 2018-12-14 10:43:55 | [diff] [blame] | 164 | return base::UTF8ToUTF16(details_->shipping_address_errors->address_line); |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 165 | |
| 166 | if (type == autofill::ADDRESS_HOME_CITY) |
Jinho Bang | 47531aa | 2018-12-14 10:43:55 | [diff] [blame] | 167 | return base::UTF8ToUTF16(details_->shipping_address_errors->city); |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 168 | |
| 169 | if (type == autofill::ADDRESS_HOME_COUNTRY) |
Jinho Bang | 47531aa | 2018-12-14 10:43:55 | [diff] [blame] | 170 | return base::UTF8ToUTF16(details_->shipping_address_errors->country); |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 171 | |
| 172 | if (type == autofill::ADDRESS_HOME_DEPENDENT_LOCALITY) |
Jinho Bang | 47531aa | 2018-12-14 10:43:55 | [diff] [blame] | 173 | return base::UTF8ToUTF16( |
| 174 | details_->shipping_address_errors->dependent_locality); |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 175 | |
| 176 | if (type == autofill::COMPANY_NAME) |
Jinho Bang | 47531aa | 2018-12-14 10:43:55 | [diff] [blame] | 177 | return base::UTF8ToUTF16(details_->shipping_address_errors->organization); |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 178 | |
| 179 | if (type == autofill::PHONE_HOME_WHOLE_NUMBER) |
Jinho Bang | 47531aa | 2018-12-14 10:43:55 | [diff] [blame] | 180 | return base::UTF8ToUTF16(details_->shipping_address_errors->phone); |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 181 | |
| 182 | if (type == autofill::ADDRESS_HOME_ZIP) |
Jinho Bang | 47531aa | 2018-12-14 10:43:55 | [diff] [blame] | 183 | return base::UTF8ToUTF16(details_->shipping_address_errors->postal_code); |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 184 | |
| 185 | if (type == autofill::NAME_FULL) |
Jinho Bang | 47531aa | 2018-12-14 10:43:55 | [diff] [blame] | 186 | return base::UTF8ToUTF16(details_->shipping_address_errors->recipient); |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 187 | |
| 188 | if (type == autofill::ADDRESS_HOME_STATE) |
Jinho Bang | 47531aa | 2018-12-14 10:43:55 | [diff] [blame] | 189 | return base::UTF8ToUTF16(details_->shipping_address_errors->region); |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 190 | |
| 191 | if (type == autofill::ADDRESS_HOME_SORTING_CODE) |
Jinho Bang | 47531aa | 2018-12-14 10:43:55 | [diff] [blame] | 192 | return base::UTF8ToUTF16(details_->shipping_address_errors->sorting_code); |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 193 | |
| 194 | return base::string16(); |
| 195 | } |
| 196 | |
| 197 | base::string16 PaymentRequestSpec::GetPayerError( |
| 198 | autofill::ServerFieldType type) { |
| 199 | if (!payer_errors_) |
| 200 | return base::string16(); |
| 201 | |
| 202 | if (type == autofill::EMAIL_ADDRESS) |
| 203 | return base::UTF8ToUTF16(payer_errors_->email); |
| 204 | |
| 205 | if (type == autofill::NAME_FULL) |
| 206 | return base::UTF8ToUTF16(payer_errors_->name); |
| 207 | |
| 208 | if (type == autofill::PHONE_HOME_WHOLE_NUMBER) |
| 209 | return base::UTF8ToUTF16(payer_errors_->phone); |
| 210 | |
| 211 | return base::string16(); |
| 212 | } |
| 213 | |
| 214 | bool PaymentRequestSpec::has_shipping_address_error() const { |
Jinho Bang | 47531aa | 2018-12-14 10:43:55 | [diff] [blame] | 215 | return details_->shipping_address_errors && request_shipping() && |
| 216 | !(details_->shipping_address_errors->address_line.empty() && |
| 217 | details_->shipping_address_errors->city.empty() && |
| 218 | details_->shipping_address_errors->country.empty() && |
| 219 | details_->shipping_address_errors->dependent_locality.empty() && |
| 220 | details_->shipping_address_errors->organization.empty() && |
| 221 | details_->shipping_address_errors->phone.empty() && |
| 222 | details_->shipping_address_errors->postal_code.empty() && |
| 223 | details_->shipping_address_errors->recipient.empty() && |
| 224 | details_->shipping_address_errors->region.empty() && |
Jinho Bang | 47531aa | 2018-12-14 10:43:55 | [diff] [blame] | 225 | details_->shipping_address_errors->sorting_code.empty()); |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 226 | } |
| 227 | |
| 228 | bool PaymentRequestSpec::has_payer_error() const { |
| 229 | return payer_errors_ && |
Jinho Bang | 7f19d89 | 2018-08-27 18:23:00 | [diff] [blame] | 230 | (request_payer_email() || request_payer_name() || |
| 231 | request_payer_phone()) && |
Jinho Bang | cac8d9a0 | 2018-08-23 19:47:22 | [diff] [blame] | 232 | !(payer_errors_->email.empty() && payer_errors_->name.empty() && |
| 233 | payer_errors_->phone.empty()); |
| 234 | } |
| 235 | |
Rouslan Solomakhin | a9ff928 | 2017-10-31 21:58:05 | [diff] [blame] | 236 | void PaymentRequestSpec::RecomputeSpecForDetails() { |
Jinho Bang | 092e716 | 2018-09-06 23:41:19 | [diff] [blame] | 237 | // Reparse the |details_| and update the observers. |
Rouslan Solomakhin | 9788d4b | 2019-04-09 13:10:23 | [diff] [blame] | 238 | bool is_initialization = |
| 239 | current_update_reason_ == UpdateReason::INITIAL_PAYMENT_DETAILS; |
| 240 | UpdateSelectedShippingOption(/*after_update=*/!is_initialization); |
Jinho Bang | 092e716 | 2018-09-06 23:41:19 | [diff] [blame] | 241 | |
mathp | 151bd31 | 2017-04-03 21:07:24 | [diff] [blame] | 242 | NotifyOnSpecUpdated(); |
Rouslan Solomakhin | 9788d4b | 2019-04-09 13:10:23 | [diff] [blame] | 243 | |
| 244 | if (is_initialization) |
| 245 | NotifyInitialized(); |
| 246 | |
Anthony Vallee-Dubois | db030dd | 2017-05-19 18:04:51 | [diff] [blame] | 247 | current_update_reason_ = UpdateReason::NONE; |
mathp | 151bd31 | 2017-04-03 21:07:24 | [diff] [blame] | 248 | } |
| 249 | |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 250 | void PaymentRequestSpec::AddObserver(Observer* observer) { |
| 251 | CHECK(observer); |
| 252 | observers_.AddObserver(observer); |
| 253 | } |
| 254 | |
| 255 | void PaymentRequestSpec::RemoveObserver(Observer* observer) { |
| 256 | observers_.RemoveObserver(observer); |
| 257 | } |
| 258 | |
Rouslan Solomakhin | 9788d4b | 2019-04-09 13:10:23 | [diff] [blame] | 259 | bool PaymentRequestSpec::IsInitialized() const { |
| 260 | return current_update_reason_ != UpdateReason::INITIAL_PAYMENT_DETAILS; |
| 261 | } |
| 262 | |
tmartino | 5f0912b8 | 2017-03-30 03:20:52 | [diff] [blame] | 263 | bool PaymentRequestSpec::request_shipping() const { |
| 264 | return options_->request_shipping; |
| 265 | } |
| 266 | bool PaymentRequestSpec::request_payer_name() const { |
| 267 | return options_->request_payer_name; |
| 268 | } |
| 269 | bool PaymentRequestSpec::request_payer_phone() const { |
| 270 | return options_->request_payer_phone; |
| 271 | } |
| 272 | bool PaymentRequestSpec::request_payer_email() const { |
| 273 | return options_->request_payer_email; |
| 274 | } |
| 275 | |
| 276 | PaymentShippingType PaymentRequestSpec::shipping_type() const { |
| 277 | // Transform Mojo-specific enum into platform-agnostic equivalent. |
| 278 | switch (options_->shipping_type) { |
| 279 | case mojom::PaymentShippingType::DELIVERY: |
| 280 | return PaymentShippingType::DELIVERY; |
| 281 | case payments::mojom::PaymentShippingType::PICKUP: |
| 282 | return PaymentShippingType::PICKUP; |
| 283 | case payments::mojom::PaymentShippingType::SHIPPING: |
| 284 | return PaymentShippingType::SHIPPING; |
| 285 | default: |
| 286 | NOTREACHED(); |
| 287 | } |
| 288 | // Needed for compilation on some platforms. |
| 289 | return PaymentShippingType::SHIPPING; |
| 290 | } |
| 291 | |
mathp | 600bab5 | 2017-03-26 03:47:59 | [diff] [blame] | 292 | bool PaymentRequestSpec::IsMethodSupportedThroughBasicCard( |
| 293 | const std::string& method_name) { |
| 294 | return basic_card_specified_networks_.count(method_name) > 0; |
| 295 | } |
| 296 | |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 297 | base::string16 PaymentRequestSpec::GetFormattedCurrencyAmount( |
Anthony Vallee-Dubois | 080d5b7 | 2017-05-11 22:34:04 | [diff] [blame] | 298 | const mojom::PaymentCurrencyAmountPtr& currency_amount) { |
Jinho Bang | 26b0ea4 | 2018-05-24 01:09:04 | [diff] [blame] | 299 | CurrencyFormatter* formatter = |
| 300 | GetOrCreateCurrencyFormatter(currency_amount->currency, app_locale_); |
Anthony Vallee-Dubois | 080d5b7 | 2017-05-11 22:34:04 | [diff] [blame] | 301 | return formatter->Format(currency_amount->value); |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 302 | } |
| 303 | |
Anthony Vallee-Dubois | 080d5b7 | 2017-05-11 22:34:04 | [diff] [blame] | 304 | std::string PaymentRequestSpec::GetFormattedCurrencyCode( |
| 305 | const mojom::PaymentCurrencyAmountPtr& currency_amount) { |
Jinho Bang | 26b0ea4 | 2018-05-24 01:09:04 | [diff] [blame] | 306 | CurrencyFormatter* formatter = |
| 307 | GetOrCreateCurrencyFormatter(currency_amount->currency, app_locale_); |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 308 | |
| 309 | return formatter->formatted_currency_code(); |
| 310 | } |
| 311 | |
anthonyvd | 2f30baa1 | 2017-04-13 22:30:50 | [diff] [blame] | 312 | void PaymentRequestSpec::StartWaitingForUpdateWith( |
| 313 | PaymentRequestSpec::UpdateReason reason) { |
Anthony Vallee-Dubois | db030dd | 2017-05-19 18:04:51 | [diff] [blame] | 314 | current_update_reason_ = reason; |
anthonyvd | 2f30baa1 | 2017-04-13 22:30:50 | [diff] [blame] | 315 | for (auto& observer : observers_) { |
| 316 | observer.OnStartUpdating(reason); |
| 317 | } |
| 318 | } |
| 319 | |
Anthony Vallee-Dubois | 080d5b7 | 2017-05-11 22:34:04 | [diff] [blame] | 320 | bool PaymentRequestSpec::IsMixedCurrency() const { |
Rouslan Solomakhin | e1a93542 | 2019-04-15 21:48:36 | [diff] [blame] | 321 | DCHECK(details_->display_items); |
Anthony Vallee-Dubois | 080d5b7 | 2017-05-11 22:34:04 | [diff] [blame] | 322 | const std::string& total_currency = details_->total->amount->currency; |
Rouslan Solomakhin | e1a93542 | 2019-04-15 21:48:36 | [diff] [blame] | 323 | return std::any_of(details_->display_items->begin(), |
| 324 | details_->display_items->end(), |
Anthony Vallee-Dubois | 080d5b7 | 2017-05-11 22:34:04 | [diff] [blame] | 325 | [&total_currency](const mojom::PaymentItemPtr& item) { |
| 326 | return item->amount->currency != total_currency; |
| 327 | }); |
| 328 | } |
| 329 | |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 330 | const mojom::PaymentItemPtr& PaymentRequestSpec::GetTotal( |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 331 | PaymentApp* selected_app) const { |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 332 | const mojom::PaymentDetailsModifierPtr* modifier = |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 333 | GetApplicableModifier(selected_app); |
Rouslan Solomakhin | 4ad4894 | 2018-02-26 17:21:15 | [diff] [blame] | 334 | return modifier && (*modifier)->total ? (*modifier)->total : details_->total; |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 335 | } |
rouslan | 69099768 | 2017-05-09 18:07:39 | [diff] [blame] | 336 | |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 337 | std::vector<const mojom::PaymentItemPtr*> PaymentRequestSpec::GetDisplayItems( |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 338 | PaymentApp* selected_app) const { |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 339 | std::vector<const mojom::PaymentItemPtr*> display_items; |
| 340 | const mojom::PaymentDetailsModifierPtr* modifier = |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 341 | GetApplicableModifier(selected_app); |
Rouslan Solomakhin | e1a93542 | 2019-04-15 21:48:36 | [diff] [blame] | 342 | DCHECK(details_->display_items); |
| 343 | for (const auto& item : *details_->display_items) { |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 344 | display_items.push_back(&item); |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 345 | } |
mathp | 363735b | 2017-03-16 18:08:05 | [diff] [blame] | 346 | |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 347 | if (modifier) { |
| 348 | for (const auto& additional_item : (*modifier)->additional_display_items) { |
| 349 | display_items.push_back(&additional_item); |
| 350 | } |
| 351 | } |
| 352 | return display_items; |
| 353 | } |
Rouslan Solomakhin | 25d708b | 2017-06-23 17:12:03 | [diff] [blame] | 354 | |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 355 | const std::vector<mojom::PaymentShippingOptionPtr>& |
| 356 | PaymentRequestSpec::GetShippingOptions() const { |
Jinho Bang | 6f591c7 | 2018-12-05 09:26:43 | [diff] [blame] | 357 | DCHECK(details_->shipping_options); |
| 358 | return *details_->shipping_options; |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 359 | } |
| 360 | |
Sahel Sharify | c8b2e0d | 2020-08-19 20:27:22 | [diff] [blame] | 361 | bool PaymentRequestSpec::IsSecurePaymentConfirmationRequested() const { |
| 362 | // No other payment method will be requested together with secure payment |
| 363 | // confirmation. |
| 364 | return payment_method_identifiers_set_.size() == 1 && |
| 365 | *payment_method_identifiers_set_.begin() == |
| 366 | methods::kSecurePaymentConfirmation; |
| 367 | } |
| 368 | |
DongJun Kim | 54690d5 | 2020-09-26 12:07:54 | [diff] [blame] | 369 | base::WeakPtr<PaymentRequestSpec> PaymentRequestSpec::AsWeakPtr() { |
Rouslan Solomakhin | 75450a4 | 2020-09-24 18:44:22 | [diff] [blame] | 370 | return weak_ptr_factory_.GetWeakPtr(); |
| 371 | } |
| 372 | |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 373 | const mojom::PaymentDetailsModifierPtr* |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 374 | PaymentRequestSpec::GetApplicableModifier(PaymentApp* selected_app) const { |
| 375 | if (!selected_app || |
Mathieu Perreault | 51339b8 | 2017-07-20 17:06:05 | [diff] [blame] | 376 | !base::FeatureList::IsEnabled(features::kWebPaymentsModifiers)) |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 377 | return nullptr; |
| 378 | |
Rouslan Solomakhin | e1a93542 | 2019-04-15 21:48:36 | [diff] [blame] | 379 | DCHECK(details_->modifiers); |
| 380 | for (const auto& modifier : *details_->modifiers) { |
gogerald | 6cf12fe | 2017-11-08 21:29:55 | [diff] [blame] | 381 | std::set<std::string> supported_card_networks_set; |
Randall Raymond | ec4e085 | 2017-07-14 01:30:45 | [diff] [blame] | 382 | // The following 4 are unused but required by PopulateValidatedMethodData. |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 383 | std::set<std::string> basic_card_specified_networks; |
gogerald | 6cf12fe | 2017-11-08 21:29:55 | [diff] [blame] | 384 | std::vector<std::string> supported_networks; |
Randall Raymond | 6a85ba0ab | 2017-08-04 23:11:54 | [diff] [blame] | 385 | std::vector<GURL> url_payment_method_identifiers; |
Rouslan Solomakhin | 4eea9bc2 | 2017-10-10 15:18:51 | [diff] [blame] | 386 | std::set<std::string> payment_method_identifiers_set; |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 387 | std::map<std::string, std::set<std::string>> stringified_method_data; |
| 388 | PopulateValidatedMethodData( |
Mohamad Ahmadi | f5544bb | 2017-09-01 21:48:22 | [diff] [blame] | 389 | {ConvertPaymentMethodData(modifier->method_data)}, &supported_networks, |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 390 | &basic_card_specified_networks, &supported_card_networks_set, |
Rouslan Solomakhin | 8aca664 | 2020-01-17 13:32:16 | [diff] [blame] | 391 | &url_payment_method_identifiers, &payment_method_identifiers_set, |
| 392 | &stringified_method_data); |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 393 | |
Rouslan Solomakhin | 5d15cb1f | 2019-11-11 18:11:39 | [diff] [blame] | 394 | if (selected_app->IsValidForModifier( |
Jinho Bang | d252ebf5b1 | 2018-07-18 00:00:59 | [diff] [blame] | 395 | modifier->method_data->supported_method, |
gogerald | 6cf12fe | 2017-11-08 21:29:55 | [diff] [blame] | 396 | !modifier->method_data->supported_networks.empty(), |
Rouslan Solomakhin | 8aca664 | 2020-01-17 13:32:16 | [diff] [blame] | 397 | supported_card_networks_set)) { |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 398 | return &modifier; |
| 399 | } |
| 400 | } |
| 401 | return nullptr; |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 402 | } |
| 403 | |
mathp | b77b873 | 2017-05-11 15:26:42 | [diff] [blame] | 404 | void PaymentRequestSpec::UpdateSelectedShippingOption(bool after_update) { |
Jinho Bang | 6f591c7 | 2018-12-05 09:26:43 | [diff] [blame] | 405 | if (!request_shipping() || !details_->shipping_options) |
mathp | 151bd31 | 2017-04-03 21:07:24 | [diff] [blame] | 406 | return; |
| 407 | |
mathp | b77b873 | 2017-05-11 15:26:42 | [diff] [blame] | 408 | selected_shipping_option_ = nullptr; |
mathp | eb8892ff | 2017-05-04 18:42:55 | [diff] [blame] | 409 | selected_shipping_option_error_.clear(); |
Rouslan Solomakhin | dfcf1e7dc | 2019-02-28 18:43:23 | [diff] [blame] | 410 | if (details_->shipping_options->empty() || !details_->error.empty()) { |
Rouslan Solomakhin | 9788d4b | 2019-04-09 13:10:23 | [diff] [blame] | 411 | // The merchant provided either no shipping options or an error message. |
mathp | b77b873 | 2017-05-11 15:26:42 | [diff] [blame] | 412 | if (after_update) { |
Mathieu Perreault | 2c1f319 | 2017-05-18 14:45:28 | [diff] [blame] | 413 | // This is after an update, which means that the selected address is not |
mathp | b77b873 | 2017-05-11 15:26:42 | [diff] [blame] | 414 | // supported. The merchant may have customized the error string, or a |
| 415 | // generic one is used. |
gogerald | 7a0cc3e | 2017-09-19 03:35:48 | [diff] [blame] | 416 | if (!details_->error.empty()) { |
| 417 | selected_shipping_option_error_ = base::UTF8ToUTF16(details_->error); |
mathp | b77b873 | 2017-05-11 15:26:42 | [diff] [blame] | 418 | } else { |
Mathieu Perreault | 2c1f319 | 2017-05-18 14:45:28 | [diff] [blame] | 419 | // The generic error string depends on the shipping type. |
| 420 | switch (shipping_type()) { |
| 421 | case PaymentShippingType::DELIVERY: |
| 422 | selected_shipping_option_error_ = l10n_util::GetStringUTF16( |
| 423 | IDS_PAYMENTS_UNSUPPORTED_DELIVERY_ADDRESS); |
| 424 | break; |
| 425 | case PaymentShippingType::PICKUP: |
| 426 | selected_shipping_option_error_ = l10n_util::GetStringUTF16( |
| 427 | IDS_PAYMENTS_UNSUPPORTED_PICKUP_ADDRESS); |
| 428 | break; |
| 429 | case PaymentShippingType::SHIPPING: |
| 430 | selected_shipping_option_error_ = l10n_util::GetStringUTF16( |
| 431 | IDS_PAYMENTS_UNSUPPORTED_SHIPPING_ADDRESS); |
| 432 | break; |
| 433 | } |
mathp | b77b873 | 2017-05-11 15:26:42 | [diff] [blame] | 434 | } |
| 435 | } |
| 436 | return; |
| 437 | } |
| 438 | |
mathp | 151bd31 | 2017-04-03 21:07:24 | [diff] [blame] | 439 | // As per the spec, the selected shipping option should initially be the last |
mathp | b77b873 | 2017-05-11 15:26:42 | [diff] [blame] | 440 | // one in the array that has its selected field set to true. If none are |
| 441 | // selected by the merchant, |selected_shipping_option_| stays nullptr. |
mathp | 151bd31 | 2017-04-03 21:07:24 | [diff] [blame] | 442 | auto selected_shipping_option_it = std::find_if( |
Jinho Bang | 6f591c7 | 2018-12-05 09:26:43 | [diff] [blame] | 443 | details_->shipping_options->rbegin(), details_->shipping_options->rend(), |
mathp | 151bd31 | 2017-04-03 21:07:24 | [diff] [blame] | 444 | [](const payments::mojom::PaymentShippingOptionPtr& element) { |
| 445 | return element->selected; |
| 446 | }); |
Jinho Bang | 6f591c7 | 2018-12-05 09:26:43 | [diff] [blame] | 447 | if (selected_shipping_option_it != details_->shipping_options->rend()) { |
mathp | 151bd31 | 2017-04-03 21:07:24 | [diff] [blame] | 448 | selected_shipping_option_ = selected_shipping_option_it->get(); |
| 449 | } |
| 450 | } |
| 451 | |
mathp | 151bd31 | 2017-04-03 21:07:24 | [diff] [blame] | 452 | void PaymentRequestSpec::NotifyOnSpecUpdated() { |
| 453 | for (auto& observer : observers_) |
| 454 | observer.OnSpecUpdated(); |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 455 | } |
| 456 | |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 457 | CurrencyFormatter* PaymentRequestSpec::GetOrCreateCurrencyFormatter( |
| 458 | const std::string& currency_code, |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 459 | const std::string& locale_name) { |
Anthony Vallee-Dubois | 080d5b7 | 2017-05-11 22:34:04 | [diff] [blame] | 460 | // Create a currency formatter for |currency_code|, or if already created |
| 461 | // return the cached version. |
| 462 | std::pair<std::map<std::string, CurrencyFormatter>::iterator, bool> |
| 463 | emplace_result = currency_formatters_.emplace( |
| 464 | std::piecewise_construct, std::forward_as_tuple(currency_code), |
Jinho Bang | 26b0ea4 | 2018-05-24 01:09:04 | [diff] [blame] | 465 | std::forward_as_tuple(currency_code, locale_name)); |
Anthony Vallee-Dubois | 080d5b7 | 2017-05-11 22:34:04 | [diff] [blame] | 466 | |
| 467 | return &(emplace_result.first->second); |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 468 | } |
| 469 | |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 470 | } // namespace payments |