PageRenderTime 48ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/event-espresso.3.1.23.P/gateways/mwarrior/Mwarrior.php

https://bitbucket.org/anneivycat/ebcookhouse
PHP | 346 lines | 180 code | 49 blank | 117 comment | 26 complexity | 7e3ee927a9583716a1f872c7c27a2515 MD5 | raw file
  1. <?php
  2. /**
  3. * Mwarrior Class
  4. *
  5. * @author Rajinesh Ravendran (rajinesh@merchantwarrior.com)
  6. * @package Event Espresso Merchant Warrior Gateway
  7. * @category Library
  8. */
  9. class Mwarrior extends PaymentGateway{
  10. public $gateway_version = '1.0';
  11. public function __construct()
  12. {
  13. parent::__construct();
  14. // Some default values of the class
  15. $this->gatewayUrl = 'https://secure.merchantwarrior.com';
  16. $this->gatewayUrlQuery = 'https://api.merchantwarrior.com/post/';
  17. $this->ipnLogFile = 'mwarrior.ipn_results.log';
  18. }
  19. /**
  20. * Enables the test mode
  21. *
  22. * @param none
  23. * @return none
  24. */
  25. public function enableTestMode()
  26. {
  27. $this->testMode = TRUE;
  28. $this->gatewayUrl = 'https://securetest.merchantwarrior.com';
  29. $this->gatewayUrlQuery = 'https://base.merchantwarrior.com/post/';
  30. }
  31. /**
  32. * Set merchant id and passphrase
  33. *
  34. * @param string merchantID
  35. * @param string passphrase
  36. * @return void
  37. */
  38. public function setMerchantInfo($merchantID, $apikey, $passphrase)
  39. {
  40. $this->merchantID = $merchantID;
  41. $this->apikey = $apikey;
  42. $this->passphrase = $passphrase;
  43. }
  44. /**
  45. * Validate the IPN notification
  46. *
  47. * @param none
  48. * @return boolean
  49. */
  50. public function validateIpn()
  51. {
  52. if (empty($_POST))
  53. {
  54. // Redirect
  55. if(!empty($_REQUEST))
  56. {
  57. $this->response['status'] = (isset($_REQUEST['status']))? $_REQUEST['status'] : "N/A";
  58. $this->response['responseData']['transactionID'] = (isset($_REQUEST['reference'])) ? $_REQUEST['reference'] : "N/A" ;
  59. $this->response['responseData']['responseMessage'] = (isset($_REQUEST['error'])) ? $_REQUEST['error'] : "N/A";
  60. $this->response['responseData']['hash'] = (isset($_REQUEST['hash'])) ? $_REQUEST['hash'] : "N/A";
  61. }
  62. $xml = "n/a";
  63. }
  64. else
  65. {
  66. // Get XML POST notification
  67. $xml = file_get_contents('php://input', NULL, NULL, 0, 1024);
  68. $this->response = $this->_parseResponse($xml);
  69. $this->response['status'] = ($this->response['status'] == true) ? "approved" : "declined";
  70. }
  71. $this->response['attendee_id'] = (isset($_REQUEST['id']))? $_REQUEST['id'] : 0;
  72. $this->response['reg_id'] = espresso_registration_id($this->response['attendee_id']);
  73. if (isset($xml) && isset($this->response['status']) && $this->_calculateHash($this->response, 'redirect') == $this->response['responseData']['hash'])
  74. {
  75. // Valid IPN transaction.
  76. $this->logResults(true);
  77. return true;
  78. }
  79. else
  80. {
  81. $this->lastError = isset($this->response['error']) ? $this->response['error'] : $this->response['responseData']['responseMessage'];
  82. $this->logResults(false);
  83. return false;
  84. }
  85. }
  86. /**
  87. * Method that parses response from Merchant Warrior
  88. *
  89. * @param string $result (XML)
  90. * @return array
  91. */
  92. public function _parseResponse($result)
  93. {
  94. // Check for any result at all
  95. if ($result === false)
  96. {
  97. return array('status' => false, 'error' => "Could not successfully communicate with Payment Processor. Check the URL.", 'result' => $result);
  98. }
  99. // Parse the XML
  100. $xml = simplexml_load_string($result);
  101. // Convert the result from a SimpleXMLObject into an array
  102. $xml = (array) $xml;
  103. // Check for a valid response code
  104. if (!isset($xml['responseCode']) || strlen($xml['responseCode']) < 1)
  105. {
  106. return array('status' => false, 'error' => "Payment Processor did not return a valid response.", 'result' => $result, 'responseData' => $xml);
  107. }
  108. // Validate the response - the only successful code is 0
  109. $status = ((int) $xml['responseCode'] === 0) ? true : false;
  110. // Set an error message if the transaction failed
  111. if ($status === false)
  112. {
  113. return array('status' => false, 'error' => "Transaction Declined: {$xml['responseMessage']}.", 'result' => $result, 'responseData' => $xml);
  114. }
  115. // Make the response a little more useable - there are a few fields that may or may not be present
  116. // depending on the different transaction types, so this handles them all generically.
  117. $response = array ( 'status' => $status,
  118. 'result' => $result,
  119. 'responseData' => $xml,
  120. 'transactionID' => (isset($xml['transactionID']) ? $xml['transactionID'] : null),
  121. 'authCode' => (isset($xml['authCode']) ? $xml['authCode'] : null));
  122. return $response;
  123. }
  124. /**
  125. * Calculate verification hash for Merchant Warrior POST API
  126. *
  127. * @param array $postData
  128. * @param string $type
  129. * @return string
  130. */
  131. public function _calculateHash(array $postData = array(), $type = '')
  132. {
  133. if ($type == "redirect") // 302 Redirect
  134. {
  135. // Generate & return the hash
  136. return md5(strtolower($this->passphrase . $this->_getHashSalt($this->response['reg_id']) . $this->merchantID . $postData['status'] . $postData['responseData']['transactionID']));
  137. }
  138. elseif ($type == "transaction")
  139. {
  140. // Generate & return the hash
  141. return md5(strtolower($this->passphrase . $this->merchantID . $postData['transactionAmount'] . $postData['transactionCurrency']));
  142. }
  143. elseif ($type == "query")
  144. {
  145. // Generate & return the hash
  146. return md5(strtolower($this->passphrase . $this->merchantID . $postData['transactionID']));
  147. }
  148. elseif ($type == "url")
  149. {
  150. // Check the amount param
  151. if (!isset($postData['returnURL']) || !strlen($postData['returnURL'])) {
  152. throw new Exception("Missing or blank return URL field in post array.");
  153. }
  154. // Check the currency param
  155. if (!isset($postData['notifyURL']) || !strlen($postData['notifyURL'])) {
  156. throw new Exception("Missing or blank notify URL field in post array.");
  157. }
  158. // Generate & return the hash
  159. return md5(strtolower($this->passphrase . $this->merchantID . $postData['returnURL'] . $postData['notifyURL']));
  160. }
  161. }
  162. /**
  163. * Helper function which returns a random alphanumeric string
  164. * which can be used as the hash salt.
  165. *
  166. * @param int $length
  167. * @return string
  168. */
  169. public function _generateHashSalt($length = 16)
  170. {
  171. $str = "";
  172. $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  173. for($i=0;$i<$length;$i++)
  174. {
  175. $str .= substr(str_shuffle($chars), 0, 1);
  176. }
  177. return $str;
  178. }
  179. /**
  180. * Helper function which returns the random alphanumeric string
  181. * which was be used to generate the hash salt from the db.
  182. *
  183. * @param string $reg_id
  184. * @return string
  185. */
  186. public function _getHashSalt($reg_id = '')
  187. {
  188. global $wpdb;
  189. $s = $wpdb->get_row("SELECT hashSalt FROM " . EVENTS_ATTENDEE_TABLE . " WHERE registration_id ='$reg_id' ORDER BY id LIMIT 1 ");
  190. return $s->hashSalt;
  191. }
  192. /**
  193. * Helper function which temporarily stores the salt in the db
  194. *
  195. * @param string $salt
  196. * @param string $reg_id
  197. * @return
  198. */
  199. public function _storeHashSalt($salt='', $reg_id = '')
  200. {
  201. global $wpdb;
  202. $sql="UPDATE ". EVENTS_ATTENDEE_TABLE . " SET hashSalt = '$salt' WHERE registration_id ='$reg_id' ";
  203. $result = $wpdb->query($sql);
  204. return $result;
  205. }
  206. /**
  207. * Helper function which returns the transaction amount
  208. *
  209. * @param
  210. * @return string
  211. */
  212. public function _getAmount($reg_id = '')
  213. {
  214. global $wpdb;
  215. /*
  216. $reg_id = (isset($reg_id)) ? $reg_id : $this->response['reg_id'];
  217. $s = $wpdb->get_row("SELECT attendee_session FROM " . EVENTS_ATTENDEE_TABLE . " WHERE registration_id='$reg_id' ORDER BY id LIMIT 1 ");
  218. $old_session_id = $s->attendee_session;
  219. $s = $wpdb->get_row("SELECT sum(amount_pd) as total FROM " . EVENTS_ATTENDEE_TABLE . " WHERE attendee_session = '$old_session_id'");
  220. */
  221. $reg_id = (isset($reg_id) && strlen($reg_id) > 0) ? $reg_id : $this->response['reg_id'];
  222. $s = $wpdb->get_row("SELECT amount_pd as total FROM " . EVENTS_ATTENDEE_TABLE . " WHERE registration_id='$reg_id' ORDER BY id LIMIT 1 ");
  223. return $s->total;
  224. }
  225. /**
  226. * Calls the MW queryCard method.
  227. *
  228. * @param string $transactionID
  229. * @return array
  230. */
  231. public function queryCard($transactionID)
  232. {
  233. $url = $this->gatewayUrlQuery;
  234. // Setup all of the core, non-optional fields
  235. $data = array('method' => 'queryCard',
  236. 'merchantUUID' => $this->merchantID,
  237. 'apiKey' => $this->apikey,
  238. 'transactionID' => $transactionID);
  239. // Create the hash
  240. $data['hash'] = $this->_calculateHash($data, 'query');
  241. $result = $this->_doCurl($url, $data);
  242. $resp = $this->_parseResponse($result['data']);
  243. return $resp['responseData'];
  244. }
  245. /**
  246. * Send request to Merchant Warrior via CURL
  247. *
  248. * @param string $url
  249. * @param array $data
  250. * @param array $options
  251. * @return string
  252. */
  253. public function _doCurl($url = null, $data = array(), array $options = array())
  254. {
  255. if (function_exists("curl_init") == true)
  256. {
  257. $result = array();
  258. // Default CURL options (these can be overwritten via $options)
  259. $baseOptions = array(CURLOPT_HEADER => false,
  260. CURLOPT_RETURNTRANSFER => true,
  261. CURLOPT_SSL_VERIFYPEER => false,
  262. CURLOPT_FORBID_REUSE => true,
  263. CURLOPT_FRESH_CONNECT => true,
  264. CURLOPT_TIMEOUT => 60,
  265. CURLOPT_CONNECTTIMEOUT => 30,
  266. CURLOPT_POST => true);
  267. if (!isset($url) || strlen($url) < 1) {
  268. return false;
  269. }
  270. // Instante a cURL object
  271. $curlHandle = curl_init($url);
  272. // Note - do NOT just pass an array to POSTFIELDS - that will make the form
  273. // get sent as multipart/form-data instead of application/x-www-form-urlencoded
  274. $options[CURLOPT_POSTFIELDS] = is_array($data) ? http_build_query($data, '', '&') : $data;
  275. // Assign any options passed into the function
  276. // This will overwrite any defaults if the setting
  277. // has been passed in - yes, just like array_merge
  278. foreach ($options AS $key => $value) {
  279. $baseOptions[$key] = $value;
  280. }
  281. // Assign the options to the curl object
  282. foreach ($baseOptions AS $optKey => $optVal) {
  283. curl_setopt($curlHandle, $optKey, $optVal);
  284. }
  285. // Execute the request
  286. $result['data'] = curl_exec($curlHandle);
  287. // Fetch a bunch of useful data - just in case
  288. $result['code'] = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
  289. $result['info'] = curl_getinfo($curlHandle);
  290. $result['err'] = curl_error($curlHandle);
  291. $result['errno'] = curl_errno($curlHandle);
  292. // Cleanup after ourselves and close the connection
  293. curl_close($curlHandle);
  294. return $result;
  295. }
  296. }
  297. }