blob: f5362a8a3e8abb9da984d26b452d4742486a7756 [file] [log] [blame]
mathpf1a7a3752017-03-15 11:23:371// 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 Wennborgdf87046c2020-04-28 11:06:249#include "base/check.h"
Mathieu Perreault51339b82017-07-20 17:06:0510#include "base/feature_list.h"
Hans Wennborgdf87046c2020-04-28 11:06:2411#include "base/notreached.h"
Rouslan Solomakhinb26faa072019-08-19 14:42:2812#include "base/stl_util.h"
13#include "base/strings/string_util.h"
mathpeb8892ff2017-05-04 18:42:5514#include "base/strings/utf_string_conversions.h"
Rouslan Solomakhin2039a342020-05-21 19:21:0415#include "components/payments/content/payment_app.h"
Mohamad Ahmadif5544bb2017-09-01 21:48:2216#include "components/payments/content/payment_request_converter.h"
Mathieu Perreault51339b82017-07-20 17:06:0517#include "components/payments/core/features.h"
Rouslan Solomakhin85b10da2019-11-05 20:03:1718#include "components/payments/core/method_strings.h"
mathpb65623a2017-04-06 02:01:5419#include "components/payments/core/payment_method_data.h"
20#include "components/payments/core/payment_request_data_util.h"
Rouslan Solomakhinb26faa072019-08-19 14:42:2821#include "components/payments/core/payments_experimental_features.h"
mathpeb8892ff2017-05-04 18:42:5522#include "components/strings/grit/components_strings.h"
23#include "ui/base/l10n/l10n_util.h"
mathpf1a7a3752017-03-15 11:23:3724
25namespace payments {
26
mathpb65623a2017-04-06 02:01:5427namespace {
28
Rouslan Solomakhin4eea9bc22017-10-10 15:18:5129// Validates the |method_data| and fills the output parameters.
Anthony Vallee-Dubois059d59a2017-07-07 15:05:4930void 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 Raymond6a85ba0ab2017-08-04 23:11:5435 std::vector<GURL>* url_payment_method_identifiers,
Rouslan Solomakhin4eea9bc22017-10-10 15:18:5136 std::set<std::string>* payment_method_identifiers_set,
Anthony Vallee-Dubois059d59a2017-07-07 15:05:4937 std::map<std::string, std::set<std::string>>* stringified_method_data) {
Randall Raymondec4e0852017-07-14 01:30:4538 data_util::ParseSupportedMethods(method_data_vector, supported_card_networks,
39 basic_card_specified_networks,
Rouslan Solomakhin4eea9bc22017-10-10 15:18:5140 url_payment_method_identifiers,
41 payment_method_identifiers_set);
Anthony Vallee-Dubois059d59a2017-07-07 15:05:4942 supported_card_networks_set->insert(supported_card_networks->begin(),
43 supported_card_networks->end());
Anthony Vallee-Dubois059d59a2017-07-07 15:05:4944}
45
46void 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 Raymond6a85ba0ab2017-08-04 23:11:5451 std::vector<GURL>* url_payment_method_identifiers,
Rouslan Solomakhin4eea9bc22017-10-10 15:18:5152 std::set<std::string>* payment_method_identifiers_set,
Anthony Vallee-Dubois059d59a2017-07-07 15:05:4953 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 Bangd252ebf5b12018-07-18 00:00:5958 (*stringified_method_data)[method_data_entry->supported_method].insert(
59 method_data_entry->stringified_data);
Anthony Vallee-Dubois059d59a2017-07-07 15:05:4960
Mohamad Ahmadif5544bb2017-09-01 21:48:2261 method_data_vector.push_back(ConvertPaymentMethodData(method_data_entry));
Anthony Vallee-Dubois059d59a2017-07-07 15:05:4962 }
63
64 PopulateValidatedMethodData(
65 method_data_vector, supported_card_networks,
66 basic_card_specified_networks, supported_card_networks_set,
Rouslan Solomakhin8aca6642020-01-17 13:32:1667 url_payment_method_identifiers, payment_method_identifiers_set,
68 stringified_method_data);
Anthony Vallee-Dubois059d59a2017-07-07 15:05:4969}
70
Rouslan Solomakhinb26faa072019-08-19 14:42:2871std::string ToString(bool value) {
72 return value ? "true" : "false";
73}
74
mathpb65623a2017-04-06 02:01:5475} // namespace
76
mathpf1a7a3752017-03-15 11:23:3777PaymentRequestSpec::PaymentRequestSpec(
78 mojom::PaymentOptionsPtr options,
79 mojom::PaymentDetailsPtr details,
80 std::vector<mojom::PaymentMethodDataPtr> method_data,
DongJun Kim54690d52020-09-26 12:07:5481 base::WeakPtr<Observer> observer,
mathpc0d616a2017-03-15 14:09:3382 const std::string& app_locale)
83 : options_(std::move(options)),
84 details_(std::move(details)),
gogerald7a0cc3e2017-09-19 03:35:4885 method_data_(std::move(method_data)),
mathp151bd312017-04-03 21:07:2486 app_locale_(app_locale),
Rouslan Solomakhin9788d4b2019-04-09 13:10:2387 selected_shipping_option_(nullptr),
88 current_update_reason_(UpdateReason::NONE) {
mathpf1a7a3752017-03-15 11:23:3789 if (observer)
DongJun Kim54690d52020-09-26 12:07:5490 AddObserver(observer.get());
Rouslan Solomakhine1a935422019-04-15 21:48:3691 if (!details_->display_items)
92 details_->display_items = std::vector<mojom::PaymentItemPtr>();
Jinho Bang6f591c72018-12-05 09:26:4393 if (!details_->shipping_options)
94 details_->shipping_options = std::vector<mojom::PaymentShippingOptionPtr>();
Rouslan Solomakhine1a935422019-04-15 21:48:3695 if (!details_->modifiers)
96 details_->modifiers = std::vector<mojom::PaymentDetailsModifierPtr>();
mathpb77b8732017-05-11 15:26:4297 UpdateSelectedShippingOption(/*after_update=*/false);
Anthony Vallee-Dubois059d59a2017-07-07 15:05:4998 PopulateValidatedMethodData(
gogerald7a0cc3e2017-09-19 03:35:4899 method_data_, &supported_card_networks_, &basic_card_specified_networks_,
Rouslan Solomakhin8aca6642020-01-17 13:32:16100 &supported_card_networks_set_, &url_payment_method_identifiers_,
101 &payment_method_identifiers_set_, &stringified_method_data_);
Rouslan Solomakhinb26faa072019-08-19 14:42:28102
103 query_for_quota_ = stringified_method_data_;
Rouslan Solomakhin85b10da2019-11-05 20:03:17104 if (base::Contains(payment_method_identifiers_set_, methods::kBasicCard) &&
Rouslan Solomakhinb26faa072019-08-19 14:42:28105 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 }
mathpf1a7a3752017-03-15 11:23:37114}
115PaymentRequestSpec::~PaymentRequestSpec() {}
116
mathp151bd312017-04-03 21:07:24117void PaymentRequestSpec::UpdateWith(mojom::PaymentDetailsPtr details) {
Jinho Bang6f591c72018-12-05 09:26:43118 DCHECK(details_);
Rouslan Solomakhin9788d4b2019-04-09 13:10:23119 DCHECK(details_->total || details->total);
Jinho Bang6f591c72018-12-05 09:26:43120 if (details->total)
121 details_->total = std::move(details->total);
Rouslan Solomakhine1a935422019-04-15 21:48:36122 if (details->display_items)
Jinho Bang94ca2b102019-02-21 05:55:57123 details_->display_items = std::move(details->display_items);
Jinho Bang6f591c72018-12-05 09:26:43124 if (details->shipping_options)
125 details_->shipping_options = std::move(details->shipping_options);
Rouslan Solomakhine1a935422019-04-15 21:48:36126 if (details->modifiers)
Jinho Bang2a2035182019-02-21 07:57:56127 details_->modifiers = std::move(details->modifiers);
Jinho Bang6f591c72018-12-05 09:26:43128 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 Solomakhine1a935422019-04-15 21:48:36134 DCHECK(details_->total);
135 DCHECK(details_->display_items);
136 DCHECK(details_->shipping_options);
137 DCHECK(details_->modifiers);
Rouslan Solomakhina9ff9282017-10-31 21:58:05138 RecomputeSpecForDetails();
139}
140
Jinho Bang745898b2019-03-25 14:00:03141void PaymentRequestSpec::Retry(
142 mojom::PaymentValidationErrorsPtr validation_errors) {
143 if (!validation_errors)
Jinho Bang092e7162018-09-06 23:41:19144 return;
Jinho Bangcac8d9a02018-08-23 19:47:22145
Jinho Bang745898b2019-03-25 14:00:03146 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 Bangcac8d9a02018-08-23 19:47:22153 current_update_reason_ = UpdateReason::RETRY;
154 NotifyOnSpecUpdated();
155 current_update_reason_ = UpdateReason::NONE;
156}
157
158base::string16 PaymentRequestSpec::GetShippingAddressError(
159 autofill::ServerFieldType type) {
Jinho Bang47531aa2018-12-14 10:43:55160 if (!details_->shipping_address_errors)
Jinho Bangcac8d9a02018-08-23 19:47:22161 return base::string16();
162
163 if (type == autofill::ADDRESS_HOME_STREET_ADDRESS)
Jinho Bang47531aa2018-12-14 10:43:55164 return base::UTF8ToUTF16(details_->shipping_address_errors->address_line);
Jinho Bangcac8d9a02018-08-23 19:47:22165
166 if (type == autofill::ADDRESS_HOME_CITY)
Jinho Bang47531aa2018-12-14 10:43:55167 return base::UTF8ToUTF16(details_->shipping_address_errors->city);
Jinho Bangcac8d9a02018-08-23 19:47:22168
169 if (type == autofill::ADDRESS_HOME_COUNTRY)
Jinho Bang47531aa2018-12-14 10:43:55170 return base::UTF8ToUTF16(details_->shipping_address_errors->country);
Jinho Bangcac8d9a02018-08-23 19:47:22171
172 if (type == autofill::ADDRESS_HOME_DEPENDENT_LOCALITY)
Jinho Bang47531aa2018-12-14 10:43:55173 return base::UTF8ToUTF16(
174 details_->shipping_address_errors->dependent_locality);
Jinho Bangcac8d9a02018-08-23 19:47:22175
176 if (type == autofill::COMPANY_NAME)
Jinho Bang47531aa2018-12-14 10:43:55177 return base::UTF8ToUTF16(details_->shipping_address_errors->organization);
Jinho Bangcac8d9a02018-08-23 19:47:22178
179 if (type == autofill::PHONE_HOME_WHOLE_NUMBER)
Jinho Bang47531aa2018-12-14 10:43:55180 return base::UTF8ToUTF16(details_->shipping_address_errors->phone);
Jinho Bangcac8d9a02018-08-23 19:47:22181
182 if (type == autofill::ADDRESS_HOME_ZIP)
Jinho Bang47531aa2018-12-14 10:43:55183 return base::UTF8ToUTF16(details_->shipping_address_errors->postal_code);
Jinho Bangcac8d9a02018-08-23 19:47:22184
185 if (type == autofill::NAME_FULL)
Jinho Bang47531aa2018-12-14 10:43:55186 return base::UTF8ToUTF16(details_->shipping_address_errors->recipient);
Jinho Bangcac8d9a02018-08-23 19:47:22187
188 if (type == autofill::ADDRESS_HOME_STATE)
Jinho Bang47531aa2018-12-14 10:43:55189 return base::UTF8ToUTF16(details_->shipping_address_errors->region);
Jinho Bangcac8d9a02018-08-23 19:47:22190
191 if (type == autofill::ADDRESS_HOME_SORTING_CODE)
Jinho Bang47531aa2018-12-14 10:43:55192 return base::UTF8ToUTF16(details_->shipping_address_errors->sorting_code);
Jinho Bangcac8d9a02018-08-23 19:47:22193
194 return base::string16();
195}
196
197base::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
214bool PaymentRequestSpec::has_shipping_address_error() const {
Jinho Bang47531aa2018-12-14 10:43:55215 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 Bang47531aa2018-12-14 10:43:55225 details_->shipping_address_errors->sorting_code.empty());
Jinho Bangcac8d9a02018-08-23 19:47:22226}
227
228bool PaymentRequestSpec::has_payer_error() const {
229 return payer_errors_ &&
Jinho Bang7f19d892018-08-27 18:23:00230 (request_payer_email() || request_payer_name() ||
231 request_payer_phone()) &&
Jinho Bangcac8d9a02018-08-23 19:47:22232 !(payer_errors_->email.empty() && payer_errors_->name.empty() &&
233 payer_errors_->phone.empty());
234}
235
Rouslan Solomakhina9ff9282017-10-31 21:58:05236void PaymentRequestSpec::RecomputeSpecForDetails() {
Jinho Bang092e7162018-09-06 23:41:19237 // Reparse the |details_| and update the observers.
Rouslan Solomakhin9788d4b2019-04-09 13:10:23238 bool is_initialization =
239 current_update_reason_ == UpdateReason::INITIAL_PAYMENT_DETAILS;
240 UpdateSelectedShippingOption(/*after_update=*/!is_initialization);
Jinho Bang092e7162018-09-06 23:41:19241
mathp151bd312017-04-03 21:07:24242 NotifyOnSpecUpdated();
Rouslan Solomakhin9788d4b2019-04-09 13:10:23243
244 if (is_initialization)
245 NotifyInitialized();
246
Anthony Vallee-Duboisdb030dd2017-05-19 18:04:51247 current_update_reason_ = UpdateReason::NONE;
mathp151bd312017-04-03 21:07:24248}
249
mathpf1a7a3752017-03-15 11:23:37250void PaymentRequestSpec::AddObserver(Observer* observer) {
251 CHECK(observer);
252 observers_.AddObserver(observer);
253}
254
255void PaymentRequestSpec::RemoveObserver(Observer* observer) {
256 observers_.RemoveObserver(observer);
257}
258
Rouslan Solomakhin9788d4b2019-04-09 13:10:23259bool PaymentRequestSpec::IsInitialized() const {
260 return current_update_reason_ != UpdateReason::INITIAL_PAYMENT_DETAILS;
261}
262
tmartino5f0912b82017-03-30 03:20:52263bool PaymentRequestSpec::request_shipping() const {
264 return options_->request_shipping;
265}
266bool PaymentRequestSpec::request_payer_name() const {
267 return options_->request_payer_name;
268}
269bool PaymentRequestSpec::request_payer_phone() const {
270 return options_->request_payer_phone;
271}
272bool PaymentRequestSpec::request_payer_email() const {
273 return options_->request_payer_email;
274}
275
276PaymentShippingType 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
mathp600bab52017-03-26 03:47:59292bool PaymentRequestSpec::IsMethodSupportedThroughBasicCard(
293 const std::string& method_name) {
294 return basic_card_specified_networks_.count(method_name) > 0;
295}
296
mathpc0d616a2017-03-15 14:09:33297base::string16 PaymentRequestSpec::GetFormattedCurrencyAmount(
Anthony Vallee-Dubois080d5b72017-05-11 22:34:04298 const mojom::PaymentCurrencyAmountPtr& currency_amount) {
Jinho Bang26b0ea42018-05-24 01:09:04299 CurrencyFormatter* formatter =
300 GetOrCreateCurrencyFormatter(currency_amount->currency, app_locale_);
Anthony Vallee-Dubois080d5b72017-05-11 22:34:04301 return formatter->Format(currency_amount->value);
mathpc0d616a2017-03-15 14:09:33302}
303
Anthony Vallee-Dubois080d5b72017-05-11 22:34:04304std::string PaymentRequestSpec::GetFormattedCurrencyCode(
305 const mojom::PaymentCurrencyAmountPtr& currency_amount) {
Jinho Bang26b0ea42018-05-24 01:09:04306 CurrencyFormatter* formatter =
307 GetOrCreateCurrencyFormatter(currency_amount->currency, app_locale_);
mathpc0d616a2017-03-15 14:09:33308
309 return formatter->formatted_currency_code();
310}
311
anthonyvd2f30baa12017-04-13 22:30:50312void PaymentRequestSpec::StartWaitingForUpdateWith(
313 PaymentRequestSpec::UpdateReason reason) {
Anthony Vallee-Duboisdb030dd2017-05-19 18:04:51314 current_update_reason_ = reason;
anthonyvd2f30baa12017-04-13 22:30:50315 for (auto& observer : observers_) {
316 observer.OnStartUpdating(reason);
317 }
318}
319
Anthony Vallee-Dubois080d5b72017-05-11 22:34:04320bool PaymentRequestSpec::IsMixedCurrency() const {
Rouslan Solomakhine1a935422019-04-15 21:48:36321 DCHECK(details_->display_items);
Anthony Vallee-Dubois080d5b72017-05-11 22:34:04322 const std::string& total_currency = details_->total->amount->currency;
Rouslan Solomakhine1a935422019-04-15 21:48:36323 return std::any_of(details_->display_items->begin(),
324 details_->display_items->end(),
Anthony Vallee-Dubois080d5b72017-05-11 22:34:04325 [&total_currency](const mojom::PaymentItemPtr& item) {
326 return item->amount->currency != total_currency;
327 });
328}
329
Anthony Vallee-Dubois059d59a2017-07-07 15:05:49330const mojom::PaymentItemPtr& PaymentRequestSpec::GetTotal(
Rouslan Solomakhin5d15cb1f2019-11-11 18:11:39331 PaymentApp* selected_app) const {
Anthony Vallee-Dubois059d59a2017-07-07 15:05:49332 const mojom::PaymentDetailsModifierPtr* modifier =
Rouslan Solomakhin5d15cb1f2019-11-11 18:11:39333 GetApplicableModifier(selected_app);
Rouslan Solomakhin4ad48942018-02-26 17:21:15334 return modifier && (*modifier)->total ? (*modifier)->total : details_->total;
Anthony Vallee-Dubois059d59a2017-07-07 15:05:49335}
rouslan690997682017-05-09 18:07:39336
Anthony Vallee-Dubois059d59a2017-07-07 15:05:49337std::vector<const mojom::PaymentItemPtr*> PaymentRequestSpec::GetDisplayItems(
Rouslan Solomakhin5d15cb1f2019-11-11 18:11:39338 PaymentApp* selected_app) const {
Anthony Vallee-Dubois059d59a2017-07-07 15:05:49339 std::vector<const mojom::PaymentItemPtr*> display_items;
340 const mojom::PaymentDetailsModifierPtr* modifier =
Rouslan Solomakhin5d15cb1f2019-11-11 18:11:39341 GetApplicableModifier(selected_app);
Rouslan Solomakhine1a935422019-04-15 21:48:36342 DCHECK(details_->display_items);
343 for (const auto& item : *details_->display_items) {
Anthony Vallee-Dubois059d59a2017-07-07 15:05:49344 display_items.push_back(&item);
mathpf1a7a3752017-03-15 11:23:37345 }
mathp363735b2017-03-16 18:08:05346
Anthony Vallee-Dubois059d59a2017-07-07 15:05:49347 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 Solomakhin25d708b2017-06-23 17:12:03354
Anthony Vallee-Dubois059d59a2017-07-07 15:05:49355const std::vector<mojom::PaymentShippingOptionPtr>&
356PaymentRequestSpec::GetShippingOptions() const {
Jinho Bang6f591c72018-12-05 09:26:43357 DCHECK(details_->shipping_options);
358 return *details_->shipping_options;
Anthony Vallee-Dubois059d59a2017-07-07 15:05:49359}
360
Sahel Sharifyc8b2e0d2020-08-19 20:27:22361bool 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 Kim54690d52020-09-26 12:07:54369base::WeakPtr<PaymentRequestSpec> PaymentRequestSpec::AsWeakPtr() {
Rouslan Solomakhin75450a42020-09-24 18:44:22370 return weak_ptr_factory_.GetWeakPtr();
371}
372
Anthony Vallee-Dubois059d59a2017-07-07 15:05:49373const mojom::PaymentDetailsModifierPtr*
Rouslan Solomakhin5d15cb1f2019-11-11 18:11:39374PaymentRequestSpec::GetApplicableModifier(PaymentApp* selected_app) const {
375 if (!selected_app ||
Mathieu Perreault51339b82017-07-20 17:06:05376 !base::FeatureList::IsEnabled(features::kWebPaymentsModifiers))
Anthony Vallee-Dubois059d59a2017-07-07 15:05:49377 return nullptr;
378
Rouslan Solomakhine1a935422019-04-15 21:48:36379 DCHECK(details_->modifiers);
380 for (const auto& modifier : *details_->modifiers) {
gogerald6cf12fe2017-11-08 21:29:55381 std::set<std::string> supported_card_networks_set;
Randall Raymondec4e0852017-07-14 01:30:45382 // The following 4 are unused but required by PopulateValidatedMethodData.
Anthony Vallee-Dubois059d59a2017-07-07 15:05:49383 std::set<std::string> basic_card_specified_networks;
gogerald6cf12fe2017-11-08 21:29:55384 std::vector<std::string> supported_networks;
Randall Raymond6a85ba0ab2017-08-04 23:11:54385 std::vector<GURL> url_payment_method_identifiers;
Rouslan Solomakhin4eea9bc22017-10-10 15:18:51386 std::set<std::string> payment_method_identifiers_set;
Anthony Vallee-Dubois059d59a2017-07-07 15:05:49387 std::map<std::string, std::set<std::string>> stringified_method_data;
388 PopulateValidatedMethodData(
Mohamad Ahmadif5544bb2017-09-01 21:48:22389 {ConvertPaymentMethodData(modifier->method_data)}, &supported_networks,
Anthony Vallee-Dubois059d59a2017-07-07 15:05:49390 &basic_card_specified_networks, &supported_card_networks_set,
Rouslan Solomakhin8aca6642020-01-17 13:32:16391 &url_payment_method_identifiers, &payment_method_identifiers_set,
392 &stringified_method_data);
Anthony Vallee-Dubois059d59a2017-07-07 15:05:49393
Rouslan Solomakhin5d15cb1f2019-11-11 18:11:39394 if (selected_app->IsValidForModifier(
Jinho Bangd252ebf5b12018-07-18 00:00:59395 modifier->method_data->supported_method,
gogerald6cf12fe2017-11-08 21:29:55396 !modifier->method_data->supported_networks.empty(),
Rouslan Solomakhin8aca6642020-01-17 13:32:16397 supported_card_networks_set)) {
Anthony Vallee-Dubois059d59a2017-07-07 15:05:49398 return &modifier;
399 }
400 }
401 return nullptr;
mathpf1a7a3752017-03-15 11:23:37402}
403
mathpb77b8732017-05-11 15:26:42404void PaymentRequestSpec::UpdateSelectedShippingOption(bool after_update) {
Jinho Bang6f591c72018-12-05 09:26:43405 if (!request_shipping() || !details_->shipping_options)
mathp151bd312017-04-03 21:07:24406 return;
407
mathpb77b8732017-05-11 15:26:42408 selected_shipping_option_ = nullptr;
mathpeb8892ff2017-05-04 18:42:55409 selected_shipping_option_error_.clear();
Rouslan Solomakhindfcf1e7dc2019-02-28 18:43:23410 if (details_->shipping_options->empty() || !details_->error.empty()) {
Rouslan Solomakhin9788d4b2019-04-09 13:10:23411 // The merchant provided either no shipping options or an error message.
mathpb77b8732017-05-11 15:26:42412 if (after_update) {
Mathieu Perreault2c1f3192017-05-18 14:45:28413 // This is after an update, which means that the selected address is not
mathpb77b8732017-05-11 15:26:42414 // supported. The merchant may have customized the error string, or a
415 // generic one is used.
gogerald7a0cc3e2017-09-19 03:35:48416 if (!details_->error.empty()) {
417 selected_shipping_option_error_ = base::UTF8ToUTF16(details_->error);
mathpb77b8732017-05-11 15:26:42418 } else {
Mathieu Perreault2c1f3192017-05-18 14:45:28419 // 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 }
mathpb77b8732017-05-11 15:26:42434 }
435 }
436 return;
437 }
438
mathp151bd312017-04-03 21:07:24439 // As per the spec, the selected shipping option should initially be the last
mathpb77b8732017-05-11 15:26:42440 // 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.
mathp151bd312017-04-03 21:07:24442 auto selected_shipping_option_it = std::find_if(
Jinho Bang6f591c72018-12-05 09:26:43443 details_->shipping_options->rbegin(), details_->shipping_options->rend(),
mathp151bd312017-04-03 21:07:24444 [](const payments::mojom::PaymentShippingOptionPtr& element) {
445 return element->selected;
446 });
Jinho Bang6f591c72018-12-05 09:26:43447 if (selected_shipping_option_it != details_->shipping_options->rend()) {
mathp151bd312017-04-03 21:07:24448 selected_shipping_option_ = selected_shipping_option_it->get();
449 }
450}
451
mathp151bd312017-04-03 21:07:24452void PaymentRequestSpec::NotifyOnSpecUpdated() {
453 for (auto& observer : observers_)
454 observer.OnSpecUpdated();
mathpf1a7a3752017-03-15 11:23:37455}
456
mathpc0d616a2017-03-15 14:09:33457CurrencyFormatter* PaymentRequestSpec::GetOrCreateCurrencyFormatter(
458 const std::string& currency_code,
mathpc0d616a2017-03-15 14:09:33459 const std::string& locale_name) {
Anthony Vallee-Dubois080d5b72017-05-11 22:34:04460 // 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 Bang26b0ea42018-05-24 01:09:04465 std::forward_as_tuple(currency_code, locale_name));
Anthony Vallee-Dubois080d5b72017-05-11 22:34:04466
467 return &(emplace_result.first->second);
mathpc0d616a2017-03-15 14:09:33468}
469
mathpf1a7a3752017-03-15 11:23:37470} // namespace payments