BraintreeCustomerGateway

Braintree CustomerGateway module Creates and manages Customers.

Defined (1)

The class is defined in the following location(s).

/classes/lib/Braintree/Braintree/CustomerGateway.php  
  1. class CustomerGateway 
  2. private $_gateway; 
  3. private $_config; 
  4. private $_http; 
  5.  
  6. public function __construct($gateway) 
  7. $this->_gateway = $gateway; 
  8. $this->_config = $gateway->config; 
  9. $this->_config->assertHasAccessTokenOrKeys(); 
  10. $this->_http = new Http($gateway->config); 
  11.  
  12. public function all() 
  13. $path = $this->_config->merchantPath() . '/customers/advanced_search_ids'; 
  14. $response = $this->_http->post($path); 
  15. $pager = [ 
  16. 'object' => $this,  
  17. 'method' => 'fetch',  
  18. 'methodArgs' => [[]] 
  19. ]; 
  20.  
  21. return new ResourceCollection($response, $pager); 
  22.  
  23. public function fetch($query, $ids) 
  24. $criteria = []; 
  25. foreach ($query as $term) { 
  26. $criteria[$term->name] = $term->toparam(); 
  27. $criteria["ids"] = CustomerSearch::ids()->in($ids)->toparam(); 
  28. $path = $this->_config->merchantPath() . '/customers/advanced_search'; 
  29. $response = $this->_http->post($path, ['search' => $criteria]); 
  30.  
  31. return Util::extractattributeasarray( 
  32. $response['customers'],  
  33. 'customer' 
  34. ); 
  35.  
  36. /** 
  37. * Creates a customer using the given +attributes+. If <tt>:id</tt> is not passed,  
  38. * the gateway will generate it. 
  39. * <code> 
  40. * $result = Customer::create(array( 
  41. * 'first_name' => 'John',  
  42. * 'last_name' => 'Smith',  
  43. * 'company' => 'Smith Co.',  
  44. * 'email' => 'john@smith.com',  
  45. * 'website' => 'www.smithco.com',  
  46. * 'fax' => '419-555-1234',  
  47. * 'phone' => '614-555-1234' 
  48. * )); 
  49. * if($result->success) { 
  50. * echo 'Created customer ' . $result->customer->id; 
  51. * } else { 
  52. * echo 'Could not create customer, see result->errors'; 
  53. * } 
  54. * </code> 
  55. * @access public 
  56. * @param array $attribs 
  57. * @return Braintree_Result_Successful|Braintree_Result_Error 
  58. */ 
  59. public function create($attribs = []) 
  60. Util::verifyKeys(self::createSignature(), $attribs); 
  61. return $this->_doCreate('/customers', ['customer' => $attribs]); 
  62.  
  63. /** 
  64. * attempts the create operation assuming all data will validate 
  65. * returns a Customer object instead of a Result 
  66. * @access public 
  67. * @param array $attribs 
  68. * @return Customer 
  69. * @throws Exception\ValidationError 
  70. */ 
  71. public function createNoValidate($attribs = []) 
  72. $result = $this->create($attribs); 
  73. return Util::returnObjectOrThrowException(__CLASS__, $result); 
  74. /** 
  75. * create a customer from a TransparentRedirect operation 
  76. * @deprecated since version 2.3.0 
  77. * @access public 
  78. * @param array $attribs 
  79. * @return Customer 
  80. */ 
  81. public function createFromTransparentRedirect($queryString) 
  82. trigger_error("DEPRECATED: Please use TransparentRedirectRequest::confirm", E_USER_NOTICE); 
  83. $params = TransparentRedirect::parseAndValidateQueryString( 
  84. $queryString 
  85. ); 
  86. return $this->_doCreate( 
  87. '/customers/all/confirm_transparent_redirect_request',  
  88. ['id' => $params['id']] 
  89. ); 
  90.  
  91. /** 
  92. * @deprecated since version 2.3.0 
  93. * @access public 
  94. * @param none 
  95. * @return string 
  96. */ 
  97. public function createCustomerUrl() 
  98. trigger_error("DEPRECATED: Please use TransparentRedirectRequest::url", E_USER_NOTICE); 
  99. return $this->_config->baseUrl() . $this->_config->merchantPath() . 
  100. '/customers/all/create_via_transparent_redirect_request'; 
  101.  
  102.  
  103. /** 
  104. * creates a full array signature of a valid create request 
  105. * @return array gateway create request format 
  106. */ 
  107. public static function createSignature() 
  108.  
  109. $creditCardSignature = CreditCardGateway::createSignature(); 
  110. unset($creditCardSignature[array_search('customerId', $creditCardSignature)]); 
  111. $signature = [ 
  112. 'id', 'company', 'email', 'fax', 'firstName',  
  113. 'lastName', 'phone', 'website', 'deviceData',  
  114. 'deviceSessionId', 'fraudMerchantId', 'paymentMethodNonce',  
  115. ['creditCard' => $creditCardSignature],  
  116. ['customFields' => ['_anyKey_']],  
  117. ]; 
  118. return $signature; 
  119.  
  120. /** 
  121. * creates a full array signature of a valid update request 
  122. * @return array update request format 
  123. */ 
  124. public static function updateSignature() 
  125. $creditCardSignature = CreditCardGateway::updateSignature(); 
  126.  
  127. foreach($creditCardSignature AS $key => $value) { 
  128. if(is_array($value) and array_key_exists('options', $value)) { 
  129. array_push($creditCardSignature[$key]['options'], 'updateExistingToken'); 
  130.  
  131. $signature = [ 
  132. 'id', 'company', 'email', 'fax', 'firstName',  
  133. 'lastName', 'phone', 'website', 'deviceData',  
  134. 'deviceSessionId', 'fraudMerchantId', 'paymentMethodNonce',  
  135. ['creditCard' => $creditCardSignature],  
  136. ['customFields' => ['_anyKey_']],  
  137. ]; 
  138. return $signature; 
  139.  
  140.  
  141. /** 
  142. * find a customer by id 
  143. * @access public 
  144. * @param string id customer Id 
  145. * @return Customer|boolean The customer object or false if the request fails. 
  146. * @throws Exception\NotFound 
  147. */ 
  148. public function find($id) 
  149. $this->_validateId($id); 
  150. try { 
  151. $path = $this->_config->merchantPath() . '/customers/' . $id; 
  152. $response = $this->_http->get($path); 
  153. return Customer::factory($response['customer']); 
  154. } catch (Exception\NotFound $e) { 
  155. throw new Exception\NotFound( 
  156. 'customer with id ' . $id . ' not found' 
  157. ); 
  158.  
  159. /** 
  160. * credit a customer for the passed transaction 
  161. * @access public 
  162. * @param int $customerId 
  163. * @param array $transactionAttribs 
  164. * @return Result\Successful|Result\Error 
  165. */ 
  166. public function credit($customerId, $transactionAttribs) 
  167. $this->_validateId($customerId); 
  168. return Transaction::credit( 
  169. array_merge($transactionAttribs,  
  170. ['customerId' => $customerId] 
  171. ); 
  172.  
  173. /** 
  174. * credit a customer, assuming validations will pass 
  175. * returns a Transaction object on success 
  176. * @access public 
  177. * @param int $customerId 
  178. * @param array $transactionAttribs 
  179. * @return Transaction 
  180. * @throws Exception\ValidationError 
  181. */ 
  182. public function creditNoValidate($customerId, $transactionAttribs) 
  183. $result = $this->credit($customerId, $transactionAttribs); 
  184. return Util::returnObjectOrThrowException('Braintree\Transaction', $result); 
  185.  
  186. /** 
  187. * delete a customer by id 
  188. * @param string $customerId 
  189. */ 
  190. public function delete($customerId) 
  191. $this->_validateId($customerId); 
  192. $path = $this->_config->merchantPath() . '/customers/' . $customerId; 
  193. $this->_http->delete($path); 
  194. return new Result\Successful(); 
  195.  
  196. /** 
  197. * create a new sale for a customer 
  198. * @param string $customerId 
  199. * @param array $transactionAttribs 
  200. * @return Result\Successful|Result\Error 
  201. * @see Transaction::sale() 
  202. */ 
  203. public function sale($customerId, $transactionAttribs) 
  204. $this->_validateId($customerId); 
  205. return Transaction::sale( 
  206. array_merge($transactionAttribs,  
  207. ['customerId' => $customerId] 
  208. ); 
  209.  
  210. /** 
  211. * create a new sale for a customer, assuming validations will pass 
  212. * returns a Transaction object on success 
  213. * @access public 
  214. * @param string $customerId 
  215. * @param array $transactionAttribs 
  216. * @return Transaction 
  217. * @throws Exception\ValidationsFailed 
  218. * @see Transaction::sale() 
  219. */ 
  220. public function saleNoValidate($customerId, $transactionAttribs) 
  221. $result = $this->sale($customerId, $transactionAttribs); 
  222. return Util::returnObjectOrThrowException('Braintree\Transaction', $result); 
  223.  
  224. /** 
  225. * Returns a ResourceCollection of customers matching the search query. 
  226. * If <b>query</b> is a string, the search will be a basic search. 
  227. * If <b>query</b> is a hash, the search will be an advanced search. 
  228. * For more detailed information and examples, see {@link http://www.braintreepayments.com/gateway/customer-api#searching http://www.braintreepaymentsolutions.com/gateway/customer-api} 
  229. * @param mixed $query search query 
  230. * @return ResourceCollection 
  231. * @throws InvalidArgumentException 
  232. */ 
  233. public function search($query) 
  234. $criteria = []; 
  235. foreach ($query as $term) { 
  236. $result = $term->toparam(); 
  237. if(is_null($result) || empty($result)) { 
  238. throw new InvalidArgumentException('Operator must be provided'); 
  239.  
  240. $criteria[$term->name] = $term->toparam(); 
  241.  
  242. $path = $this->_config->merchantPath() . '/customers/advanced_search_ids'; 
  243. $response = $this->_http->post($path, ['search' => $criteria]); 
  244. $pager = [ 
  245. 'object' => $this,  
  246. 'method' => 'fetch',  
  247. 'methodArgs' => [$query] 
  248. ]; 
  249.  
  250. return new ResourceCollection($response, $pager); 
  251.  
  252. /** 
  253. * updates the customer record 
  254. * if calling this method in static context, customerId 
  255. * is the 2nd attribute. customerId is not sent in object context. 
  256. * @access public 
  257. * @param string $customerId (optional) 
  258. * @param array $attributes 
  259. * @return Result\Successful|Result\Error 
  260. */ 
  261. public function update($customerId, $attributes) 
  262. Util::verifyKeys(self::updateSignature(), $attributes); 
  263. $this->_validateId($customerId); 
  264. return $this->_doUpdate( 
  265. 'put',  
  266. '/customers/' . $customerId,  
  267. ['customer' => $attributes] 
  268. ); 
  269.  
  270. /** 
  271. * update a customer record, assuming validations will pass 
  272. * if calling this method in static context, customerId 
  273. * is the 2nd attribute. customerId is not sent in object context. 
  274. * returns a Customer object on success 
  275. * @access public 
  276. * @param string $customerId 
  277. * @param array $attributes 
  278. * @return Customer 
  279. * @throws Exception\ValidationsFailed 
  280. */ 
  281. public function updateNoValidate($customerId, $attributes) 
  282. $result = $this->update($customerId, $attributes); 
  283. return Util::returnObjectOrThrowException(__CLASS__, $result); 
  284. /** 
  285. * @deprecated since version 2.3.0 
  286. * @access public 
  287. * @return string 
  288. */ 
  289. public function updateCustomerUrl() 
  290. trigger_error("DEPRECATED: Please use TransparentRedirectRequest::url", E_USER_NOTICE); 
  291. return $this->_config->baseUrl() . $this->_config->merchantPath() . 
  292. '/customers/all/update_via_transparent_redirect_request'; 
  293.  
  294. /** 
  295. * update a customer from a TransparentRedirect operation 
  296. * @deprecated since version 2.3.0 
  297. * @access public 
  298. * @param string $queryString 
  299. * @return object 
  300. */ 
  301. public function updateFromTransparentRedirect($queryString) 
  302. trigger_error("DEPRECATED: Please use TransparentRedirectRequest::confirm", E_USER_NOTICE); 
  303. $params = TransparentRedirect::parseAndValidateQueryString( 
  304. $queryString 
  305. ); 
  306. return $this->_doUpdate( 
  307. 'post',  
  308. '/customers/all/confirm_transparent_redirect_request',  
  309. ['id' => $params['id']] 
  310. ); 
  311.  
  312. /** instance methods */ 
  313.  
  314. /** 
  315. * sets instance properties from an array of values 
  316. * @ignore 
  317. * @access protected 
  318. * @param array $customerAttribs array of customer data 
  319. * @return void 
  320. */ 
  321. protected function _initialize($customerAttribs) 
  322. // set the attributes 
  323. $this->_attributes = $customerAttribs; 
  324.  
  325. // map each address into its own object 
  326. $addressArray = []; 
  327. if (isset($customerAttribs['addresses'])) { 
  328.  
  329. foreach ($customerAttribs['addresses'] AS $address) { 
  330. $addressArray[] = Address::factory($address); 
  331. $this->_set('addresses', $addressArray); 
  332.  
  333. // map each creditCard into its own object 
  334. $creditCardArray = []; 
  335. if (isset($customerAttribs['creditCards'])) { 
  336. foreach ($customerAttribs['creditCards'] AS $creditCard) { 
  337. $creditCardArray[] = CreditCard::factory($creditCard); 
  338. $this->_set('creditCards', $creditCardArray); 
  339.  
  340. // map each coinbaseAccount into its own object 
  341. $coinbaseAccountArray = []; 
  342. if (isset($customerAttribs['coinbaseAccounts'])) { 
  343. foreach ($customerAttribs['coinbaseAccounts'] AS $coinbaseAccount) { 
  344. $coinbaseAccountArray[] = CoinbaseAccount::factory($coinbaseAccount); 
  345. $this->_set('coinbaseAccounts', $coinbaseAccountArray); 
  346.  
  347. // map each paypalAccount into its own object 
  348. $paypalAccountArray = []; 
  349. if (isset($customerAttribs['paypalAccounts'])) { 
  350. foreach ($customerAttribs['paypalAccounts'] AS $paypalAccount) { 
  351. $paypalAccountArray[] = PayPalAccount::factory($paypalAccount); 
  352. $this->_set('paypalAccounts', $paypalAccountArray); 
  353.  
  354. // map each applePayCard into its own object 
  355. $applePayCardArray = []; 
  356. if (isset($customerAttribs['applePayCards'])) { 
  357. foreach ($customerAttribs['applePayCards'] AS $applePayCard) { 
  358. $applePayCardArray[] = ApplePayCard::factory($applePayCard); 
  359. $this->_set('applePayCards', $applePayCardArray); 
  360.  
  361. // map each androidPayCard into its own object 
  362. $androidPayCardArray = []; 
  363. if (isset($customerAttribs['androidPayCards'])) { 
  364. foreach ($customerAttribs['androidPayCards'] AS $androidPayCard) { 
  365. $androidPayCardArray[] = AndroidPayCard::factory($androidPayCard); 
  366. $this->_set('androidPayCards', $androidPayCardArray); 
  367.  
  368. $this->_set('paymentMethods', array_merge($this->creditCards, $this->paypalAccounts, $this->applePayCards, $this->coinbaseAccounts, $this->androidPayCards)); 
  369.  
  370. /** 
  371. * returns a string representation of the customer 
  372. * @return string 
  373. */ 
  374. public function __toString() 
  375. return __CLASS__ . '[' . 
  376. Util::attributesToString($this->_attributes) .']'; 
  377.  
  378. /** 
  379. * returns false if comparing object is not a Customer,  
  380. * or is a Customer with a different id 
  381. * @param object $otherCust customer to compare against 
  382. * @return boolean 
  383. */ 
  384. public function isEqual($otherCust) 
  385. return !($otherCust instanceof Customer) ? false : $this->id === $otherCust->id; 
  386.  
  387. /** 
  388. * returns an array containt all of the customer's payment methods 
  389. * @return array 
  390. */ 
  391. public function paymentMethods() 
  392. return $this->paymentMethods; 
  393.  
  394. /** 
  395. * returns the customer's default payment method 
  396. * @return CreditCard|PayPalAccount|ApplePayCard|AndroidPayCard 
  397. */ 
  398. public function defaultPaymentMethod() 
  399. $defaultPaymentMethods = array_filter($this->paymentMethods, 'Braintree\\Customer::_defaultPaymentMethodFilter'); 
  400. return current($defaultPaymentMethods); 
  401.  
  402. public static function _defaultPaymentMethodFilter($paymentMethod) 
  403. return $paymentMethod->isDefault(); 
  404.  
  405. /** private class properties */ 
  406.  
  407. /** 
  408. * @access protected 
  409. * @var array registry of customer data 
  410. */ 
  411. protected $_attributes = [ 
  412. 'addresses' => '',  
  413. 'company' => '',  
  414. 'creditCards' => '',  
  415. 'email' => '',  
  416. 'fax' => '',  
  417. 'firstName' => '',  
  418. 'id' => '',  
  419. 'lastName' => '',  
  420. 'phone' => '',  
  421. 'createdAt' => '',  
  422. 'updatedAt' => '',  
  423. 'website' => '',  
  424. ]; 
  425.  
  426. /** 
  427. * sends the create request to the gateway 
  428. * @ignore 
  429. * @param string $subPath 
  430. * @param array $params 
  431. * @return mixed 
  432. */ 
  433. public function _doCreate($subPath, $params) 
  434. $fullPath = $this->_config->merchantPath() . $subPath; 
  435. $response = $this->_http->post($fullPath, $params); 
  436.  
  437. return $this->_verifyGatewayResponse($response); 
  438.  
  439. /** 
  440. * verifies that a valid customer id is being used 
  441. * @ignore 
  442. * @param string customer id 
  443. * @throws InvalidArgumentException 
  444. */ 
  445. private function _validateId($id = null) { 
  446. if (is_null($id)) { 
  447. throw new InvalidArgumentException( 
  448. 'expected customer id to be set' 
  449. ); 
  450. if (!preg_match('/^[0-9A-Za-z_-]+$/', $id)) { 
  451. throw new InvalidArgumentException( 
  452. $id . ' is an invalid customer id.' 
  453. ); 
  454.  
  455.  
  456. /** private class methods */ 
  457.  
  458. /** 
  459. * sends the update request to the gateway 
  460. * @ignore 
  461. * @param string $subPath 
  462. * @param array $params 
  463. * @return mixed 
  464. */ 
  465. private function _doUpdate($httpVerb, $subPath, $params) 
  466. $fullPath = $this->_config->merchantPath() . $subPath; 
  467. $response = $this->_http->$httpVerb($fullPath, $params); 
  468.  
  469. return $this->_verifyGatewayResponse($response); 
  470.  
  471. /** 
  472. * generic method for validating incoming gateway responses 
  473. * creates a new Customer object and encapsulates 
  474. * it inside a Result\Successful object, or 
  475. * encapsulates a Errors object inside a Result\Error 
  476. * alternatively, throws an Unexpected exception if the response is invalid. 
  477. * @ignore 
  478. * @param array $response gateway response values 
  479. * @return Result\Successful|Result\Error 
  480. * @throws Exception\Unexpected 
  481. */ 
  482. private function _verifyGatewayResponse($response) 
  483. if (isset($response['customer'])) { 
  484. // return a populated instance of Customer 
  485. return new Result\Successful( 
  486. Customer::factory($response['customer']) 
  487. ); 
  488. } else if (isset($response['apiErrorResponse'])) { 
  489. return new Result\Error($response['apiErrorResponse']); 
  490. } else { 
  491. throw new Exception\Unexpected( 
  492. "Expected customer or apiErrorResponse" 
  493. );