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