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_manager.h" | 5 #import "ios/chrome/browser/ui/payments/payment_request_manager.h" |
6 | 6 |
7 #include "base/ios/block_types.h" | 7 #include "base/ios/block_types.h" |
8 #include "base/ios/ios_util.h" | 8 #include "base/ios/ios_util.h" |
9 #import "base/mac/bind_objc_block.h" | 9 #import "base/mac/bind_objc_block.h" |
10 #include "base/mac/foundation_util.h" | 10 #include "base/mac/foundation_util.h" |
11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
12 #include "base/strings/string16.h" | 12 #include "base/strings/string16.h" |
13 #include "base/strings/sys_string_conversions.h" | 13 #include "base/strings/sys_string_conversions.h" |
14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
15 #import "base/values.h" | 15 #import "base/values.h" |
| 16 #include "components/autofill/core/browser/autofill_country.h" |
16 #include "components/autofill/core/browser/autofill_data_util.h" | 17 #include "components/autofill/core/browser/autofill_data_util.h" |
17 #include "components/autofill/core/browser/autofill_manager.h" | 18 #include "components/autofill/core/browser/autofill_manager.h" |
18 #include "components/autofill/core/browser/credit_card.h" | 19 #include "components/autofill/core/browser/credit_card.h" |
19 #include "components/autofill/core/browser/personal_data_manager.h" | 20 #include "components/autofill/core/browser/personal_data_manager.h" |
20 #include "components/autofill/ios/browser/autofill_driver_ios.h" | 21 #include "components/autofill/ios/browser/autofill_driver_ios.h" |
| 22 #include "components/payments/core/address_normalization_manager.h" |
| 23 #include "components/payments/core/address_normalizer_impl.h" |
21 #include "components/payments/core/payment_address.h" | 24 #include "components/payments/core/payment_address.h" |
22 #include "components/payments/core/payment_request_data_util.h" | 25 #include "components/payments/core/payment_request_data_util.h" |
23 #include "ios/chrome/browser/application_context.h" | 26 #include "ios/chrome/browser/application_context.h" |
24 #include "ios/chrome/browser/autofill/personal_data_manager_factory.h" | 27 #include "ios/chrome/browser/autofill/personal_data_manager_factory.h" |
| 28 #include "ios/chrome/browser/autofill/validation_rules_storage_factory.h" |
25 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" | 29 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" |
26 #include "ios/chrome/browser/payments/payment_request.h" | 30 #include "ios/chrome/browser/payments/payment_request.h" |
27 #include "ios/chrome/browser/procedural_block_types.h" | 31 #include "ios/chrome/browser/procedural_block_types.h" |
28 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h" | 32 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h" |
29 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h" | 33 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h" |
30 #import "ios/chrome/browser/ui/commands/ios_command_ids.h" | 34 #import "ios/chrome/browser/ui/commands/ios_command_ids.h" |
31 #import "ios/chrome/browser/ui/payments/js_payment_request_manager.h" | 35 #import "ios/chrome/browser/ui/payments/js_payment_request_manager.h" |
32 #import "ios/chrome/browser/ui/payments/payment_request_coordinator.h" | 36 #import "ios/chrome/browser/ui/payments/payment_request_coordinator.h" |
33 #include "ios/web/public/favicon_status.h" | 37 #include "ios/web/public/favicon_status.h" |
34 #include "ios/web/public/navigation_item.h" | 38 #include "ios/web/public/navigation_item.h" |
35 #include "ios/web/public/navigation_manager.h" | 39 #include "ios/web/public/navigation_manager.h" |
36 #include "ios/web/public/payments/payment_request.h" | 40 #include "ios/web/public/payments/payment_request.h" |
37 #include "ios/web/public/ssl_status.h" | 41 #include "ios/web/public/ssl_status.h" |
38 #import "ios/web/public/url_scheme_util.h" | 42 #import "ios/web/public/url_scheme_util.h" |
39 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" | 43 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" |
40 #import "ios/web/public/web_state/ui/crw_web_view_proxy.h" | 44 #import "ios/web/public/web_state/ui/crw_web_view_proxy.h" |
41 #include "ios/web/public/web_state/url_verification_constants.h" | 45 #include "ios/web/public/web_state/url_verification_constants.h" |
42 #include "ios/web/public/web_state/web_state.h" | 46 #include "ios/web/public/web_state/web_state.h" |
43 #import "ios/web/public/web_state/web_state_observer_bridge.h" | 47 #import "ios/web/public/web_state/web_state_observer_bridge.h" |
| 48 #include "third_party/libaddressinput/chromium/chrome_metadata_source.h" |
| 49 #include "third_party/libaddressinput/chromium/chrome_storage_impl.h" |
44 | 50 |
45 #if !defined(__has_feature) || !__has_feature(objc_arc) | 51 #if !defined(__has_feature) || !__has_feature(objc_arc) |
46 #error "This file requires ARC support." | 52 #error "This file requires ARC support." |
47 #endif | 53 #endif |
48 | 54 |
49 namespace { | 55 namespace { |
50 | 56 |
51 // Command prefix for injected JavaScript. | 57 // Command prefix for injected JavaScript. |
52 const char kCommandPrefix[] = "paymentRequest"; | 58 const char kCommandPrefix[] = "paymentRequest"; |
53 | 59 |
54 // Time interval between attempts to unblock the webview's JS event queue. | 60 // Time interval between attempts to unblock the webview's JS event queue. |
55 const NSTimeInterval kNoopInterval = 0.1; | 61 const NSTimeInterval kNoopInterval = 0.1; |
56 | 62 |
57 // Time interval before closing the UI if the page has not yet called | 63 // Time interval before closing the UI if the page has not yet called |
58 // PaymentResponse.complete(). | 64 // PaymentResponse.complete(). |
59 const NSTimeInterval kTimeoutInterval = 60.0; | 65 const NSTimeInterval kTimeoutInterval = 60.0; |
60 | 66 |
61 NSString* kAbortMessage = @"The payment request was aborted."; | 67 NSString* kAbortMessage = @"The payment request was aborted."; |
62 NSString* kCancelMessage = @"The payment request was canceled."; | 68 NSString* kCancelMessage = @"The payment request was canceled."; |
63 | 69 |
| 70 struct PendingPaymentResponse { |
| 71 autofill::CreditCard creditCard; |
| 72 base::string16 verificationCode; |
| 73 autofill::AutofillProfile billingAddress; |
| 74 autofill::AutofillProfile shippingAddress; |
| 75 autofill::AutofillProfile contactAddress; |
| 76 }; |
| 77 |
64 } // namespace | 78 } // namespace |
65 | 79 |
66 @interface PaymentRequestManager ()<CRWWebStateObserver, | 80 @interface PaymentRequestManager ()<CRWWebStateObserver, |
67 PaymentRequestCoordinatorDelegate> { | 81 PaymentRequestCoordinatorDelegate> { |
68 // View controller used to present the PaymentRequest view controller. | 82 // View controller used to present the PaymentRequest view controller. |
69 __weak UIViewController* _baseViewController; | 83 __weak UIViewController* _baseViewController; |
70 | 84 |
71 // PersonalDataManager used to manage user credit cards and addresses. | 85 // PersonalDataManager used to manage user credit cards and addresses. |
72 autofill::PersonalDataManager* _personalDataManager; | 86 autofill::PersonalDataManager* _personalDataManager; |
73 | 87 |
(...skipping 23 matching lines...) Expand all Loading... |
97 // Timer used to periodically unblock the webview's JS event queue. | 111 // Timer used to periodically unblock the webview's JS event queue. |
98 NSTimer* _unblockEventQueueTimer; | 112 NSTimer* _unblockEventQueueTimer; |
99 | 113 |
100 // Timer used to complete the Payment Request flow and close the UI if the | 114 // Timer used to complete the Payment Request flow and close the UI if the |
101 // page does not call PaymentResponse.complete() in a timely fashion. | 115 // page does not call PaymentResponse.complete() in a timely fashion. |
102 NSTimer* _paymentResponseTimeoutTimer; | 116 NSTimer* _paymentResponseTimeoutTimer; |
103 | 117 |
104 // Timer used to cancel the Payment Request flow and close the UI if the | 118 // Timer used to cancel the Payment Request flow and close the UI if the |
105 // page does not settle the pending update promise in a timely fashion. | 119 // page does not settle the pending update promise in a timely fashion. |
106 NSTimer* _updateEventTimeoutTimer; | 120 NSTimer* _updateEventTimeoutTimer; |
| 121 |
| 122 // AddressNormalizationManager used to normalize the various addresses (e.g. |
| 123 // shipping, contact, billing). |
| 124 std::unique_ptr<payments::AddressNormalizationManager> |
| 125 _addressNormalizationManager; |
| 126 |
| 127 // Storage for data to return in the payment response, until we're ready to |
| 128 // send an actual PaymentResponse. |
| 129 PendingPaymentResponse _pendingPaymentResponse; |
107 } | 130 } |
108 | 131 |
109 // Object that manages JavaScript injection into the web view. | 132 // Object that manages JavaScript injection into the web view. |
110 @property(nonatomic, weak) JSPaymentRequestManager* paymentRequestJsManager; | 133 @property(nonatomic, weak) JSPaymentRequestManager* paymentRequestJsManager; |
111 | 134 |
112 // Synchronous method executed by -asynchronouslyEnablePaymentRequest: | 135 // Synchronous method executed by -asynchronouslyEnablePaymentRequest: |
113 - (void)doEnablePaymentRequest:(BOOL)enabled; | 136 - (void)doEnablePaymentRequest:(BOOL)enabled; |
114 | 137 |
115 // Terminates the pending request with an error message and dismisses the UI. | 138 // Terminates the pending request with an error message and dismisses the UI. |
116 // Invokes the callback once the request has been terminated. | 139 // Invokes the callback once the request has been terminated. |
(...skipping 11 matching lines...) Expand all Loading... |
128 // Handles invocations of PaymentRequest.abort(). Returns YES if the invocation | 151 // Handles invocations of PaymentRequest.abort(). Returns YES if the invocation |
129 // was successful. | 152 // was successful. |
130 - (BOOL)handleRequestAbort:(const base::DictionaryValue&)message; | 153 - (BOOL)handleRequestAbort:(const base::DictionaryValue&)message; |
131 | 154 |
132 // Handles invocations of PaymentRequest.canMakePayment(). Returns YES if the | 155 // Handles invocations of PaymentRequest.canMakePayment(). Returns YES if the |
133 // invocation was successful. | 156 // invocation was successful. |
134 - (BOOL)handleCanMakePayment:(const base::DictionaryValue&)message; | 157 - (BOOL)handleCanMakePayment:(const base::DictionaryValue&)message; |
135 | 158 |
136 // Called by |_updateEventTimeoutTimer|, displays an error message. Upon | 159 // Called by |_updateEventTimeoutTimer|, displays an error message. Upon |
137 // dismissal of the error message, cancels the Payment Request as if it was | 160 // dismissal of the error message, cancels the Payment Request as if it was |
138 // performend by the user. | 161 // performed by the user. |
139 - (BOOL)displayErrorThenCancelRequest; | 162 - (BOOL)displayErrorThenCancelRequest; |
140 | 163 |
141 // Called by |_paymentResponseTimeoutTimer|, invokes handleResponseComplete: | 164 // Called by |_paymentResponseTimeoutTimer|, invokes handleResponseComplete: |
142 // as if PaymentResponse.complete() was invoked with the default "unknown" | 165 // as if PaymentResponse.complete() was invoked with the default "unknown" |
143 // argument. | 166 // argument. |
144 - (BOOL)doResponseComplete; | 167 - (BOOL)doResponseComplete; |
145 | 168 |
146 // Handles invocations of PaymentResponse.complete(). Returns YES if the | 169 // Handles invocations of PaymentResponse.complete(). Returns YES if the |
147 // invocation was successful. | 170 // invocation was successful. |
148 - (BOOL)handleResponseComplete:(const base::DictionaryValue&)message; | 171 - (BOOL)handleResponseComplete:(const base::DictionaryValue&)message; |
(...skipping 13 matching lines...) Expand all Loading... |
162 // called with no arguments. | 185 // called with no arguments. |
163 - (void)setPaymentResponseTimeoutTimer; | 186 - (void)setPaymentResponseTimeoutTimer; |
164 | 187 |
165 // Establishes a timer that dismisses the Payment Request UI when it times out. | 188 // Establishes a timer that dismisses the Payment Request UI when it times out. |
166 // Per the spec, implementations may choose to consider a timeout for the | 189 // Per the spec, implementations may choose to consider a timeout for the |
167 // promise provided with the PaymentRequestUpdateEvent.updateWith() call. If the | 190 // promise provided with the PaymentRequestUpdateEvent.updateWith() call. If the |
168 // promise doesn't get settled in a reasonable amount of time, it is as if it | 191 // promise doesn't get settled in a reasonable amount of time, it is as if it |
169 // was rejected. | 192 // was rejected. |
170 - (void)setUpdateEventTimeoutTimer; | 193 - (void)setUpdateEventTimeoutTimer; |
171 | 194 |
| 195 // Called when the relevant addresses from a Payment Request have been |
| 196 // normalized. Resolves the request promise with a PaymentResponse. |
| 197 - (void)paymentRequestAddressNormalizationDidComplete; |
| 198 |
172 @end | 199 @end |
173 | 200 |
174 @implementation PaymentRequestManager | 201 @implementation PaymentRequestManager |
175 | 202 |
176 @synthesize enabled = _enabled; | 203 @synthesize enabled = _enabled; |
177 @synthesize webState = _webState; | 204 @synthesize webState = _webState; |
178 @synthesize browserState = _browserState; | 205 @synthesize browserState = _browserState; |
179 @synthesize paymentRequestJsManager = _paymentRequestJsManager; | 206 @synthesize paymentRequestJsManager = _paymentRequestJsManager; |
180 | 207 |
181 - (instancetype)initWithBaseViewController:(UIViewController*)viewController | 208 - (instancetype)initWithBaseViewController:(UIViewController*)viewController |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 } | 342 } |
316 if (command == "paymentRequest.responseComplete") { | 343 if (command == "paymentRequest.responseComplete") { |
317 return [self handleResponseComplete:JSONCommand]; | 344 return [self handleResponseComplete:JSONCommand]; |
318 } | 345 } |
319 if (command == "paymentRequest.updatePaymentDetails") { | 346 if (command == "paymentRequest.updatePaymentDetails") { |
320 return [self handleUpdatePaymentDetails:JSONCommand]; | 347 return [self handleUpdatePaymentDetails:JSONCommand]; |
321 } | 348 } |
322 return NO; | 349 return NO; |
323 } | 350 } |
324 | 351 |
| 352 - (void)startAddressNormalizer { |
| 353 autofill::PersonalDataManager* personalDataManager = |
| 354 _paymentRequest->GetPersonalDataManager(); |
| 355 |
| 356 std::unique_ptr<i18n::addressinput::Source> addressNormalizerSource = |
| 357 base::MakeUnique<autofill::ChromeMetadataSource>( |
| 358 I18N_ADDRESS_VALIDATION_DATA_URL, |
| 359 personalDataManager->GetURLRequestContextGetter()); |
| 360 |
| 361 std::unique_ptr<i18n::addressinput::Storage> addressNormalizerStorage = |
| 362 autofill::ValidationRulesStorageFactory::CreateStorage(); |
| 363 |
| 364 std::unique_ptr<payments::AddressNormalizer> addressNormalizer = |
| 365 base::MakeUnique<payments::AddressNormalizerImpl>( |
| 366 std::move(addressNormalizerSource), |
| 367 std::move(addressNormalizerStorage)); |
| 368 |
| 369 // Kickoff the process of loading the rules (which is asynchronous) for each |
| 370 // profile's country, to get faster address normalization later. |
| 371 for (const autofill::AutofillProfile* profile : |
| 372 personalDataManager->GetProfilesToSuggest()) { |
| 373 std::string countryCode = |
| 374 base::UTF16ToUTF8(profile->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY)); |
| 375 if (autofill::data_util::IsValidCountryCode(countryCode)) { |
| 376 addressNormalizer->LoadRulesForRegion(countryCode); |
| 377 } |
| 378 } |
| 379 |
| 380 const std::string default_country_code = |
| 381 autofill::AutofillCountry::CountryCodeForLocale( |
| 382 GetApplicationContext()->GetApplicationLocale()); |
| 383 |
| 384 _addressNormalizationManager = |
| 385 base::MakeUnique<payments::AddressNormalizationManager>( |
| 386 std::move(addressNormalizer), default_country_code); |
| 387 } |
| 388 |
325 // Ensures that |_paymentRequest| is set to the correct value for |message|. | 389 // Ensures that |_paymentRequest| is set to the correct value for |message|. |
326 // Returns YES if |_paymentRequest| was already set to the right value, or if it | 390 // Returns YES if |_paymentRequest| was already set to the right value, or if it |
327 // was updated to match |message|. | 391 // was updated to match |message|. |
328 - (BOOL)createPaymentRequestFromMessage:(const base::DictionaryValue&)message { | 392 - (BOOL)createPaymentRequestFromMessage:(const base::DictionaryValue&)message { |
329 const base::DictionaryValue* paymentRequestData; | 393 const base::DictionaryValue* paymentRequestData; |
330 web::PaymentRequest webPaymentRequest; | 394 web::PaymentRequest webPaymentRequest; |
331 if (!message.GetDictionary("payment_request", &paymentRequestData)) { | 395 if (!message.GetDictionary("payment_request", &paymentRequestData)) { |
332 DLOG(ERROR) << "JS message parameter 'payment_request' is missing"; | 396 DLOG(ERROR) << "JS message parameter 'payment_request' is missing"; |
333 return NO; | 397 return NO; |
334 } | 398 } |
(...skipping 17 matching lines...) Expand all Loading... |
352 - (BOOL)handleRequestShow:(const base::DictionaryValue&)message { | 416 - (BOOL)handleRequestShow:(const base::DictionaryValue&)message { |
353 // TODO(crbug.com/602666): check that there's not already a pending request. | 417 // TODO(crbug.com/602666): check that there's not already a pending request. |
354 // TODO(crbug.com/602666): compare our supported payment types (i.e. autofill | 418 // TODO(crbug.com/602666): compare our supported payment types (i.e. autofill |
355 // credit card types) against the merchant supported types and return NO | 419 // credit card types) against the merchant supported types and return NO |
356 // if the intersection is empty. | 420 // if the intersection is empty. |
357 | 421 |
358 if (![self createPaymentRequestFromMessage:message]) { | 422 if (![self createPaymentRequestFromMessage:message]) { |
359 return NO; | 423 return NO; |
360 } | 424 } |
361 | 425 |
| 426 [self startAddressNormalizer]; |
| 427 |
362 UIImage* pageFavicon = nil; | 428 UIImage* pageFavicon = nil; |
363 web::NavigationItem* navigationItem = | 429 web::NavigationItem* navigationItem = |
364 [self webState]->GetNavigationManager()->GetVisibleItem(); | 430 [self webState]->GetNavigationManager()->GetVisibleItem(); |
365 if (navigationItem && !navigationItem->GetFavicon().image.IsEmpty()) | 431 if (navigationItem && !navigationItem->GetFavicon().image.IsEmpty()) |
366 pageFavicon = navigationItem->GetFavicon().image.ToUIImage(); | 432 pageFavicon = navigationItem->GetFavicon().image.ToUIImage(); |
367 NSString* pageTitle = base::SysUTF16ToNSString([self webState]->GetTitle()); | 433 NSString* pageTitle = base::SysUTF16ToNSString([self webState]->GetTitle()); |
368 NSString* pageHost = | 434 NSString* pageHost = |
369 base::SysUTF8ToNSString([self webState]->GetLastCommittedURL().host()); | 435 base::SysUTF8ToNSString([self webState]->GetLastCommittedURL().host()); |
370 autofill::AutofillManager* autofillManager = | 436 autofill::AutofillManager* autofillManager = |
371 autofill::AutofillDriverIOS::FromWebState(_webState)->autofill_manager(); | 437 autofill::AutofillDriverIOS::FromWebState(_webState)->autofill_manager(); |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 DCHECK(mainWindow); | 625 DCHECK(mainWindow); |
560 GenericChromeCommand* command = | 626 GenericChromeCommand* command = |
561 [[GenericChromeCommand alloc] initWithTag:IDC_SHOW_AUTOFILL_SETTINGS]; | 627 [[GenericChromeCommand alloc] initWithTag:IDC_SHOW_AUTOFILL_SETTINGS]; |
562 [mainWindow chromeExecuteCommand:command]; | 628 [mainWindow chromeExecuteCommand:command]; |
563 }; | 629 }; |
564 | 630 |
565 [self terminateRequestWithErrorMessage:kCancelMessage callback:callback]; | 631 [self terminateRequestWithErrorMessage:kCancelMessage callback:callback]; |
566 } | 632 } |
567 | 633 |
568 - (void)paymentRequestCoordinator:(PaymentRequestCoordinator*)coordinator | 634 - (void)paymentRequestCoordinator:(PaymentRequestCoordinator*)coordinator |
569 didCompletePaymentRequest:(PaymentRequest*)paymentRequest | 635 didCompletePaymentRequestWithCard:(const autofill::CreditCard&)card |
570 card:(const autofill::CreditCard&)card | 636 verificationCode:(const base::string16&)verificationCode { |
571 verificationCode:(const base::string16&)verificationCode { | 637 _pendingPaymentResponse.creditCard = card; |
572 web::PaymentResponse paymentResponse; | 638 _pendingPaymentResponse.verificationCode = verificationCode; |
573 | |
574 // If the merchant specified the card network as part of the "basic-card" | |
575 // payment method, return "basic-card" as the method_name. Otherwise, return | |
576 // the name of the network directly. | |
577 std::string issuer_network = | |
578 autofill::data_util::GetPaymentRequestData(card.network()) | |
579 .basic_card_issuer_network; | |
580 paymentResponse.method_name = | |
581 paymentRequest->basic_card_specified_networks().find(issuer_network) != | |
582 paymentRequest->basic_card_specified_networks().end() | |
583 ? base::ASCIIToUTF16("basic-card") | |
584 : base::ASCIIToUTF16(issuer_network); | |
585 | |
586 // Get the billing address | |
587 autofill::AutofillProfile billingAddress; | |
588 | 639 |
589 // TODO(crbug.com/714768): Make sure the billing address is set and valid | 640 // TODO(crbug.com/714768): Make sure the billing address is set and valid |
590 // before getting here. Once the bug is addressed, there will be no need to | 641 // before getting here. Once the bug is addressed, there will be no need to |
591 // copy the address, *billing_address_ptr can be used to get the basic card | 642 // copy the address, *billing_address_ptr can be used to get the basic card |
592 // response. | 643 // response. |
593 if (!card.billing_address_id().empty()) { | 644 if (!card.billing_address_id().empty()) { |
594 autofill::AutofillProfile* billingAddressPtr = | 645 autofill::AutofillProfile* billingAddressPtr = |
595 autofill::PersonalDataManager::GetProfileFromProfilesByGUID( | 646 autofill::PersonalDataManager::GetProfileFromProfilesByGUID( |
596 card.billing_address_id(), paymentRequest->billing_profiles()); | 647 card.billing_address_id(), _paymentRequest->billing_profiles()); |
597 if (billingAddressPtr) | 648 if (billingAddressPtr) { |
598 billingAddress = *billingAddressPtr; | 649 _pendingPaymentResponse.billingAddress = *billingAddressPtr; |
| 650 _addressNormalizationManager->StartNormalizingAddress( |
| 651 &_pendingPaymentResponse.billingAddress); |
| 652 } |
599 } | 653 } |
600 | 654 |
| 655 if (_paymentRequest->request_shipping()) { |
| 656 // TODO(crbug.com/602666): User should get here only if they have selected |
| 657 // a shipping address. |
| 658 DCHECK(_paymentRequest->selected_shipping_profile()); |
| 659 _pendingPaymentResponse.shippingAddress = |
| 660 *_paymentRequest->selected_shipping_profile(); |
| 661 _addressNormalizationManager->StartNormalizingAddress( |
| 662 &_pendingPaymentResponse.shippingAddress); |
| 663 } |
| 664 |
| 665 if (_paymentRequest->request_payer_name() || |
| 666 _paymentRequest->request_payer_email() || |
| 667 _paymentRequest->request_payer_phone()) { |
| 668 // TODO(crbug.com/602666): User should get here only if they have selected |
| 669 // a contact info. |
| 670 DCHECK(_paymentRequest->selected_contact_profile()); |
| 671 _pendingPaymentResponse.contactAddress = |
| 672 *_paymentRequest->selected_contact_profile(); |
| 673 _addressNormalizationManager->StartNormalizingAddress( |
| 674 &_pendingPaymentResponse.contactAddress); |
| 675 } |
| 676 |
| 677 __weak PaymentRequestManager* weakSelf = self; |
| 678 _addressNormalizationManager->FinalizeWithCompletionCallback( |
| 679 base::BindBlockArc(^() { |
| 680 [weakSelf paymentRequestAddressNormalizationDidComplete]; |
| 681 })); |
| 682 } |
| 683 |
| 684 - (void)paymentRequestAddressNormalizationDidComplete { |
| 685 web::PaymentResponse paymentResponse; |
| 686 |
| 687 // If the merchant specified the card network as part of the "basic-card" |
| 688 // payment method, return "basic-card" as the method_name. Otherwise, return |
| 689 // the name of the network directly. |
| 690 std::string issuer_network = autofill::data_util::GetPaymentRequestData( |
| 691 _pendingPaymentResponse.creditCard.network()) |
| 692 .basic_card_issuer_network; |
| 693 paymentResponse.method_name = |
| 694 _paymentRequest->basic_card_specified_networks().find(issuer_network) != |
| 695 _paymentRequest->basic_card_specified_networks().end() |
| 696 ? base::ASCIIToUTF16("basic-card") |
| 697 : base::ASCIIToUTF16(issuer_network); |
| 698 |
601 paymentResponse.details = | 699 paymentResponse.details = |
602 payments::data_util::GetBasicCardResponseFromAutofillCreditCard( | 700 payments::data_util::GetBasicCardResponseFromAutofillCreditCard( |
603 card, verificationCode, billingAddress, | 701 _pendingPaymentResponse.creditCard, |
| 702 _pendingPaymentResponse.verificationCode, |
| 703 _pendingPaymentResponse.billingAddress, |
604 GetApplicationContext()->GetApplicationLocale()); | 704 GetApplicationContext()->GetApplicationLocale()); |
605 | 705 |
606 if (paymentRequest->request_shipping()) { | 706 if (_paymentRequest->request_shipping()) { |
607 autofill::AutofillProfile* shippingAddress = | |
608 paymentRequest->selected_shipping_profile(); | |
609 // TODO(crbug.com/602666): User should get here only if they have selected | |
610 // a shipping address. | |
611 DCHECK(shippingAddress); | |
612 paymentResponse.shipping_address = | 707 paymentResponse.shipping_address = |
613 payments::data_util::GetPaymentAddressFromAutofillProfile( | 708 payments::data_util::GetPaymentAddressFromAutofillProfile( |
614 *shippingAddress, GetApplicationContext()->GetApplicationLocale()); | 709 _pendingPaymentResponse.shippingAddress, |
| 710 GetApplicationContext()->GetApplicationLocale()); |
615 | 711 |
616 web::PaymentShippingOption* shippingOption = | 712 web::PaymentShippingOption* shippingOption = |
617 paymentRequest->selected_shipping_option(); | 713 _paymentRequest->selected_shipping_option(); |
618 DCHECK(shippingOption); | 714 DCHECK(shippingOption); |
619 paymentResponse.shipping_option = shippingOption->id; | 715 paymentResponse.shipping_option = shippingOption->id; |
620 } | 716 } |
621 | 717 |
622 if (paymentRequest->request_payer_name()) { | 718 if (_paymentRequest->request_payer_name()) { |
623 autofill::AutofillProfile* contactInfo = | 719 paymentResponse.payer_name = _pendingPaymentResponse.contactAddress.GetInfo( |
624 paymentRequest->selected_contact_profile(); | 720 autofill::AutofillType(autofill::NAME_FULL), |
625 // TODO(crbug.com/602666): User should get here only if they have selected | 721 GetApplicationContext()->GetApplicationLocale()); |
626 // a contact info. | |
627 DCHECK(contactInfo); | |
628 paymentResponse.payer_name = | |
629 contactInfo->GetInfo(autofill::AutofillType(autofill::NAME_FULL), | |
630 GetApplicationContext()->GetApplicationLocale()); | |
631 } | 722 } |
632 | 723 |
633 if (paymentRequest->request_payer_email()) { | 724 if (_paymentRequest->request_payer_email()) { |
634 autofill::AutofillProfile* contactInfo = | |
635 paymentRequest->selected_contact_profile(); | |
636 // TODO(crbug.com/602666): User should get here only if they have selected | |
637 // a contact info. | |
638 DCHECK(contactInfo); | |
639 paymentResponse.payer_email = | 725 paymentResponse.payer_email = |
640 contactInfo->GetRawInfo(autofill::EMAIL_ADDRESS); | 726 _pendingPaymentResponse.contactAddress.GetRawInfo( |
| 727 autofill::EMAIL_ADDRESS); |
641 } | 728 } |
642 | 729 |
643 if (paymentRequest->request_payer_phone()) { | 730 if (_paymentRequest->request_payer_phone()) { |
644 autofill::AutofillProfile* contactInfo = | |
645 paymentRequest->selected_contact_profile(); | |
646 // TODO(crbug.com/602666): User should get here only if they have selected | |
647 // a contact info. | |
648 DCHECK(contactInfo); | |
649 paymentResponse.payer_phone = | 731 paymentResponse.payer_phone = |
650 contactInfo->GetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER); | 732 _pendingPaymentResponse.contactAddress.GetRawInfo( |
| 733 autofill::PHONE_HOME_WHOLE_NUMBER); |
651 } | 734 } |
652 | 735 |
653 [_paymentRequestJsManager | 736 [_paymentRequestJsManager |
654 resolveRequestPromiseWithPaymentResponse:paymentResponse | 737 resolveRequestPromiseWithPaymentResponse:paymentResponse |
655 completionHandler:nil]; | 738 completionHandler:nil]; |
656 [self setUnblockEventQueueTimer]; | 739 [self setUnblockEventQueueTimer]; |
657 [self setPaymentResponseTimeoutTimer]; | 740 [self setPaymentResponseTimeoutTimer]; |
658 } | 741 } |
659 | 742 |
660 - (void)paymentRequestCoordinator:(PaymentRequestCoordinator*)coordinator | 743 - (void)paymentRequestCoordinator:(PaymentRequestCoordinator*)coordinator |
(...skipping 15 matching lines...) Expand all Loading... |
676 #pragma mark - CRWWebStateObserver methods | 759 #pragma mark - CRWWebStateObserver methods |
677 | 760 |
678 - (void)webState:(web::WebState*)webState | 761 - (void)webState:(web::WebState*)webState |
679 didCommitNavigationWithDetails: | 762 didCommitNavigationWithDetails: |
680 (const web::LoadCommittedDetails&)load_details { | 763 (const web::LoadCommittedDetails&)load_details { |
681 [self dismissUI]; | 764 [self dismissUI]; |
682 [self enableCurrentWebState]; | 765 [self enableCurrentWebState]; |
683 } | 766 } |
684 | 767 |
685 @end | 768 @end |
OLD | NEW |