PageRenderTime 80ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/www/wp-content/plugins/ithemes-exchange/core-addons/transaction-methods/paypal-standard-secure/init.php

https://github.com/ArzuA/gitwordpress
PHP | 1427 lines | 894 code | 211 blank | 322 comment | 172 complexity | ad386b5f2a70f59ed0dca0eda1f43838 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * Hooks for PayPal Standard (secure) add-on
  4. *
  5. * @package IT_Exchange
  6. * @since 0.2.0
  7. */
  8. if ( !defined( 'PAYPAL_LIVE_URL' ) )
  9. define( 'PAYPAL_LIVE_URL', 'https://www.paypal.com/' );
  10. if ( !defined( 'PAYPAL_SANDBOX_URL' ) )
  11. define( 'PAYPAL_SANDBOX_URL', 'https://www.sandbox.paypal.com/' );
  12. if ( !defined( 'PAYPAL_PAYMENT_SANDBOX_URL' ) )
  13. define( 'PAYPAL_PAYMENT_SANDBOX_URL', 'https://www.sandbox.paypal.com/cgi-bin/webscr' );
  14. if ( !defined( 'PAYPAL_PAYMENT_LIVE_URL' ) )
  15. define( 'PAYPAL_PAYMENT_LIVE_URL', 'https://www.paypal.com/cgi-bin/webscr' );
  16. if ( !defined( 'PAYPAL_NVP_API_SANDBOX_URL' ) )
  17. define( 'PAYPAL_NVP_API_SANDBOX_URL', 'https://api-3t.sandbox.paypal.com/nvp' );
  18. if ( !defined( 'PAYPAL_NVP_API_LIVE_URL' ) )
  19. define( 'PAYPAL_NVP_API_LIVE_URL', 'https://api-3t.paypal.com/nvp' );
  20. /**
  21. * Mark this transaction method as okay to manually change transactions
  22. *
  23. * @since 1.9.2
  24. */
  25. add_filter( 'it_exchange_paypal-standard-secure_transaction_status_can_be_manually_changed', '__return_true' );
  26. /**
  27. * Returns status options
  28. *
  29. * @since 1.9.2
  30. * @return array
  31. */
  32. function it_exchange_paypal_standard_secure_get_default_status_options() {
  33. $options = array(
  34. 'Pending' => _x( 'Pending', 'Transaction Status', 'it-l10n-ithemes-exchange' ),
  35. 'Completed' => _x( 'Paid', 'Transaction Status', 'it-l10n-ithemes-exchange' ),
  36. 'Reversed' => _x( 'Reversed', 'Transaction Status', 'it-l10n-ithemes-exchange' ),
  37. 'Refunded' => _x( 'Refunded', 'Transaction Status', 'it-l10n-ithemes-exchange' ),
  38. 'Voided' => _x( 'Voided', 'Transaction Status', 'it-l10n-ithemes-exchange' ),
  39. );
  40. return $options;
  41. }
  42. add_filter( 'it_exchange_get_status_options_for_paypal-standard-secure_transaction', 'it_exchange_paypal_standard_secure_get_default_status_options' );
  43. /**
  44. * Outputs wizard settings for PayPal
  45. *
  46. * @since 0.4.0
  47. * @todo make this better, probably
  48. * @param object $form Current IT Form object
  49. * @return void
  50. */
  51. function it_exchange_print_paypal_standard_secure_wizard_settings( $form ) {
  52. $IT_Exchange_paypal_standard_secure_Add_On = new IT_Exchange_paypal_standard_secure_Add_On();
  53. $settings = it_exchange_get_option( 'addon_paypal_standard_secure', true );
  54. $form_values = ITUtility::merge_defaults( ITForm::get_post_data(), $settings );
  55. // Alter setting keys for wizard
  56. foreach( $form_values as $key => $value ) {
  57. $form_values['paypal-standard-secure-' . $key] = $value;
  58. unset( $form_values[$key] );
  59. }
  60. $hide_if_js = it_exchange_is_addon_enabled( 'paypal-standard-secure' ) ? '' : 'hide-if-js';
  61. ?>
  62. <div class="field paypal-standard-secure-wizard <?php echo $hide_if_js; ?>">
  63. <?php if ( empty( $hide_if_js ) ) { ?>
  64. <input class="enable-paypal-standard-secure" type="hidden" name="it-exchange-transaction-methods[]" value="paypal-standard-secure" />
  65. <?php } ?>
  66. <?php $IT_Exchange_paypal_standard_secure_Add_On->get_paypal_standard_secure_payment_form_table( $form, $form_values ); ?>
  67. </div>
  68. <?php
  69. }
  70. add_action( 'it_exchange_print_paypal-standard-secure_wizard_settings', 'it_exchange_print_paypal_standard_secure_wizard_settings' );
  71. /**
  72. * PayPal URL to perform refunds
  73. *
  74. * @since 0.4.0
  75. *
  76. * @param string $url passed by WP filter.
  77. * @param string $url transaction URL
  78. */
  79. function it_exchange_refund_url_for_paypal_standard_secure( $url ) {
  80. return 'https://paypal.com/';
  81. }
  82. add_filter( 'it_exchange_refund_url_for_paypal-standard-secure', 'it_exchange_refund_url_for_paypal_standard_secure' );
  83. /**
  84. * This proccesses a paypal transaction.
  85. *
  86. * @since 0.4.0
  87. *
  88. * @param string $status passed by WP filter.
  89. * @param object $transaction_object The transaction object
  90. */
  91. function it_exchange_process_paypal_standard_secure_addon_transaction( $status, $transaction_object ) {
  92. if ( $status ) //if this has been modified as true already, return.
  93. return $status;
  94. if ( !empty( $_REQUEST['it-exchange-transaction-method'] ) && 'paypal-standard-secure' === $_REQUEST['it-exchange-transaction-method'] ) {
  95. if ( !empty( $_REQUEST['paypal-standard-secure-nonce'] ) && wp_verify_nonce( $_REQUEST['paypal-standard-secure-nonce'], 'ppss-nonce' ) ) {
  96. if ( !empty( $_REQUEST['tx'] ) ) //if PDT is enabled
  97. $transaction_id = $_REQUEST['tx'];
  98. else if ( !empty( $_REQUEST['txn_id'] ) ) //if PDT is not enabled
  99. $transaction_id = $_REQUEST['txn_id'];
  100. else
  101. $transaction_id = NULL;
  102. if ( !empty( $_REQUEST['amt'] ) ) //if PDT is enabled
  103. $transaction_amount = $_REQUEST['amt'];
  104. else if ( !empty( $_REQUEST['mc_gross'] ) ) //if PDT is not enabled
  105. $transaction_amount = $_REQUEST['mc_gross'];
  106. else
  107. $transaction_amount = NULL;
  108. if ( !empty( $_REQUEST['st'] ) ) //if PDT is enabled
  109. $transaction_status = $_REQUEST['st'];
  110. else if ( !empty( $_REQUEST['payment_status'] ) ) //if PDT is not enabled
  111. $transaction_status = $_REQUEST['payment_status'];
  112. else
  113. $transaction_status = NULL;
  114. $general_settings = it_exchange_get_option( 'settings_general' );
  115. $paypal_settings = it_exchange_get_option( 'addon_paypal_standard_secure' );
  116. $it_exchange_customer = it_exchange_get_current_customer();
  117. if ( !empty( $transaction_id ) && !empty( $transaction_amount ) && !empty( $transaction_status ) ) {
  118. try {
  119. $paypal_api_url = ( $paypal_settings['sandbox-mode'] ) ? PAYPAL_NVP_API_SANDBOX_URL : PAYPAL_NVP_API_LIVE_URL;
  120. $paypal_api_username = ( $paypal_settings['sandbox-mode'] ) ? $paypal_settings['sandbox-api-username'] : $paypal_settings['live-api-username'];
  121. $paypal_api_password = ( $paypal_settings['sandbox-mode'] ) ? $paypal_settings['sandbox-api-password'] : $paypal_settings['live-api-password'];
  122. $paypal_api_signature = ( $paypal_settings['sandbox-mode'] ) ? $paypal_settings['sandbox-api-signature'] : $paypal_settings['live-api-signature'];
  123. $request = array(
  124. 'USER' => trim( $paypal_api_username ),
  125. 'PWD' => trim( $paypal_api_password ),
  126. 'SIGNATURE' => trim( $paypal_api_signature ),
  127. 'VERSION' => '96.0', //The PayPal API version
  128. 'METHOD' => 'GetTransactionDetails',
  129. 'TRANSACTIONID' => $transaction_id,
  130. );
  131. $response = wp_remote_post( $paypal_api_url, array( 'body' => $request ) );
  132. if ( !is_wp_error( $response ) ) {
  133. $array = array();
  134. parse_str( wp_remote_retrieve_body( $response ), $response_array );
  135. it_exchange_set_paypal_standard_secure_addon_customer_id( $it_exchange_customer->id, $response_array['PAYERID'] );
  136. it_exchange_set_paypal_standard_secure_addon_customer_email( $it_exchange_customer->id, $response_array['EMAIL'] );
  137. $transaction_status = $response_array['PAYMENTSTATUS'];
  138. if ( $transaction_id != $response_array['TRANSACTIONID'] )
  139. throw new Exception( __( 'Error: Transaction IDs do not match! %s, %s', 'it-l10n-ithemes-exchange' ) );
  140. if ( number_format( $response_array['AMT'], '2', '', '' ) != number_format( $transaction_object->total, '2', '', '' ) )
  141. throw new Exception( sprintf( __( 'Error: Amount charged is not the same as the cart total! %s | %s', 'it-l10n-ithemes-exchange' ), $response_array['AMT'], $transaction_object->total ) );
  142. } else {
  143. throw new Exception( $response->get_error_message() );
  144. }
  145. }
  146. catch ( Exception $e ) {
  147. it_exchange_add_message( 'error', $e->getMessage() );
  148. return false;
  149. }
  150. return it_exchange_add_transaction( 'paypal-standard-secure', $transaction_id, $transaction_status, $it_exchange_customer->id, $transaction_object );
  151. } else {
  152. //nonce verified, so let's check if this was a free trial -- no transaction data is sent from PayPal until
  153. //an actual monetary transaction occurs, so we need to improvise.
  154. $fake_id = $_REQUEST['paypal-standard-secure-nonce'];
  155. $transaction_object->total = 0;
  156. //set to pending until the IPN verifies...
  157. $transaction_id = it_exchange_add_transaction( 'paypal-standard-secure', $fake_id, 'pending', $it_exchange_customer->id, $transaction_object );
  158. return $transaction_id;
  159. }
  160. it_exchange_add_message( 'error', __( 'Unknown error while processing with PayPal. Please check your PayPal account for any charges and try again later.', 'it-l10n-ithemes-exchange' ) );
  161. }
  162. }
  163. return false;
  164. }
  165. add_action( 'it_exchange_do_transaction_paypal-standard-secure', 'it_exchange_process_paypal_standard_secure_addon_transaction', 10, 2 );
  166. /**
  167. * Call to cancel PayPal subscription automatically (on upgrade/downgrade)
  168. *
  169. * @since 1.7.18
  170. *
  171. * @param array $subscription_details the Exchange Subscription Details
  172. */
  173. function it_exchange_cancel_paypal_standard_secure_subscription( $subscription_details ) {
  174. if ( empty( $subscription_details['old_subscriber_id'] ) )
  175. return;
  176. $subscriber_id = $subscription_details['old_subscriber_id'];
  177. $paypal_settings = it_exchange_get_option( 'addon_paypal_standard_secure' );
  178. $paypal_api_url = ( $paypal_settings['sandbox-mode'] ) ? PAYPAL_NVP_API_SANDBOX_URL : PAYPAL_NVP_API_LIVE_URL;
  179. $paypal_api_username = ( $paypal_settings['sandbox-mode'] ) ? $paypal_settings['sandbox-api-username'] : $paypal_settings['live-api-username'];
  180. $paypal_api_password = ( $paypal_settings['sandbox-mode'] ) ? $paypal_settings['sandbox-api-password'] : $paypal_settings['live-api-password'];
  181. $paypal_api_signature = ( $paypal_settings['sandbox-mode'] ) ? $paypal_settings['sandbox-api-signature'] : $paypal_settings['live-api-signature'];
  182. if ( ! empty( $paypal_api_username )
  183. && ! empty( $paypal_api_password )
  184. && ! empty( $paypal_api_signature ) ) {
  185. $button_request = array(
  186. 'USER' => trim( $paypal_api_username ),
  187. 'PWD' => trim( $paypal_api_password ),
  188. 'SIGNATURE' => trim( $paypal_api_signature ),
  189. 'VERSION' => '96.0', //The PayPal API version
  190. 'METHOD' => 'ManageRecurringPaymentsProfileStatus',
  191. 'PROFILEID' => $subscriber_id,
  192. 'ACTION' => 'CANCEL',
  193. 'NOTE' => __( 'Canceled during Upgrade/Downgrade Process', 'it-l10n-ithemes-exchange' ),
  194. );
  195. $response = wp_remote_post( $paypal_api_url, array( 'body' => $button_request ) );
  196. if ( !is_wp_error( $response ) ) {
  197. parse_str( wp_remote_retrieve_body( $response ), $response_array );
  198. if ( !empty( $response_array['ACK'] ) && 'Success' === $response_array['ACK'] ) {
  199. if ( !empty( $response_array['WEBSITECODE'] ) )
  200. $payment_form = str_replace( array( "\r\n", "\r", "\n" ), '', stripslashes( $response_array['WEBSITECODE'] ) );
  201. //Strip out the newline characters because parse_str/PayPal adds a \n to the encrypted code, whic breaks the digital ID
  202. }
  203. }
  204. }
  205. }
  206. add_action( 'it_exchange_cancel_paypal-standard-secure_subscription', 'it_exchange_cancel_paypal_standard_secure_subscription' );
  207. /**
  208. * Grab the paypal customer ID for a WP user
  209. *
  210. * @since 0.4.0
  211. *
  212. * @param integer $customer_id the WP customer ID
  213. * @return string
  214. */
  215. function it_exchange_get_paypal_standard_secure_addon_customer_id( $customer_id ) {
  216. return get_user_meta( $customer_id, '_it_exchange_paypal_standard_secure_id', true );
  217. }
  218. /**
  219. * Add the paypal customer email as user meta on a WP user
  220. *
  221. * @since 0.4.0
  222. *
  223. * @param integer $customer_id the WP user ID
  224. * @param integer $paypal_standard_secure_id the paypal customer ID
  225. * @return boolean
  226. */
  227. function it_exchange_set_paypal_standard_secure_addon_customer_id( $customer_id, $paypal_standard_secure_id ) {
  228. return update_user_meta( $customer_id, '_it_exchange_paypal_standard_secure_id', $paypal_standard_secure_id );
  229. }
  230. /**
  231. * Grab the paypal customer email for a WP user
  232. *
  233. * @since 0.4.0
  234. *
  235. * @param integer $customer_id the WP customer ID
  236. * @return string
  237. */
  238. function it_exchange_get_paypal_standard_secure_addon_customer_email( $customer_id ) {
  239. return get_user_meta( $customer_id, '_it_exchange_paypal_standard_secure_email', true );
  240. }
  241. /**
  242. * Add the paypal customer email as user meta on a WP user
  243. *
  244. * @since 0.4.0
  245. *
  246. * @param integer $customer_id the WP user ID
  247. * @param string $paypal_standard_secure_email the paypal customer email
  248. * @return boolean
  249. */
  250. function it_exchange_set_paypal_standard_secure_addon_customer_email( $customer_id, $paypal_standard_secure_email ) {
  251. return update_user_meta( $customer_id, '_it_exchange_paypal_standard_secure_email', $paypal_standard_secure_email );
  252. }
  253. /**
  254. * This is the function registered in the options array when it_exchange_register_addon was called for paypal
  255. *
  256. * It tells Exchange where to find the settings page
  257. *
  258. * @return void
  259. */
  260. function it_exchange_paypal_standard_secure_settings_callback() {
  261. $IT_Exchange_paypal_standard_secure_Add_On = new IT_Exchange_paypal_standard_secure_Add_On();
  262. $IT_Exchange_paypal_standard_secure_Add_On->print_settings_page();
  263. }
  264. /**
  265. * This is the function prints the payment form on the Wizard Settings screen
  266. *
  267. * @return void
  268. */
  269. function paypal_standard_secure_print_wizard_settings( $form ) {
  270. $IT_Exchange_paypal_standard_secure_Add_On = new IT_Exchange_paypal_standard_secure_Add_On();
  271. $settings = it_exchange_get_option( 'addon_paypal_standard_secure', true );
  272. ?>
  273. <div class="field paypal_standard_secure-wizard hide-if-js">
  274. <?php $IT_Exchange_paypal_standard_secure_Add_On->get_paypal_standard_secure_payment_form_table( $form, $settings ); ?>
  275. </div>
  276. <?php
  277. }
  278. /**
  279. * Saves paypal settings when the Wizard is saved
  280. *
  281. * @since 0.4.0
  282. *
  283. * @return void
  284. */
  285. function it_exchange_save_paypal_standard_secure_wizard_settings( $errors ) {
  286. if ( ! empty( $errors ) )
  287. return $errors;
  288. $IT_Exchange_paypal_standard_secure_Add_On = new IT_Exchange_paypal_standard_secure_Add_On();
  289. return $IT_Exchange_paypal_standard_secure_Add_On->paypal_standard_secure_save_wizard_settings();
  290. }
  291. add_action( 'it_exchange_save_paypal-standard-secure_wizard_settings', 'it_exchange_save_paypal_standard_secure_wizard_settings' );
  292. /**
  293. * Default settings for paypal_standard_secure
  294. *
  295. * @since 0.4.0
  296. *
  297. * @param array $values
  298. * @return array
  299. */
  300. function it_exchange_paypal_standard_secure_addon_default_settings( $values ) {
  301. $defaults = array(
  302. 'live-email-address' => '',
  303. 'live-api-username' => '',
  304. 'live-api-password' => '',
  305. 'live-api-signature' => '',
  306. 'sandbox-email-address' => '',
  307. 'sandbox-api-username' => '',
  308. 'sandbox-api-password' => '',
  309. 'sandbox-api-signature' => '',
  310. 'sandbox-mode' => false,
  311. 'purchase-button-label' => __( 'Pay with PayPal', 'it-l10n-ithemes-exchange' ),
  312. );
  313. $values = ITUtility::merge_defaults( $values, $defaults );
  314. return $values;
  315. }
  316. add_filter( 'it_storage_get_defaults_exchange_addon_paypal_standard_secure', 'it_exchange_paypal_standard_secure_addon_default_settings' );
  317. /**
  318. * Returns the button for making the PayPal faux payment button
  319. *
  320. * @since 0.4.19
  321. *
  322. * @param array $options
  323. * @return string HTML button
  324. */
  325. function it_exchange_paypal_standard_secure_addon_make_payment_button( $options ) {
  326. if ( 0 >= it_exchange_get_cart_total( false ) )
  327. return;
  328. $general_settings = it_exchange_get_option( 'settings_general' );
  329. $paypal_settings = it_exchange_get_option( 'addon_paypal_standard_secure' );
  330. $payment_form = '';
  331. $it_exchange_customer = it_exchange_get_current_customer();
  332. $payment_form .= '<form action="" method="post">';
  333. $payment_form .= '<input type="submit" class="it-exchange-paypal-standard-button" name="paypal_standard_secure_purchase" value="' . esc_attr( $paypal_settings['purchase-button-label'] ) .'" />';
  334. $payment_form .= '</form>';
  335. return $payment_form;
  336. }
  337. add_filter( 'it_exchange_get_paypal-standard-secure_make_payment_button', 'it_exchange_paypal_standard_secure_addon_make_payment_button', 10, 2 );
  338. /**
  339. * Process the faux PayPal Standard secure form
  340. *
  341. * @since 0.4.19
  342. *
  343. * @param array $options
  344. * @return string HTML button
  345. */
  346. function it_exchange_process_paypal_standard_secure_form() {
  347. $paypal_settings = it_exchange_get_option( 'addon_paypal_standard_secure' );
  348. if ( ! empty( $_REQUEST['paypal_standard_secure_purchase'] ) ) {
  349. if ( $url = it_exchange_paypal_standard_secure_addon_get_payment_url() ) {
  350. wp_redirect( $url );
  351. die();
  352. } else {
  353. it_exchange_add_message( 'error', __( 'Error processing PayPal form. Missing valid PayPal information.', 'it-l10n-ithemes-exchange' ) );
  354. $url = ! wp_get_referer() ? it_exchange_get_page_url( 'checkout' ) : wp_get_referer();
  355. wp_redirect( $url );
  356. die();
  357. }
  358. }
  359. }
  360. add_action( 'template_redirect', 'it_exchange_process_paypal_standard_secure_form', 11 );
  361. /**
  362. * Returns the button for making the payment
  363. *
  364. * @since 0.4.0
  365. *
  366. * @return string PayPal payment URL
  367. */
  368. function it_exchange_paypal_standard_secure_addon_get_payment_url() {
  369. if ( 0 >= it_exchange_get_cart_total( false ) )
  370. return;
  371. $general_settings = it_exchange_get_option( 'settings_general' );
  372. $paypal_settings = it_exchange_get_option( 'addon_paypal_standard_secure' );
  373. $payment_form = '';
  374. $paypal_api_url = ( $paypal_settings['sandbox-mode'] ) ? PAYPAL_NVP_API_SANDBOX_URL : PAYPAL_NVP_API_LIVE_URL;
  375. $paypal_payment_url = ( $paypal_settings['sandbox-mode'] ) ? 'https://www.sandbox.paypal.com/cgi-bin/webscr' : 'https://www.paypal.com/cgi-bin/webscr';
  376. $paypal_email = ( $paypal_settings['sandbox-mode'] ) ? $paypal_settings['sandbox-email-address'] : $paypal_settings['live-email-address'];
  377. $paypal_api_username = ( $paypal_settings['sandbox-mode'] ) ? $paypal_settings['sandbox-api-username'] : $paypal_settings['live-api-username'];
  378. $paypal_api_password = ( $paypal_settings['sandbox-mode'] ) ? $paypal_settings['sandbox-api-password'] : $paypal_settings['live-api-password'];
  379. $paypal_api_signature = ( $paypal_settings['sandbox-mode'] ) ? $paypal_settings['sandbox-api-signature'] : $paypal_settings['live-api-signature'];
  380. if ( ! empty( $paypal_email )
  381. && ! empty( $paypal_api_username )
  382. && ! empty( $paypal_api_password )
  383. && ! empty( $paypal_api_signature ) ) {
  384. $subscription = false;
  385. $it_exchange_customer = it_exchange_get_current_customer();
  386. remove_filter( 'the_title', 'wptexturize' ); // remove this because it screws up the product titles in PayPal
  387. $cart = it_exchange_get_cart_products();
  388. if ( 1 === absint( count( $cart ) ) ) {
  389. foreach( $cart as $product ) {
  390. if ( it_exchange_product_supports_feature( $product['product_id'], 'recurring-payments', array( 'setting' => 'auto-renew' ) ) ) {
  391. if ( it_exchange_product_has_feature( $product['product_id'], 'recurring-payments', array( 'setting' => 'auto-renew' ) ) ) {
  392. $time = it_exchange_get_product_feature( $product['product_id'], 'recurring-payments', array( 'setting' => 'time' ) );
  393. switch( $time ) {
  394. case 'yearly':
  395. $unit = 'Y';
  396. break;
  397. case 'monthly':
  398. default:
  399. $unit = 'M';
  400. break;
  401. }
  402. $unit = apply_filters( 'it_exchange_paypal-standard_subscription_unit', $unit, $time );
  403. $duration = apply_filters( 'it_exchange_paypal-standard_subscription_duration', 1, $time );
  404. $subscription = true;
  405. $product_id = $product['product_id'];
  406. }
  407. }
  408. }
  409. }
  410. $button_request = array(
  411. 'USER' => trim( $paypal_api_username ),
  412. 'PWD' => trim( $paypal_api_password ),
  413. 'SIGNATURE' => trim( $paypal_api_signature ),
  414. 'VERSION' => '96.0', //The PayPal API version
  415. 'METHOD' => 'BMCreateButton',
  416. 'BUTTONCODE' => 'ENCRYPTED',
  417. 'BUTTONIMAGE' => 'REG',
  418. 'BUYNOWTEXT' => 'PAYNOW',
  419. );
  420. $upgrade_downgrade = it_exchange_get_session_data( 'updowngrade_details' );
  421. if ( !empty( $upgrade_downgrade ) ) {
  422. foreach( $cart as $product ) {
  423. if ( !empty( $upgrade_downgrade[$product['product_id']] ) ) {
  424. $product_id = $product['product_id'];
  425. if ( !empty( $upgrade_downgrade[$product_id]['old_transaction_id'] )
  426. && !empty( $upgrade_downgrade[$product_id]['old_transaction_method'] ) ) {
  427. $subscription_details[$product_id] = array(
  428. 'product_id' => $product_id,
  429. 'free_days' => $upgrade_downgrade[$product_id]['free_days'],
  430. 'credit' => $upgrade_downgrade[$product_id]['credit'],
  431. 'old_transaction_id' => $upgrade_downgrade[$product_id]['old_transaction_id'],
  432. 'old_transaction_method' => $upgrade_downgrade[$product_id]['old_transaction_method'],
  433. );
  434. if ( !empty( $upgrade_downgrade[$product_id]['old_subscriber_id'] ) )
  435. $subscription_details[$product_id]['old_subscriber_id'] = $upgrade_downgrade[$product_id]['old_subscriber_id'];
  436. it_exchange_update_session_data( 'cancel_subscription', $subscription_details );
  437. }
  438. }
  439. }
  440. } else {
  441. it_exchange_clear_session_data( 'cancel_subscription' );
  442. }
  443. if ( $subscription ) {
  444. //https://developer.paypal.com/webapps/developer/docs/classic/paypal-payments-standard/integration-guide/Appx_websitestandard_htmlvariables/#id08A6HI00JQU
  445. //a1, t1, p1 are for the first trial periods which is not supported with the Recurring Payments add-on
  446. //a2, t2, p2 are for the second trial period, which is not supported with the Recurring Payments add-on
  447. //a3, t3, p3 are required for the actual subscription details
  448. $trial_duration_1 = empty( $upgrade_downgrade[$product_id]['free_days'] ) ? null : $upgrade_downgrade[$product_id]['free_days']; //stripe returns null if it isn't set
  449. $trial_duration_2 = 0;
  450. $button_request['BUTTONTYPE'] = 'SUBSCRIBE';
  451. if ( !empty( $trial_duration_1 ) ) {
  452. /*
  453. D – for days; allowable range for p2 is 1 to 90
  454. W – for weeks; allowable range for p2 is 1 to 52
  455. M – for months; allowable range for p2 is 1 to 24
  456. Y – for years; allowable range for p2 is 1 to 5
  457. Source: https://developer.paypal.com/webapps/developer/docs/classic/paypal-payments-standard/integration-guide/Appx_websitestandard_htmlvariables/#id08A6HF00TZS
  458. */
  459. $trial_unit_1 = 'D'; //Days by default
  460. $trial_unit_2 = 'D';
  461. if ( 90 < $trial_duration_1 ) { //If greater than 90 days, we need to modify
  462. $years = floor( $trial_duration_1 / 365 );
  463. $years_remainder = $trial_duration_1 % 365;
  464. $months = floor( $trial_duration_1 / 30 );
  465. $months_remainder = $trial_duration_1 % 30;
  466. $weeks = floor( $trial_duration_1 / 7 );
  467. $weeks_remainder = $trial_duration_1 % 7;
  468. if ( 10 == $years ) { //the most we can do
  469. $trial_unit_1 = 'Y';
  470. $trial_duration_1 = 5;
  471. $trial_unit_2 = 'Y';
  472. $trial_duration_2 = 5;
  473. } else if ( !empty( $years ) && 5 >= $years ) {
  474. $trial_unit_1 = 'Y';
  475. $trial_duration_1 = $years;
  476. if ( !empty( $years_remainder ) )
  477. $trial_duration_2 = $years_remainder;
  478. } else if ( !empty( $months ) && 24 >= $months ) {
  479. $trial_unit_1 = 'M';
  480. $trial_duration_1 = $months;
  481. if ( !empty( $months_remainder ) )
  482. $trial_duration_2 = $months_remainder;
  483. } else if ( !empty( $weeks ) && 52 >= $weeks ) {
  484. $trial_unit_1 = 'W';
  485. $trial_duration_1 = $weeks;
  486. if ( !empty( $weeks_remainder ) )
  487. $trial_duration_2 = $weeks_remainder;
  488. } else {
  489. $trial_duration_1 = 0;
  490. $trial_duration_2 = 0;
  491. }
  492. }
  493. if ( 90 < $trial_duration_2 ) { //If greater than 90 days, we need to modify
  494. $weeks = floor( $trial_duration_2 / 7 );
  495. $months = floor( $trial_duration_2 / 30 );
  496. $years = floor( $trial_duration_2 / 365 );
  497. if ( !empty( $weeks ) && 52 >= $weeks ) {
  498. $trial_unit_2 = 'W';
  499. $trial_duration_2 = $weeks;
  500. } else if ( !empty( $months ) && 24 >= $months ) {
  501. $trial_unit_2 = 'M';
  502. $trial_duration_2 = $months;
  503. } else if ( !empty( $years ) && 5 >= $years ) {
  504. $trial_unit_2 = 'Y';
  505. $trial_duration_2 = $years;
  506. } else {
  507. $trial_duration_2 = 0;
  508. }
  509. }
  510. if ( $trial_duration_1 ) {
  511. $L_BUTTONVARS[] = 'a1=0'; //Free trial subscription price.
  512. $L_BUTTONVARS[] = 'p1=' . $trial_duration_1; //Trial period.
  513. $L_BUTTONVARS[] = 't1=' . $trial_unit_1;
  514. }
  515. if ( $trial_duration_2 ) {
  516. $L_BUTTONVARS[] = 'a2=0.01'; //Free trial subscription price. (needs to be greater than 0)
  517. $L_BUTTONVARS[] = 'p2=' . $trial_duration_2; //Trial period.
  518. $L_BUTTONVARS[] = 't2=' . $trial_unit_2;
  519. }
  520. }
  521. $L_BUTTONVARS[] = 'a3=' . number_format( it_exchange_get_cart_total( false ), 2, '.', '' ); //Regular subscription price.
  522. $L_BUTTONVARS[] = 'p3=' . $duration; //Subscription duration. Specify an integer value in the allowable range for the units of duration that you specify with t3.
  523. $L_BUTTONVARS[] = 't3=' . $unit; //Regular subscription units of duration. (D, W, M, Y) -- we only use M,Y by default
  524. $L_BUTTONVARS[] = 'src=1'; //Recurring payments.
  525. } else {
  526. $button_request['BUTTONTYPE'] = 'BUYNOW';
  527. $L_BUTTONVARS[] = 'amount=' . number_format( it_exchange_get_cart_total( false ), 2, '.', '' );
  528. $L_BUTTONVARS[] = 'quantity=1';
  529. }
  530. $nonce = wp_create_nonce( 'ppss-nonce' );
  531. $L_BUTTONVARS[] = 'business=' . $paypal_email;
  532. $L_BUTTONVARS[] = 'item_name=' . it_exchange_get_cart_description();
  533. $L_BUTTONVARS[] = 'return=' . add_query_arg( array( 'it-exchange-transaction-method' => 'paypal-standard-secure', 'paypal-standard-secure-nonce' => $nonce ), it_exchange_get_page_url( 'transaction' ) );
  534. $L_BUTTONVARS[] = 'currency_code=' . $general_settings['default-currency'];
  535. $L_BUTTONVARS[] = 'notify_url=' . get_site_url() . '/?' . it_exchange_get_webhook( 'paypal-standard-secure' ) . '=1';
  536. $L_BUTTONVARS[] = 'no_note=1';
  537. $L_BUTTONVARS[] = 'no_shipping=1';
  538. $L_BUTTONVARS[] = 'shipping=0';
  539. $L_BUTTONVARS[] = 'email=' . $it_exchange_customer->data->user_email;
  540. $L_BUTTONVARS[] = 'rm=2'; //Return Method - https://developer.paypal.com/webapps/developer/docs/classic/button-manager/integration-guide/ButtonManagerHTMLVariables/
  541. $L_BUTTONVARS[] = 'cancel_return=' . it_exchange_get_page_url( 'cart' );
  542. $L_BUTTONVARS[] = 'custom=' . $nonce;
  543. $L_BUTTONVARS = apply_filters( 'it_exchange_paypal_standard_secure_button_vars', $L_BUTTONVARS );
  544. $count = 0;
  545. foreach( $L_BUTTONVARS as $L_BUTTONVAR ) {
  546. $button_request['L_BUTTONVAR' . $count] = $L_BUTTONVAR;
  547. $count++;
  548. }
  549. $button_request = apply_filters( 'it_exchange_paypal_standard_secure_button_request', $button_request );
  550. $response = wp_remote_post( $paypal_api_url, array( 'body' => $button_request ) );
  551. if ( !is_wp_error( $response ) ) {
  552. parse_str( wp_remote_retrieve_body( $response ), $response_array );
  553. if ( !empty( $response_array['ACK'] ) && 'Success' === $response_array['ACK'] ) {
  554. if ( !empty( $response_array['WEBSITECODE'] ) )
  555. $payment_form = str_replace( array( "\r\n", "\r", "\n" ), '', stripslashes( $response_array['WEBSITECODE'] ) );
  556. //Strip out the newline characters because parse_str/PayPal adds a \n to the encrypted code, whic breaks the digital ID
  557. }
  558. }
  559. if ( preg_match( '/-----BEGIN PKCS7-----.*-----END PKCS7-----/i', $payment_form, $matches ) ) {
  560. $query = array(
  561. 'cmd' => '_s-xclick',
  562. 'encrypted' => $matches[0],
  563. );
  564. $paypal_payment_url = $paypal_payment_url . '?' . http_build_query( $query );
  565. return $paypal_payment_url;
  566. }
  567. }
  568. return false;
  569. }
  570. /**
  571. * Adds the paypal webhook to the global array of keys to listen for
  572. *
  573. * @since 0.4.0
  574. *
  575. * @param array $webhooks existing
  576. * @return array
  577. */
  578. function it_exchange_paypal_standard_secure_addon_register_webhook() {
  579. $key = 'paypal-standard-secure';
  580. $param = apply_filters( 'it_exchange_paypal-standard-secure_webhook', 'it_exchange_paypal-standard-secure' );
  581. it_exchange_register_webhook( $key, $param );
  582. }
  583. add_filter( 'init', 'it_exchange_paypal_standard_secure_addon_register_webhook' );
  584. /**
  585. * Processes webhooks for PayPal Web Standard
  586. *
  587. * @since 0.4.0
  588. * @todo actually handle the exceptions
  589. *
  590. * @param array $request really just passing $_REQUEST
  591. */
  592. function it_exchange_paypal_standard_secure_addon_process_webhook( $request ) {
  593. $general_settings = it_exchange_get_option( 'settings_general' );
  594. $settings = it_exchange_get_option( 'addon_paypal_standard_secure' );
  595. $subscriber_id = !empty( $request['subscr_id'] ) ? $request['subscr_id'] : false;
  596. $subscriber_id = !empty( $request['recurring_payment_id'] ) ? $request['recurring_payment_id'] : $subscriber_id;
  597. if ( !empty( $request['txn_type'] ) ) {
  598. if ( !empty( $request['custom'] ) && $transaction_data = it_exchange_get_transaction( 'paypal-standard-secure', $request['custom'] ) ) {
  599. if ( !empty( $request['txn_id'] ) )
  600. update_post_meta( $transaction_data->ID, '_it_exchange_transaction_method_id', $request['txn_id'] );
  601. else
  602. $request['txn_id'] = $request['custom'];
  603. it_exchange_paypal_standard_secure_addon_update_transaction_status( $request['txn_id'], 'success' );
  604. it_exchange_paypal_standard_secure_addon_update_subscriber_id( $request['txn_id'], $subscriber_id );
  605. }
  606. switch( $request['txn_type'] ) {
  607. case 'web_accept':
  608. switch( strtolower( $request['payment_status'] ) ) {
  609. case 'completed':
  610. it_exchange_paypal_standard_secure_addon_update_transaction_status( $request['txn_id'], $request['payment_status'] );
  611. break;
  612. case 'reversed':
  613. it_exchange_paypal_standard_secure_addon_update_transaction_status( $request['parent_txn_id'], $request['reason_code'] );
  614. break;
  615. }
  616. break;
  617. case 'subscr_payment':
  618. switch( strtolower( $request['payment_status'] ) ) {
  619. case 'completed':
  620. if ( !it_exchange_paypal_standard_secure_addon_update_transaction_status( $request['txn_id'], $request['payment_status'] ) ) {
  621. //If the transaction isn't found, we've got a new payment
  622. it_exchange_paypal_standard_secure_addon_add_child_transaction( $request['txn_id'], $request['payment_status'], $subscriber_id, $request['mc_gross'] );
  623. } else {
  624. //If it is found, make sure the subscriber ID is attached to it
  625. it_exchange_paypal_standard_secure_addon_update_subscriber_id( $request['txn_id'], $subscriber_id );
  626. }
  627. it_exchange_paypal_standard_secure_addon_update_subscriber_status( $subscriber_id, 'active' );
  628. break;
  629. }
  630. break;
  631. case 'subscr_signup':
  632. it_exchange_paypal_standard_secure_addon_update_subscriber_status( $subscriber_id, 'active' );
  633. break;
  634. case 'recurring_payment_suspended':
  635. it_exchange_paypal_standard_secure_addon_update_subscriber_status( $subscriber_id, 'suspended' );
  636. break;
  637. case 'subscr_cancel':
  638. it_exchange_paypal_standard_secure_addon_update_subscriber_status( $subscriber_id, 'cancelled' );
  639. break;
  640. case 'subscr_eot':
  641. it_exchange_paypal_standard_secure_addon_update_subscriber_status( $subscriber_id, 'deactivated' );
  642. break;
  643. }
  644. } else {
  645. //These IPNs don't have txn_types, why PayPal!? WHY!?
  646. if ( !empty( $request['reason_code'] ) ) {
  647. switch( $request['reason_code'] ) {
  648. case 'refund':
  649. it_exchange_paypal_standard_secure_addon_update_transaction_status( $request['parent_txn_id'], $request['payment_status'] );
  650. it_exchange_paypal_standard_secure_addon_add_refund_to_transaction( $request['parent_txn_id'], $request['mc_gross'] );
  651. if ( $subscriber_id )
  652. it_exchange_paypal_standard_secure_addon_update_subscriber_status( $subscriber_id, 'refunded' );
  653. break;
  654. }
  655. }
  656. }
  657. }
  658. add_action( 'it_exchange_webhook_it_exchange_paypal-standard-secure', 'it_exchange_paypal_standard_secure_addon_process_webhook' );
  659. /**
  660. * Grab a transaction from the paypal transaction ID
  661. *
  662. * @since 0.4.0
  663. *
  664. * @param integer $paypal_standard_secure_id id of paypal transaction
  665. * @return transaction object
  666. */
  667. function it_exchange_paypal_standard_secure_addon_get_transaction_id( $paypal_standard_secure_id ) {
  668. $args = array(
  669. 'meta_key' => '_it_exchange_transaction_method_id',
  670. 'meta_value' => $paypal_standard_secure_id,
  671. 'numberposts' => 1, //we should only have one, so limit to 1
  672. );
  673. return it_exchange_get_transactions( $args );
  674. }
  675. /**
  676. * Grab a transaction from the paypal subscriber ID
  677. *
  678. * @since 0.4.0
  679. *
  680. * @param integer $paypal_standard_secure_id id of paypal transaction
  681. * @return transaction object
  682. */
  683. function it_exchange_paypal_standard_secure_addon_get_transaction_id_by_subscriber_id( $subscriber_id ) {
  684. $args = array(
  685. 'meta_key' => '_it_exchange_transaction_subscriber_id',
  686. 'meta_value' => $subscriber_id,
  687. 'numberposts' => 1, //we should only have one, so limit to 1
  688. );
  689. return it_exchange_get_transactions( $args );
  690. }
  691. /**
  692. * Updates a paypals transaction status based on paypal ID
  693. *
  694. * @since 0.4.0
  695. *
  696. * @param integer $paypal_standard_secure_id id of paypal transaction
  697. * @param string $new_status new status
  698. * @return bool
  699. */
  700. function it_exchange_paypal_standard_secure_addon_update_transaction_status( $paypal_standard_secure_id, $new_status ) {
  701. $transactions = it_exchange_paypal_standard_secure_addon_get_transaction_id( $paypal_standard_secure_id );
  702. foreach( $transactions as $transaction ) { //really only one
  703. $current_status = it_exchange_get_transaction_status( $transaction );
  704. if ( $new_status !== $current_status )
  705. it_exchange_update_transaction_status( $transaction, $new_status );
  706. return true;
  707. }
  708. return false;
  709. }
  710. /**
  711. * Add a new transaction, really only used for subscription payments.
  712. * If a subscription pays again, we want to create another transaction in Exchange
  713. * This transaction needs to be linked to the parent transaction.
  714. *
  715. * @since 1.3.0
  716. *
  717. * @param integer $paypal_standard_secure_id id of paypal transaction
  718. * @param string $payment_status new status
  719. * @param string $subscriber_id from PayPal (optional)
  720. * @return bool
  721. */
  722. function it_exchange_paypal_standard_secure_addon_add_child_transaction( $paypal_standard_secure_id, $payment_status, $subscriber_id=false, $amount ) {
  723. $transactions = it_exchange_paypal_standard_secure_addon_get_transaction_id( $paypal_standard_secure_id );
  724. if ( !empty( $transactions ) ) {
  725. //this transaction DOES exist, don't try to create a new one, just update the status
  726. it_exchange_paypal_standard_secure_addon_update_transaction_status( $paypal_standard_secure_id, $payment_status );
  727. } else {
  728. if ( !empty( $subscriber_id ) ) {
  729. $transactions = it_exchange_paypal_standard_secure_addon_get_transaction_id_by_subscriber_id( $subscriber_id );
  730. foreach( $transactions as $transaction ) { //really only one
  731. $parent_tx_id = $transaction->ID;
  732. $customer_id = get_post_meta( $transaction->ID, '_it_exchange_customer_id', true );
  733. }
  734. } else {
  735. $parent_tx_id = false;
  736. $customer_id = false;
  737. }
  738. if ( $parent_tx_id && $customer_id ) {
  739. $transaction_object = new stdClass;
  740. $transaction_object->total = $amount;
  741. it_exchange_add_child_transaction( 'paypal-standard-secure', $paypal_standard_secure_id, $payment_status, $customer_id, $parent_tx_id, $transaction_object );
  742. return true;
  743. }
  744. }
  745. return false;
  746. }
  747. /**
  748. * Adds a refund to post_meta for a paypal transaction
  749. *
  750. * @since 0.4.0
  751. * @param string $paypal_standard_secure_id PayPal Transaction ID
  752. * @param string $refund Refund Amount
  753. */
  754. function it_exchange_paypal_standard_secure_addon_add_refund_to_transaction( $paypal_standard_secure_id, $refund ) {
  755. $transactions = it_exchange_paypal_standard_secure_addon_get_transaction_id( $paypal_standard_secure_id );
  756. foreach( $transactions as $transaction ) { //really only one
  757. it_exchange_add_refund_to_transaction( $transaction, number_format( abs( $refund ), '2', '.', '' ) );
  758. }
  759. }
  760. /**
  761. * Updates a subscription ID to post_meta for a paypal transaction
  762. *
  763. * @since 1.3.0
  764. * @param string $paypal_standard_id PayPal Transaction ID
  765. * @param string $subscriber_id PayPal Subscriber ID
  766. */
  767. function it_exchange_paypal_standard_secure_addon_update_subscriber_id( $paypal_standard_secure_id, $subscriber_id ) {
  768. $transactions = it_exchange_paypal_standard_secure_addon_get_transaction_id( $paypal_standard_secure_id );
  769. foreach( $transactions as $transaction ) { //really only one
  770. do_action( 'it_exchange_update_transaction_subscription_id', $transaction, $subscriber_id );
  771. }
  772. }
  773. /**
  774. * Updates a subscription status to post_meta for a paypal transaction
  775. *
  776. * @since 1.3.0
  777. * @param string $subscriber_id PayPal Subscriber ID
  778. * @param string $status Status of Subscription
  779. */
  780. function it_exchange_paypal_standard_secure_addon_update_subscriber_status( $subscriber_id, $status ) {
  781. $transactions = it_exchange_paypal_standard_secure_addon_get_transaction_id_by_subscriber_id( $subscriber_id );
  782. foreach( $transactions as $transaction ) { //really only one
  783. // If the subscription has been cancelled/suspended and fully refunded, they need to be deactivated
  784. if ( !in_array( $status, array( 'active', 'deactivated' ) ) ) {
  785. if ( $transaction->has_refunds() && 0 === it_exchange_get_transaction_total( $transaction, false ) )
  786. $status = 'deactivated';
  787. if ( $transaction->has_children() ) {
  788. //Get the last child and make sure it hasn't been fully refunded
  789. $args = array(
  790. 'numberposts' => 1,
  791. 'order' => 'ASC',
  792. );
  793. $last_child_transaction = $transaction->get_children( $args );
  794. foreach( $last_child_transaction as $last_transaction ) { //really only one
  795. $last_transaction = it_exchange_get_transaction( $last_transaction );
  796. if ( $last_transaction->has_refunds() && 0 === it_exchange_get_transaction_total( $last_transaction, false ) )
  797. $status = 'deactivated';
  798. }
  799. }
  800. }
  801. do_action( 'it_exchange_update_transaction_subscription_status', $transaction, $subscriber_id, $status );
  802. }
  803. }
  804. /**
  805. * Gets the interpretted transaction status from valid paypal transaction statuses
  806. *
  807. * @since 0.4.0
  808. *
  809. * @param string $status the string of the paypal transaction
  810. * @return string translaction transaction status
  811. */
  812. function it_exchange_paypal_standard_secure_addon_transaction_status_label( $status ) {
  813. switch ( strtolower( $status ) ) {
  814. case 'completed':
  815. case 'success':
  816. case 'canceled_reversal':
  817. case 'processed' :
  818. return __( 'Paid', 'it-l10n-ithemes-exchange' );
  819. case 'refunded':
  820. case 'refund':
  821. return __( 'Refund', 'it-l10n-ithemes-exchange' );
  822. case 'reversed':
  823. return __( 'Reversed', 'it-l10n-ithemes-exchange' );
  824. case 'buyer_complaint':
  825. return __( 'Buyer Complaint', 'it-l10n-ithemes-exchange' );
  826. case 'denied' :
  827. return __( 'Denied', 'it-l10n-ithemes-exchange' );
  828. case 'expired' :
  829. return __( 'Expired', 'it-l10n-ithemes-exchange' );
  830. case 'failed' :
  831. return __( 'Failed', 'it-l10n-ithemes-exchange' );
  832. case 'pending' :
  833. return __( 'Pending', 'it-l10n-ithemes-exchange' );
  834. case 'voided' :
  835. return __( 'Voided', 'it-l10n-ithemes-exchange' );
  836. case 'cancelled' :
  837. return __( 'Cancelled', 'it-l10n-ithemes-exchange' );
  838. default:
  839. return __( 'Unknown', 'it-l10n-ithemes-exchange' );
  840. }
  841. }
  842. add_filter( 'it_exchange_transaction_status_label_paypal-standard-secure', 'it_exchange_paypal_standard_secure_addon_transaction_status_label' );
  843. /**
  844. * Returns a boolean. Is this transaction a status that warrants delivery of any products attached to it?
  845. *
  846. * @since 0.4.2
  847. *
  848. * @param boolean $cleared passed in through WP filter. Ignored here.
  849. * @param object $transaction
  850. * @return boolean
  851. */
  852. function it_exchange_paypal_standard_secure_transaction_is_cleared_for_delivery( $cleared, $transaction ) {
  853. $valid_stati = array(
  854. 'completed',
  855. 'success',
  856. 'canceled_reversal',
  857. 'processed',
  858. );
  859. return in_array( strtolower( it_exchange_get_transaction_status( $transaction ) ), $valid_stati );
  860. }
  861. add_filter( 'it_exchange_paypal-standard-secure_transaction_is_cleared_for_delivery', 'it_exchange_paypal_standard_secure_transaction_is_cleared_for_delivery', 10, 2 );
  862. /*
  863. * Returns the unsubscribe action for PayPal autorenewing payments
  864. *
  865. * @since 1.3.0
  866. *
  867. * @param string $output Should be an empty string
  868. * @param array $options Array of options passed from Recurring Payments add-on
  869. * @return string $output Unsubscribe action
  870. */
  871. function it_exchange_paypal_standard_secure_unsubscribe_action( $output, $options ) {
  872. $paypal_settings = it_exchange_get_option( 'addon_paypal_standard_secure' );
  873. $paypal_url = ( $paypal_settings['sandbox-mode'] ) ? PAYPAL_PAYMENT_SANDBOX_URL : PAYPAL_PAYMENT_LIVE_URL;
  874. $paypal_email = ( $paypal_settings['sandbox-mode'] ) ? $paypal_settings['sandbox-email-address'] : $paypal_settings['live-email-address'];
  875. $output = '<a class="button" href="' . $paypal_url . '?cmd=_subscr-find&alias=' . urlencode( $paypal_email ) . '">';
  876. $output .= $options['label'];
  877. $output .= '</a>';
  878. return $output;
  879. }
  880. add_filter( 'it_exchange_paypal-standard-secure_unsubscribe_action', 'it_exchange_paypal_standard_secure_unsubscribe_action', 10, 2 );
  881. /**
  882. * Output the Cancel URL for the Payments screen
  883. *
  884. * @since 1.3.1
  885. *
  886. * @param object $transaction iThemes Transaction object
  887. * @return void
  888. */
  889. function it_exchange_paypal_standard_secure_after_payment_details_cancel_url( $transaction ) {
  890. $paypal_settings = it_exchange_get_option( 'addon_paypal_standard_secure' );
  891. $paypal_url = ( $paypal_settings['sandbox-mode'] ) ? PAYPAL_SANDBOX_URL : PAYPAL_LIVE_URL;
  892. $cart_object = get_post_meta( $transaction->ID, '_it_exchange_cart_object', true );
  893. foreach ( $cart_object->products as $product ) {
  894. $autorenews = $transaction->get_transaction_meta( 'subscription_autorenew_' . $product['product_id'], true );
  895. if ( $autorenews ) {
  896. $subscriber_id = $transaction->get_transaction_meta( 'subscriber_id', true );
  897. $status = $transaction->get_transaction_meta( 'subscriber_status', true );
  898. switch( $status ) {
  899. case 'deactivated':
  900. $output = __( 'Recurring payment has been deactivated', 'it-l10n-ithemes-exchange' );
  901. break;
  902. case 'cancelled':
  903. $output = __( 'Recurring payment has been cancelled', 'it-l10n-ithemes-exchange' );
  904. break;
  905. case 'suspended':
  906. $output = __( 'Recurring payment has been suspended', 'it-l10n-ithemes-exchange' );
  907. break;
  908. case 'active':
  909. default:
  910. $output = '<a href="' . $paypal_url . '">' . __( 'Cancel Recurring Payment', 'it-l10n-ithemes-exchange' ) . ' (' . __( 'Profile ID', 'it-l10n-ithemes-exchange' ) . ': ' . $subscriber_id . ')</a>';
  911. break;
  912. }
  913. ?>
  914. <div class="transaction-autorenews clearfix spacing-wrapper">
  915. <div class="recurring-payment-cancel-options left">
  916. <div class="recurring-payment-status-name"><?php echo $output; ?></div>
  917. </div>
  918. </div>
  919. <?php
  920. continue;
  921. }
  922. }
  923. }
  924. add_action( 'it_exchange_after_payment_details_cancel_url_for_paypal-standard-secure', 'it_exchange_paypal_standard_secure_after_payment_details_cancel_url' );
  925. /**
  926. * Convert old option keys to new option keys
  927. *
  928. * Our original option keys for this plugin were generating form field names 80+ chars in length
  929. *
  930. * @since 1.6.2
  931. *
  932. * @param array $options options as pulled from the DB
  933. * @param string $key the key for the options
  934. * @param boolean $break_cache was the flag to break cache passed?
  935. * @param boolean $merge_defaults was the flag to merge defaults passed?
  936. * @return array
  937. */
  938. function it_exchange_paypal_standard_secure_convert_option_keys( $options, $key, $break_cache, $merge_defaults ) {
  939. if ( 'addon_paypal_standard_secure' != $key )
  940. return $options;
  941. foreach( $options as $key => $value ) {
  942. if ( 'paypal-standard-secure-' == substr( $key, 0, 23 ) && empty( $opitons[substr( $key, 23 )] ) ) {
  943. $options[substr( $key, 23 )] = $value;
  944. unset( $options[$key] );
  945. }
  946. }
  947. return $options;
  948. }
  949. add_filter( 'it_exchange_get_option', 'it_exchange_paypal_standard_secure_convert_option_keys', 10, 4 );
  950. /**
  951. * Class for Stripe
  952. * @since 0.4.0
  953. */
  954. class IT_Exchange_paypal_standard_secure_Add_On {
  955. /**
  956. * @var boolean $_is_admin true or false
  957. * @since 0.4.0
  958. */
  959. var $_is_admin;
  960. /**
  961. * @var string $_current_page Current $_GET['page'] value
  962. * @since 0.4.0
  963. */
  964. var $_current_page;
  965. /**
  966. * @var string $_current_add_on Current $_GET['add-on-settings'] value
  967. * @since 0.4.0
  968. */
  969. var $_current_add_on;
  970. /**
  971. * @var string $status_message will be displayed if not empty
  972. * @since 0.4.0
  973. */
  974. var $status_message;
  975. /**
  976. * @var string $error_message will be displayed if not empty
  977. * @since 0.4.0
  978. */
  979. var $error_message;
  980. /**
  981. * Class constructor
  982. *
  983. * Sets up the class.
  984. * @since 0.4.0
  985. * @return void
  986. */
  987. function IT_Exchange_paypal_standard_secure_Add_On() {
  988. $this->_is_admin = is_admin();
  989. $this->_current_page = empty( $_GET['page'] ) ? false : $_GET['page'];
  990. $this->_current_add_on = empty( $_GET['add-on-settings'] ) ? false : $_GET['add-on-settings'];
  991. if ( ! empty( $_POST ) && $this->_is_admin && 'it-exchange-addons' == $this->_current_page && 'paypal-standard-secure' == $this->_current_add_on ) {
  992. $this->save_settings();
  993. }
  994. }
  995. function print_settings_page() {
  996. $settings = it_exchange_get_option( 'addon_paypal_standard_secure', true );
  997. $form_values = empty( $this->error_message ) ? $settings : ITForm::get_post_data();
  998. $form_options = array(
  999. 'id' => apply_filters( 'it_exchange_add_on_paypal-standard-secure', 'it-exchange-add-on-paypal-standard-secure-settings' ),
  1000. 'enctype' => apply_filters( 'it_exchange_add_on_paypal-standard-secure_settings_form_enctype', false ),
  1001. 'action' => 'admin.php?page=it-exchange-addons&add-on-settings=paypal-standard-secure',
  1002. );
  1003. $form = new ITForm( $form_values, array( 'prefix' => 'it-exchange-add-on-paypal_standard_secure' ) );
  1004. if ( ! empty ( $this->status_message ) )
  1005. ITUtility::show_status_message( $this->status_message );
  1006. if ( ! empty( $this->error_message ) )
  1007. ITUtility::show_error_message( $this->error_message );
  1008. ?>
  1009. <div class="wrap">
  1010. <?php ITUtility::screen_icon( 'it-exchange' ); ?>
  1011. <h2><?php _e( 'PayPal Standard Settings - Secure', 'it-l10n-ithemes-exchange' ); ?></h2>
  1012. <?php do_action( 'it_exchange_paypal-standard-secure_settings_page_top' ); ?>
  1013. <?php do_action( 'it_exchange_addon_settings_page_top' ); ?>
  1014. <?php $form->start_form( $form_options, 'it-exchange-paypal-standard-secure-settings' ); ?>
  1015. <?php do_action( 'it_exchange_paypal-standard-secure_settings_form_top' ); ?>
  1016. <?php $this->get_paypal_standard_secure_payment_form_table( $form, $form_values ); ?>
  1017. <?php do_action( 'it_exchange_paypal-standard-secure_settings_form_bottom' ); ?>
  1018. <p class="submit">
  1019. <?php $form->add_submit( 'submit', array( 'value' => __( 'Save Changes', 'it-l10n-ithemes-exchange' ), 'class' => 'button button-primary button-large' ) ); ?>
  1020. </p>
  1021. <?php $form->end_form(); ?>
  1022. <?php do_action( 'it_exchange_paypal-standard-secure_settings_page_bottom' ); ?>
  1023. <?php do_action( 'it_exchange_addon_settings_page_bottom' ); ?>
  1024. </div>
  1025. <?php
  1026. }
  1027. function get_paypal_standard_secure_payment_form_table( $form, $settings = array() ) {
  1028. $general_settings = it_exchange_get_option( 'settings_general' );
  1029. if ( ! empty( $_GET['page'] ) && 'it-exchange-setup' == $_GET['page'] ) : ?>
  1030. <h3><?php _e( 'PayPal Standard - Secure (Highly Recommended)', 'it-l10n-ithemes-exchange' ); ?></h3>
  1031. <?php endif;
  1032. if ( !empty( $settings ) )
  1033. foreach ( $settings as $key => $var )
  1034. $form->set_option( $key, $var );
  1035. ?>
  1036. <div class="it-exchange-addon-settings it-exchange-paypal-addon-settings">
  1037. <p>
  1038. <?php _e( 'Although this PayPal version for iThemes Exchange takes more effort and time, it is well worth it for the security options for your store. To get PayPal set up for use with Exchange, you\'ll need to add the following information from your PayPal account.', 'it-l10n-ithemes-exchange' ); ?><br /><br />
  1039. <?php _e( 'Video:', 'it-l10n-ithemes-exchange' ); ?>&nbsp;<a href="http://ithemes.com/tutorials/setting-up-paypal-standard-secure/" target="_blank"><?php _e( 'Setting Up PayPal Standard Secure', 'it-l10n-ithemes-exchange' ); ?></a>
  1040. </p>
  1041. <p><?php _e( 'Don\'t have a PayPal account yet?', 'it-l10n-ithemes-exchange' ); ?> <a href="http://paypal.com" target="_blank"><?php _e( 'Go set one up here', 'it-l10n-ithemes-exchange' ); ?></a>.</p>
  1042. <h4><?php _e( 'Step 1. Fill out your PayPal email address', 'it-l10n-ithemes-exchange' ); ?></h4>
  1043. <p>
  1044. <label for="live-email-address"><?php _e( 'PayPal Email Address', 'it-l10n-ithemes-exchange' ); ?> <span class="tip" title="<?php _e( 'We need this to tie payments to your account.', 'it-l10n-ithemes-exchange' ); ?>">i</span></label>
  1045. <?php
  1046. if ( ! empty( $_GET['page'] ) && 'it-exchange-setup' == $_GET['page'] )
  1047. $form->add_text_box( 'paypal-standard-secure-live-email-address' );
  1048. else
  1049. $form->add_text_box( 'live-email-address' );
  1050. ?>
  1051. </p>
  1052. <h4><?php _e( 'Step 2. Fill out your PayPal API credentials', 'it-l10n-ithemes-exchange' ); ?></h4>
  1053. <p>
  1054. <label for="live-api-username"><?php _e( 'PayPal API Username', 'it-l10n-ithemes-exchange' ); ?> <span class="tip" title="<?php _e( 'At PayPal, see: Profile &rarr; My Selling Tools &rarr; API Access &rarr; Update &rarr; View API Signature (or Request API Credentials).', 'it-l10n-ithemes-exchange' ); ?>">i</span></label>
  1055. <?php
  1056. if ( ! empty( $_GET['page'] ) && 'it-exchange-setup' == $_GET['page'] )
  1057. $form->add_text_box( 'paypal-standard-secure-live-api-username' );
  1058. else
  1059. $form->add_text_box( 'live-api-username' );
  1060. ?>
  1061. </p>
  1062. <p>
  1063. <label for="live-api-password"><?php _e( 'PayPal API Password', 'it-l10n-ithemes-exchange' ); ?> <span class="tip" title="<?php _e( 'At PayPal, see: Profile &rarr; My Selling Tools &rarr; API Access &rarr; Update &rarr; View API Signature (or Request API Credentials).', 'it-l10n-ithemes-exchange' ); ?>">i</span></label>
  1064. <?php
  1065. if ( ! empty( $_GET['page'] ) && 'it-exchange-setup' == $_GET['page'] )
  1066. $form->add_text_box( 'paypal-standard-secure-live-api-password' );
  1067. else
  1068. $form->add_text_box( 'live-api-password' );
  1069. ?>
  1070. </p>
  1071. <p>
  1072. <label for="live-api-signature"

Large files files are truncated, but you can click here to view the full file