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 | |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 24 | // Validates the |method_data| and fills |supported_card_networks_|, |
Randall Raymond | ec4e085 | 2017-07-14 01:30:45 | [diff] [blame] | 25 | // |supported_card_networks_set_|, |basic_card_specified_networks_|, |
| 26 | // and |url_payment_method_identifiers_|. |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 27 | void PopulateValidatedMethodData( |
| 28 | const std::vector<PaymentMethodData>& method_data_vector, |
| 29 | std::vector<std::string>* supported_card_networks, |
| 30 | std::set<std::string>* basic_card_specified_networks, |
| 31 | std::set<std::string>* supported_card_networks_set, |
| 32 | std::set<autofill::CreditCard::CardType>* supported_card_types_set, |
Randall Raymond | 6a85ba0ab | 2017-08-04 23:11:54 | [diff] [blame] | 33 | std::vector<GURL>* url_payment_method_identifiers, |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 34 | std::map<std::string, std::set<std::string>>* stringified_method_data) { |
Randall Raymond | ec4e085 | 2017-07-14 01:30:45 | [diff] [blame] | 35 | data_util::ParseSupportedMethods(method_data_vector, supported_card_networks, |
| 36 | basic_card_specified_networks, |
| 37 | url_payment_method_identifiers); |
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, |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 52 | std::map<std::string, std::set<std::string>>* stringified_method_data) { |
| 53 | std::vector<PaymentMethodData> method_data_vector; |
| 54 | method_data_vector.reserve(method_data_mojom.size()); |
| 55 | for (const mojom::PaymentMethodDataPtr& method_data_entry : |
| 56 | method_data_mojom) { |
| 57 | for (const std::string& method : method_data_entry->supported_methods) { |
| 58 | (*stringified_method_data)[method].insert( |
| 59 | method_data_entry->stringified_data); |
| 60 | } |
| 61 | |
Mohamad Ahmadi | f5544bb | 2017-09-01 21:48:22 | [diff] [blame] | 62 | method_data_vector.push_back(ConvertPaymentMethodData(method_data_entry)); |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 63 | } |
| 64 | |
| 65 | PopulateValidatedMethodData( |
| 66 | method_data_vector, supported_card_networks, |
| 67 | basic_card_specified_networks, supported_card_networks_set, |
Randall Raymond | ec4e085 | 2017-07-14 01:30:45 | [diff] [blame] | 68 | supported_card_types_set, url_payment_method_identifiers, |
| 69 | stringified_method_data); |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 70 | } |
| 71 | |
mathp | b65623a | 2017-04-06 02:01:54 | [diff] [blame] | 72 | } // namespace |
| 73 | |
mathp | 600bab5 | 2017-03-26 03:47:59 | [diff] [blame] | 74 | const char kBasicCardMethodName[] = "basic-card"; |
Mathieu Perreault | 627b97c | 2017-08-12 00:44:22 | [diff] [blame] | 75 | const char kGooglePayMethodName[] = "https://google.com/pay"; |
| 76 | const char kAndroidPayMethodName[] = "https://android.com/pay"; |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 77 | |
| 78 | PaymentRequestSpec::PaymentRequestSpec( |
| 79 | mojom::PaymentOptionsPtr options, |
| 80 | mojom::PaymentDetailsPtr details, |
| 81 | std::vector<mojom::PaymentMethodDataPtr> method_data, |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 82 | Observer* observer, |
| 83 | const std::string& app_locale) |
| 84 | : options_(std::move(options)), |
| 85 | details_(std::move(details)), |
gogerald | 7a0cc3e | 2017-09-19 03:35:48 | [diff] [blame^] | 86 | method_data_(std::move(method_data)), |
mathp | 151bd31e | 2017-04-03 21:07:24 | [diff] [blame] | 87 | app_locale_(app_locale), |
Anthony Vallee-Dubois | db030dd | 2017-05-19 18:04:51 | [diff] [blame] | 88 | selected_shipping_option_(nullptr) { |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 89 | if (observer) |
| 90 | AddObserver(observer); |
mathp | b77b873 | 2017-05-11 15:26:42 | [diff] [blame] | 91 | UpdateSelectedShippingOption(/*after_update=*/false); |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 92 | PopulateValidatedMethodData( |
gogerald | 7a0cc3e | 2017-09-19 03:35:48 | [diff] [blame^] | 93 | method_data_, &supported_card_networks_, &basic_card_specified_networks_, |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 94 | &supported_card_networks_set_, &supported_card_types_set_, |
Randall Raymond | ec4e085 | 2017-07-14 01:30:45 | [diff] [blame] | 95 | &url_payment_method_identifiers_, &stringified_method_data_); |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 96 | } |
| 97 | PaymentRequestSpec::~PaymentRequestSpec() {} |
| 98 | |
mathp | 151bd31e | 2017-04-03 21:07:24 | [diff] [blame] | 99 | void PaymentRequestSpec::UpdateWith(mojom::PaymentDetailsPtr details) { |
| 100 | details_ = std::move(details); |
| 101 | // We reparse the |details_| and update the observers. |
mathp | b77b873 | 2017-05-11 15:26:42 | [diff] [blame] | 102 | UpdateSelectedShippingOption(/*after_update=*/true); |
mathp | 151bd31e | 2017-04-03 21:07:24 | [diff] [blame] | 103 | NotifyOnSpecUpdated(); |
Anthony Vallee-Dubois | db030dd | 2017-05-19 18:04:51 | [diff] [blame] | 104 | current_update_reason_ = UpdateReason::NONE; |
mathp | 151bd31e | 2017-04-03 21:07:24 | [diff] [blame] | 105 | } |
| 106 | |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 107 | void PaymentRequestSpec::AddObserver(Observer* observer) { |
| 108 | CHECK(observer); |
| 109 | observers_.AddObserver(observer); |
| 110 | } |
| 111 | |
| 112 | void PaymentRequestSpec::RemoveObserver(Observer* observer) { |
| 113 | observers_.RemoveObserver(observer); |
| 114 | } |
| 115 | |
tmartino | 5f0912b8 | 2017-03-30 03:20:52 | [diff] [blame] | 116 | bool PaymentRequestSpec::request_shipping() const { |
| 117 | return options_->request_shipping; |
| 118 | } |
| 119 | bool PaymentRequestSpec::request_payer_name() const { |
| 120 | return options_->request_payer_name; |
| 121 | } |
| 122 | bool PaymentRequestSpec::request_payer_phone() const { |
| 123 | return options_->request_payer_phone; |
| 124 | } |
| 125 | bool PaymentRequestSpec::request_payer_email() const { |
| 126 | return options_->request_payer_email; |
| 127 | } |
| 128 | |
| 129 | PaymentShippingType PaymentRequestSpec::shipping_type() const { |
| 130 | // Transform Mojo-specific enum into platform-agnostic equivalent. |
| 131 | switch (options_->shipping_type) { |
| 132 | case mojom::PaymentShippingType::DELIVERY: |
| 133 | return PaymentShippingType::DELIVERY; |
| 134 | case payments::mojom::PaymentShippingType::PICKUP: |
| 135 | return PaymentShippingType::PICKUP; |
| 136 | case payments::mojom::PaymentShippingType::SHIPPING: |
| 137 | return PaymentShippingType::SHIPPING; |
| 138 | default: |
| 139 | NOTREACHED(); |
| 140 | } |
| 141 | // Needed for compilation on some platforms. |
| 142 | return PaymentShippingType::SHIPPING; |
| 143 | } |
| 144 | |
mathp | 600bab5 | 2017-03-26 03:47:59 | [diff] [blame] | 145 | bool PaymentRequestSpec::IsMethodSupportedThroughBasicCard( |
| 146 | const std::string& method_name) { |
| 147 | return basic_card_specified_networks_.count(method_name) > 0; |
| 148 | } |
| 149 | |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 150 | base::string16 PaymentRequestSpec::GetFormattedCurrencyAmount( |
Anthony Vallee-Dubois | 080d5b7 | 2017-05-11 22:34:04 | [diff] [blame] | 151 | const mojom::PaymentCurrencyAmountPtr& currency_amount) { |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 152 | CurrencyFormatter* formatter = GetOrCreateCurrencyFormatter( |
Anthony Vallee-Dubois | 080d5b7 | 2017-05-11 22:34:04 | [diff] [blame] | 153 | currency_amount->currency, currency_amount->currency_system, app_locale_); |
| 154 | return formatter->Format(currency_amount->value); |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 155 | } |
| 156 | |
Anthony Vallee-Dubois | 080d5b7 | 2017-05-11 22:34:04 | [diff] [blame] | 157 | std::string PaymentRequestSpec::GetFormattedCurrencyCode( |
| 158 | const mojom::PaymentCurrencyAmountPtr& currency_amount) { |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 159 | CurrencyFormatter* formatter = GetOrCreateCurrencyFormatter( |
Anthony Vallee-Dubois | 080d5b7 | 2017-05-11 22:34:04 | [diff] [blame] | 160 | currency_amount->currency, currency_amount->currency_system, app_locale_); |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 161 | |
| 162 | return formatter->formatted_currency_code(); |
| 163 | } |
| 164 | |
anthonyvd | 2f30baa1 | 2017-04-13 22:30:50 | [diff] [blame] | 165 | void PaymentRequestSpec::StartWaitingForUpdateWith( |
| 166 | PaymentRequestSpec::UpdateReason reason) { |
Anthony Vallee-Dubois | db030dd | 2017-05-19 18:04:51 | [diff] [blame] | 167 | current_update_reason_ = reason; |
anthonyvd | 2f30baa1 | 2017-04-13 22:30:50 | [diff] [blame] | 168 | for (auto& observer : observers_) { |
| 169 | observer.OnStartUpdating(reason); |
| 170 | } |
| 171 | } |
| 172 | |
Anthony Vallee-Dubois | 080d5b7 | 2017-05-11 22:34:04 | [diff] [blame] | 173 | bool PaymentRequestSpec::IsMixedCurrency() const { |
| 174 | const std::string& total_currency = details_->total->amount->currency; |
| 175 | return std::any_of(details_->display_items.begin(), |
| 176 | details_->display_items.end(), |
| 177 | [&total_currency](const mojom::PaymentItemPtr& item) { |
| 178 | return item->amount->currency != total_currency; |
| 179 | }); |
| 180 | } |
| 181 | |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 182 | const mojom::PaymentItemPtr& PaymentRequestSpec::GetTotal( |
| 183 | PaymentInstrument* selected_instrument) const { |
| 184 | const mojom::PaymentDetailsModifierPtr* modifier = |
| 185 | GetApplicableModifier(selected_instrument); |
gogerald | 7a0cc3e | 2017-09-19 03:35:48 | [diff] [blame^] | 186 | return modifier ? (*modifier)->total : details_->total; |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 187 | } |
rouslan | 69099768 | 2017-05-09 18:07:39 | [diff] [blame] | 188 | |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 189 | std::vector<const mojom::PaymentItemPtr*> PaymentRequestSpec::GetDisplayItems( |
| 190 | PaymentInstrument* selected_instrument) const { |
| 191 | std::vector<const mojom::PaymentItemPtr*> display_items; |
| 192 | const mojom::PaymentDetailsModifierPtr* modifier = |
| 193 | GetApplicableModifier(selected_instrument); |
gogerald | 7a0cc3e | 2017-09-19 03:35:48 | [diff] [blame^] | 194 | for (const auto& item : details_->display_items) { |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 195 | display_items.push_back(&item); |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 196 | } |
mathp | 363735b | 2017-03-16 18:08:05 | [diff] [blame] | 197 | |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 198 | if (modifier) { |
| 199 | for (const auto& additional_item : (*modifier)->additional_display_items) { |
| 200 | display_items.push_back(&additional_item); |
| 201 | } |
| 202 | } |
| 203 | return display_items; |
| 204 | } |
Rouslan Solomakhin | 25d708b | 2017-06-23 17:12:03 | [diff] [blame] | 205 | |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 206 | const std::vector<mojom::PaymentShippingOptionPtr>& |
| 207 | PaymentRequestSpec::GetShippingOptions() const { |
gogerald | 7a0cc3e | 2017-09-19 03:35:48 | [diff] [blame^] | 208 | return details_->shipping_options; |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 209 | } |
| 210 | |
| 211 | const mojom::PaymentDetailsModifierPtr* |
| 212 | PaymentRequestSpec::GetApplicableModifier( |
| 213 | PaymentInstrument* selected_instrument) const { |
Mathieu Perreault | 51339b8 | 2017-07-20 17:06:05 | [diff] [blame] | 214 | if (!selected_instrument || |
| 215 | !base::FeatureList::IsEnabled(features::kWebPaymentsModifiers)) |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 216 | return nullptr; |
| 217 | |
gogerald | 7a0cc3e | 2017-09-19 03:35:48 | [diff] [blame^] | 218 | for (const auto& modifier : details_->modifiers) { |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 219 | std::vector<std::string> supported_networks; |
| 220 | std::set<autofill::CreditCard::CardType> supported_types; |
Randall Raymond | ec4e085 | 2017-07-14 01:30:45 | [diff] [blame] | 221 | // The following 4 are unused but required by PopulateValidatedMethodData. |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 222 | std::set<std::string> basic_card_specified_networks; |
| 223 | std::set<std::string> supported_card_networks_set; |
Randall Raymond | 6a85ba0ab | 2017-08-04 23:11:54 | [diff] [blame] | 224 | std::vector<GURL> url_payment_method_identifiers; |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 225 | std::map<std::string, std::set<std::string>> stringified_method_data; |
| 226 | PopulateValidatedMethodData( |
Mohamad Ahmadi | f5544bb | 2017-09-01 21:48:22 | [diff] [blame] | 227 | {ConvertPaymentMethodData(modifier->method_data)}, &supported_networks, |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 228 | &basic_card_specified_networks, &supported_card_networks_set, |
Randall Raymond | ec4e085 | 2017-07-14 01:30:45 | [diff] [blame] | 229 | &supported_types, &url_payment_method_identifiers, |
| 230 | &stringified_method_data); |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 231 | |
| 232 | if (selected_instrument->IsValidForModifier( |
Anthony Vallee-Dubois | 6fae047 | 2017-08-07 16:51:35 | [diff] [blame] | 233 | modifier->method_data->supported_methods, supported_networks, |
| 234 | supported_types, !modifier->method_data->supported_types.empty())) { |
Anthony Vallee-Dubois | 059d59a | 2017-07-07 15:05:49 | [diff] [blame] | 235 | return &modifier; |
| 236 | } |
| 237 | } |
| 238 | return nullptr; |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 239 | } |
| 240 | |
mathp | b77b873 | 2017-05-11 15:26:42 | [diff] [blame] | 241 | void PaymentRequestSpec::UpdateSelectedShippingOption(bool after_update) { |
mathp | 151bd31e | 2017-04-03 21:07:24 | [diff] [blame] | 242 | if (!request_shipping()) |
| 243 | return; |
| 244 | |
mathp | b77b873 | 2017-05-11 15:26:42 | [diff] [blame] | 245 | selected_shipping_option_ = nullptr; |
mathp | eb8892ff | 2017-05-04 18:42:55 | [diff] [blame] | 246 | selected_shipping_option_error_.clear(); |
gogerald | 7a0cc3e | 2017-09-19 03:35:48 | [diff] [blame^] | 247 | if (details_->shipping_options.empty()) { |
mathp | b77b873 | 2017-05-11 15:26:42 | [diff] [blame] | 248 | // No options are provided by the merchant. |
| 249 | if (after_update) { |
Mathieu Perreault | 2c1f319 | 2017-05-18 14:45:28 | [diff] [blame] | 250 | // This is after an update, which means that the selected address is not |
mathp | b77b873 | 2017-05-11 15:26:42 | [diff] [blame] | 251 | // supported. The merchant may have customized the error string, or a |
| 252 | // generic one is used. |
gogerald | 7a0cc3e | 2017-09-19 03:35:48 | [diff] [blame^] | 253 | if (!details_->error.empty()) { |
| 254 | selected_shipping_option_error_ = base::UTF8ToUTF16(details_->error); |
mathp | b77b873 | 2017-05-11 15:26:42 | [diff] [blame] | 255 | } else { |
Mathieu Perreault | 2c1f319 | 2017-05-18 14:45:28 | [diff] [blame] | 256 | // The generic error string depends on the shipping type. |
| 257 | switch (shipping_type()) { |
| 258 | case PaymentShippingType::DELIVERY: |
| 259 | selected_shipping_option_error_ = l10n_util::GetStringUTF16( |
| 260 | IDS_PAYMENTS_UNSUPPORTED_DELIVERY_ADDRESS); |
| 261 | break; |
| 262 | case PaymentShippingType::PICKUP: |
| 263 | selected_shipping_option_error_ = l10n_util::GetStringUTF16( |
| 264 | IDS_PAYMENTS_UNSUPPORTED_PICKUP_ADDRESS); |
| 265 | break; |
| 266 | case PaymentShippingType::SHIPPING: |
| 267 | selected_shipping_option_error_ = l10n_util::GetStringUTF16( |
| 268 | IDS_PAYMENTS_UNSUPPORTED_SHIPPING_ADDRESS); |
| 269 | break; |
| 270 | } |
mathp | b77b873 | 2017-05-11 15:26:42 | [diff] [blame] | 271 | } |
| 272 | } |
| 273 | return; |
| 274 | } |
| 275 | |
mathp | 151bd31e | 2017-04-03 21:07:24 | [diff] [blame] | 276 | // As per the spec, the selected shipping option should initially be the last |
mathp | b77b873 | 2017-05-11 15:26:42 | [diff] [blame] | 277 | // one in the array that has its selected field set to true. If none are |
| 278 | // selected by the merchant, |selected_shipping_option_| stays nullptr. |
mathp | 151bd31e | 2017-04-03 21:07:24 | [diff] [blame] | 279 | auto selected_shipping_option_it = std::find_if( |
gogerald | 7a0cc3e | 2017-09-19 03:35:48 | [diff] [blame^] | 280 | details_->shipping_options.rbegin(), details_->shipping_options.rend(), |
mathp | 151bd31e | 2017-04-03 21:07:24 | [diff] [blame] | 281 | [](const payments::mojom::PaymentShippingOptionPtr& element) { |
| 282 | return element->selected; |
| 283 | }); |
gogerald | 7a0cc3e | 2017-09-19 03:35:48 | [diff] [blame^] | 284 | if (selected_shipping_option_it != details_->shipping_options.rend()) { |
mathp | 151bd31e | 2017-04-03 21:07:24 | [diff] [blame] | 285 | selected_shipping_option_ = selected_shipping_option_it->get(); |
| 286 | } |
| 287 | } |
| 288 | |
mathp | 151bd31e | 2017-04-03 21:07:24 | [diff] [blame] | 289 | void PaymentRequestSpec::NotifyOnSpecUpdated() { |
| 290 | for (auto& observer : observers_) |
| 291 | observer.OnSpecUpdated(); |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 292 | } |
| 293 | |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 294 | CurrencyFormatter* PaymentRequestSpec::GetOrCreateCurrencyFormatter( |
| 295 | const std::string& currency_code, |
| 296 | const std::string& currency_system, |
| 297 | const std::string& locale_name) { |
Anthony Vallee-Dubois | 080d5b7 | 2017-05-11 22:34:04 | [diff] [blame] | 298 | // Create a currency formatter for |currency_code|, or if already created |
| 299 | // return the cached version. |
| 300 | std::pair<std::map<std::string, CurrencyFormatter>::iterator, bool> |
| 301 | emplace_result = currency_formatters_.emplace( |
| 302 | std::piecewise_construct, std::forward_as_tuple(currency_code), |
| 303 | std::forward_as_tuple(currency_code, currency_system, locale_name)); |
| 304 | |
| 305 | return &(emplace_result.first->second); |
mathp | c0d616a | 2017-03-15 14:09:33 | [diff] [blame] | 306 | } |
| 307 | |
mathp | f1a7a375 | 2017-03-15 11:23:37 | [diff] [blame] | 308 | } // namespace payments |