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