OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "ios/chrome/browser/ui/payments/payment_request_coordinator.h" | 5 #import "ios/chrome/browser/ui/payments/payment_request_coordinator.h" |
6 | 6 |
7 #include <unordered_set> | 7 #include <unordered_set> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
11 #include "base/strings/sys_string_conversions.h" | 11 #include "base/strings/sys_string_conversions.h" |
12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
13 #include "components/autofill/core/browser/autofill_client.h" | 13 #include "components/autofill/core/browser/autofill_client.h" |
14 #include "components/autofill/core/browser/autofill_data_util.h" | 14 #include "components/autofill/core/browser/autofill_data_util.h" |
15 #include "components/autofill/core/browser/autofill_manager.h" | 15 #include "components/autofill/core/browser/autofill_manager.h" |
16 #include "components/autofill/core/browser/autofill_profile.h" | 16 #include "components/autofill/core/browser/autofill_profile.h" |
17 #include "components/autofill/core/browser/credit_card.h" | 17 #include "components/autofill/core/browser/credit_card.h" |
18 #include "components/autofill/core/browser/field_types.h" | 18 #include "components/autofill/core/browser/field_types.h" |
19 #include "components/autofill/core/browser/payments/full_card_request.h" | 19 #include "components/autofill/core/browser/payments/full_card_request.h" |
20 #include "components/autofill/core/browser/personal_data_manager.h" | 20 #include "components/autofill/core/browser/personal_data_manager.h" |
21 #include "components/autofill/core/browser/ui/card_unmask_prompt_controller_impl
.h" | 21 #include "components/autofill/core/browser/ui/card_unmask_prompt_controller_impl
.h" |
| 22 #include "components/payments/core/address_normalizer_impl.h" |
22 #include "components/payments/core/payment_address.h" | 23 #include "components/payments/core/payment_address.h" |
23 #include "components/payments/core/payment_request_data_util.h" | 24 #include "components/payments/core/payment_request_data_util.h" |
24 #include "components/signin/core/browser/signin_manager.h" | 25 #include "components/signin/core/browser/signin_manager.h" |
25 #include "components/strings/grit/components_strings.h" | 26 #include "components/strings/grit/components_strings.h" |
26 #include "ios/chrome/browser/application_context.h" | 27 #include "ios/chrome/browser/application_context.h" |
| 28 #include "ios/chrome/browser/autofill/validation_rules_storage_factory.h" |
27 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" | 29 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" |
28 #include "ios/chrome/browser/payments/payment_request.h" | 30 #include "ios/chrome/browser/payments/payment_request.h" |
29 #include "ios/chrome/browser/payments/payment_request_util.h" | 31 #include "ios/chrome/browser/payments/payment_request_util.h" |
30 #include "ios/chrome/browser/signin/signin_manager_factory.h" | 32 #include "ios/chrome/browser/signin/signin_manager_factory.h" |
31 #include "ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.h" | 33 #include "ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.h" |
| 34 #include "third_party/libaddressinput/chromium/chrome_metadata_source.h" |
| 35 #include "third_party/libaddressinput/chromium/chrome_storage_impl.h" |
32 #include "ui/base/l10n/l10n_util.h" | 36 #include "ui/base/l10n/l10n_util.h" |
33 | 37 |
34 #if !defined(__has_feature) || !__has_feature(objc_arc) | 38 #if !defined(__has_feature) || !__has_feature(objc_arc) |
35 #error "This file requires ARC support." | 39 #error "This file requires ARC support." |
36 #endif | 40 #endif |
37 | 41 |
38 namespace { | 42 namespace { |
39 using ::payments::data_util::GetBasicCardResponseFromAutofillCreditCard; | 43 using ::payments::data_util::GetBasicCardResponseFromAutofillCreditCard; |
40 using ::payments::data_util::GetPaymentAddressFromAutofillProfile; | 44 using ::payments::data_util::GetPaymentAddressFromAutofillProfile; |
41 } // namespace | 45 |
| 46 constexpr int kAddressNormalizationTimeoutSeconds = 5; |
| 47 |
| 48 // Receives notifications from the AddressNormalizer, and forwards the details |
| 49 // to a callback. This is needed as there is currently no way to know, when |
| 50 // the |payments::AddressNormalizer::Delegate| methods are called, which address |
| 51 // has been normalized (shipping or contact). The callback mechanism is needed |
| 52 // in order to keep track of which address this delegate was created for. |
| 53 class AddressNormalizerDelegate : public payments::AddressNormalizer::Delegate { |
| 54 public: |
| 55 // Block to be called with the profile information, once normalized. |
| 56 typedef void (^Callback)(const autofill::AutofillProfile&); |
| 57 |
| 58 AddressNormalizerDelegate() {} |
| 59 ~AddressNormalizerDelegate() override {} |
| 60 |
| 61 void SetCallback(Callback callback) { callback_ = callback; } |
| 62 |
| 63 // payments::AddressNormalizer::Delegate: |
| 64 void OnAddressNormalized( |
| 65 const autofill::AutofillProfile& normalizedProfile) override { |
| 66 DCHECK(callback_); |
| 67 callback_(normalizedProfile); |
| 68 } |
| 69 |
| 70 // payments::AddressNormalizer::Delegate: |
| 71 void OnCouldNotNormalize(const autofill::AutofillProfile& profile) override { |
| 72 // Since the phone number is formatted in either case, this profile should |
| 73 // be used. |
| 74 DCHECK(callback_); |
| 75 callback_(profile); |
| 76 } |
| 77 |
| 78 private: |
| 79 Callback callback_ = nullptr; |
| 80 |
| 81 DISALLOW_COPY_AND_ASSIGN(AddressNormalizerDelegate); |
| 82 }; |
42 | 83 |
43 // The unmask prompt UI for Payment Request. | 84 // The unmask prompt UI for Payment Request. |
44 class PRCardUnmaskPromptViewBridge | 85 class PRCardUnmaskPromptViewBridge |
45 : public autofill::CardUnmaskPromptViewBridge { | 86 : public autofill::CardUnmaskPromptViewBridge { |
46 public: | 87 public: |
47 explicit PRCardUnmaskPromptViewBridge( | 88 PRCardUnmaskPromptViewBridge(autofill::CardUnmaskPromptController* controller, |
48 autofill::CardUnmaskPromptController* controller, | 89 UIViewController* base_view_controller) |
49 UIViewController* base_view_controller) | |
50 : autofill::CardUnmaskPromptViewBridge(controller), | 90 : autofill::CardUnmaskPromptViewBridge(controller), |
51 base_view_controller_(base_view_controller) {} | 91 base_view_controller_(base_view_controller) {} |
52 | 92 |
53 // autofill::CardUnmaskPromptView: | 93 // autofill::CardUnmaskPromptView: |
54 void Show() override { | 94 void Show() override { |
55 view_controller_.reset( | 95 view_controller_.reset( |
56 [[CardUnmaskPromptViewController alloc] initWithBridge:this]); | 96 [[CardUnmaskPromptViewController alloc] initWithBridge:this]); |
57 [base_view_controller_ presentViewController:view_controller_ | 97 [base_view_controller_ presentViewController:view_controller_ |
58 animated:YES | 98 animated:YES |
59 completion:nil]; | 99 completion:nil]; |
60 }; | 100 }; |
61 | 101 |
62 private: | 102 private: |
63 __weak UIViewController* base_view_controller_; | 103 __weak UIViewController* base_view_controller_; |
64 DISALLOW_COPY_AND_ASSIGN(PRCardUnmaskPromptViewBridge); | 104 DISALLOW_COPY_AND_ASSIGN(PRCardUnmaskPromptViewBridge); |
65 }; | 105 }; |
66 | 106 |
67 // Receives the full credit card details. Also displays the unmask prompt UI. | 107 // Receives the full credit card details. Also displays the unmask prompt UI. |
68 class FullCardRequester | 108 class FullCardRequester |
69 : public autofill::payments::FullCardRequest::ResultDelegate, | 109 : public autofill::payments::FullCardRequest::ResultDelegate, |
70 public autofill::payments::FullCardRequest::UIDelegate, | 110 public autofill::payments::FullCardRequest::UIDelegate, |
71 public base::SupportsWeakPtr<FullCardRequester> { | 111 public base::SupportsWeakPtr<FullCardRequester> { |
72 public: | 112 public: |
73 explicit FullCardRequester(PaymentRequestCoordinator* owner, | 113 FullCardRequester(PaymentRequestCoordinator* owner, |
74 UIViewController* base_view_controller, | 114 UIViewController* base_view_controller, |
75 ios::ChromeBrowserState* browser_state) | 115 ios::ChromeBrowserState* browser_state) |
76 : owner_(owner), | 116 : owner_(owner), |
77 base_view_controller_(base_view_controller), | 117 base_view_controller_(base_view_controller), |
78 unmask_controller_(browser_state->GetPrefs(), | 118 unmask_controller_(browser_state->GetPrefs(), |
79 browser_state->IsOffTheRecord()) {} | 119 browser_state->IsOffTheRecord()) {} |
80 | 120 |
81 void GetFullCard(autofill::CreditCard* card, | 121 void GetFullCard(autofill::CreditCard* card, |
82 autofill::AutofillManager* autofill_manager) { | 122 autofill::AutofillManager* autofill_manager) { |
83 DCHECK(card); | 123 DCHECK(card); |
84 DCHECK(autofill_manager); | 124 DCHECK(autofill_manager); |
85 autofill_manager->GetOrCreateFullCardRequest()->GetFullCard( | 125 autofill_manager->GetOrCreateFullCardRequest()->GetFullCard( |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 } | 160 } |
121 | 161 |
122 private: | 162 private: |
123 __weak PaymentRequestCoordinator* owner_; | 163 __weak PaymentRequestCoordinator* owner_; |
124 __weak UIViewController* base_view_controller_; | 164 __weak UIViewController* base_view_controller_; |
125 autofill::CardUnmaskPromptControllerImpl unmask_controller_; | 165 autofill::CardUnmaskPromptControllerImpl unmask_controller_; |
126 | 166 |
127 DISALLOW_COPY_AND_ASSIGN(FullCardRequester); | 167 DISALLOW_COPY_AND_ASSIGN(FullCardRequester); |
128 }; | 168 }; |
129 | 169 |
| 170 struct FullCard { |
| 171 autofill::CreditCard creditCard; |
| 172 base::string16 cvc; |
| 173 autofill::AutofillProfile billingAddress; |
| 174 }; |
| 175 |
| 176 } // namespace |
| 177 |
| 178 @interface PaymentRequestCoordinator () |
| 179 |
| 180 // Starts normalization of |profileToNormalize| (usually asynchronous). The |
| 181 // |delegate| will be notified on success/failure, and |
| 182 // |normalizationRequestPendingFlag| will be updated to NO when normalization |
| 183 // compleptes. |
| 184 - (void)normalizeProfile:(autofill::AutofillProfile*)profileToNormalize |
| 185 delegate:(AddressNormalizerDelegate*)delegate |
| 186 flag:(BOOL*)normalizationRequestPendingFlag; |
| 187 |
| 188 @end |
| 189 |
130 @implementation PaymentRequestCoordinator { | 190 @implementation PaymentRequestCoordinator { |
131 UINavigationController* _navigationController; | 191 UINavigationController* _navigationController; |
132 PaymentRequestViewController* _viewController; | 192 PaymentRequestViewController* _viewController; |
133 PaymentRequestErrorCoordinator* _errorCoordinator; | 193 PaymentRequestErrorCoordinator* _errorCoordinator; |
134 PaymentItemsDisplayCoordinator* _itemsDisplayCoordinator; | 194 PaymentItemsDisplayCoordinator* _itemsDisplayCoordinator; |
135 ShippingAddressSelectionCoordinator* _shippingAddressSelectionCoordinator; | 195 ShippingAddressSelectionCoordinator* _shippingAddressSelectionCoordinator; |
136 ShippingOptionSelectionCoordinator* _shippingOptionSelectionCoordinator; | 196 ShippingOptionSelectionCoordinator* _shippingOptionSelectionCoordinator; |
137 PaymentMethodSelectionCoordinator* _methodSelectionCoordinator; | 197 PaymentMethodSelectionCoordinator* _methodSelectionCoordinator; |
138 | 198 |
139 // Receiver of the full credit card details. Also displays the unmask prompt | 199 // Receiver of the full credit card details. Also displays the unmask prompt |
140 // UI. | 200 // UI. |
141 std::unique_ptr<FullCardRequester> _fullCardRequester; | 201 std::unique_ptr<FullCardRequester> _fullCardRequester; |
142 | 202 |
143 // The selected shipping address, pending approval from the page. | 203 // The selected shipping address, pending approval from the page. |
144 autofill::AutofillProfile* _pendingShippingAddress; | 204 autofill::AutofillProfile* _pendingShippingAddress; |
| 205 |
| 206 // The address normalizer, to normalize contact & shipping addresses. Also, |
| 207 // delegates to handle callbacks for normalization of each address. |
| 208 std::unique_ptr<payments::AddressNormalizer> _addressNormalizer; |
| 209 AddressNormalizerDelegate _contactAddressNormalizerDelegate; |
| 210 AddressNormalizerDelegate _shippingAddressNormalizerDelegate; |
| 211 AddressNormalizerDelegate _billingAddressNormalizerDelegate; |
| 212 |
| 213 // Member variables to keep track of which operations are still pending. |
| 214 BOOL _contactAddressNormalizationPending; |
| 215 BOOL _shippingAddressNormalizationPending; |
| 216 BOOL _fullCardRequestPending; |
| 217 BOOL _billingAddressNormalizationPending; |
| 218 |
| 219 // Storage for the full card. |
| 220 FullCard _fullCard; |
145 } | 221 } |
146 | 222 |
147 @synthesize paymentRequest = _paymentRequest; | 223 @synthesize paymentRequest = _paymentRequest; |
148 @synthesize autofillManager = _autofillManager; | 224 @synthesize autofillManager = _autofillManager; |
149 @synthesize browserState = _browserState; | 225 @synthesize browserState = _browserState; |
150 @synthesize pageFavicon = _pageFavicon; | 226 @synthesize pageFavicon = _pageFavicon; |
151 @synthesize pageTitle = _pageTitle; | 227 @synthesize pageTitle = _pageTitle; |
152 @synthesize pageHost = _pageHost; | 228 @synthesize pageHost = _pageHost; |
153 @synthesize delegate = _delegate; | 229 @synthesize delegate = _delegate; |
154 | 230 |
| 231 - (void)startAddressNormalizer { |
| 232 autofill::PersonalDataManager* personalDataManager = |
| 233 _paymentRequest->GetPersonalDataManager(); |
| 234 |
| 235 std::unique_ptr<i18n::addressinput::Source> addressNormalizerSource = |
| 236 base::MakeUnique<autofill::ChromeMetadataSource>( |
| 237 I18N_ADDRESS_VALIDATION_DATA_URL, |
| 238 personalDataManager->GetURLRequestContextGetter()); |
| 239 |
| 240 std::unique_ptr<i18n::addressinput::Storage> addressNormalizerStorage = |
| 241 autofill::ValidationRulesStorageFactory::CreateStorage(); |
| 242 |
| 243 _addressNormalizer.reset(new payments::AddressNormalizerImpl( |
| 244 std::move(addressNormalizerSource), std::move(addressNormalizerStorage))); |
| 245 |
| 246 // Kickoff the process of loading the rules (which is asynchronous) for each |
| 247 // profile's country, to get faster address normalization later. |
| 248 for (const autofill::AutofillProfile* profile : |
| 249 personalDataManager->GetProfilesToSuggest()) { |
| 250 std::string countryCode = |
| 251 base::UTF16ToUTF8(profile->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY)); |
| 252 if (autofill::data_util::IsValidCountryCode(countryCode)) { |
| 253 _addressNormalizer->LoadRulesForRegion(countryCode); |
| 254 } |
| 255 } |
| 256 } |
| 257 |
155 - (void)start { | 258 - (void)start { |
156 _viewController = [[PaymentRequestViewController alloc] | 259 _viewController = [[PaymentRequestViewController alloc] |
157 initWithPaymentRequest:_paymentRequest]; | 260 initWithPaymentRequest:_paymentRequest]; |
158 [_viewController setPageFavicon:_pageFavicon]; | 261 [_viewController setPageFavicon:_pageFavicon]; |
159 [_viewController setPageTitle:_pageTitle]; | 262 [_viewController setPageTitle:_pageTitle]; |
160 [_viewController setPageHost:_pageHost]; | 263 [_viewController setPageHost:_pageHost]; |
161 [_viewController setDelegate:self]; | 264 [_viewController setDelegate:self]; |
162 DCHECK(_browserState); | 265 DCHECK(_browserState); |
163 const SigninManager* signinManager = | 266 const SigninManager* signinManager = |
164 ios::SigninManagerFactory::GetForBrowserStateIfExists(_browserState); | 267 ios::SigninManagerFactory::GetForBrowserStateIfExists(_browserState); |
165 if (signinManager && signinManager->IsAuthenticated()) { | 268 if (signinManager && signinManager->IsAuthenticated()) { |
166 NSString* accountName = base::SysUTF8ToNSString( | 269 NSString* accountName = base::SysUTF8ToNSString( |
167 signinManager->GetAuthenticatedAccountInfo().email); | 270 signinManager->GetAuthenticatedAccountInfo().email); |
168 [_viewController setAuthenticatedAccountName:accountName]; | 271 [_viewController setAuthenticatedAccountName:accountName]; |
169 } | 272 } |
170 [_viewController loadModel]; | 273 [_viewController loadModel]; |
171 | 274 |
172 _navigationController = [[UINavigationController alloc] | 275 _navigationController = [[UINavigationController alloc] |
173 initWithRootViewController:_viewController]; | 276 initWithRootViewController:_viewController]; |
174 [_navigationController setNavigationBarHidden:YES]; | 277 [_navigationController setNavigationBarHidden:YES]; |
175 | 278 |
176 [[self baseViewController] presentViewController:_navigationController | 279 [[self baseViewController] presentViewController:_navigationController |
177 animated:YES | 280 animated:YES |
178 completion:nil]; | 281 completion:nil]; |
| 282 |
| 283 [self startAddressNormalizer]; |
179 } | 284 } |
180 | 285 |
181 - (void)stop { | 286 - (void)stop { |
182 [[_navigationController presentingViewController] | 287 [[_navigationController presentingViewController] |
183 dismissViewControllerAnimated:YES | 288 dismissViewControllerAnimated:YES |
184 completion:nil]; | 289 completion:nil]; |
185 [_itemsDisplayCoordinator stop]; | 290 [_itemsDisplayCoordinator stop]; |
186 _itemsDisplayCoordinator = nil; | 291 _itemsDisplayCoordinator = nil; |
187 [_shippingAddressSelectionCoordinator stop]; | 292 [_shippingAddressSelectionCoordinator stop]; |
188 _shippingAddressSelectionCoordinator = nil; | 293 _shippingAddressSelectionCoordinator = nil; |
189 [_shippingOptionSelectionCoordinator stop]; | 294 [_shippingOptionSelectionCoordinator stop]; |
190 _shippingOptionSelectionCoordinator = nil; | 295 _shippingOptionSelectionCoordinator = nil; |
191 [_methodSelectionCoordinator stop]; | 296 [_methodSelectionCoordinator stop]; |
192 _methodSelectionCoordinator = nil; | 297 _methodSelectionCoordinator = nil; |
193 [_errorCoordinator stop]; | 298 [_errorCoordinator stop]; |
194 _errorCoordinator = nil; | 299 _errorCoordinator = nil; |
195 _viewController = nil; | 300 _viewController = nil; |
196 _navigationController = nil; | 301 _navigationController = nil; |
197 } | 302 } |
198 | 303 |
199 - (void)sendPaymentResponse { | 304 - (void)normalizeProfile:(autofill::AutofillProfile*)profileToNormalize |
| 305 delegate:(AddressNormalizerDelegate*)delegate |
| 306 flag:(BOOL*)normalizationRequestPendingFlag { |
| 307 DCHECK(normalizationRequestPendingFlag); |
| 308 |
| 309 __weak PaymentRequestCoordinator* weakSelf = self; |
| 310 |
| 311 delegate->SetCallback(^(const autofill::AutofillProfile& normalizedProfile) { |
| 312 // Check that PaymentRequestCoordinator still exists as |profileToNormalize| |
| 313 // and |normalizationRequestPendingFlag| are member variables of that |
| 314 // object. |
| 315 if (!weakSelf) |
| 316 return; |
| 317 |
| 318 *profileToNormalize = normalizedProfile; |
| 319 *normalizationRequestPendingFlag = NO; |
| 320 [weakSelf sendPaymentResponseIfAllAsyncCallsCompleted]; |
| 321 }); |
| 322 |
| 323 std::string country_code = base::UTF16ToUTF8( |
| 324 profileToNormalize->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY)); |
| 325 if (!autofill::data_util::IsValidCountryCode(country_code)) { |
| 326 country_code = base::SysNSStringToUTF8( |
| 327 [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode]); |
| 328 DCHECK(autofill::data_util::IsValidCountryCode(country_code)); |
| 329 } |
| 330 _addressNormalizer->StartAddressNormalization( |
| 331 *profileToNormalize, country_code, kAddressNormalizationTimeoutSeconds, |
| 332 delegate); |
| 333 } |
| 334 |
| 335 - (void)requestFullCardAndNormalizeProfiles { |
| 336 // Set these before starting any potentially asynchronous calls, to ensure we |
| 337 // wait for completion of all operations before proceeding. |
| 338 _contactAddressNormalizationPending = YES; |
| 339 _shippingAddressNormalizationPending = _paymentRequest->request_shipping(); |
| 340 _fullCardRequestPending = YES; |
| 341 |
200 DCHECK(_paymentRequest->selected_credit_card()); | 342 DCHECK(_paymentRequest->selected_credit_card()); |
201 autofill::CreditCard* card = _paymentRequest->selected_credit_card(); | 343 autofill::CreditCard* card = _paymentRequest->selected_credit_card(); |
202 _fullCardRequester = base::MakeUnique<FullCardRequester>( | 344 _fullCardRequester = base::MakeUnique<FullCardRequester>( |
203 self, _navigationController, _browserState); | 345 self, _navigationController, _browserState); |
204 _fullCardRequester->GetFullCard(card, _autofillManager); | 346 _fullCardRequester->GetFullCard(card, _autofillManager); |
| 347 |
| 348 if (_paymentRequest->request_shipping()) { |
| 349 [self normalizeProfile:_paymentRequest->selected_shipping_profile() |
| 350 delegate:&_shippingAddressNormalizerDelegate |
| 351 flag:&_shippingAddressNormalizationPending]; |
| 352 } |
| 353 |
| 354 [self normalizeProfile:_paymentRequest->selected_contact_profile() |
| 355 delegate:&_contactAddressNormalizerDelegate |
| 356 flag:&_contactAddressNormalizationPending]; |
205 } | 357 } |
206 | 358 |
207 - (void)fullCardRequestDidSucceedWithCard:(const autofill::CreditCard&)card | 359 - (void)fullCardRequestDidSucceedWithCard:(const autofill::CreditCard&)card |
208 CVC:(const base::string16&)cvc { | 360 CVC:(const base::string16&)cvc { |
209 web::PaymentResponse paymentResponse; | |
210 | |
211 // If the merchant specified the card network as part of the "basic-card" | |
212 // payment method, return "basic-card" as the method_name. Otherwise, return | |
213 // the name of the network directly. | |
214 std::string issuer_network = | |
215 autofill::data_util::GetPaymentRequestData(card.network()) | |
216 .basic_card_issuer_network; | |
217 paymentResponse.method_name = | |
218 _paymentRequest->basic_card_specified_networks().find(issuer_network) != | |
219 _paymentRequest->basic_card_specified_networks().end() | |
220 ? base::ASCIIToUTF16("basic-card") | |
221 : base::ASCIIToUTF16(issuer_network); | |
222 | |
223 // Get the billing address | |
224 autofill::AutofillProfile billingAddress; | |
225 | |
226 // TODO(crbug.com/714768): Make sure the billing address is set and valid | 361 // TODO(crbug.com/714768): Make sure the billing address is set and valid |
227 // before getting here. Once the bug is addressed, there will be no need to | 362 // before getting here. Once the bug is addressed, there will be no need to |
228 // copy the address, *billing_address_ptr can be used to get the basic card | 363 // copy the address, *billing_address_ptr can be used to get the basic card |
229 // response. | 364 // response. |
230 if (!card.billing_address_id().empty()) { | 365 if (!card.billing_address_id().empty()) { |
231 autofill::AutofillProfile* billingAddressPtr = | 366 autofill::AutofillProfile* billingAddress = |
232 autofill::PersonalDataManager::GetProfileFromProfilesByGUID( | 367 autofill::PersonalDataManager::GetProfileFromProfilesByGUID( |
233 card.billing_address_id(), _paymentRequest->billing_profiles()); | 368 card.billing_address_id(), _paymentRequest->billing_profiles()); |
234 if (billingAddressPtr) | 369 if (billingAddress) { |
235 billingAddress = *billingAddressPtr; | 370 _fullCard.billingAddress = *billingAddress; |
| 371 _billingAddressNormalizationPending = YES; |
| 372 |
| 373 [self normalizeProfile:&_fullCard.billingAddress |
| 374 delegate:&_billingAddressNormalizerDelegate |
| 375 flag:&_billingAddressNormalizationPending]; |
| 376 } |
236 } | 377 } |
237 | 378 |
238 paymentResponse.details = GetBasicCardResponseFromAutofillCreditCard( | 379 _fullCard.creditCard = card; |
239 card, cvc, billingAddress, | 380 _fullCard.cvc = cvc; |
240 GetApplicationContext()->GetApplicationLocale()); | 381 _fullCardRequestPending = NO; |
241 | |
242 if (_paymentRequest->request_shipping()) { | |
243 autofill::AutofillProfile* shippingAddress = | |
244 _paymentRequest->selected_shipping_profile(); | |
245 // TODO(crbug.com/602666): User should get here only if they have selected | |
246 // a shipping address. | |
247 DCHECK(shippingAddress); | |
248 paymentResponse.shipping_address = GetPaymentAddressFromAutofillProfile( | |
249 *shippingAddress, GetApplicationContext()->GetApplicationLocale()); | |
250 | |
251 web::PaymentShippingOption* shippingOption = | |
252 _paymentRequest->selected_shipping_option(); | |
253 DCHECK(shippingOption); | |
254 paymentResponse.shipping_option = shippingOption->id; | |
255 } | |
256 | |
257 if (_paymentRequest->request_payer_name()) { | |
258 autofill::AutofillProfile* contactInfo = | |
259 _paymentRequest->selected_contact_profile(); | |
260 // TODO(crbug.com/602666): User should get here only if they have selected | |
261 // a contact info. | |
262 DCHECK(contactInfo); | |
263 paymentResponse.payer_name = | |
264 contactInfo->GetInfo(autofill::AutofillType(autofill::NAME_FULL), | |
265 GetApplicationContext()->GetApplicationLocale()); | |
266 } | |
267 | |
268 if (_paymentRequest->request_payer_email()) { | |
269 autofill::AutofillProfile* contactInfo = | |
270 _paymentRequest->selected_contact_profile(); | |
271 // TODO(crbug.com/602666): User should get here only if they have selected | |
272 // a contact info. | |
273 DCHECK(contactInfo); | |
274 paymentResponse.payer_email = | |
275 contactInfo->GetRawInfo(autofill::EMAIL_ADDRESS); | |
276 } | |
277 | |
278 if (_paymentRequest->request_payer_phone()) { | |
279 autofill::AutofillProfile* contactInfo = | |
280 _paymentRequest->selected_contact_profile(); | |
281 // TODO(crbug.com/602666): User should get here only if they have selected | |
282 // a contact info. | |
283 DCHECK(contactInfo); | |
284 paymentResponse.payer_phone = | |
285 contactInfo->GetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER); | |
286 } | |
287 | 382 |
288 _viewController.view.userInteractionEnabled = NO; | 383 _viewController.view.userInteractionEnabled = NO; |
289 [_viewController setPending:YES]; | 384 [_viewController setPending:YES]; |
290 [_viewController loadModel]; | 385 [_viewController loadModel]; |
291 [[_viewController collectionView] reloadData]; | 386 [[_viewController collectionView] reloadData]; |
292 | 387 |
293 [_delegate paymentRequestCoordinator:self | 388 [self sendPaymentResponseIfAllAsyncCallsCompleted]; |
294 didConfirmWithPaymentResponse:paymentResponse]; | 389 } |
| 390 |
| 391 - (void)sendPaymentResponseIfAllAsyncCallsCompleted { |
| 392 if (_contactAddressNormalizationPending == NO && |
| 393 _shippingAddressNormalizationPending == NO && |
| 394 _billingAddressNormalizationPending == NO && |
| 395 _fullCardRequestPending == NO) { |
| 396 web::PaymentResponse paymentResponse; |
| 397 |
| 398 // If the merchant specified the card network as part of the "basic-card" |
| 399 // payment method, return "basic-card" as the method_name. Otherwise, return |
| 400 // the name of the network directly. |
| 401 const std::string issuer_network = |
| 402 autofill::data_util::GetPaymentRequestData( |
| 403 _fullCard.creditCard.network()) |
| 404 .basic_card_issuer_network; |
| 405 paymentResponse.method_name = |
| 406 _paymentRequest->basic_card_specified_networks().find(issuer_network) != |
| 407 _paymentRequest->basic_card_specified_networks().end() |
| 408 ? base::ASCIIToUTF16("basic-card") |
| 409 : base::ASCIIToUTF16(issuer_network); |
| 410 |
| 411 paymentResponse.details = GetBasicCardResponseFromAutofillCreditCard( |
| 412 _fullCard.creditCard, _fullCard.cvc, _fullCard.billingAddress, |
| 413 GetApplicationContext()->GetApplicationLocale()); |
| 414 |
| 415 if (_paymentRequest->request_shipping()) { |
| 416 autofill::AutofillProfile* shippingAddress = |
| 417 _paymentRequest->selected_shipping_profile(); |
| 418 // TODO(crbug.com/602666): User should get here only if they have selected |
| 419 // a shipping address. |
| 420 DCHECK(shippingAddress); |
| 421 paymentResponse.shipping_address = GetPaymentAddressFromAutofillProfile( |
| 422 *shippingAddress, GetApplicationContext()->GetApplicationLocale()); |
| 423 |
| 424 web::PaymentShippingOption* shippingOption = |
| 425 _paymentRequest->selected_shipping_option(); |
| 426 DCHECK(shippingOption); |
| 427 paymentResponse.shipping_option = shippingOption->id; |
| 428 } |
| 429 |
| 430 if (_paymentRequest->request_payer_name()) { |
| 431 autofill::AutofillProfile* contactInfo = |
| 432 _paymentRequest->selected_contact_profile(); |
| 433 // TODO(crbug.com/602666): User should get here only if they have selected |
| 434 // a contact info. |
| 435 DCHECK(contactInfo); |
| 436 paymentResponse.payer_name = |
| 437 contactInfo->GetInfo(autofill::AutofillType(autofill::NAME_FULL), |
| 438 GetApplicationContext()->GetApplicationLocale()); |
| 439 } |
| 440 |
| 441 if (_paymentRequest->request_payer_email()) { |
| 442 autofill::AutofillProfile* contactInfo = |
| 443 _paymentRequest->selected_contact_profile(); |
| 444 // TODO(crbug.com/602666): User should get here only if they have selected |
| 445 // a contact info. |
| 446 DCHECK(contactInfo); |
| 447 paymentResponse.payer_email = |
| 448 contactInfo->GetRawInfo(autofill::EMAIL_ADDRESS); |
| 449 } |
| 450 |
| 451 if (_paymentRequest->request_payer_phone()) { |
| 452 autofill::AutofillProfile* contactInfo = |
| 453 _paymentRequest->selected_contact_profile(); |
| 454 // TODO(crbug.com/602666): User should get here only if they have selected |
| 455 // a contact info. |
| 456 DCHECK(contactInfo); |
| 457 paymentResponse.payer_phone = |
| 458 contactInfo->GetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER); |
| 459 } |
| 460 |
| 461 [_delegate paymentRequestCoordinator:self |
| 462 didConfirmWithPaymentResponse:paymentResponse]; |
| 463 } |
295 } | 464 } |
296 | 465 |
297 - (void)updatePaymentDetails:(web::PaymentDetails)paymentDetails { | 466 - (void)updatePaymentDetails:(web::PaymentDetails)paymentDetails { |
298 BOOL totalValueChanged = | 467 BOOL totalValueChanged = |
299 (_paymentRequest->payment_details().total != paymentDetails.total); | 468 (_paymentRequest->payment_details().total != paymentDetails.total); |
300 _paymentRequest->set_payment_details(paymentDetails); | 469 _paymentRequest->set_payment_details(paymentDetails); |
301 | 470 |
302 if (_paymentRequest->shipping_options().empty()) { | 471 if (_paymentRequest->shipping_options().empty()) { |
303 // Display error in the shipping address/option selection view. | 472 // Display error in the shipping address/option selection view. |
304 if (_shippingAddressSelectionCoordinator) { | 473 if (_shippingAddressSelectionCoordinator) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 | 517 |
349 #pragma mark - PaymentRequestViewControllerDelegate | 518 #pragma mark - PaymentRequestViewControllerDelegate |
350 | 519 |
351 - (void)paymentRequestViewControllerDidCancel: | 520 - (void)paymentRequestViewControllerDidCancel: |
352 (PaymentRequestViewController*)controller { | 521 (PaymentRequestViewController*)controller { |
353 [_delegate paymentRequestCoordinatorDidCancel:self]; | 522 [_delegate paymentRequestCoordinatorDidCancel:self]; |
354 } | 523 } |
355 | 524 |
356 - (void)paymentRequestViewControllerDidConfirm: | 525 - (void)paymentRequestViewControllerDidConfirm: |
357 (PaymentRequestViewController*)controller { | 526 (PaymentRequestViewController*)controller { |
358 [self sendPaymentResponse]; | 527 [self requestFullCardAndNormalizeProfiles]; |
359 } | 528 } |
360 | 529 |
361 - (void)paymentRequestViewControllerDidSelectSettings: | 530 - (void)paymentRequestViewControllerDidSelectSettings: |
362 (PaymentRequestViewController*)controller { | 531 (PaymentRequestViewController*)controller { |
363 [_delegate paymentRequestCoordinatorDidSelectSettings:self]; | 532 [_delegate paymentRequestCoordinatorDidSelectSettings:self]; |
364 } | 533 } |
365 | 534 |
366 - (void)paymentRequestViewControllerDidSelectPaymentSummaryItem: | 535 - (void)paymentRequestViewControllerDidSelectPaymentSummaryItem: |
367 (PaymentRequestViewController*)controller { | 536 (PaymentRequestViewController*)controller { |
368 _itemsDisplayCoordinator = [[PaymentItemsDisplayCoordinator alloc] | 537 _itemsDisplayCoordinator = [[PaymentItemsDisplayCoordinator alloc] |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 (PaymentItemsDisplayCoordinator*)coordinator { | 593 (PaymentItemsDisplayCoordinator*)coordinator { |
425 // Clear the 'Updated' label on the payment summary item, if there is one. | 594 // Clear the 'Updated' label on the payment summary item, if there is one. |
426 [_viewController updatePaymentSummaryWithTotalValueChanged:NO]; | 595 [_viewController updatePaymentSummaryWithTotalValueChanged:NO]; |
427 | 596 |
428 [_itemsDisplayCoordinator stop]; | 597 [_itemsDisplayCoordinator stop]; |
429 _itemsDisplayCoordinator = nil; | 598 _itemsDisplayCoordinator = nil; |
430 } | 599 } |
431 | 600 |
432 - (void)paymentItemsDisplayCoordinatorDidConfirm: | 601 - (void)paymentItemsDisplayCoordinatorDidConfirm: |
433 (PaymentItemsDisplayCoordinator*)coordinator { | 602 (PaymentItemsDisplayCoordinator*)coordinator { |
434 [self sendPaymentResponse]; | 603 [self requestFullCardAndNormalizeProfiles]; |
435 } | 604 } |
436 | 605 |
437 #pragma mark - ShippingAddressSelectionCoordinatorDelegate | 606 #pragma mark - ShippingAddressSelectionCoordinatorDelegate |
438 | 607 |
439 - (void)shippingAddressSelectionCoordinator: | 608 - (void)shippingAddressSelectionCoordinator: |
440 (ShippingAddressSelectionCoordinator*)coordinator | 609 (ShippingAddressSelectionCoordinator*)coordinator |
441 didSelectShippingAddress: | 610 didSelectShippingAddress: |
442 (autofill::AutofillProfile*)shippingAddress { | 611 (autofill::AutofillProfile*)shippingAddress { |
443 _pendingShippingAddress = shippingAddress; | 612 _pendingShippingAddress = shippingAddress; |
444 DCHECK(shippingAddress); | 613 DCHECK(shippingAddress); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 - (void)paymentMethodSelectionCoordinatorDidReturn: | 663 - (void)paymentMethodSelectionCoordinatorDidReturn: |
495 (PaymentMethodSelectionCoordinator*)coordinator { | 664 (PaymentMethodSelectionCoordinator*)coordinator { |
496 // Clear the 'Updated' label on the payment summary item, if there is one. | 665 // Clear the 'Updated' label on the payment summary item, if there is one. |
497 [_viewController updatePaymentSummaryWithTotalValueChanged:NO]; | 666 [_viewController updatePaymentSummaryWithTotalValueChanged:NO]; |
498 | 667 |
499 [_methodSelectionCoordinator stop]; | 668 [_methodSelectionCoordinator stop]; |
500 _methodSelectionCoordinator = nil; | 669 _methodSelectionCoordinator = nil; |
501 } | 670 } |
502 | 671 |
503 @end | 672 @end |
OLD | NEW |