PageRenderTime 49ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/wp-content/plugins/wp-e-commerce/wpsc-merchants/paypal-pro.merchant.php

https://github.com/AaronFernandes/aquestionof
PHP | 421 lines | 314 code | 62 blank | 45 comment | 29 complexity | e6604ed0819c68ab4c1aeaf3c960cca7 MD5 | raw file
Possible License(s): AGPL-1.0, GPL-2.0
  1. <?php
  2. $nzshpcrt_gateways[$num] = array(
  3. 'name' => 'PayPal Pro 2.0',
  4. 'api_version' => 2.0,
  5. 'class_name' => 'wpsc_merchant_paypal_pro',
  6. 'has_recurring_billing' => true,
  7. 'wp_admin_cannot_cancel' => true,
  8. 'display_name' => 'PayPal Pro',
  9. 'image' => WPSC_URL . '/images/cc.gif',
  10. 'requirements' => array(
  11. 'php_version' => 4.3, // so that you can restrict merchant modules to PHP 5, if you use PHP 5 features
  12. 'extra_modules' => array() // for modules that may not be present, like curl
  13. ),
  14. 'form' => 'form_paypal_pro',
  15. 'submit_function' => 'submit_paypal_pro',
  16. 'internalname' => 'wpsc_merchant_paypal_pro', // this may be legacy, not yet decided
  17. // All array members below here are legacy, and use the code in paypal_multiple.php
  18. // 'form' => 'form_paypal_multiple',
  19. // 'submit_function' => 'submit_paypal_multiple',
  20. 'payment_type' => 'paypal',
  21. 'supported_currencies' => array(
  22. 'currency_list' => array( 'AUD', 'BRL', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD', 'HUF', 'ILS', 'JPY', 'MXN', 'MYR', 'NOK', 'NZD', 'PHP', 'PLN', 'SEK', 'SGD', 'THB', 'TWD', 'USD' ),
  23. 'option_name' => 'paypal_curcode'
  24. )
  25. );
  26. /**
  27. * WP eCommerce PayPal Standard Merchant Class
  28. *
  29. * This is the paypal standard merchant class, it extends the base merchant class
  30. *
  31. * @package wp-e-commerce
  32. * @since 3.7.6
  33. * @subpackage wpsc-merchants
  34. */
  35. class wpsc_merchant_paypal_pro extends wpsc_merchant {
  36. var $name = 'PayPal Pro 2.0';
  37. var $paypal_ipn_values = array( );
  38. /**
  39. * construct value array method, converts the data gathered by the base class code to something acceptable to the gateway
  40. * @access public
  41. */
  42. function construct_value_array() {
  43. //$collected_gateway_data
  44. $paypal_vars = array( );
  45. // Store settings to be sent to paypal
  46. $data = array( );
  47. $data['USER'] = get_option( 'paypal_pro_username' );
  48. $data['PWD'] = get_option( 'paypal_pro_password' );
  49. $data['SIGNATURE'] = get_option( 'paypal_pro_signature' );
  50. $data['VERSION'] = "52.0";
  51. $data['METHOD'] = "DoDirectPayment";
  52. $data['PAYMENTACTION'] = "Sale";
  53. $data['RETURNFMFDETAILS'] = "1"; // optional - return fraud management filter data
  54. // Basic Cart Data
  55. $data['INVNUM'] = $this->cart_data['session_id'];
  56. $data['NOTIFYURL'] = add_query_arg( 'gateway', 'wpsc_merchant_paypal_pro', $this->cart_data['notification_url'] );
  57. $data['IPADDRESS'] = $_SERVER["REMOTE_ADDR"];
  58. // Billing Data
  59. $data['FIRSTNAME'] = $this->cart_data['billing_address']['first_name'];
  60. $data['LASTNAME'] = $this->cart_data['billing_address']['last_name'];
  61. $data['EMAIL'] = $this->cart_data['email_address'];
  62. $data['STREET'] = $this->cart_data['billing_address']['address'];
  63. $data['CITY'] = $this->cart_data['billing_address']['city'];
  64. $data['STATE'] = $this->cart_data['billing_address']['state'];
  65. $data['COUNTRYCODE'] = $this->cart_data['billing_address']['country'];
  66. $data['ZIP'] = $this->cart_data['billing_address']['post_code'];
  67. // Shipping Data
  68. $data['SHIPTONAME'] = $this->cart_data['shipping_address']['first_name'] . " " . $this->cart_data['shipping_address']['last_name'];
  69. $data['SHIPTOSTREET'] = $this->cart_data['shipping_address']['address'];
  70. $data['SHIPTOCITY'] = $this->cart_data['shipping_address']['city'];
  71. // Check the state for internal numeric ID and trap it
  72. if ( is_numeric( $this->cart_data['shipping_address']['state'] ) )
  73. $this->cart_data['shipping_address']['state'] = wpsc_get_state_by_id( $this->cart_data['shipping_address']['state'], 'code' );
  74. $data['SHIPTOSTATE'] = $this->cart_data['shipping_address']['state'];
  75. $data['SHIPTOCOUNTRY'] = $this->cart_data['shipping_address']['country'];
  76. $data['SHIPTOZIP'] = $this->cart_data['shipping_address']['post_code'];
  77. // Credit Card Data
  78. $data['CREDITCARDTYPE'] = $_POST['cctype'];
  79. $data['ACCT'] = $_POST['card_number'];
  80. $data['EXPDATE'] = $_POST['expiry']['month'] . $_POST['expiry']['year'];
  81. $data['CVV2'] = $_POST['card_code'];
  82. // Ordered Items
  83. // Cart Item Data
  84. $i = $item_total = $tax_total = 0;
  85. $shipping_total = $this->cart_data['base_shipping'];
  86. foreach ( $this->cart_items as $cart_row ) {
  87. $cart_items['L_NAME' . $i] = $cart_row['name'];
  88. $cart_items['L_AMT' . $i] = $this->format_price( $cart_row['price'] );
  89. $cart_items['L_NUMBER' . $i] = $i;
  90. $cart_items['L_QTY' . $i] = $cart_row['quantity'];
  91. $cart_items['L_TAXAMT' . $i] = $this->format_price( 0 );
  92. $item_total += $this->format_price( $cart_row['price'] * $cart_row['quantity'] );
  93. $tax_total += $this->format_price( $cart_row['tax'] );
  94. ++$i;
  95. }
  96. $data = array_merge( $data, $cart_items );
  97. // Cart totals
  98. $data['ITEMAMT'] = number_format( $item_total, 2 );
  99. $data['SHIPPINGAMT'] = number_format( $shipping_total, 2 );
  100. $data['TAXAMT'] = number_format( $tax_total, 2 );
  101. $data['AMT'] = number_format( $item_total + $tax_total + $shipping_total, 2 );
  102. $this->collected_gateway_data = $data;
  103. }
  104. /**
  105. * submit method, sends the received data to the payment gateway
  106. * @access public
  107. */
  108. function submit() {
  109. if ( get_option( 'paypal_pro_testmode' ) == "on" )
  110. $paypal_url = "https://api-3t.beta-sandbox.paypal.com/nvp"; // Sandbox testing
  111. else
  112. $paypal_url = "https://api-3t.paypal.com/nvp"; // Live
  113. $options = array(
  114. 'timeout' => 5,
  115. 'body' => $this->collected_gateway_data,
  116. 'user-agent' => $this->cart_data['software_name'] . " " . get_bloginfo( 'url' )
  117. );
  118. $response = wp_remote_post( $paypal_url, $options );
  119. // parse the response body
  120. $error_data = array( );
  121. if ( is_wp_error( $response ) ) {
  122. $error_data[0]['error_code'] = null;
  123. $error_data[0]['error_message'] = __( 'There was a problem connecting to the payment gateway.', 'wpsc' );
  124. } else {
  125. parse_str( $response['body'], $parsed_response );
  126. }
  127. // List of error codes that we need to convert to something more human readable
  128. $paypal_error_codes = array( '10500', '10501', '10507', '10548', '10549', '10550', '10552', '10758', '10760', '15003' );
  129. // Extract the error messages from the array
  130. foreach ( (array)$parsed_response as $response_key => $response_value ) {
  131. if ( preg_match( "/L_([A-Z]+){1}(\d+){1}()/", $response_key, $matches ) ) {
  132. $error_number = $matches[2];
  133. switch ( $matches[1] ) {
  134. case 'ERRORCODE':
  135. $error_data[$error_number]['error_code'] = $response_value;
  136. if ( in_array( $response_value, $paypal_error_codes ) ) {
  137. $error_data[$error_number]['error_message'] = __( 'There is a problem with your PayPal account configuration, please contact PayPal for further information.', 'wpsc' ) . $response_value;
  138. break 2;
  139. }
  140. break;
  141. case 'LONGMESSAGE':
  142. // Oddly, this comes with two levels of slashes, so strip them twice
  143. $error_data[$error_number]['error_message'] = htmlentities( stripslashes( stripslashes( $response_value ) ), ENT_QUOTES, 'UTF-8' );
  144. break;
  145. }
  146. }
  147. }
  148. switch ( $parsed_response['ACK'] ) {
  149. case 'Success':
  150. case 'SuccessWithWarning':
  151. $this->set_transaction_details( $parsed_response['TRANSACTIONID'], 3 );
  152. $this->go_to_transaction_results( $this->cart_data['session_id'] );
  153. break;
  154. case 'Failure': /// case 2 is order denied
  155. default: /// default is http or unknown error state
  156. foreach ( (array)$error_data as $error_row ) {
  157. $this->set_error_message( $error_row['error_message'] );
  158. }
  159. $this->return_to_checkout();
  160. exit();
  161. break;
  162. }
  163. }
  164. /**
  165. * parse_gateway_notification method, receives data from the payment gateway
  166. * @access private
  167. */
  168. function parse_gateway_notification() {
  169. /// PayPal first expects the IPN variables to be returned to it within 30 seconds, so we do this first.
  170. $paypal_url = get_option( 'paypal_multiple_url' );
  171. $received_values = array( );
  172. $received_values['cmd'] = '_notify-validate';
  173. $received_values += $_POST;
  174. $options = array(
  175. 'timeout' => 5,
  176. 'body' => $received_values,
  177. 'user-agent' => ('WP e-Commerce/' . WPSC_PRESENTABLE_VERSION)
  178. );
  179. $response = wp_remote_post( $paypal_url, $options );
  180. if ( strpos( $response['body'], 'VERIFIED' ) !== false ) {
  181. $this->paypal_ipn_values = $received_values;
  182. $this->session_id = $received_values['invoice'];
  183. } else {
  184. exit( "IPN Request Failure" );
  185. }
  186. }
  187. /**
  188. * process_gateway_notification method, receives data from the payment gateway
  189. * @access public
  190. */
  191. function process_gateway_notification() {
  192. // Compare the received store owner email address to the set one
  193. if ( strtolower( $this->paypal_ipn_values['receiver_email'] ) == strtolower( get_option( 'paypal_multiple_business' ) ) ) {
  194. switch ( $this->paypal_ipn_values['txn_type'] ) {
  195. case 'cart':
  196. case 'express_checkout':
  197. if ( (float)$this->paypal_ipn_values['mc_gross'] == (float)$this->cart_data['total_price'] ) {
  198. $this->set_transaction_details( $this->paypal_ipn_values['txn_id'], 3 );
  199. transaction_results( $this->cart_data['session_id'], false );
  200. }
  201. break;
  202. case 'subscr_signup':
  203. case 'subscr_payment':
  204. $this->set_transaction_details( $this->paypal_ipn_values['subscr_id'], 3 );
  205. foreach ( $this->cart_items as $cart_row ) {
  206. if ( $cart_row['is_recurring'] == true ) {
  207. do_action( 'wpsc_activate_subscription', $cart_row['cart_item_id'], $this->paypal_ipn_values['subscr_id'] );
  208. }
  209. }
  210. transaction_results( $this->cart_data['session_id'], false );
  211. break;
  212. case 'subscr_cancel':
  213. case 'subscr_eot':
  214. case 'subscr_failed':
  215. foreach ( $this->cart_items as $cart_row ) {
  216. $altered_count = 0;
  217. if ( (bool)$cart_row['is_recurring'] == true ) {
  218. $altered_count++;
  219. wpsc_update_cartmeta( $cart_row['cart_item_id'], 'is_subscribed', 0 );
  220. }
  221. }
  222. break;
  223. default:
  224. break;
  225. }
  226. }
  227. $message = "
  228. {$this->paypal_ipn_values['receiver_email']} => " . get_option( 'paypal_multiple_business' ) . "
  229. {$this->paypal_ipn_values['txn_type']}
  230. {$this->paypal_ipn_values['mc_gross']} => {$this->cart_data['total_price']}
  231. {$this->paypal_ipn_values['txn_id']}
  232. " . print_r( $this->cart_items, true ) . "
  233. {$altered_count}
  234. ";
  235. }
  236. function format_price( $price ) {
  237. $paypal_currency_code = get_option( 'paypal_curcode' );
  238. switch ( $paypal_currency_code ) {
  239. case "JPY":
  240. $decimal_places = 0;
  241. break;
  242. case "HUF":
  243. $decimal_places = 0;
  244. default:
  245. $decimal_places = 2;
  246. break;
  247. }
  248. $price = number_format( sprintf( "%01.2f", $price ), $decimal_places, '.', '' );
  249. return $price;
  250. }
  251. }
  252. function submit_paypal_pro() {
  253. if ( isset( $_POST['PayPalPro']['username'] ) )
  254. update_option( 'paypal_pro_username', $_POST['PayPalPro']['username'] );
  255. if ( isset( $_POST['PayPalPro']['password'] ) )
  256. update_option( 'paypal_pro_password', $_POST['PayPalPro']['password'] );
  257. if ( isset( $_POST['PayPalPro']['signature'] ) )
  258. update_option( 'paypal_pro_signature', $_POST['PayPalPro']['signature'] );
  259. if ( isset( $_POST['PayPalPro']['testmode'] ) )
  260. update_option( 'paypal_pro_testmode', $_POST['PayPalPro']['testmode'] );
  261. return true;
  262. }
  263. function form_paypal_pro() {
  264. if ( get_option( 'paypal_pro_testmode' ) == "on" )
  265. $selected = 'checked="checked"';
  266. else
  267. $selected = '';
  268. $output = '
  269. <tr>
  270. <td>
  271. <label for="paypal_pro_username">' . __( 'API Username:', 'wpsc' ) . '</label>
  272. </td>
  273. <td>
  274. <input type="text" name="PayPalPro[username]" id="paypal_pro_username" value="' . get_option( "paypal_pro_username" ) . '" size="30" />
  275. </td>
  276. </tr>
  277. <tr>
  278. <td>
  279. <label for="paypal_pro_password">' . __( 'API Password:', 'wpsc' ) . '</label>
  280. </td>
  281. <td>
  282. <input type="password" name="PayPalPro[password]" id="paypal_pro_password" value="' . get_option( 'paypal_pro_password' ) . '" size="16" />
  283. </td>
  284. </tr>
  285. <tr>
  286. <td>
  287. <label for="paypal_pro_signature">' . __( 'API Signature:', 'wpsc' ) . '</label>
  288. </td>
  289. <td>
  290. <input type="text" name="PayPalPro[signature]" id="paypal_pro_signature" value="' . get_option( 'paypal_pro_signature' ) . '" size="48" />
  291. </td>
  292. </tr>
  293. <tr>
  294. <td>
  295. <label for="paypal_pro_testmode">' . __( 'Test Mode Enabled:', 'wpsc' ) . '</label>
  296. </td>
  297. <td>
  298. <input type="hidden" name="PayPalPro[testmode]" value="off" /><input type="checkbox" name="PayPalPro[testmode]" id="paypal_pro_testmode" value="on" ' . $selected . ' />
  299. </td>
  300. </tr>';
  301. return $output;
  302. }
  303. $years = $months = '';
  304. if ( in_array( 'wpsc_merchant_paypal_pro', (array)get_option( 'custom_gateway_options' ) ) ) {
  305. $curryear = date( 'Y' );
  306. //generate year options
  307. for ( $i = 0; $i < 10; $i++ ) {
  308. $years .= "<option value='" . $curryear . "'>" . $curryear . "</option>\r\n";
  309. $curryear++;
  310. }
  311. $gateway_checkout_form_fields[$nzshpcrt_gateways[$num]['internalname']] = "
  312. <tr>
  313. <td class='wpsc_CC_details'>" . __( 'Credit Card Number *', 'wpsc' ) . "</td>
  314. <td>
  315. <input type='text' value='' name='card_number' />
  316. </td>
  317. </tr>
  318. <tr>
  319. <td class='wpsc_CC_details'>" . __( 'Credit Card Expiry *', 'wpsc' ) . "</td>
  320. <td>
  321. <select class='wpsc_ccBox' name='expiry[month]'>
  322. " . $months . "
  323. <option value='01'>01</option>
  324. <option value='02'>02</option>
  325. <option value='03'>03</option>
  326. <option value='04'>04</option>
  327. <option value='05'>05</option>
  328. <option value='06'>06</option>
  329. <option value='07'>07</option>
  330. <option value='08'>08</option>
  331. <option value='09'>09</option>
  332. <option value='10'>10</option>
  333. <option value='11'>11</option>
  334. <option value='12'>12</option>
  335. </select>
  336. <select class='wpsc_ccBox' name='expiry[year]'>
  337. " . $years . "
  338. </select>
  339. </td>
  340. </tr>
  341. <tr>
  342. <td class='wpsc_CC_details'>" . __( 'CVV *', 'wpsc' ) . "</td>
  343. <td><input type='text' size='4' value='' maxlength='4' name='card_code' />
  344. </td>
  345. </tr>
  346. <tr>
  347. <td class='wpsc_CC_details'>" . __( 'Card Type *', 'wpsc' ) . "</td>
  348. <td>
  349. <select class='wpsc_ccBox' name='cctype'>
  350. <option value='Visa'>" . __( 'Visa', 'wpsc' ) . "</option>
  351. <option value='Mastercard'>" . __( 'MasterCard', 'wpsc' ) . "</option>
  352. <option value='Discover'>" . __( 'Discover', 'wpsc' ) . "</option>
  353. <option value='Amex'>" . __( 'Amex', 'wpsc' ) . "</option>
  354. </select>
  355. </td>
  356. </tr>
  357. ";
  358. }
  359. ?>