BraintreeCreditCardGateway

Braintree CreditCardGateway module Creates and manages Braintree CreditCards.

Defined (1)

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

/includes/lib/Braintree/lib/Braintree/CreditCardGateway.php  
  1. class CreditCardGateway 
  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 create($attribs) 
  13. Util::verifyKeys(self::createSignature(), $attribs); 
  14. return $this->_doCreate('/payment_methods', ['credit_card' => $attribs]); 
  15.  
  16. /** 
  17. * attempts the create operation assuming all data will validate 
  18. * returns a CreditCard object instead of a Result 
  19. * @access public 
  20. * @param array $attribs 
  21. * @return CreditCard 
  22. * @throws Exception\ValidationError 
  23. */ 
  24. public function createNoValidate($attribs) 
  25. $result = $this->create($attribs); 
  26. return Util::returnObjectOrThrowException(__CLASS__, $result); 
  27. /** 
  28. * create a customer from a TransparentRedirect operation 
  29. * @deprecated since version 2.3.0 
  30. * @access public 
  31. * @param array $attribs 
  32. * @return Result\Successful|Result\Error 
  33. */ 
  34. public function createFromTransparentRedirect($queryString) 
  35. trigger_error("DEPRECATED: Please use TransparentRedirectRequest::confirm", E_USER_NOTICE); 
  36. $params = TransparentRedirect::parseAndValidateQueryString( 
  37. $queryString 
  38. ); 
  39. return $this->_doCreate( 
  40. '/payment_methods/all/confirm_transparent_redirect_request',  
  41. ['id' => $params['id']] 
  42. ); 
  43.  
  44. /** 
  45. * @deprecated since version 2.3.0 
  46. * @access public 
  47. * @param none 
  48. * @return string 
  49. */ 
  50. public function createCreditCardUrl() 
  51. trigger_error("DEPRECATED: Please use TransparentRedirectRequest::url", E_USER_NOTICE); 
  52. return $this->_config->baseUrl() . $this->_config->merchantPath(). 
  53. '/payment_methods/all/create_via_transparent_redirect_request'; 
  54.  
  55. /** 
  56. * returns a ResourceCollection of expired credit cards 
  57. * @return ResourceCollection 
  58. */ 
  59. public function expired() 
  60. $path = $this->_config->merchantPath() . '/payment_methods/all/expired_ids'; 
  61. $response = $this->_http->post($path); 
  62. $pager = [ 
  63. 'object' => $this,  
  64. 'method' => 'fetchExpired',  
  65. 'methodArgs' => [] 
  66. ]; 
  67.  
  68. return new ResourceCollection($response, $pager); 
  69.  
  70. public function fetchExpired($ids) 
  71. $path = $this->_config->merchantPath() . "/payment_methods/all/expired"; 
  72. $response = $this->_http->post($path, ['search' => ['ids' => $ids]]); 
  73.  
  74. return Util::extractattributeasarray( 
  75. $response['paymentMethods'],  
  76. 'creditCard' 
  77. ); 
  78. /** 
  79. * returns a ResourceCollection of credit cards expiring between start/end 
  80. * @return ResourceCollection 
  81. */ 
  82. public function expiringBetween($startDate, $endDate) 
  83. $queryPath = $this->_config->merchantPath() . '/payment_methods/all/expiring_ids?start=' . date('mY', $startDate) . '&end=' . date('mY', $endDate); 
  84. $response = $this->_http->post($queryPath); 
  85. $pager = [ 
  86. 'object' => $this,  
  87. 'method' => 'fetchExpiring',  
  88. 'methodArgs' => [$startDate, $endDate] 
  89. ]; 
  90.  
  91. return new ResourceCollection($response, $pager); 
  92.  
  93. public function fetchExpiring($startDate, $endDate, $ids) 
  94. $queryPath = $this->_config->merchantPath() . '/payment_methods/all/expiring?start=' . date('mY', $startDate) . '&end=' . date('mY', $endDate); 
  95. $response = $this->_http->post($queryPath, ['search' => ['ids' => $ids]]); 
  96.  
  97. return Util::extractAttributeAsArray( 
  98. $response['paymentMethods'],  
  99. 'creditCard' 
  100. ); 
  101.  
  102. /** 
  103. * find a creditcard by token 
  104. * @access public 
  105. * @param string $token credit card unique id 
  106. * @return CreditCard 
  107. * @throws Exception\NotFound 
  108. */ 
  109. public function find($token) 
  110. $this->_validateId($token); 
  111. try { 
  112. $path = $this->_config->merchantPath() . '/payment_methods/credit_card/' . $token; 
  113. $response = $this->_http->get($path); 
  114. return CreditCard::factory($response['creditCard']); 
  115. } catch (Exception\NotFound $e) { 
  116. throw new Exception\NotFound( 
  117. 'credit card with token ' . $token . ' not found' 
  118. ); 
  119.  
  120.  
  121. /** 
  122. * Convert a payment method nonce to a credit card 
  123. * @access public 
  124. * @param string $nonce payment method nonce 
  125. * @return CreditCard 
  126. * @throws Exception\NotFound 
  127. */ 
  128. public function fromNonce($nonce) 
  129. $this->_validateId($nonce, "nonce"); 
  130. try { 
  131. $path = $this->_config->merchantPath() . '/payment_methods/from_nonce/' . $nonce; 
  132. $response = $this->_http->get($path); 
  133. return CreditCard::factory($response['creditCard']); 
  134. } catch (Exception\NotFound $e) { 
  135. throw new Exception\NotFound( 
  136. 'credit card with nonce ' . $nonce . ' locked, consumed or not found' 
  137. ); 
  138.  
  139.  
  140. /** 
  141. * create a credit on the card for the passed transaction 
  142. * @access public 
  143. * @param array $attribs 
  144. * @return Result\Successful|Result\Error 
  145. */ 
  146. public function credit($token, $transactionAttribs) 
  147. $this->_validateId($token); 
  148. return Transaction::credit( 
  149. array_merge( 
  150. $transactionAttribs,  
  151. ['paymentMethodToken' => $token] 
  152. ); 
  153.  
  154. /** 
  155. * create a credit on this card, assuming validations will pass 
  156. * returns a Transaction object on success 
  157. * @access public 
  158. * @param array $attribs 
  159. * @return Transaction 
  160. * @throws Exception\ValidationError 
  161. */ 
  162. public function creditNoValidate($token, $transactionAttribs) 
  163. $result = $this->credit($token, $transactionAttribs); 
  164. return Util::returnObjectOrThrowException('Braintree\Transaction', $result); 
  165.  
  166. /** 
  167. * create a new sale for the current card 
  168. * @param string $token 
  169. * @param array $transactionAttribs 
  170. * @return Result\Successful|Result\Error 
  171. * @see Transaction::sale() 
  172. */ 
  173. public function sale($token, $transactionAttribs) 
  174. $this->_validateId($token); 
  175. return Transaction::sale( 
  176. array_merge( 
  177. $transactionAttribs,  
  178. ['paymentMethodToken' => $token] 
  179. ); 
  180.  
  181. /** 
  182. * create a new sale using this card, assuming validations will pass 
  183. * returns a Transaction object on success 
  184. * @access public 
  185. * @param array $transactionAttribs 
  186. * @param string $token 
  187. * @return Transaction 
  188. * @throws Exception\ValidationsFailed 
  189. * @see Transaction::sale() 
  190. */ 
  191. public function saleNoValidate($token, $transactionAttribs) 
  192. $result = $this->sale($token, $transactionAttribs); 
  193. return Util::returnObjectOrThrowException('Braintree\Transaction', $result); 
  194.  
  195. /** 
  196. * updates the creditcard record 
  197. * if calling this method in context, $token 
  198. * is the 2nd attribute. $token is not sent in object context. 
  199. * @access public 
  200. * @param array $attributes 
  201. * @param string $token (optional) 
  202. * @return Result\Successful|Result\Error 
  203. */ 
  204. public function update($token, $attributes) 
  205. Util::verifyKeys(self::updateSignature(), $attributes); 
  206. $this->_validateId($token); 
  207. return $this->_doUpdate('put', '/payment_methods/credit_card/' . $token, ['creditCard' => $attributes]); 
  208.  
  209. /** 
  210. * update a creditcard record, assuming validations will pass 
  211. * if calling this method in context, $token 
  212. * is the 2nd attribute. $token is not sent in object context. 
  213. * returns a CreditCard object on success 
  214. * @access public 
  215. * @param array $attributes 
  216. * @param string $token 
  217. * @return CreditCard 
  218. * @throws Exception\ValidationsFailed 
  219. */ 
  220. public function updateNoValidate($token, $attributes) 
  221. $result = $this->update($token, $attributes); 
  222. return Util::returnObjectOrThrowException(__CLASS__, $result); 
  223. /** 
  224. * @access public 
  225. * @param none 
  226. * @return string 
  227. */ 
  228. public function updateCreditCardUrl() 
  229. trigger_error("DEPRECATED: Please use TransparentRedirectRequest::url", E_USER_NOTICE); 
  230. return $this->_config->baseUrl() . $this->_config->merchantPath() . 
  231. '/payment_methods/all/update_via_transparent_redirect_request'; 
  232.  
  233. /** 
  234. * update a customer from a TransparentRedirect operation 
  235. * @deprecated since version 2.3.0 
  236. * @access public 
  237. * @param array $attribs 
  238. * @return object 
  239. */ 
  240. public function updateFromTransparentRedirect($queryString) 
  241. trigger_error("DEPRECATED: Please use TransparentRedirectRequest::confirm", E_USER_NOTICE); 
  242. $params = TransparentRedirect::parseAndValidateQueryString( 
  243. $queryString 
  244. ); 
  245. return $this->_doUpdate( 
  246. 'post',  
  247. '/payment_methods/all/confirm_transparent_redirect_request',  
  248. ['id' => $params['id']] 
  249. ); 
  250.  
  251. public function delete($token) 
  252. $this->_validateId($token); 
  253. $path = $this->_config->merchantPath() . '/payment_methods/credit_card/' . $token; 
  254. $this->_http->delete($path); 
  255. return new Result\Successful(); 
  256.  
  257. private static function baseOptions() 
  258. return ['makeDefault', 'verificationMerchantAccountId', 'verifyCard', 'verificationAmount', 'venmoSdkSession']; 
  259.  
  260. private static function baseSignature($options) 
  261. return [ 
  262. 'billingAddressId', 'cardholderName', 'cvv', 'number', 'deviceSessionId',  
  263. 'expirationDate', 'expirationMonth', 'expirationYear', 'token', 'venmoSdkPaymentMethodCode',  
  264. 'deviceData', 'fraudMerchantId', 'paymentMethodNonce',  
  265. ['options' => $options],  
  266. 'billingAddress' => self::billingAddressSignature() 
  267. ],  
  268. ]; 
  269.  
  270. public static function billingAddressSignature() 
  271. return [ 
  272. 'firstName',  
  273. 'lastName',  
  274. 'company',  
  275. 'countryCodeAlpha2',  
  276. 'countryCodeAlpha3',  
  277. 'countryCodeNumeric',  
  278. 'countryName',  
  279. 'extendedAddress',  
  280. 'locality',  
  281. 'region',  
  282. 'postalCode',  
  283. 'streetAddress' 
  284. ]; 
  285.  
  286. public static function createSignature() 
  287. $options = self::baseOptions(); 
  288. $options[] = "failOnDuplicatePaymentMethod"; 
  289. $signature = self::baseSignature($options); 
  290. $signature[] = 'customerId'; 
  291. return $signature; 
  292.  
  293. public static function updateSignature() 
  294. $options = self::baseOptions(); 
  295. $options[] = "failOnDuplicatePaymentMethod"; 
  296. $signature = self::baseSignature($options); 
  297.  
  298. $updateExistingBillingSignature = [ 
  299. 'options' => [ 
  300. 'updateExisting' 
  301. ]; 
  302.  
  303. foreach($signature AS $key => $value) { 
  304. if(is_array($value) and array_key_exists('billingAddress', $value)) { 
  305. $signature[$key]['billingAddress'] = array_merge_recursive($value['billingAddress'], $updateExistingBillingSignature); 
  306.  
  307. return $signature; 
  308.  
  309. /** 
  310. * sends the create request to the gateway 
  311. * @ignore 
  312. * @param string $subPath 
  313. * @param array $params 
  314. * @return mixed 
  315. */ 
  316. public function _doCreate($subPath, $params) 
  317. $fullPath = $this->_config->merchantPath() . $subPath; 
  318. $response = $this->_http->post($fullPath, $params); 
  319.  
  320. return $this->_verifyGatewayResponse($response); 
  321.  
  322. /** 
  323. * verifies that a valid credit card identifier is being used 
  324. * @ignore 
  325. * @param string $identifier 
  326. * @param Optional $string $identifierType type of identifier supplied, default "token" 
  327. * @throws InvalidArgumentException 
  328. */ 
  329. private function _validateId($identifier = null, $identifierType = "token") 
  330. if (empty($identifier)) { 
  331. throw new InvalidArgumentException( 
  332. 'expected credit card id to be set' 
  333. ); 
  334. if (!preg_match('/^[0-9A-Za-z_-]+$/', $identifier)) { 
  335. throw new InvalidArgumentException( 
  336. $identifier . ' is an invalid credit card ' . $identifierType . '.' 
  337. ); 
  338.  
  339. /** 
  340. * sends the update request to the gateway 
  341. * @ignore 
  342. * @param string $url 
  343. * @param array $params 
  344. * @return mixed 
  345. */ 
  346. private function _doUpdate($httpVerb, $subPath, $params) 
  347. $fullPath = $this->_config->merchantPath() . $subPath; 
  348. $response = $this->_http->$httpVerb($fullPath, $params); 
  349. return $this->_verifyGatewayResponse($response); 
  350.  
  351. /** 
  352. * generic method for validating incoming gateway responses 
  353. * creates a new CreditCard object and encapsulates 
  354. * it inside a Result\Successful object, or 
  355. * encapsulates a Errors object inside a Result\Error 
  356. * alternatively, throws an Unexpected exception if the response is invalid 
  357. * @ignore 
  358. * @param array $response gateway response values 
  359. * @return Result\Successful|Result\Error 
  360. * @throws Exception\Unexpected 
  361. */ 
  362. private function _verifyGatewayResponse($response) 
  363. if (isset($response['creditCard'])) { 
  364. // return a populated instance of Address 
  365. return new Result\Successful( 
  366. CreditCard::factory($response['creditCard']) 
  367. ); 
  368. } elseif (isset($response['apiErrorResponse'])) { 
  369. return new Result\Error($response['apiErrorResponse']); 
  370. } else { 
  371. throw new Exception\Unexpected( 
  372. "Expected address or apiErrorResponse" 
  373. );