BraintreeTransactionGateway

Braintree TransactionGateway processor Creates and manages transactions.

Defined (1)

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

/includes/lib/Braintree/lib/Braintree/TransactionGateway.php  
  1. class TransactionGateway 
  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 cloneTransaction($transactionId, $attribs) 
  13. Util::verifyKeys(self::cloneSignature(), $attribs); 
  14. return $this->_doCreate('/transactions/' . $transactionId . '/clone', ['transactionClone' => $attribs]); 
  15.  
  16. /** 
  17. * @ignore 
  18. * @access private 
  19. * @param array $attribs 
  20. * @return object 
  21. */ 
  22. private function create($attribs) 
  23. Util::verifyKeys(self::createSignature(), $attribs); 
  24. return $this->_doCreate('/transactions', ['transaction' => $attribs]); 
  25.  
  26. /** 
  27. * @ignore 
  28. * @access private 
  29. * @param array $attribs 
  30. * @return object 
  31. * @throws Exception\ValidationError 
  32. */ 
  33. private function createNoValidate($attribs) 
  34. $result = $this->create($attribs); 
  35. return Util::returnObjectOrThrowException(__CLASS__, $result); 
  36. /** 
  37. * @deprecated since version 2.3.0 
  38. * @access public 
  39. * @param array $attribs 
  40. * @return object 
  41. */ 
  42. public function createFromTransparentRedirect($queryString) 
  43. trigger_error("DEPRECATED: Please use TransparentRedirectRequest::confirm", E_USER_NOTICE); 
  44. $params = TransparentRedirect::parseAndValidateQueryString( 
  45. $queryString 
  46. ); 
  47. return $this->_doCreate( 
  48. '/transactions/all/confirm_transparent_redirect_request',  
  49. ['id' => $params['id']] 
  50. ); 
  51. /** 
  52. * @deprecated since version 2.3.0 
  53. * @access public 
  54. * @param none 
  55. * @return string 
  56. */ 
  57. public function createTransactionUrl() 
  58. trigger_error("DEPRECATED: Please use TransparentRedirectRequest::url", E_USER_NOTICE); 
  59. return $this->_config->baseUrl() . $this->_config->merchantPath() . 
  60. '/transactions/all/create_via_transparent_redirect_request'; 
  61.  
  62. public static function cloneSignature() 
  63. return ['amount', 'channel', ['options' => ['submitForSettlement']]]; 
  64.  
  65. /** 
  66. * creates a full array signature of a valid gateway request 
  67. * @return array gateway request signature format 
  68. */ 
  69. public static function createSignature() 
  70. return [ 
  71. 'amount',  
  72. 'billingAddressId',  
  73. 'channel',  
  74. 'customerId',  
  75. 'deviceData',  
  76. 'deviceSessionId',  
  77. 'fraudMerchantId',  
  78. 'merchantAccountId',  
  79. 'orderId',  
  80. 'paymentMethodNonce',  
  81. 'paymentMethodToken',  
  82. 'purchaseOrderNumber',  
  83. 'recurring',  
  84. 'serviceFeeAmount',  
  85. 'sharedPaymentMethodToken',  
  86. 'sharedCustomerId',  
  87. 'sharedShippingAddressId',  
  88. 'sharedBillingAddressId',  
  89. 'shippingAddressId',  
  90. 'taxAmount',  
  91. 'taxExempt',  
  92. 'threeDSecureToken',  
  93. 'transactionSource',  
  94. 'type',  
  95. 'venmoSdkPaymentMethodCode',  
  96. ['riskData' => 
  97. ['customerBrowser', 'customerIp', 'customer_browser', 'customer_ip'] 
  98. ],  
  99. ['creditCard' => 
  100. ['token', 'cardholderName', 'cvv', 'expirationDate', 'expirationMonth', 'expirationYear', 'number'],  
  101. ],  
  102. ['customer' => 
  103. 'id', 'company', 'email', 'fax', 'firstName',  
  104. 'lastName', 'phone', 'website'],  
  105. ],  
  106. ['billing' => 
  107. 'firstName', 'lastName', 'company', 'countryName',  
  108. 'countryCodeAlpha2', 'countryCodeAlpha3', 'countryCodeNumeric',  
  109. 'extendedAddress', 'locality', 'postalCode', 'region',  
  110. 'streetAddress'],  
  111. ],  
  112. ['shipping' => 
  113. 'firstName', 'lastName', 'company', 'countryName',  
  114. 'countryCodeAlpha2', 'countryCodeAlpha3', 'countryCodeNumeric',  
  115. 'extendedAddress', 'locality', 'postalCode', 'region',  
  116. 'streetAddress'],  
  117. ],  
  118. ['threeDSecurePassThru' => 
  119. 'eciFlag',  
  120. 'cavv',  
  121. 'xid'],  
  122. ],  
  123. ['options' => 
  124. 'holdInEscrow',  
  125. 'storeInVault',  
  126. 'storeInVaultOnSuccess',  
  127. 'submitForSettlement',  
  128. 'addBillingAddressToPaymentMethod',  
  129. 'venmoSdkSession',  
  130. 'storeShippingAddressInVault',  
  131. 'payeeEmail',  
  132. 'skipAdvancedFraudChecking',  
  133. ['threeDSecure' => 
  134. ['required'] 
  135. ],  
  136. # Included for backwards compatiblity. Remove in the next major version 
  137. ['three_d_secure' => 
  138. ['required'] 
  139. ],  
  140. ['paypal' => 
  141. 'payeeEmail',  
  142. 'customField',  
  143. 'description',  
  144. ['supplementaryData' => ['_anyKey_']],  
  145. ],  
  146. ['amexRewards' => 
  147. 'requestId',  
  148. 'points',  
  149. 'currencyAmount',  
  150. 'currencyIsoCode' 
  151. ],  
  152. ],  
  153. ['customFields' => ['_anyKey_']],  
  154. ['descriptor' => ['name', 'phone', 'url']],  
  155. ['paypalAccount' => ['payeeEmail']],  
  156. ['apple_pay_card' => ['number', 'cardholder_name', 'cryptogram', 'expiration_month', 'expiration_year']], #backwards compatibility 
  157. ['applePayCard' => ['number', 'cardholderName', 'cryptogram', 'expirationMonth', 'expirationYear']],  
  158. ['industry' => 
  159. ['industryType',  
  160. ['data' => 
  161. 'folioNumber',  
  162. 'checkInDate',  
  163. 'checkOutDate',  
  164. 'travelPackage',  
  165. 'departureDate',  
  166. 'lodgingCheckInDate',  
  167. 'lodgingCheckOutDate',  
  168. 'lodgingName',  
  169. 'roomRate' 
  170. ]; 
  171.  
  172. public static function submitForSettlementSignature() 
  173. return ['orderId', ['descriptor' => ['name', 'phone', 'url']]]; 
  174.  
  175. public static function updateDetailsSignature() 
  176. return ['amount', 'orderId', ['descriptor' => ['name', 'phone', 'url']]]; 
  177.  
  178. public static function refundSignature() 
  179. return ['amount', 'orderId']; 
  180.  
  181. /** 
  182. * @access public 
  183. * @param array $attribs 
  184. * @return Result\Successful|Result\Error 
  185. */ 
  186. public function credit($attribs) 
  187. return $this->create(array_merge($attribs, ['type' => Transaction::CREDIT])); 
  188.  
  189. /** 
  190. * @access public 
  191. * @param array $attribs 
  192. * @return Result\Successful|Result\Error 
  193. * @throws Exception\ValidationError 
  194. */ 
  195. public function creditNoValidate($attribs) 
  196. $result = $this->credit($attribs); 
  197. return Util::returnObjectOrThrowException(__CLASS__, $result); 
  198.  
  199. /** 
  200. * @access public 
  201. * @param string id 
  202. * @return Transaction 
  203. */ 
  204. public function find($id) 
  205. $this->_validateId($id); 
  206. try { 
  207. $path = $this->_config->merchantPath() . '/transactions/' . $id; 
  208. $response = $this->_http->get($path); 
  209. return Transaction::factory($response['transaction']); 
  210. } catch (Exception\NotFound $e) { 
  211. throw new Exception\NotFound( 
  212. 'transaction with id ' . $id . ' not found' 
  213. ); 
  214. /** 
  215. * new sale 
  216. * @param array $attribs 
  217. * @return array 
  218. */ 
  219. public function sale($attribs) 
  220. return $this->create(array_merge(['type' => Transaction::SALE], $attribs)); 
  221.  
  222. /** 
  223. * roughly equivalent to the ruby bang method 
  224. * @access public 
  225. * @param array $attribs 
  226. * @return array 
  227. * @throws Exception\ValidationsFailed 
  228. */ 
  229. public function saleNoValidate($attribs) 
  230. $result = $this->sale($attribs); 
  231. return Util::returnObjectOrThrowException(__CLASS__, $result); 
  232.  
  233. /** 
  234. * Returns a ResourceCollection of transactions matching the search query. 
  235. * If <b>query</b> is a string, the search will be a basic search. 
  236. * If <b>query</b> is a hash, the search will be an advanced search. 
  237. * For more detailed information and examples, see {@link http://www.braintreepayments.com/gateway/transaction-api#searching http://www.braintreepaymentsolutions.com/gateway/transaction-api} 
  238. * @param mixed $query search query 
  239. * @param array $options options such as page number 
  240. * @return ResourceCollection 
  241. * @throws InvalidArgumentException 
  242. */ 
  243. public function search($query) 
  244. $criteria = []; 
  245. foreach ($query as $term) { 
  246. $criteria[$term->name] = $term->toparam(); 
  247.  
  248. $path = $this->_config->merchantPath() . '/transactions/advanced_search_ids'; 
  249. $response = $this->_http->post($path, ['search' => $criteria]); 
  250. if (array_key_exists('searchResults', $response)) { 
  251. $pager = [ 
  252. 'object' => $this,  
  253. 'method' => 'fetch',  
  254. 'methodArgs' => [$query] 
  255. ]; 
  256.  
  257. return new ResourceCollection($response, $pager); 
  258. } else { 
  259. throw new Exception\DownForMaintenance(); 
  260.  
  261. public function fetch($query, $ids) 
  262. $criteria = []; 
  263. foreach ($query as $term) { 
  264. $criteria[$term->name] = $term->toparam(); 
  265. $criteria["ids"] = TransactionSearch::ids()->in($ids)->toparam(); 
  266. $path = $this->_config->merchantPath() . '/transactions/advanced_search'; 
  267. $response = $this->_http->post($path, ['search' => $criteria]); 
  268.  
  269. if (array_key_exists('creditCardTransactions', $response)) { 
  270. return Util::extractattributeasarray( 
  271. $response['creditCardTransactions'],  
  272. 'transaction' 
  273. ); 
  274. } else { 
  275. throw new Exception\DownForMaintenance(); 
  276.  
  277. /** 
  278. * void a transaction by id 
  279. * @param string $id transaction id 
  280. * @return Result\Successful|Result\Error 
  281. */ 
  282. public function void($transactionId) 
  283. $this->_validateId($transactionId); 
  284.  
  285. $path = $this->_config->merchantPath() . '/transactions/'. $transactionId . '/void'; 
  286. $response = $this->_http->put($path); 
  287. return $this->_verifyGatewayResponse($response); 
  288. /** 
  289. */ 
  290. public function voidNoValidate($transactionId) 
  291. $result = $this->void($transactionId); 
  292. return Util::returnObjectOrThrowException(__CLASS__, $result); 
  293.  
  294. public function submitForSettlement($transactionId, $amount = null, $attribs = []) 
  295. $this->_validateId($transactionId); 
  296. Util::verifyKeys(self::submitForSettlementSignature(), $attribs); 
  297. $attribs['amount'] = $amount; 
  298.  
  299. $path = $this->_config->merchantPath() . '/transactions/'. $transactionId . '/submit_for_settlement'; 
  300. $response = $this->_http->put($path, ['transaction' => $attribs]); 
  301. return $this->_verifyGatewayResponse($response); 
  302.  
  303. public function submitForSettlementNoValidate($transactionId, $amount = null, $attribs = []) 
  304. $result = $this->submitForSettlement($transactionId, $amount, $attribs); 
  305. return Util::returnObjectOrThrowException(__CLASS__, $result); 
  306.  
  307. public function updateDetails($transactionId, $attribs = []) 
  308. $this->_validateId($transactionId); 
  309. Util::verifyKeys(self::updateDetailsSignature(), $attribs); 
  310.  
  311. $path = $this->_config->merchantPath() . '/transactions/'. $transactionId . '/update_details'; 
  312. $response = $this->_http->put($path, ['transaction' => $attribs]); 
  313. return $this->_verifyGatewayResponse($response); 
  314.  
  315. public function submitForPartialSettlement($transactionId, $amount, $attribs = []) 
  316. $this->_validateId($transactionId); 
  317. Util::verifyKeys(self::submitForSettlementSignature(), $attribs); 
  318. $attribs['amount'] = $amount; 
  319.  
  320. $path = $this->_config->merchantPath() . '/transactions/'. $transactionId . '/submit_for_partial_settlement'; 
  321. $response = $this->_http->post($path, ['transaction' => $attribs]); 
  322. return $this->_verifyGatewayResponse($response); 
  323.  
  324. public function holdInEscrow($transactionId) 
  325. $this->_validateId($transactionId); 
  326.  
  327. $path = $this->_config->merchantPath() . '/transactions/' . $transactionId . '/hold_in_escrow'; 
  328. $response = $this->_http->put($path, []); 
  329. return $this->_verifyGatewayResponse($response); 
  330.  
  331. public function releaseFromEscrow($transactionId) 
  332. $this->_validateId($transactionId); 
  333.  
  334. $path = $this->_config->merchantPath() . '/transactions/' . $transactionId . '/release_from_escrow'; 
  335. $response = $this->_http->put($path, []); 
  336. return $this->_verifyGatewayResponse($response); 
  337.  
  338. public function cancelRelease($transactionId) 
  339. $this->_validateId($transactionId); 
  340.  
  341. $path = $this->_config->merchantPath() . '/transactions/' . $transactionId . '/cancel_release'; 
  342. $response = $this->_http->put($path, []); 
  343. return $this->_verifyGatewayResponse($response); 
  344.  
  345. public function refund($transactionId, $amount_or_options = null) 
  346. self::_validateId($transactionId); 
  347.  
  348. if(gettype($amount_or_options) == "array") { 
  349. $options = $amount_or_options; 
  350. } else { 
  351. $options = [ 
  352. "amount" => $amount_or_options 
  353. ]; 
  354. Util::verifyKeys(self::refundSignature(), $options); 
  355.  
  356. $params = ['transaction' => $options]; 
  357. $path = $this->_config->merchantPath() . '/transactions/' . $transactionId . '/refund'; 
  358. $response = $this->_http->post($path, $params); 
  359. return $this->_verifyGatewayResponse($response); 
  360.  
  361. /** 
  362. * sends the create request to the gateway 
  363. * @ignore 
  364. * @param var $subPath 
  365. * @param array $params 
  366. * @return mixed 
  367. */ 
  368. public function _doCreate($subPath, $params) 
  369. $fullPath = $this->_config->merchantPath() . $subPath; 
  370. $response = $this->_http->post($fullPath, $params); 
  371.  
  372. return $this->_verifyGatewayResponse($response); 
  373.  
  374. /** 
  375. * verifies that a valid transaction id is being used 
  376. * @ignore 
  377. * @param string transaction id 
  378. * @throws InvalidArgumentException 
  379. */ 
  380. private function _validateId($id = null) { 
  381. if (empty($id)) { 
  382. throw new InvalidArgumentException( 
  383. 'expected transaction id to be set' 
  384. ); 
  385. if (!preg_match('/^[0-9a-z]+$/', $id)) { 
  386. throw new InvalidArgumentException( 
  387. $id . ' is an invalid transaction id.' 
  388. ); 
  389.  
  390. /** 
  391. * generic method for validating incoming gateway responses 
  392. * creates a new Transaction object and encapsulates 
  393. * it inside a Result\Successful object, or 
  394. * encapsulates a Errors object inside a Result\Error 
  395. * alternatively, throws an Unexpected exception if the response is invalid. 
  396. * @ignore 
  397. * @param array $response gateway response values 
  398. * @return Result\Successful|Result\Error 
  399. * @throws Exception\Unexpected 
  400. */ 
  401. private function _verifyGatewayResponse($response) 
  402. if (isset($response['transaction'])) { 
  403. // return a populated instance of Transaction 
  404. return new Result\Successful( 
  405. Transaction::factory($response['transaction']) 
  406. ); 
  407. } else if (isset($response['apiErrorResponse'])) { 
  408. return new Result\Error($response['apiErrorResponse']); 
  409. } else { 
  410. throw new Exception\Unexpected( 
  411. "Expected transaction or apiErrorResponse" 
  412. );