diff options
Diffstat (limited to 'chromium/components/payments/content/payment_request_spec.cc')
-rw-r--r-- | chromium/components/payments/content/payment_request_spec.cc | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/chromium/components/payments/content/payment_request_spec.cc b/chromium/components/payments/content/payment_request_spec.cc new file mode 100644 index 00000000000..6fbfc5f63cd --- /dev/null +++ b/chromium/components/payments/content/payment_request_spec.cc @@ -0,0 +1,220 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/payments/content/payment_request_spec.h" + +#include <utility> + +#include "base/logging.h" +#include "components/payments/core/payment_method_data.h" +#include "components/payments/core/payment_request_data_util.h" + +namespace payments { + +namespace { + +// Returns the card network name associated with a given BasicCardNetwork. Names +// are inspired by https://www.w3.org/Payments/card-network-ids. +std::string GetBasicCardNetworkName(const mojom::BasicCardNetwork& network) { + switch (network) { + case mojom::BasicCardNetwork::AMEX: + return "amex"; + case mojom::BasicCardNetwork::DINERS: + return "diners"; + case mojom::BasicCardNetwork::DISCOVER: + return "discover"; + case mojom::BasicCardNetwork::JCB: + return "jcb"; + case mojom::BasicCardNetwork::MASTERCARD: + return "mastercard"; + case mojom::BasicCardNetwork::MIR: + return "mir"; + case mojom::BasicCardNetwork::UNIONPAY: + return "unionpay"; + case mojom::BasicCardNetwork::VISA: + return "visa"; + } + NOTREACHED(); + return std::string(); +} + +} // namespace + +const char kBasicCardMethodName[] = "basic-card"; + +PaymentRequestSpec::PaymentRequestSpec( + mojom::PaymentOptionsPtr options, + mojom::PaymentDetailsPtr details, + std::vector<mojom::PaymentMethodDataPtr> method_data, + Observer* observer, + const std::string& app_locale) + : options_(std::move(options)), + details_(std::move(details)), + app_locale_(app_locale), + selected_shipping_option_(nullptr), + observer_for_testing_(nullptr) { + if (observer) + AddObserver(observer); + UpdateSelectedShippingOption(); + PopulateValidatedMethodData(method_data); +} +PaymentRequestSpec::~PaymentRequestSpec() {} + +void PaymentRequestSpec::UpdateWith(mojom::PaymentDetailsPtr details) { + details_ = std::move(details); + // We reparse the |details_| and update the observers. + UpdateSelectedShippingOption(); + NotifyOnSpecUpdated(); +} + +void PaymentRequestSpec::AddObserver(Observer* observer) { + CHECK(observer); + observers_.AddObserver(observer); +} + +void PaymentRequestSpec::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +bool PaymentRequestSpec::request_shipping() const { + return options_->request_shipping; +} +bool PaymentRequestSpec::request_payer_name() const { + return options_->request_payer_name; +} +bool PaymentRequestSpec::request_payer_phone() const { + return options_->request_payer_phone; +} +bool PaymentRequestSpec::request_payer_email() const { + return options_->request_payer_email; +} + +PaymentShippingType PaymentRequestSpec::shipping_type() const { + // Transform Mojo-specific enum into platform-agnostic equivalent. + switch (options_->shipping_type) { + case mojom::PaymentShippingType::DELIVERY: + return PaymentShippingType::DELIVERY; + case payments::mojom::PaymentShippingType::PICKUP: + return PaymentShippingType::PICKUP; + case payments::mojom::PaymentShippingType::SHIPPING: + return PaymentShippingType::SHIPPING; + default: + NOTREACHED(); + } + // Needed for compilation on some platforms. + return PaymentShippingType::SHIPPING; +} + +bool PaymentRequestSpec::IsMethodSupportedThroughBasicCard( + const std::string& method_name) { + return basic_card_specified_networks_.count(method_name) > 0; +} + +base::string16 PaymentRequestSpec::GetFormattedCurrencyAmount( + const std::string& amount) { + CurrencyFormatter* formatter = GetOrCreateCurrencyFormatter( + details_->total->amount->currency, + details_->total->amount->currency_system, app_locale_); + return formatter->Format(amount); +} + +std::string PaymentRequestSpec::GetFormattedCurrencyCode() { + CurrencyFormatter* formatter = GetOrCreateCurrencyFormatter( + details_->total->amount->currency, + details_->total->amount->currency_system, app_locale_); + + return formatter->formatted_currency_code(); +} + +void PaymentRequestSpec::StartWaitingForUpdateWith( + PaymentRequestSpec::UpdateReason reason) { + for (auto& observer : observers_) { + observer.OnStartUpdating(reason); + } +} + +void PaymentRequestSpec::PopulateValidatedMethodData( + const std::vector<mojom::PaymentMethodDataPtr>& method_data_mojom) { + if (method_data_mojom.empty()) { + LOG(ERROR) << "Invalid payment methods or data"; + NotifyOnInvalidSpecProvided(); + return; + } + + std::vector<PaymentMethodData> method_data_vector; + method_data_vector.reserve(method_data_mojom.size()); + for (const mojom::PaymentMethodDataPtr& method_data_entry : + method_data_mojom) { + PaymentMethodData method_data; + method_data.supported_methods = method_data_entry->supported_methods; + // Transfer the supported basic card networks. + std::vector<std::string> supported_networks; + for (const mojom::BasicCardNetwork& network : + method_data_entry->supported_networks) { + supported_networks.push_back(GetBasicCardNetworkName(network)); + } + method_data.supported_networks = std::move(supported_networks); + + // TODO(crbug.com/708603): Add browser-side support for + // |method_data.supported_types|. + method_data_vector.push_back(std::move(method_data)); + } + + if (!data_util::ParseBasicCardSupportedNetworks( + method_data_vector, &supported_card_networks_, + &basic_card_specified_networks_)) { + LOG(ERROR) << "Invalid payment methods or data"; + NotifyOnInvalidSpecProvided(); + return; + } + supported_card_networks_set_.insert(supported_card_networks_.begin(), + supported_card_networks_.end()); +} + +void PaymentRequestSpec::UpdateSelectedShippingOption() { + if (!request_shipping()) + return; + + // As per the spec, the selected shipping option should initially be the last + // one in the array that has its selected field set to true. + auto selected_shipping_option_it = std::find_if( + details().shipping_options.rbegin(), details().shipping_options.rend(), + [](const payments::mojom::PaymentShippingOptionPtr& element) { + return element->selected; + }); + if (selected_shipping_option_it != details().shipping_options.rend()) { + selected_shipping_option_ = selected_shipping_option_it->get(); + } else { + // It's possible that there is no selected shipping option. + // TODO(crbug.com/710004): Show an error in this case. + selected_shipping_option_ = nullptr; + } +} + +void PaymentRequestSpec::NotifyOnInvalidSpecProvided() { + for (auto& observer : observers_) + observer.OnInvalidSpecProvided(); + if (observer_for_testing_) + observer_for_testing_->OnInvalidSpecProvided(); +} + +void PaymentRequestSpec::NotifyOnSpecUpdated() { + for (auto& observer : observers_) + observer.OnSpecUpdated(); + if (observer_for_testing_) + observer_for_testing_->OnSpecUpdated(); +} + +CurrencyFormatter* PaymentRequestSpec::GetOrCreateCurrencyFormatter( + const std::string& currency_code, + const std::string& currency_system, + const std::string& locale_name) { + if (!currency_formatter_) { + currency_formatter_.reset( + new CurrencyFormatter(currency_code, currency_system, locale_name)); + } + return currency_formatter_.get(); +} + +} // namespace payments |