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