1 // Copyright 2013 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 #ifndef COMPONENTS_AUTOFILL_CONTENT_BROWSER_WALLET_WALLET_CLIENT_H_ 6 #define COMPONENTS_AUTOFILL_CONTENT_BROWSER_WALLET_WALLET_CLIENT_H_ 7 8 #include <queue> 9 #include <string> 10 #include <vector> 11 12 #include "base/callback.h" // For base::Closure. 13 #include "base/memory/ref_counted.h" 14 #include "base/memory/weak_ptr.h" 15 #include "base/time/time.h" 16 #include "base/values.h" 17 #include "components/autofill/content/browser/autocheckout_statistic.h" 18 #include "components/autofill/content/browser/wallet/full_wallet.h" 19 #include "components/autofill/content/browser/wallet/wallet_items.h" 20 #include "components/autofill/core/browser/autofill_manager_delegate.h" 21 #include "components/autofill/core/browser/autofill_metrics.h" 22 #include "components/autofill/core/common/autocheckout_status.h" 23 #include "net/url_request/url_fetcher_delegate.h" 24 #include "testing/gtest/include/gtest/gtest_prod.h" 25 #include "url/gurl.h" 26 27 namespace net { 28 class URLFetcher; 29 class URLRequestContextGetter; 30 } 31 32 namespace autofill { 33 namespace wallet { 34 35 class Address; 36 class FullWallet; 37 class Instrument; 38 class WalletClientDelegate; 39 40 // WalletClient is responsible for making calls to the Online Wallet backend on 41 // the user's behalf. The normal flow for using this class is as follows: 42 // 1) GetWalletItems should be called to retrieve the user's Wallet. 43 // a) If the user does not have a Wallet, they must AcceptLegalDocuments and 44 // SaveToWallet to set up their account before continuing. 45 // b) If the user has not accepted the most recent legal documents for 46 // Wallet, they must AcceptLegalDocuments. 47 // 2) The user then chooses what instrument and shipping address to use for the 48 // current transaction. 49 // a) If they choose an instrument with a zip code only address, the billing 50 // address will need to be updated using SaveToWallet. 51 // b) The user may also choose to add a new instrument or address using 52 // SaveToWallet. 53 // 3) Once the user has selected the backing instrument and shipping address 54 // for this transaction, a FullWallet with the fronting card is generated 55 // using GetFullWallet. 56 // a) GetFullWallet may return a Risk challenge for the user. In that case, 57 // the user will need to verify who they are by authenticating their 58 // chosen backing instrument through AuthenticateInstrument 59 // 4) If the user initiated Autocheckout, SendAutocheckoutStatus to notify 60 // Online Wallet of the status flow to record various metrics. 61 // 62 // WalletClient is designed so only one request to Online Wallet can be outgoing 63 // at any one time. If |HasRequestInProgress()| is true while calling e.g. 64 // GetWalletItems(), the request will be queued and started later. Queued 65 // requests start in the order they were received. 66 67 class WalletClient : public net::URLFetcherDelegate { 68 public: 69 // The Risk challenges supported by users of WalletClient. 70 enum RiskCapability { 71 RELOGIN, 72 VERIFY_CVC, 73 }; 74 75 // The type of error returned by Online Wallet. 76 enum ErrorType { 77 // Errors to display to users. 78 BUYER_ACCOUNT_ERROR, // Risk deny, unsupported country, or 79 // account closed. 80 BUYER_LEGAL_ADDRESS_NOT_SUPPORTED, // User's Buyer Legal Address is 81 // unsupported by Online Wallet. 82 UNVERIFIED_KNOW_YOUR_CUSTOMER_STATUS, // User's "know your customer" KYC 83 // state is not verified (either 84 // KYC_REFER or KYC_FAIL). 85 UNSUPPORTED_MERCHANT, // Merchant is blacklisted due to 86 // compliance violation. 87 88 // API errors. 89 BAD_REQUEST, // Request was very malformed or sent to the 90 // wrong endpoint. 91 INVALID_PARAMS, // API call had missing or invalid parameters. 92 UNSUPPORTED_API_VERSION, // The server API version of the request is no 93 // longer supported. 94 95 // Server errors. 96 INTERNAL_ERROR, // Unknown server side error. 97 SERVICE_UNAVAILABLE, // Online Wallet is down. 98 99 // Other errors. 100 MALFORMED_RESPONSE, // The response from Wallet was malformed. 101 NETWORK_ERROR, // The response code of the server was something 102 // other than a 200 or 400. 103 104 UNKNOWN_ERROR, // Catch all error type. 105 }; 106 107 struct FullWalletRequest { 108 public: 109 FullWalletRequest(const std::string& instrument_id, 110 const std::string& address_id, 111 const GURL& source_url, 112 const std::string& google_transaction_id, 113 const std::vector<RiskCapability> risk_capabilities); 114 ~FullWalletRequest(); 115 116 // The ID of the backing instrument. Should have been selected by the user 117 // in some UI. 118 std::string instrument_id; 119 120 // The ID of the shipping address. Should have been selected by the user 121 // in some UI. 122 std::string address_id; 123 124 // The URL that Online Wallet usage is being initiated on. 125 GURL source_url; 126 127 // The transaction ID from GetWalletItems. 128 std::string google_transaction_id; 129 130 // The Risk challenges supported by the user of WalletClient 131 std::vector<RiskCapability> risk_capabilities; 132 133 private: 134 DISALLOW_ASSIGN(FullWalletRequest); 135 }; 136 137 // |context_getter| is reference counted so it has no lifetime or ownership 138 // requirements. |delegate| must outlive |this|. 139 WalletClient(net::URLRequestContextGetter* context_getter, 140 WalletClientDelegate* delegate); 141 142 virtual ~WalletClient(); 143 144 // GetWalletItems retrieves the user's online wallet. The WalletItems 145 // returned may require additional action such as presenting legal documents 146 // to the user to be accepted. 147 virtual void GetWalletItems(const GURL& source_url); 148 149 // The GetWalletItems call to the Online Wallet backend may require the user 150 // to accept various legal documents before a FullWallet can be generated. 151 // The |google_transaction_id| is provided in the response to the 152 // GetWalletItems call. If |documents| are empty, |delegate_| will not receive 153 // a corresponding |OnDidAcceptLegalDocuments()| call. 154 virtual void AcceptLegalDocuments( 155 const std::vector<WalletItems::LegalDocument*>& documents, 156 const std::string& google_transaction_id, 157 const GURL& source_url); 158 159 // Authenticates that |card_verification_number| is for the backing instrument 160 // with |instrument_id|. |obfuscated_gaia_id| is used as a key when escrowing 161 // |card_verification_number|. |delegate_| is notified when the request is 162 // complete. Used to respond to Risk challenges. 163 virtual void AuthenticateInstrument( 164 const std::string& instrument_id, 165 const std::string& card_verification_number); 166 167 // GetFullWallet retrieves the a FullWallet for the user. 168 virtual void GetFullWallet(const FullWalletRequest& full_wallet_request); 169 170 // Saves the data in |instrument| and/or |address| to Wallet. |instrument| 171 // does not have to be complete if its being used to update an existing 172 // instrument, like in the case of expiration date or address only updates. 173 virtual void SaveToWallet(scoped_ptr<Instrument> instrument, 174 scoped_ptr<Address> address, 175 const GURL& source_url); 176 177 // SendAutocheckoutStatus is used for tracking the success of Autocheckout 178 // flows. |status| is the result of the flow, |source_url| is the domain 179 // where the purchase occured, and |google_transaction_id| is the same as the 180 // one provided by GetWalletItems. |latency_statistics| contain statistics 181 // required to measure Autocheckout process. 182 virtual void SendAutocheckoutStatus( 183 autofill::AutocheckoutStatus status, 184 const GURL& source_url, 185 const std::vector<AutocheckoutStatistic>& latency_statistics, 186 const std::string& google_transaction_id); 187 188 bool HasRequestInProgress() const; 189 190 // Cancels and clears the current |request_| and |pending_requests_| (if any). 191 void CancelRequests(); 192 193 private: 194 FRIEND_TEST_ALL_PREFIXES(WalletClientTest, PendingRequest); 195 FRIEND_TEST_ALL_PREFIXES(WalletClientTest, CancelRequests); 196 197 enum RequestType { 198 NO_PENDING_REQUEST, 199 ACCEPT_LEGAL_DOCUMENTS, 200 AUTHENTICATE_INSTRUMENT, 201 GET_FULL_WALLET, 202 GET_WALLET_ITEMS, 203 SAVE_TO_WALLET, 204 SEND_STATUS, 205 }; 206 207 // Like AcceptLegalDocuments, but takes a vector of document ids. 208 void DoAcceptLegalDocuments( 209 const std::vector<std::string>& document_ids, 210 const std::string& google_transaction_id, 211 const GURL& source_url); 212 213 // Posts |post_body| to |url| with content type |mime_type| and notifies 214 // |delegate_| when the request is complete. 215 void MakeWalletRequest(const GURL& url, 216 const std::string& post_body, 217 const std::string& mime_type); 218 219 // Performs bookkeeping tasks for any invalid requests. 220 void HandleMalformedResponse(net::URLFetcher* request); 221 void HandleNetworkError(int response_code); 222 void HandleWalletError(ErrorType error_type); 223 224 // Start the next pending request (if any). 225 void StartNextPendingRequest(); 226 227 // net::URLFetcherDelegate: 228 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 229 230 // Logs an UMA metric for each of the |required_actions|. 231 void LogRequiredActions( 232 const std::vector<RequiredAction>& required_actions) const; 233 234 // Converts |request_type| to an UMA metric. 235 AutofillMetrics::WalletApiCallMetric RequestTypeToUmaMetric( 236 RequestType request_type) const; 237 238 // The context for the request. Ensures the gdToken cookie is set as a header 239 // in the requests to Online Wallet if it is present. 240 scoped_refptr<net::URLRequestContextGetter> context_getter_; 241 242 // Observer class that has its various On* methods called based on the results 243 // of a request to Online Wallet. 244 WalletClientDelegate* const delegate_; // must outlive |this|. 245 246 // The current request object. 247 scoped_ptr<net::URLFetcher> request_; 248 249 // The type of the current request. Must be NO_PENDING_REQUEST for a request 250 // to be initiated as only one request may be running at a given time. 251 RequestType request_type_; 252 253 // The one time pad used for GetFullWallet encryption. 254 std::vector<uint8> one_time_pad_; 255 256 // Requests that are waiting to be run. 257 std::queue<base::Closure> pending_requests_; 258 259 // When the current request started. Used to track client side latency. 260 base::Time request_started_timestamp_; 261 262 base::WeakPtrFactory<WalletClient> weak_ptr_factory_; 263 264 DISALLOW_COPY_AND_ASSIGN(WalletClient); 265 }; 266 267 } // namespace wallet 268 } // namespace autofill 269 270 #endif // COMPONENTS_AUTOFILL_CONTENT_BROWSER_WALLET_WALLET_CLIENT_H_ 271