PageRenderTime 55ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/marketpress/marketpress-includes/plugins-gateway/payflow.php

https://github.com/bfay/maniacal-kitten
PHP | 1017 lines | 763 code | 162 blank | 92 comment | 113 complexity | d866cdb7d440505b136f972c9ff08062 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, AGPL-1.0, LGPL-3.0, LGPL-2.1
  1. <?php
  2. /*
  3. MarketPress Payflow Pro Gateway Plugin
  4. Author: Sue Cline (Cyclonic Consulting)
  5. Modifications: Robert M. Hall - www.impossibilities.com
  6. Revision-History: 09/04/2012 - Added support for passing along SHIPTO information in the main transaction
  7. */
  8. class MP_Gateway_Payflow extends MP_Gateway_API {
  9. //private gateway slug. Lowercase alpha (a-z) and dashes (-) only please!
  10. var $plugin_name = 'payflow';
  11. //name of your gateway, for the admin side.
  12. var $admin_name = '';
  13. //public name of your gateway, for lists and such.
  14. var $public_name = '';
  15. //url for an image for your checkout method. Displayed on checkout form if set
  16. var $method_img_url = '';
  17. //url for an submit button image for your checkout method. Displayed on checkout form if set
  18. var $method_button_img_url = '';
  19. //whether or not ssl is needed for checkout page
  20. var $force_ssl = true;
  21. //always contains the url to send payment notifications to if needed by your gateway. Populated by the parent class
  22. var $ipn_url;
  23. //whether if this is the only enabled gateway it can skip the payment_form step
  24. var $skip_form = false;
  25. //credit card vars
  26. var $API_Username, $API_Password, $API_Signature, $SandboxFlag, $returnURL, $cancelURL, $API_Endpoint, $version, $currencyCode, $locale;
  27. /****** Below are the public methods you may overwrite via a plugin ******/
  28. /**
  29. * Runs when your class is instantiated. Use to setup your plugin instead of __construct()
  30. */
  31. function on_creation() {
  32. global $mp;
  33. $settings = get_option('mp_settings');
  34. //set names here to be able to translate
  35. $this->admin_name = __('PayPal Payflow Pro', 'mp');
  36. $this->public_name = __('Credit Card', 'mp');
  37. $this->method_img_url = $mp->plugin_url . 'images/credit_card.png';
  38. $this->method_button_img_url = $mp->plugin_url . 'images/cc-button.png';
  39. $this->version = "63.0"; //api version
  40. //set credit card vars
  41. if ( isset( $settings['gateways']['payflow'] ) ) {
  42. $this->API_Username = $settings['gateways']['payflow']['api_user'];
  43. $this->API_Password = $settings['gateways']['payflow']['api_pass'];
  44. $this->API_Signature = $settings['gateways']['payflow']['api_sig'];
  45. $this->currencyCode = $settings['gateways']['payflow']['currency'];
  46. $this->locale = $settings['gateways']['payflow']['locale'];
  47. //set api urls
  48. if ($settings['gateways']['payflow']['mode'] == 'sandbox') {
  49. $this->API_Endpoint = "https://pilot-payflowpro.paypal.com";
  50. } else {
  51. $this->API_Endpoint = "https://payflowpro.paypal.com";
  52. }
  53. }
  54. }
  55. /**
  56. * Return fields you need to add to the top of the payment screen, like your credit card info fields
  57. *
  58. * @param array $cart. Contains the cart contents for the current blog, global cart if $mp->global_cart is true
  59. * @param array $shipping_info. Contains shipping info and email in case you need it
  60. */
  61. function payment_form($cart, $shipping_info) {
  62. global $mp;
  63. $content = '';
  64. if (isset($_GET['cancel'])) {
  65. $content .= '<div class="mp_checkout_error">' . __('Your credit card transaction has been canceled.', 'mp') . '</div>';
  66. }
  67. $settings = get_option('mp_settings');
  68. $meta = get_user_meta($current_user->ID, 'mp_billing_info', true);
  69. $email = (!empty($_SESSION['mp_billing_info']['email'])) ? $_SESSION['mp_billing_info']['email'] : (!empty($meta['email'])?$meta['email']:$_SESSION['mp_shipping_info']['email']);
  70. $name = (!empty($_SESSION['mp_billing_info']['name'])) ? $_SESSION['mp_billing_info']['name'] : (!empty($meta['name'])?$meta['name']:$_SESSION['mp_shipping_info']['name']);
  71. $address1 = (!empty($_SESSION['mp_billing_info']['address1'])) ? $_SESSION['mp_billing_info']['address1'] : (!empty($meta['address1'])?$meta['address1']:$_SESSION['mp_shipping_info']['address1']);
  72. $address2 = (!empty($_SESSION['mp_billing_info']['address2'])) ? $_SESSION['mp_billing_info']['address2'] : (!empty($meta['address2'])?$meta['address2']:$_SESSION['mp_shipping_info']['address2']);
  73. $city = (!empty($_SESSION['mp_billing_info']['city'])) ? $_SESSION['mp_billing_info']['city'] : (!empty($meta['city'])?$meta['city']:$_SESSION['mp_shipping_info']['city']);
  74. $state = (!empty($_SESSION['mp_billing_info']['state'])) ? $_SESSION['mp_billing_info']['state'] : (!empty($meta['state'])?$meta['state']:$_SESSION['mp_shipping_info']['state']);
  75. $zip = (!empty($_SESSION['mp_billing_info']['zip'])) ? $_SESSION['mp_billing_info']['zip'] : (!empty($meta['zip'])?$meta['zip']:$_SESSION['mp_shipping_info']['zip']);
  76. $country = (!empty($_SESSION['mp_billing_info']['country'])) ? $_SESSION['mp_billing_info']['country'] : (!empty($meta['country'])?$meta['country']:$_SESSION['mp_shipping_info']['country']);
  77. if (!$country)
  78. $country = $settings['base_country'];
  79. $phone = (!empty($_SESSION['mp_billing_info']['phone'])) ? $_SESSION['mp_billing_info']['phone'] : (!empty($meta['phone'])?$meta['phone']:$_SESSION['mp_shipping_info']['phone']);
  80. $content .= '<style type="text/css">
  81. .cardimage {
  82. height: 23px;
  83. width: 157px;
  84. display: inline-table;
  85. }
  86. .nocard {
  87. background-position: 0px 0px !important;
  88. }
  89. .visa_card {
  90. background-position: 0px -23px !important;
  91. }
  92. .mastercard {
  93. background-position: 0px -46px !important;
  94. }
  95. .discover_card {
  96. background-position: 0px -69px !important;
  97. }
  98. .amex {
  99. background-position: 0px -92px !important;
  100. }
  101. </style>
  102. <script type="text/javascript">
  103. function cc_card_pick(card_image, card_num){
  104. if (card_image == null) {
  105. card_image = "#cardimage";
  106. }
  107. if (card_num == null) {
  108. card_num = "#card_num";
  109. }
  110. numLength = jQuery(card_num).val().length;
  111. number = jQuery(card_num).val();
  112. if (numLength > 10)
  113. {
  114. if((number.charAt(0) == "4") && ((numLength == 13)||(numLength==16))) { jQuery(card_image).removeClass(); jQuery(card_image).addClass("cardimage visa_card"); }
  115. else if((number.charAt(0) == "5" && ((number.charAt(1) >= "1") && (number.charAt(1) <= "5"))) && (numLength==16)) { jQuery(card_image).removeClass(); jQuery(card_image).addClass("cardimage mastercard"); }
  116. else if(number.substring(0,4) == "6011" && (numLength==16)) { jQuery(card_image).removeClass(); jQuery(card_image).addClass("cardimage amex"); }
  117. else if((number.charAt(0) == "3" && ((number.charAt(1) == "4") || (number.charAt(1) == "7"))) && (numLength==15)) { jQuery(card_image).removeClass(); jQuery(card_image).addClass("cardimage discover_card"); }
  118. else { jQuery(card_image).removeClass(); jQuery(card_image).addClass("cardimage nocard"); }
  119. }
  120. }
  121. jQuery(document).ready( function() {
  122. jQuery(".noautocomplete").attr("autocomplete", "off");
  123. });
  124. </script>';
  125. $content .= '<table class="mp_cart_billing">
  126. <thead><tr>
  127. <th colspan="2">'.__('Enter Your Billing Information:', 'mp').'</th>
  128. </tr></thead>
  129. <tbody>
  130. <tr>
  131. <td align="right">'.__('Email:', 'mp').'*</td><td>
  132. '.apply_filters( 'mp_checkout_error_email', '' ).'
  133. <input size="35" name="email" type="text" value="'.esc_attr($email).'" /></td>
  134. </tr>
  135. <tr>
  136. <td align="right">'.__('Full Name:', 'mp').'*</td><td>
  137. '.apply_filters( 'mp_checkout_error_name', '' ).'
  138. <input size="35" name="name" type="text" value="'.esc_attr($name).'" /> </td>
  139. </tr>
  140. <tr>
  141. <td align="right">'.__('Address:', 'mp').'*</td><td>
  142. '.apply_filters( 'mp_checkout_error_address1', '' ).'
  143. <input size="45" name="address1" type="text" value="'.esc_attr($address1).'" /><br />
  144. <small><em>'.__('Street address, P.O. box, company name, c/o', 'mp').'</em></small>
  145. </td>
  146. </tr>
  147. <tr>
  148. <td align="right">'.__('Address 2:', 'mp').'&nbsp;</td><td>
  149. <input size="45" name="address2" type="text" value="'.esc_attr($address2).'" /><br />
  150. <small><em>'.__('Apartment, suite, unit, building, floor, etc.', 'mp').'</em></small>
  151. </td>
  152. </tr>
  153. <tr>
  154. <td align="right">'.__('City:', 'mp').'*</td><td>
  155. '.apply_filters( 'mp_checkout_error_city', '' ).'
  156. <input size="25" name="city" type="text" value="'.esc_attr($city).'" /></td>
  157. </tr>
  158. <tr>
  159. <td align="right">'.__('State/Province/Region:', 'mp').'*</td><td>
  160. '.apply_filters( 'mp_checkout_error_state', '' ).'
  161. <input size="15" name="state" type="text" value="'.esc_attr($state).'" /></td>
  162. </tr>
  163. <tr>
  164. <td align="right">'.__('Postal/Zip Code:', 'mp').'*</td><td>
  165. '.apply_filters( 'mp_checkout_error_zip', '' ).'
  166. <input size="10" id="mp_zip" name="zip" type="text" value="'.esc_attr($zip).'" /></td>
  167. </tr>
  168. <tr>
  169. <td align="right">'.__('Country:', 'mp').'*</td><td>
  170. '.apply_filters( 'mp_checkout_error_country', '' ).'
  171. <select id="mp_" name="country">';
  172. foreach ((array)$settings['shipping']['allowed_countries'] as $code) {
  173. $content .= '<option value="'.$code.'"'.selected($country, $code, false).'>'.esc_attr($mp->countries[$code]).'</option>';
  174. }
  175. $content .= '</select>
  176. </td>
  177. </tr>
  178. <tr>
  179. <td align="right">'.__('Phone Number:', 'mp').'</td><td>
  180. <input size="20" name="phone" type="text" value="'.esc_attr($phone).'" /></td>
  181. </tr>
  182. <tr>
  183. <td align="right">'.__('Credit Card Number:', 'mp').'*</td>
  184. <td>
  185. '.apply_filters( 'mp_checkout_error_card_num', '' ).'
  186. <input name="card_num" onkeyup="cc_card_pick(\'#cardimage\', \'#card_num\');"
  187. id="card_num" class="credit_card_number input_field noautocomplete"
  188. type="text" size="22" maxlength="22" />
  189. <div class="hide_after_success nocard cardimage" id="cardimage" style="background: url('.$mp->plugin_url.'images/card_array.png) no-repeat;"></div></td>
  190. </tr>
  191. <tr>
  192. <td align="right">'.__('Expiration Date:', 'mp').'*</td>
  193. <td>
  194. '.apply_filters( 'mp_checkout_error_exp', '' ).'
  195. <label class="inputLabel" for="exp_month">'.__('Month', 'mp').'</label>
  196. <select name="exp_month" id="exp_month">
  197. '.$this->_print_month_dropdown().'
  198. </select>
  199. <label class="inputLabel" for="exp_year">'.__('Year', 'mp').'</label>
  200. <select name="exp_year" id="exp_year">
  201. '.$this->_print_year_dropdown('', true).'
  202. </select>
  203. </td>
  204. </tr>
  205. <tr>
  206. <td align="right">'.__('Security Code:', 'mp').'</td>
  207. <td>'.apply_filters( 'mp_checkout_error_card_code', '' ).'
  208. <input id="card_code" name="card_code" class="input_field noautocomplete"
  209. style="width: 70px;" type="text" size="4" maxlength="4" /></td>
  210. </tr>
  211. </tbody>
  212. </table>';
  213. return $content;
  214. }
  215. function _print_year_dropdown($sel='', $pfp = false) {
  216. $localDate=getdate();
  217. $minYear = $localDate["year"];
  218. $maxYear = $minYear + 15;
  219. $output = "<option value=''>--</option>";
  220. for($i=$minYear; $i<$maxYear; $i++) {
  221. if ($pfp) {
  222. $output .= "<option value='". substr($i, 0, 4) ."'".($sel==(substr($i, 0, 4))?' selected':'').
  223. ">". $i ."</option>";
  224. } else {
  225. $output .= "<option value='". substr($i, 2, 2) ."'".($sel==(substr($i, 2, 2))?' selected':'').
  226. ">". $i ."</option>";
  227. }
  228. }
  229. return($output);
  230. }
  231. function _print_month_dropdown($sel='') {
  232. $output = "<option value=''>--</option>";
  233. $output .= "<option " . ($sel==1?' selected':'') . " value='01'>01 - Jan</option>";
  234. $output .= "<option " . ($sel==2?' selected':'') . " value='02'>02 - Feb</option>";
  235. $output .= "<option " . ($sel==3?' selected':'') . " value='03'>03 - Mar</option>";
  236. $output .= "<option " . ($sel==4?' selected':'') . " value='04'>04 - Apr</option>";
  237. $output .= "<option " . ($sel==5?' selected':'') . " value='05'>05 - May</option>";
  238. $output .= "<option " . ($sel==6?' selected':'') . " value='06'>06 - Jun</option>";
  239. $output .= "<option " . ($sel==7?' selected':'') . " value='07'>07 - Jul</option>";
  240. $output .= "<option " . ($sel==8?' selected':'') . " value='08'>08 - Aug</option>";
  241. $output .= "<option " . ($sel==9?' selected':'') . " value='09'>09 - Sep</option>";
  242. $output .= "<option " . ($sel==10?' selected':'') . " value='10'>10 - Oct</option>";
  243. $output .= "<option " . ($sel==11?' selected':'') . " value='11'>11 - Nov</option>";
  244. $output .= "<option " . ($sel==12?' selected':'') . " value='12'>12 - Dec</option>";
  245. return($output);
  246. }
  247. /**
  248. * Use this to process any fields you added. Use the $_POST global,
  249. * and be sure to save it to both the $_SESSION and usermeta if logged in.
  250. * DO NOT save credit card details to usermeta as it's not PCI compliant.
  251. * Call $mp->cart_checkout_error($msg, $context); to handle errors. If no errors
  252. * it will redirect to the next step.
  253. *
  254. * @param array $cart. Contains the cart contents for the current blog, global cart if $mp->global_cart is true
  255. * @param array $shipping_info. Contains shipping info and email in case you need it
  256. */
  257. function process_payment_form($cart, $shipping_info) {
  258. global $mp;
  259. $settings = get_option('mp_settings');
  260. if (!is_email($_POST['email']))
  261. $mp->cart_checkout_error('Please enter a valid Email Address.', 'email');
  262. if (empty($_POST['name']))
  263. $mp->cart_checkout_error('Please enter your Full Name.', 'name');
  264. if (empty($_POST['address1']))
  265. $mp->cart_checkout_error('Please enter your Street Address.', 'address1');
  266. if (empty($_POST['city']))
  267. $mp->cart_checkout_error('Please enter your City.', 'city');
  268. if (($_POST['country'] == 'US' || $_POST['country'] == 'CA') && empty($_POST['state']))
  269. $mp->cart_checkout_error('Please enter your State/Province/Region.', 'state');
  270. if (empty($_POST['zip']))
  271. $mp->cart_checkout_error('Please enter your Zip/Postal Code.', 'zip');
  272. if (empty($_POST['country']) || strlen($_POST['country']) != 2)
  273. $mp->cart_checkout_error('Please enter your Country.', 'country');
  274. //for checkout plugins
  275. do_action( 'mp_billing_process' );
  276. //save to session
  277. global $current_user;
  278. $meta = get_user_meta($current_user->ID, 'mp_billing_info', true);
  279. $_SESSION['mp_billing_info']['email'] = ($_POST['email']) ? trim(stripslashes($_POST['email'])) : $current_user->user_email;
  280. $_SESSION['mp_billing_info']['name'] = ($_POST['name']) ? trim(stripslashes($_POST['name'])) : $current_user->user_firstname . ' ' . $current_user->user_lastname;
  281. $_SESSION['mp_billing_info']['address1'] = ($_POST['address1']) ? trim(stripslashes($_POST['address1'])) : $meta['address1'];
  282. $_SESSION['mp_billing_info']['address2'] = ($_POST['address2']) ? trim(stripslashes($_POST['address2'])) : $meta['address2'];
  283. $_SESSION['mp_billing_info']['city'] = ($_POST['city']) ? trim(stripslashes($_POST['city'])) : $meta['city'];
  284. $_SESSION['mp_billing_info']['state'] = ($_POST['state']) ? trim(stripslashes($_POST['state'])) : $meta['state'];
  285. $_SESSION['mp_billing_info']['zip'] = ($_POST['zip']) ? trim(stripslashes($_POST['zip'])) : $meta['zip'];
  286. $_SESSION['mp_billing_info']['country'] = ($_POST['country']) ? trim($_POST['country']) : $meta['country'];
  287. $_SESSION['mp_billing_info']['phone'] = ($_POST['phone']) ? preg_replace('/[^0-9-\(\) ]/', '', trim($_POST['phone'])) : $meta['phone'];
  288. //save to user meta
  289. if ($current_user->ID)
  290. update_user_meta($current_user->ID, 'mp_billing_info', $_SESSION['mp_billing_info']);
  291. if (!isset($_POST['exp_month']) || !isset($_POST['exp_year']) || empty($_POST['exp_month']) || empty($_POST['exp_year'])) {
  292. $mp->cart_checkout_error( __('Please select your credit card expiration date.', 'mp'), 'exp');
  293. }
  294. if (!isset($_POST['card_code']) || empty($_POST['card_code'])) {
  295. $mp->cart_checkout_error( __('Please enter your credit card security code', 'mp'), 'card_code');
  296. }
  297. if (!isset($_POST['card_num']) || empty($_POST['card_num'])) {
  298. $mp->cart_checkout_error( __('Please enter your credit card number', 'mp'), 'card_num');
  299. } else {
  300. if ($this->_get_card_type($_POST['card_num']) == "") {
  301. $mp->cart_checkout_error( __('Please enter a valid credit card number', 'mp'), 'card_num');
  302. }
  303. }
  304. if (!$mp->checkout_error) {
  305. if (
  306. ($this->_get_card_type($_POST['card_num']) == "American Express" && strlen($_POST['card_code']) != 4) ||
  307. ($this->_get_card_type($_POST['card_num']) != "American Express" && strlen($_POST['card_code']) != 3)
  308. ) {
  309. $mp->cart_checkout_error(__('Please enter a valid credit card security code', 'mp'), 'card_code');
  310. }
  311. }
  312. if (!$mp->checkout_error) {
  313. $_SESSION['card_num'] = $_POST['card_num'];
  314. $_SESSION['card_code'] = $_POST['card_code'];
  315. $_SESSION['exp_month'] = $_POST['exp_month'];
  316. $_SESSION['exp_year'] = $_POST['exp_year'];
  317. $mp->generate_order_id();
  318. }
  319. }
  320. function _get_card_type($number) {
  321. $num_length = strlen($number);
  322. if ($num_length > 10 && preg_match('/[0-9]+/', $number) >= 1) {
  323. if((substr($number, 0, 1) == '4') && (($num_length == 13)||($num_length == 16))) {
  324. return "Visa";
  325. } else if((substr($number, 0, 1) == '5' && ((substr($number, 1, 1) >= '1') && (substr($number, 1, 1) <= '5'))) && ($num_length == 16)) {
  326. return "Mastercard";
  327. } else if(substr($number, 0, 4) == "6011" && ($num_length == 16)) {
  328. return "Discover Card";
  329. } else if((substr($number, 0, 1) == '3' && ((substr($number, 1, 1) == '4') || (substr($number, 1, 1) == '7'))) && ($num_length == 15)) {
  330. return "American Express";
  331. }
  332. }
  333. return "";
  334. }
  335. /**
  336. * Return the chosen payment details here for final confirmation. You probably don't need
  337. * to post anything in the form as it should be in your $_SESSION var already.
  338. *
  339. * @param array $cart. Contains the cart contents for the current blog, global cart if $mp->global_cart is true
  340. * @param array $shipping_info. Contains shipping info and email in case you need it
  341. */
  342. function confirm_payment_form($cart, $shipping_info) {
  343. global $mp;
  344. $settings = get_option('mp_settings');
  345. $meta = get_user_meta($current_user->ID, 'mp_billing_info', true);
  346. $email = (!empty($_SESSION['mp_billing_info']['email'])) ? $_SESSION['mp_billing_info']['email'] : (!empty($meta['email'])?$meta['email']:$_SESSION['mp_shipping_info']['email']);
  347. $name = (!empty($_SESSION['mp_billing_info']['name'])) ? $_SESSION['mp_billing_info']['name'] : (!empty($meta['name'])?$meta['name']:$_SESSION['mp_shipping_info']['name']);
  348. $address1 = (!empty($_SESSION['mp_billing_info']['address1'])) ? $_SESSION['mp_billing_info']['address1'] : (!empty($meta['address1'])?$meta['address1']:$_SESSION['mp_shipping_info']['address1']);
  349. $address2 = (!empty($_SESSION['mp_billing_info']['address2'])) ? $_SESSION['mp_billing_info']['address2'] : (!empty($meta['address2'])?$meta['address2']:$_SESSION['mp_shipping_info']['address2']);
  350. $city = (!empty($_SESSION['mp_billing_info']['city'])) ? $_SESSION['mp_billing_info']['city'] : (!empty($meta['city'])?$meta['city']:$_SESSION['mp_shipping_info']['city']);
  351. $state = (!empty($_SESSION['mp_billing_info']['state'])) ? $_SESSION['mp_billing_info']['state'] : (!empty($meta['state'])?$meta['state']:$_SESSION['mp_shipping_info']['state']);
  352. $zip = (!empty($_SESSION['mp_billing_info']['zip'])) ? $_SESSION['mp_billing_info']['zip'] : (!empty($meta['zip'])?$meta['zip']:$_SESSION['mp_shipping_info']['zip']);
  353. $country = (!empty($_SESSION['mp_billing_info']['country'])) ? $_SESSION['mp_billing_info']['country'] : (!empty($meta['country'])?$meta['country']:$_SESSION['mp_shipping_info']['country']);
  354. if (!$country)
  355. $country = $settings['base_country'];
  356. $phone = (!empty($_SESSION['mp_billing_info']['phone'])) ? $_SESSION['mp_billing_info']['phone'] : (!empty($meta['phone'])?$meta['phone']:$_SESSION['mp_shipping_info']['phone']);
  357. $content = '';
  358. $content .= '<table class="mp_cart_billing">';
  359. $content .= '<thead><tr>';
  360. $content .= '<th>'.__('Billing Information:', 'mp').'</th>';
  361. $content .= '<th align="right"><a href="'. mp_checkout_step_url('checkout').'">'.__('&laquo; Edit', 'mp').'</a></th>';
  362. $content .= '</tr></thead>';
  363. $content .= '<tbody>';
  364. $content .= '<tr>';
  365. $content .= '<td align="right">'.__('Email:', 'mp').'</td><td>';
  366. $content .= esc_attr($email).'</td>';
  367. $content .= '</tr>';
  368. $content .= '<tr>';
  369. $content .= '<td align="right">'.__('Full Name:', 'mp').'</td><td>';
  370. $content .= esc_attr($name).'</td>';
  371. $content .= '</tr>';
  372. $content .= '<tr>';
  373. $content .= '<td align="right">'.__('Address:', 'mp').'</td>';
  374. $content .= '<td>'.esc_attr($address1).'</td>';
  375. $content .= '</tr>';
  376. if ($address2) {
  377. $content .= '<tr>';
  378. $content .= '<td align="right">'.__('Address 2:', 'mp').'</td>';
  379. $content .= '<td>'.esc_attr($address2).'</td>';
  380. $content .= '</tr>';
  381. }
  382. $content .= '<tr>';
  383. $content .= '<td align="right">'.__('City:', 'mp').'</td>';
  384. $content .= '<td>'.esc_attr($city).'</td>';
  385. $content .= '</tr>';
  386. if ($state) {
  387. $content .= '<tr>';
  388. $content .= '<td align="right">'.__('State/Province/Region:', 'mp').'</td>';
  389. $content .= '<td>'.esc_attr($state).'</td>';
  390. $content .= '</tr>';
  391. }
  392. $content .= '<tr>';
  393. $content .= '<td align="right">'.__('Postal/Zip Code:', 'mp').'</td>';
  394. $content .= '<td>'.esc_attr($zip).'</td>';
  395. $content .= '</tr>';
  396. $content .= '<tr>';
  397. $content .= '<td align="right">'.__('Country:', 'mp').'</td>';
  398. $content .= '<td>'.$mp->countries[$country].'</td>';
  399. $content .= '</tr>';
  400. if ($phone) {
  401. $content .= '<tr>';
  402. $content .= '<td align="right">'.__('Phone Number:', 'mp').'</td>';
  403. $content .= '<td>'.esc_attr($phone).'</td>';
  404. $content .= '</tr>';
  405. }
  406. $content .= '<tr>';
  407. $content .= '<td align="right">'.__('Payment method:', 'mp').'</td>';
  408. $content .= '<td>'.$this->_get_card_type($_SESSION['card_num']).' ending in '. substr($_SESSION['card_num'], strlen($_SESSION['card_num'])-4, 4).'</td>';
  409. $content .= '</tr>';
  410. $content .= '</tbody>';
  411. $content .= '</table>';
  412. return $content;
  413. }
  414. /**
  415. * Use this to do the final payment. Create the order then process the payment. If
  416. * you know the payment is successful right away go ahead and change the order status
  417. * as well.
  418. * Call $mp->cart_checkout_error($msg, $context); to handle errors. If no errors
  419. * it will redirect to the next step.
  420. *
  421. * @param array $cart. Contains the cart contents for the current blog, global cart if $mp->global_cart is true
  422. * @param array $shipping_info. Contains shipping info and email in case you need it
  423. */
  424. function process_payment($cart, $shipping_info) {
  425. global $mp;
  426. $timestamp = time();
  427. $settings = get_option('mp_settings');
  428. $billing_info = $_SESSION['mp_billing_info'];
  429. $payment = new MP_Gateway_Worker_Payflow($this->API_Endpoint,
  430. $settings['gateways']['payflow']['delim_data'],
  431. $settings['gateways']['payflow']['delim_char'],
  432. $settings['gateways']['payflow']['encap_char'],
  433. $settings['gateways']['payflow']['api_user'],
  434. $settings['gateways']['payflow']['api_key'],
  435. ($settings['gateways']['payflow']['mode'] == 'sandbox'));
  436. $payment->transaction($_SESSION['card_num']);
  437. $payment->setParameter("EXPDATE", $_SESSION['exp_month'] .substr($_SESSION['exp_year'],2,2));
  438. $payment->setParameter("CVV2", $_SESSION['card_code'] );
  439. $payment->setParameter("USER", $settings['gateways']['payflow']['api_user']);
  440. $payment->setParameter("VENDOR", $settings['gateways']['payflow']['api_vendor']);
  441. $payment->setParameter("PWD", $settings['gateways']['payflow']['api_pwd']);
  442. $payment->setParameter("PARTNER", $settings['gateways']['payflow']['api_partner']);
  443. $totals = array();
  444. foreach ($cart as $product_id => $variations) {
  445. foreach ($variations as $variation => $data) {
  446. $totals[] = $mp->before_tax_price($data['price'], $product_id) * $data['quantity'];
  447. $i++;
  448. }
  449. }
  450. $total = array_sum($totals);
  451. //coupon line
  452. if ( $coupon = $mp->coupon_value($mp->get_coupon_code(), $total) ) {
  453. $total = $coupon['new_total'];
  454. }
  455. //shipping line
  456. if ( ($shipping_price = $mp->shipping_price()) !== false ) {
  457. $total = $total + $shipping_price;
  458. }
  459. //tax line
  460. if ( ($tax_price = $mp->tax_price()) !== false ) {
  461. $total = $total + $tax_price;
  462. }
  463. // Billing Info
  464. $payment->setParameter("TENDER", 'C');
  465. $payment->setParameter("TRXTYPE", 'S');
  466. $payment->setParameter("AMT", number_format($total, 2, '.', ''));
  467. $payment->setParameter("CURRENCY",$this->currencyCode);
  468. // Order Info
  469. $payment->setParameter("COMMENT1", "Order ID: ".$_SESSION['mp_order']);
  470. $payment->setParameter("INVNUM", $_SESSION['mp_order']);
  471. // E-mail
  472. $_names = split(" ", $billing_info['name']);
  473. if (isset($_names[0])) {
  474. $first_name = array_shift($_names);
  475. } else {
  476. $first_name = "";
  477. }
  478. if (isset($_names[0])) {
  479. $last_name = join(" ", $_names);
  480. } else {
  481. $last_name = "";
  482. }
  483. $address = $billing_info['address1'];
  484. if (!empty($billing_info['address2'])) {
  485. $address .= "\n".$billing_info['address2'];
  486. }
  487. //Customer Info
  488. $payment->setParameter("FIRSTNAME", $first_name);
  489. $payment->setParameter("LASTNAME", $last_name);
  490. $payment->setParameter("STREET", $address);
  491. $payment->setParameter("CITY", $billing_info['city']);
  492. $payment->setParameter("STATE", $billing_info['state']);
  493. $payment->setParameter("COUNTRY", $billing_info['country']);
  494. $payment->setParameter("ZIP", $billing_info['zip']);
  495. $payment->setParameter("EMAIL", $billing_info['email']);
  496. $_ship_names = split(" ", $shipping_info['name']);
  497. if (isset($_ship_names[0])) {
  498. $first_name_shipping = array_shift($_ship_names);
  499. } else {
  500. $first_name_shipping = "";
  501. }
  502. if (isset($_ship_names[0])) {
  503. $last_name_shipping = join(" ", $_ship_names);
  504. } else {
  505. $last_name_shipping = "";
  506. }
  507. $ship_address = $shipping_info['address1'];
  508. if (!empty($shipping_info['address2'])) {
  509. $ship_address .= "\n".$shipping_info['address2'];
  510. }
  511. $payment->setParameter("SHIPTOFIRSTNAME", $first_name_shipping);
  512. $payment->setParameter("SHIPTOLASTNAME", $last_name_shipping);
  513. $payment->setParameter("SHIPTOCITY", $shipping_info["city"]);
  514. $payment->setParameter("SHIPTOSTATE", $shipping_info["state"]);
  515. $payment->setParameter("SHIPTOCOUNTRY", $shipping_info["country"]);
  516. $payment->setParameter("SHIPTOZIP", $shipping_info["zip"]);
  517. $payment->setParameter("SHIPTOSTREET", $ship_address);
  518. $payment->setParameter("CLIENTIP", $_SERVER['REMOTE_ADDR']);
  519. $payment->process();
  520. //file_put_contents("pp.txt",serialize($payment));
  521. if ($payment->isApproved()) {
  522. $status = __('The payment has been completed, and the funds have been added successfully to your account balance.', 'mp');
  523. $paid = true;
  524. $payment_info['gateway_public_name'] = $this->public_name;
  525. $payment_info['gateway_private_name'] = $this->admin_name;
  526. $payment_info['method'] = $payment->getMethod();
  527. $payment_info['status'][$timestamp] = "paid";
  528. $payment_info['total'] = $total;
  529. $payment_info['currency'] = "USD"; // Authorize.net only supports USD transactions
  530. $payment_info['transaction_id'] = $payment->getTransactionID();
  531. //succesful payment, create our order now
  532. $result = $mp->create_order($_SESSION['mp_order'], $cart, $shipping_info, $payment_info, $paid);
  533. } else {
  534. $error = $payment->getResponseText();
  535. $mp->cart_checkout_error( sprintf(__('There was a problem finalizing your purchase. %s Please <a href="%s">go back and try again</a>.', 'mp') , $error, mp_checkout_step_url('checkout')) );
  536. }
  537. }
  538. /**
  539. * Filters the order confirmation email message body. You may want to append something to
  540. * the message. Optional
  541. *
  542. * Don't forget to return!
  543. */
  544. function order_confirmation_email($msg) {
  545. return $msg;
  546. }
  547. /**
  548. * Return any html you want to show on the confirmation screen after checkout. This
  549. * should be a payment details box and message.
  550. */
  551. function order_confirmation_msg($content, $order) {
  552. global $mp;
  553. if ($order->post_status == 'order_received') {
  554. $content .= '<p>' . sprintf(__('Your credit card payment for this order totaling %s is not yet complete. Here is the latest status:', 'mp'), $mp->format_currency($order->mp_payment_info['currency'], $order->mp_payment_info['total'])) . '</p>';
  555. $statuses = $order->mp_payment_info['status'];
  556. krsort($statuses); //sort with latest status at the top
  557. $status = reset($statuses);
  558. $timestamp = key($statuses);
  559. $content .= '<p><strong>' . date(get_option('date_format') . ' - ' . get_option('time_format'), $timestamp) . ':</strong> ' . htmlentities($status) . '</p>';
  560. } else {
  561. $content .= '<p>' . sprintf(__('Your credit card payment for this order totaling %s is complete. The credit card transaction number is <strong>%s</strong>.', 'mp'), $mp->format_currency($order->mp_payment_info['currency'], $order->mp_payment_info['total']), $order->mp_payment_info['transaction_id']) . '</p>';
  562. }
  563. return $content;
  564. }
  565. /**
  566. * Runs before page load incase you need to run any scripts before loading the success message page
  567. */
  568. function order_confirmation($order) {
  569. }
  570. /**
  571. * Echo a settings meta box with whatever settings you need for you gateway.
  572. * Form field names should be prefixed with mp[gateways][plugin_name], like "mp[gateways][plugin_name][mysetting]".
  573. * You can access saved settings via $settings array.
  574. */
  575. function gateway_settings_box($settings) {
  576. global $mp;
  577. $defaults = array(
  578. 'mode' => 'sandbox',
  579. 'api_user' => '',
  580. 'api_vendor' => '',
  581. 'api_partner' => '',
  582. 'api_pwd' => '',
  583. 'email_customer' => 'yes',
  584. 'header_email_receipt' => 'Thanks for your payment!',
  585. 'footer_email_receipt' => ''
  586. );
  587. if ( !isset( $settings['gateways']['payflow'] ) )
  588. $settings['gateways']['payflow'] = array();
  589. $settings['gateways']['payflow'] = $settings['gateways']['payflow'] + $defaults;
  590. ?>
  591. <div id="mp_payflow_express" class="postbox">
  592. <h3 class='hndle'><span><?php _e('PayPal Payflow Settings', 'mp'); ?></span></h3>
  593. <div class="inside">
  594. <a href="https://merchant.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=merchant/payment_gateway" target="_blank"><img src="<?php echo $mp->plugin_url . 'images/paypal-payflow.png'; ?>" /></a>
  595. <p class="description"><?php _e('Use Payflow payment gateway to accept online payments using your Internet merchant account and processing network. PayPal Payflow Pro is a customizable payment processing solution that gives the merchant control over all the steps in processing a transaction. An SSL certificate is required to use this gateway. USD is the only currency supported by this gateway.', 'mp') ?></p>
  596. <table class="form-table">
  597. <tr>
  598. <th scope="row"><?php _e('Mode', 'mp') ?></th>
  599. <td>
  600. <p>
  601. <select name="mp[gateways][payflow][mode]">
  602. <option value="sandbox" <?php selected($settings['gateways']['payflow']['mode'], 'sandbox') ?>><?php _e('Sandbox', 'mp') ?></option>
  603. <option value="live" <?php selected($settings['gateways']['payflow']['mode'], 'live') ?>><?php _e('Live', 'mp') ?></option>
  604. </select>
  605. </p>
  606. </td>
  607. </tr>
  608. <tr>
  609. <th scope="row"><?php _e('Gateway Credentials', 'mp') ?></th>
  610. <td>
  611. <p>
  612. <label><?php _e('USER', 'mp') ?><br />
  613. <input value="<?php echo esc_attr($settings['gateways']['payflow']['api_user']); ?>" size="30" name="mp[gateways][payflow][api_user]" type="text" />
  614. </label>
  615. </p>
  616. <p>
  617. <label><?php _e('VENDOR', 'mp') ?><br />
  618. <input value="<?php echo esc_attr($settings['gateways']['payflow']['api_vendor']); ?>" size="30" name="mp[gateways][payflow][api_vendor]" type="text" />
  619. </label>
  620. </p>
  621. <p>
  622. <label><?php _e('PARTNER', 'mp') ?><br />
  623. <input value="<?php echo esc_attr($settings['gateways']['payflow']['api_partner']); ?>" size="30" name="mp[gateways][payflow][api_partner]" type="text" />
  624. </label>
  625. </p>
  626. <p>
  627. <label><?php _e('PWD', 'mp') ?><br />
  628. <input value="<?php echo esc_attr($settings['gateways']['payflow']['api_pwd']); ?>" size="30" name="mp[gateways][payflow][api_pwd]" type="password" />
  629. </label>
  630. </p>
  631. </td>
  632. </tr>
  633. <tr>
  634. <th scope="row"><?php _e('Advanced Settings', 'mp') ?></th>
  635. <td>
  636. <span class="description"><?php _e('Optional settings to control advanced options', 'mp') ?></span>
  637. <p>
  638. <label><?php _e('Email Customer (on success):', 'mp'); ?><br />
  639. <select name="mp[gateways][payflow][email_customer]">
  640. <option value="yes" <?php selected($settings['gateways']['payflow']['email_customer'], 'yes') ?>><?php _e('Yes', 'mp') ?></option>
  641. <option value="no" <?php selected($settings['gateways']['payflow']['email_customer'], 'no') ?>><?php _e('No', 'mp') ?></option>
  642. </select>
  643. </label>
  644. </p>
  645. <p>
  646. <label><a title="<?php _e('This text will appear as the header of the email receipt sent to the customer.', 'mp'); ?>"><?php _e('Customer Receipt Email Header', 'mp'); ?></a><br/>
  647. <input value="<?php echo empty($settings['gateways']['payflow']['header_email_receipt'])?__('Thanks for your payment!', 'mp'):esc_attr($settings['gateways']['payflow']['header_email_receipt']); ?>" size="40" name="mp[gateways][payflow][header_email_receipt]" type="text" />
  648. </label>
  649. </p>
  650. <p>
  651. <label><a title="<?php _e('This text will appear as the footer on the email receipt sent to the customer.', 'mp'); ?>"><?php _e('Customer Receipt Email Footer', 'mp'); ?></a><br/>
  652. <input value="<?php echo empty($settings['gateways']['payflow']['footer_email_receipt']) ? '' : esc_attr($settings['gateways']['payflow']['footer_email_receipt']); ?>" size="40" name="mp[gateways][payflow][footer_email_receipt]" type="text" />
  653. </label>
  654. </p>
  655. </td>
  656. </tr>
  657. </table>
  658. </div>
  659. </div>
  660. <?php
  661. }
  662. /**
  663. * Filters posted data from your settings form. Do anything you need to the $settings['gateways']['plugin_name']
  664. * array. Don't forget to return!
  665. */
  666. function process_gateway_settings($settings) {
  667. return $settings;
  668. }
  669. }
  670. if(!class_exists('MP_Gateway_Worker_Payflow')) {
  671. class MP_Gateway_Worker_Payflow
  672. {
  673. var $login;
  674. var $transkey;
  675. var $params = array();
  676. var $results = array();
  677. var $line_items = array();
  678. var $approved = false;
  679. var $declined = false;
  680. var $error = true;
  681. var $method = "";
  682. var $fields;
  683. var $response;
  684. var $instances = 0;
  685. function __construct($url, $delim_data, $delim_char, $encap_char, $gw_username, $gw_tran_key, $gw_test_mode)
  686. {
  687. if ($this->instances == 0)
  688. {
  689. $this->url = $url;
  690. $this->instances++;
  691. } else {
  692. return false;
  693. }
  694. }
  695. function transaction($cardnum)
  696. {
  697. $this->params['ACCT'] = trim($cardnum);
  698. }
  699. function addLineItem($id, $name, $description, $quantity, $price, $taxable = 0)
  700. {
  701. $this->line_items[] = "{$id}<|>{$name}<|>{$description}<|>{$quantity}<|>{$price}<|>{$taxable}";
  702. }
  703. function process($retries = 1)
  704. {
  705. global $mp;
  706. $post_string = '';
  707. foreach ($this->params as $key => $value) {
  708. $post_string .= $key . '[' . strlen(utf8_encode(trim($value))) . ']=' . utf8_encode(trim($value)) . '&';
  709. }
  710. $post_string = substr($post_string, 0, -1);
  711. $count = 0;
  712. //use built in WP http class to work with most server setups
  713. //$response = wp_remote_post($this->url, $args);
  714. $response = $this->sendTransactionToGateway($this->url,$post_string );
  715. $response_array = array();
  716. parse_str($response, $response_array);
  717. $this->results = $response_array;
  718. $this->results["METHOD"] = "Sale";
  719. if($response_array["RESULT"] == 0)
  720. {
  721. $this->approved = true;
  722. $this->declined = false;
  723. $this->error = false;
  724. $this->method = $this->getMethod();
  725. }else
  726. {
  727. $this->approved = false;
  728. $this->declined = true;
  729. $this->error = false;
  730. }
  731. }
  732. function sendTransactionToGateway($url, $parameters, $headers = null) {
  733. $header = array();
  734. $server = parse_url($url);
  735. if (!isset($server['port'])) {
  736. $server['port'] = ($server['scheme'] == 'https') ? 443 : 80;
  737. }
  738. if (!isset($server['path'])) {
  739. $server['path'] = '/';
  740. }
  741. if (isset($server['user']) && isset($server['pass'])) {
  742. $header[] = 'Authorization: Basic ' . base64_encode($server['user'] . ':' . $server['pass']);
  743. }
  744. if (!empty($headers) && is_array($headers)) {
  745. $header = array_merge($header, $headers);
  746. }
  747. if (function_exists('curl_init')) {
  748. $curl = curl_init($server['scheme'] . '://' . $server['host'] . $server['path'] . (isset($server['query']) ? '?' . $server['query'] : ''));
  749. curl_setopt($curl, CURLOPT_PORT, $server['port']);
  750. curl_setopt($curl, CURLOPT_HEADER, 0);
  751. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
  752. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  753. curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);
  754. curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1);
  755. curl_setopt($curl, CURLOPT_POST, 1);
  756. curl_setopt($curl, CURLOPT_POSTFIELDS, $parameters);
  757. if (!empty($header)) {
  758. curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
  759. }
  760. $result = curl_exec($curl);
  761. curl_close($curl);
  762. } else {
  763. exec(escapeshellarg(MODULE_PAYMENT_PAYPAL_PRO_PAYFLOW_DP_CURL) . ' -d ' . escapeshellarg($parameters) . ' "' . $server['scheme'] . '://' . $server['host'] . $server['path'] . (isset($server['query']) ? '?' . $server['query'] : '') . '" -P ' . $server['port'] . ' -k' . (!empty($header) ? ' -H ' . escapeshellarg(implode("\r\n", $header)) : ''), $result);
  764. $result = implode("\n", $result);
  765. }
  766. return $result;
  767. }
  768. function parseResults()
  769. {
  770. $this->results = explode("&", $this->response);
  771. }
  772. function setParameter($param, $value)
  773. {
  774. $param = trim($param);
  775. $value = trim($value);
  776. $this->params[$param] = $value;
  777. }
  778. function _prepareParameters()
  779. {
  780. foreach($this->params as $key => $value)
  781. {
  782. $this->fields .= "$key=" . urlencode($value) . "&";
  783. }
  784. for($i=0; $i<count($this->line_items); $i++) {
  785. $this->fields .= "x_line_item={$this->line_items[$i]}&";
  786. }
  787. }
  788. function getMethod()
  789. {
  790. if (isset($this->results["METHOD"]))
  791. {
  792. return $this->results["METHOD"];
  793. }
  794. return "";
  795. }
  796. function getGatewayResponse()
  797. {
  798. return $this->results["RESULT"];
  799. }
  800. function getResultResponseFull()
  801. {
  802. return $this->results["RESPMSG"];
  803. }
  804. function isApproved()
  805. {
  806. return $this->approved;
  807. }
  808. function isDeclined()
  809. {
  810. return $this->declined;
  811. }
  812. function isError()
  813. {
  814. return $this->error;
  815. }
  816. function getResponseText()
  817. {
  818. return $this->results["RESPMSG"];
  819. }
  820. function getAuthCode()
  821. {
  822. return $this->results["AUTHCODE"];
  823. }
  824. function getAVSResponse()
  825. {
  826. return true;
  827. }
  828. function getTransactionID()
  829. {
  830. return $this->results["PNREF"];
  831. }
  832. }
  833. }
  834. //register payment gateway plugin
  835. mp_register_gateway_plugin( 'MP_Gateway_Payflow', 'payflow', __('PayPal Payflow Pro', 'mp') );
  836. ?>