/app_old/membershipincludes/gateways/gateway.paypalexpress.php

  1. <?php 
  2. /** 
  3. Addon Name: PayPal Express Gateway 
  4. Author: Barry (Incsub) 
  5. Author URI: http://caffeinatedb.com 
  6. Gateway ID: paypalexpress 
  7. */ 
  8.  
  9. class paypalexpress extends M_Gateway { 
  10.  
  11. var $gateway = 'paypalexpress'; 
  12. var $title = 'PayPal Express - with Subscriptions'; 
  13.  
  14. function paypalexpress() { 
  15. parent::M_Gateway(); 
  16.  
  17. //echo "booboo"; 
  18.  
  19. add_action('M_gateways_settings_' . $this->gateway, array(&$this, 'mysettings')); 
  20.  
  21. // If I want to override the transactions output - then I can use this action 
  22. //add_action('M_gateways_transactions_' . $this->gateway, array(&$this, 'mytransactions')); 
  23.  
  24. if($this->is_active()) { 
  25. // Subscription form gateway 
  26. add_action('membership_purchase_button', array(&$this, 'display_subscribe_button'), 1, 3); 
  27.  
  28. // Payment return 
  29. add_action('membership_handle_payment_return_' . $this->gateway, array(&$this, 'handle_paypal_return')); 
  30. add_filter( 'membership_subscription_form_subscription_process', array(&$this, 'signup_free_subscription'), 10, 2 ); 
  31.  
  32.  
  33. function mysettings() { 
  34.  
  35. global $M_options; 
  36.  
  37. ?> 
  38. <table class="form-table"> 
  39. <tbody> 
  40. <tr valign="top"> 
  41. <th scope="row"><?php _e('PayPal Email', 'membership') ?></th> 
  42. <td><input type="text" name="paypal_email" value="<?php esc_attr_e(get_option( $this->gateway . "_paypal_email" )); ?>" /> 
  43. <br /> 
  44. </td> 
  45. </tr> 
  46. <tr valign="top"> 
  47. <th scope="row"><?php _e('PayPal Site', 'membership') ?></th> 
  48. <td><select name="paypal_site"> 
  49. <?php 
  50. $paypal_site = get_option( $this->gateway . "_paypal_site" ); 
  51. $sel_locale = empty($paypal_site) ? 'US' : $paypal_site; 
  52. $locales = array( 
  53. 'AU' => __('Australia', 'membership'),  
  54. 'AT' => __('Austria', 'membership'),  
  55. 'BE' => __('Belgium', 'membership'),  
  56. 'CA' => __('Canada', 'membership'),  
  57. 'CN' => __('China', 'membership'),  
  58. 'FR' => __('France', 'membership'),  
  59. 'DE' => __('Germany', 'membership'),  
  60. 'HK' => __('Hong Kong', 'membership'),  
  61. 'IT' => __('Italy', 'membership'),  
  62. 'jp_JP' => __('Japan', 'membership'),  
  63. 'MX' => __('Mexico', 'membership'),  
  64. 'NL' => __('Netherlands', 'membership'),  
  65. 'NZ' => __('New Zealand', 'membership'),  
  66. 'PL' => __('Poland', 'membership'),  
  67. 'SG' => __('Singapore', 'membership'),  
  68. 'ES' => __('Spain', 'membership'),  
  69. 'SE' => __('Sweden', 'membership'),  
  70. 'CH' => __('Switzerland', 'membership'),  
  71. 'GB' => __('United Kingdom', 'membership'),  
  72. 'US' => __('United States', 'membership') 
  73. ); 
  74.  
  75. $locales = apply_filters('membership_gateway_locals', $locales, $this->gateway); 
  76.  
  77. foreach ($locales as $key => $value) { 
  78. echo '<option value="' . esc_attr($key) . '"'; 
  79. if($key == $sel_locale) echo 'selected="selected"'; 
  80. echo '>' . esc_html($value) . '</option>' . "\n"; 
  81. ?> 
  82. </select> 
  83. <br /> 
  84. <?php //_e('Format: 00.00 - Ex: 1.25', 'supporter') ?></td> 
  85. </tr> 
  86. <tr valign="top"> 
  87. <th scope="row"><?php _e('Paypal Currency', 'membership') ?></th> 
  88. <td><?php 
  89. if(empty($M_options['paymentcurrency'])) { 
  90. $M_options['paymentcurrency'] = 'USD'; 
  91. echo esc_html($M_options['paymentcurrency']); ?></td> 
  92. </tr> 
  93. <tr valign="top"> 
  94. <th scope="row"><?php _e('PayPal Mode', 'membership') ?></th> 
  95. <td><select name="paypal_status"> 
  96. <option value="live" <?php if (get_option( $this->gateway . "_paypal_status" ) == 'live') echo 'selected="selected"'; ?>><?php _e('Live Site', 'membership') ?></option> 
  97. <option value="test" <?php if (get_option( $this->gateway . "_paypal_status" ) == 'test') echo 'selected="selected"'; ?>><?php _e('Test Mode (Sandbox)', 'membership') ?></option> 
  98. </select> 
  99. <br /> 
  100. </td> 
  101. </tr> 
  102. <tr valign="top"> 
  103. <th scope="row"><?php _e('Subscription button', 'membership') ?></th> 
  104. <?php 
  105. $button = get_option( $this->gateway . "_paypal_button", 'https://www.paypal.com/en_US/i/btn/btn_subscribe_LG.gif' ); 
  106. ?> 
  107. <td><input type="text" name="paypal_button" value="<?php esc_attr_e($button); ?>" style='width: 40em;' /> 
  108. <br /> 
  109. </td> 
  110. </tr> 
  111. <tr valign="top"> 
  112. <th scope="row"><?php _e('Upgrade button', 'membership') ?></th> 
  113. <?php 
  114. $button = get_option( $this->gateway . "_paypal_upgrade_button", 'https://www.paypal.com/en_US/i/btn/btn_subscribe_LG.gif' ); 
  115. ?> 
  116. <td><input type="text" name="_paypal_upgrade_button" value="<?php esc_attr_e($button); ?>" style='width: 40em;' /> 
  117. <br /> 
  118. </td> 
  119. </tr> 
  120. <tr valign="top"> 
  121. <th scope="row"><?php _e('Cancel button', 'membership') ?></th> 
  122. <?php 
  123. $button = get_option( $this->gateway . "_paypal_cancel_button", 'https://www.paypal.com/en_US/i/btn/btn_unsubscribe_LG.gif' ); 
  124. ?> 
  125. <td><input type="text" name="_paypal_cancel_button" value="<?php esc_attr_e($button); ?>" style='width: 40em;' /> 
  126. <br /> 
  127. </td> 
  128. </tr> 
  129. </tbody> 
  130. </table> 
  131. <?php 
  132.  
  133. function build_custom($user_id, $sub_id, $amount, $fromsub_id = false) { 
  134.  
  135. global $M_options; 
  136.  
  137. $custom = ''; 
  138.  
  139. //fake:user:sub:key 
  140.  
  141. $custom = time() . ':' . $user_id . ':' . $sub_id . ':'; 
  142. $key = md5('MEMBERSHIP' . apply_filters('membership_amount_' . $M_options['paymentcurrency'], $amount)); 
  143.  
  144. $custom .= $key; 
  145.  
  146. if($fromsub_id !== false) { 
  147. $custom .= ":" . $fromsub_id; 
  148.  
  149. return $custom; 
  150.  
  151.  
  152. function single_sub_button($pricing, $subscription, $user_id, $norepeat = false) { 
  153.  
  154. global $M_options; 
  155.  
  156. if(empty($M_options['paymentcurrency'])) { 
  157. $M_options['paymentcurrency'] = 'USD'; 
  158.  
  159. $form = ''; 
  160.  
  161. //if($pricing[0]['type'] == 'indefinite') $pricing[0]['days'] = 365; 
  162.  
  163. if (get_option( $this->gateway . "_paypal_status" ) == 'live') { 
  164. $form .= '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">'; 
  165. } else { 
  166. $form .= '<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">'; 
  167. $form .= '<input type="hidden" name="charset" value="utf-8">'; 
  168. $form .= '<input type="hidden" name="business" value="' . esc_attr(get_option( $this->gateway . "_paypal_email" )) . '">'; 
  169. $form .= '<input type="hidden" name="cmd" value="_xclick-subscriptions">'; 
  170. $form .= '<input type="hidden" name="item_name" value="' . $subscription->sub_name() . '">'; 
  171. $form .= '<input type="hidden" name="item_number" value="' . $subscription->sub_id() . '">'; 
  172. $form .= '<input type="hidden" name="currency_code" value="' . $M_options['paymentcurrency'] .'">'; 
  173. $form .= '<input type="hidden" name="a3" value="' . apply_filters('membership_amount_' . $M_options['paymentcurrency'], number_format($pricing[0]['amount'], 2)) . '">'; 
  174. $form .= '<input type="hidden" name="p3" value="' . $pricing[0]['period'] . '">'; 
  175. $form .= '<input type="hidden" name="t3" value="' . strtoupper($pricing[0]['unit']) . '"> <!-- Set recurring payments until canceled. -->'; 
  176.  
  177. $form .= '<input type="hidden" name="custom" value="' . $this->build_custom($user_id, $subscription->id, number_format($pricing[0]['amount'], 2)) .'">'; 
  178.  
  179. $form .= '<input type="hidden" name="return" value="' . apply_filters( 'membership_return_url_' . $this->gateway, M_get_returnurl_permalink()) . '">'; 
  180. $form .= '<input type="hidden" name="cancel_return" value="' . apply_filters( 'membership_cancel_url_' . $this->gateway, M_get_subscription_permalink()) . '">'; 
  181.  
  182. $form .= '<input type="hidden" name="lc" value="' . esc_attr(get_option( $this->gateway . "_paypal_site" )) . '">'; 
  183. $form .= '<input type="hidden" name="notify_url" value="' . apply_filters( 'membership_notify_url_' . $this->gateway, trailingslashit(get_option('home')) . 'paymentreturn/' . esc_attr($this->gateway)) . '">'; 
  184.  
  185. if($norepeat) { 
  186. $form .= '<input type="hidden" name="src" value="0">'; 
  187. } else { 
  188. $form .= '<input type="hidden" name="src" value="1">'; 
  189.  
  190. $button = get_option( $this->gateway . "_paypal_button", 'https://www.paypal.com/en_US/i/btn/btn_subscribe_LG.gif' ); 
  191.  
  192. $form .= '<!-- Display the payment button. --> <input type="image" name="submit" border="0" src="' . $button . '" alt="PayPal - The safer, easier way to pay online">'; 
  193. $form .= '<img alt="" border="0" width="1" height="1" src="https://www.paypal.com/en_US/i/scr/pixel.gif" >'; 
  194. $form .= '</form>'; 
  195.  
  196. return $form; 
  197.  
  198.  
  199. function complex_sub_button($pricing, $subscription, $user_id) { 
  200.  
  201. global $M_options; 
  202.  
  203. if(empty($M_options['paymentcurrency'])) { 
  204. $M_options['paymentcurrency'] = 'USD'; 
  205.  
  206. $form = ''; 
  207.  
  208. if (get_option( $this->gateway . "_paypal_status" ) == 'live') { 
  209. $form .= '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">'; 
  210. } else { 
  211. $form .= '<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">'; 
  212. $form .= '<input type="hidden" name="charset" value="utf-8">'; 
  213. $form .= '<input type="hidden" name="business" value="' . esc_attr(get_option( $this->gateway . "_paypal_email" )) . '">'; 
  214. $form .= '<input type="hidden" name="cmd" value="_xclick-subscriptions">'; 
  215. $form .= '<input type="hidden" name="item_name" value="' . $subscription->sub_name() . '">'; 
  216. $form .= '<input type="hidden" name="item_number" value="' . $subscription->sub_id() . '">'; 
  217. $form .= '<input type="hidden" name="currency_code" value="' . $M_options['paymentcurrency'] .'">'; 
  218.  
  219. // complex bits here 
  220. $count = 1; 
  221. $ff = array(); 
  222. foreach((array) $pricing as $key => $price) { 
  223.  
  224. switch($price['type']) { 
  225.  
  226. case 'finite': if(empty($price['amount'])) $price['amount'] = '0'; 
  227. if($count < 3) { 
  228. $ff['a' . $count] = apply_filters('membership_amount_' . $M_options['paymentcurrency'], number_format($price['amount'], 2, '.' , '')); 
  229. $ff['p' . $count] = $price['period']; 
  230. $ff['t' . $count] = strtoupper($price['unit']); 
  231. } else { 
  232. // Or last finite is going to be the end of the subscription payments 
  233. $ff['a3'] = apply_filters('membership_amount_' . $M_options['paymentcurrency'], number_format($price['amount'], 2, '.' , '')); 
  234. $ff['p3'] = $price['period']; 
  235. $ff['t3'] = strtoupper($price['unit']); 
  236. $ff['src'] = '0'; 
  237. $count++; 
  238. break; 
  239.  
  240. case 'indefinite': 
  241. if(empty($price['amount'])) $price['amount'] = '0'; 
  242.  
  243. if($price['amount'] == '0') { 
  244. // The indefinite rule is free, we need to move any previous 
  245. // steps up to this one as we can't have a free a3 
  246. if( isset($ff['a2']) && $ff['a2'] != '0.00' ) { 
  247. // we have some other earlier rule so move it up 
  248. $ff['a3'] = $ff['a2']; 
  249. $ff['p3'] = $ff['p2']; 
  250. $ff['t3'] = $ff['t2']; 
  251. unset($ff['a2']); 
  252. unset($ff['p2']); 
  253. unset($ff['t2']); 
  254. $ff['src'] = '0'; 
  255. } elseif( isset($ff['a1']) && $ff['a1'] != '0.00' ) { 
  256. $ff['a3'] = $ff['a1']; 
  257. $ff['p3'] = $ff['p1']; 
  258. $ff['t3'] = $ff['t1']; 
  259. unset($ff['a1']); 
  260. unset($ff['p1']); 
  261. unset($ff['t1']); 
  262. $ff['src'] = '0'; 
  263. } else { 
  264. $ff['a3'] = apply_filters('membership_amount_' . $M_options['paymentcurrency'], number_format($price['amount'], 2, '.' , '')); 
  265. $ff['p3'] = 1; 
  266. $ff['t3'] = 'Y'; 
  267. $ff['src'] = '0'; 
  268. break; 
  269. case 'serial': 
  270. if(empty($price['amount'])) $price['amount'] = '0'; 
  271.  
  272. if($price['amount'] == '0') { 
  273. // The serial rule is free, we need to move any previous 
  274. // steps up to this one as we can't have a free a3 
  275. if( isset($ff['a2']) && $ff['a2'] != '0.00' ) { 
  276. // we have some other earlier rule so move it up 
  277. $ff['a3'] = $ff['a2']; 
  278. $ff['p3'] = $ff['p2']; 
  279. $ff['t3'] = $ff['t2']; 
  280. unset($ff['a2']); 
  281. unset($ff['p2']); 
  282. unset($ff['t2']); 
  283. $ff['src'] = '1'; 
  284. } elseif( isset($ff['a1']) && $ff['a1'] != '0.00' ) { 
  285. $ff['a3'] = $ff['a1']; 
  286. $ff['p3'] = $ff['p1']; 
  287. $ff['t3'] = $ff['t1']; 
  288. unset($ff['a1']); 
  289. unset($ff['p1']); 
  290. unset($ff['t1']); 
  291. $ff['src'] = '1'; 
  292. } else { 
  293. $ff['a3'] = apply_filters('membership_amount_' . $M_options['paymentcurrency'], number_format($price['amount'], 2, '.' , '')); 
  294. $ff['p3'] = $price['period']; 
  295. $ff['t3'] = strtoupper($price['unit']); 
  296. $ff['src'] = '1'; 
  297.  
  298. break; 
  299.  
  300. if(!empty($ff)) { 
  301. foreach($ff as $key => $value) { 
  302. $form .= '<input type="hidden" name="' . $key . '" value="' . $value . '">'; 
  303.  
  304. $form .= '<input type="hidden" name="custom" value="' . $this->build_custom($user_id, $subscription->id, $ff['a3']) .'">'; 
  305.  
  306. // Remainder of the easy bits 
  307.  
  308. $form .= '<input type="hidden" name="return" value="' . apply_filters( 'membership_return_url_' . $this->gateway, M_get_returnurl_permalink()) . '">'; 
  309. $form .= '<input type="hidden" name="cancel_return" value="' . apply_filters( 'membership_cancel_url_' . $this->gateway, M_get_subscription_permalink()) . '">'; 
  310.  
  311.  
  312. $form .= '<input type="hidden" name="lc" value="' . esc_attr(get_option( $this->gateway . "_paypal_site" )) . '">'; 
  313. $form .= '<input type="hidden" name="notify_url" value="' . apply_filters( 'membership_notify_url_' . $this->gateway, trailingslashit(get_option('home')) . 'paymentreturn/' . esc_attr($this->gateway)) . '">'; 
  314.  
  315. $button = get_option( $this->gateway . "_paypal_button", 'https://www.paypal.com/en_US/i/btn/btn_subscribe_LG.gif' ); 
  316.  
  317. $form .= '<!-- Display the payment button. --> <input type="image" name="submit" border="0" src="' . $button . '" alt="PayPal - The safer, easier way to pay online">'; 
  318. $form .= '<img alt="" border="0" width="1" height="1" src="https://www.paypal.com/en_US/i/scr/pixel.gif" >'; 
  319. $form .= '</form>'; 
  320.  
  321. return $form; 
  322.  
  323.  
  324. function build_subscribe_button($subscription, $pricing, $user_id) { 
  325.  
  326. if(!empty($pricing)) { 
  327.  
  328. // check to make sure there is a price in the subscription 
  329. // we don't want to display free ones for a payment system 
  330. $free = true; 
  331. foreach($pricing as $key => $price) { 
  332. if(!empty($price['amount']) && $price['amount'] > 0 ) { 
  333. $free = false; 
  334.  
  335. if(!$free) { 
  336.  
  337. if(count($pricing) == 1) { 
  338. // A basic price or a single subscription 
  339. if(in_array($pricing[0]['type'], array('indefinite', 'finite'))) { 
  340. // one-off payment 
  341. return $this->single_sub_button($pricing, $subscription, $user_id, true); 
  342. } else { 
  343. // simple subscription 
  344. return $this->single_sub_button($pricing, $subscription, $user_id); 
  345. } else { 
  346. // something much more complex 
  347.  
  348. return $this->complex_sub_button($pricing, $subscription, $user_id); 
  349.  
  350. } else { 
  351. // Free subscription - so we'll use the free code 
  352. return $this->single_free_button($pricing, $subscription, $user_id, true); 
  353.  
  354.  
  355.  
  356. function single_upgrade_button($pricing, $subscription, $user_id, $norepeat = false, $fromsub_id = false) { 
  357.  
  358. global $M_options; 
  359.  
  360. if(empty($M_options['paymentcurrency'])) { 
  361. $M_options['paymentcurrency'] = 'USD'; 
  362.  
  363. $form = ''; 
  364.  
  365. //if($pricing[0]['type'] == 'indefinite') $pricing[0]['days'] = 365; 
  366.  
  367. if (get_option( $this->gateway . "_paypal_status" ) == 'live') { 
  368. $form .= '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">'; 
  369. } else { 
  370. $form .= '<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">'; 
  371. $form .= '<input type="hidden" name="charset" value="utf-8">'; 
  372. $form .= '<input type="hidden" name="business" value="' . esc_attr(get_option( $this->gateway . "_paypal_email" )) . '">'; 
  373. $form .= '<input type="hidden" name="cmd" value="_xclick-subscriptions">'; 
  374. $form .= '<input type="hidden" name="item_name" value="' . $subscription->sub_name() . '">'; 
  375. $form .= '<input type="hidden" name="item_number" value="' . $subscription->sub_id() . '">'; 
  376. $form .= '<input type="hidden" name="currency_code" value="' . $M_options['paymentcurrency'] .'">'; 
  377. $form .= '<input type="hidden" name="a3" value="' . apply_filters('membership_amount_' . $M_options['paymentcurrency'], number_format($pricing[0]['amount'], 2, '.' , '')) . '">'; 
  378. $form .= '<input type="hidden" name="p3" value="' . $pricing[0]['period'] . '">'; 
  379. $form .= '<input type="hidden" name="t3" value="' . strtoupper($pricing[0]['unit']) . '"> <!-- Set recurring payments until canceled. -->'; 
  380.  
  381. $form .= '<input type="hidden" name="custom" value="' . $this->build_custom($user_id, $subscription->id, number_format($pricing[0]['amount'], 2, '.' , ''), $fromsub_id) .'">'; 
  382.  
  383. $form .= '<input type="hidden" name="return" value="' . apply_filters( 'membership_return_url_' . $this->gateway, M_get_returnurl_permalink()) . '">'; 
  384. $form .= '<input type="hidden" name="cancel_return" value="' . apply_filters( 'membership_cancel_url_' . $this->gateway, M_get_subscription_permalink()) . '">'; 
  385.  
  386. $form .= '<input type="hidden" name="lc" value="' . esc_attr(get_option( $this->gateway . "_paypal_site" )) . '">'; 
  387. $form .= '<input type="hidden" name="notify_url" value="' . apply_filters( 'membership_notify_url_' . $this->gateway, trailingslashit(get_option('home')) . 'paymentreturn/' . esc_attr($this->gateway)) . '">'; 
  388.  
  389. if($norepeat) { 
  390. $form .= '<input type="hidden" name="src" value="0">'; 
  391. } else { 
  392. $form .= '<input type="hidden" name="src" value="1">'; 
  393.  
  394. $form .= '<input type="hidden" name="modify" value="2">'; 
  395.  
  396. $button = get_option( $this->gateway . "_paypal_upgrade_button", 'https://www.paypal.com/en_US/i/btn/btn_subscribe_LG.gif' ); 
  397.  
  398. $form .= '<!-- Display the payment button. --> <input type="image" name="submit" border="0" src="' . $button . '" alt="PayPal - The safer, easier way to pay online">'; 
  399. $form .= '<img alt="" border="0" width="1" height="1" src="https://www.paypal.com/en_US/i/scr/pixel.gif" >'; 
  400. $form .= '</form>'; 
  401.  
  402. return $form; 
  403.  
  404.  
  405. function complex_upgrade_button($pricing, $subscription, $user_id, $fromsub_id = false) { 
  406.  
  407. global $M_options; 
  408.  
  409. if(empty($M_options['paymentcurrency'])) { 
  410. $M_options['paymentcurrency'] = 'USD'; 
  411.  
  412. $form = ''; 
  413.  
  414. if (get_option( $this->gateway . "_paypal_status" ) == 'live') { 
  415. $form .= '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">'; 
  416. } else { 
  417. $form .= '<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">'; 
  418. $form .= '<input type="hidden" name="business" value="' . esc_attr(get_option( $this->gateway . "_paypal_email" )) . '">'; 
  419. $form .= '<input type="hidden" name="cmd" value="_xclick-subscriptions">'; 
  420. $form .= '<input type="hidden" name="item_name" value="' . $subscription->sub_name() . '">'; 
  421. $form .= '<input type="hidden" name="item_number" value="' . $subscription->sub_id() . '">'; 
  422. $form .= '<input type="hidden" name="currency_code" value="' . $M_options['paymentcurrency'] .'">'; 
  423.  
  424. // complex bits here 
  425. $count = 1; 
  426. $ff = array(); 
  427. foreach((array) $pricing as $key => $price) { 
  428.  
  429. switch($price['type']) { 
  430.  
  431. case 'finite': if(empty($price['amount'])) $price['amount'] = '0'; 
  432. if($count < 3) { 
  433. $ff['a' . $count] = apply_filters('membership_amount_' . $M_options['paymentcurrency'], number_format($price['amount'], 2, '.' , '')); 
  434. $ff['p' . $count] = $price['period']; 
  435. $ff['t' . $count] = strtoupper($price['unit']); 
  436. } else { 
  437. // Or last finite is going to be the end of the subscription payments 
  438. $ff['a3'] = number_format($price['amount'], 2, '.' , ''); 
  439. $ff['p3'] = $price['period']; 
  440. $ff['t3'] = strtoupper($price['unit']); 
  441. $ff['src'] = '0'; 
  442. $count++; 
  443. break; 
  444.  
  445. case 'indefinite': 
  446. if(empty($price['amount'])) $price['amount'] = '0'; 
  447.  
  448. if($price['amount'] == '0') { 
  449. // The indefinite rule is free, we need to move any previous 
  450. // steps up to this one as we can't have a free a3 
  451. if( isset($ff['a2']) && $ff['a2'] != '0.00' ) { 
  452. // we have some other earlier rule so move it up 
  453. $ff['a3'] = $ff['a2']; 
  454. $ff['p3'] = $ff['p2']; 
  455. $ff['t3'] = $ff['t2']; 
  456. unset($ff['a2']); 
  457. unset($ff['p2']); 
  458. unset($ff['t2']); 
  459. $ff['src'] = '0'; 
  460. } elseif( isset($ff['a1']) && $ff['a1'] != '0.00' ) { 
  461. $ff['a3'] = $ff['a1']; 
  462. $ff['p3'] = $ff['p1']; 
  463. $ff['t3'] = $ff['t1']; 
  464. unset($ff['a1']); 
  465. unset($ff['p1']); 
  466. unset($ff['t1']); 
  467. $ff['src'] = '0'; 
  468. } else { 
  469. $ff['a3'] = apply_filters('membership_amount_' . $M_options['paymentcurrency'], number_format($price['amount'], 2, '.' , '')); 
  470. $ff['p3'] = 1; 
  471. $ff['t3'] = 'Y'; 
  472. $ff['src'] = '0'; 
  473. break; 
  474. case 'serial': 
  475. if(empty($price['amount'])) $price['amount'] = '0'; 
  476.  
  477. if($price['amount'] == '0') { 
  478. // The serial rule is free, we need to move any previous 
  479. // steps up to this one as we can't have a free a3 
  480. if( isset($ff['a2']) && $ff['a2'] != '0.00' ) { 
  481. // we have some other earlier rule so move it up 
  482. $ff['a3'] = $ff['a2']; 
  483. $ff['p3'] = $ff['p2']; 
  484. $ff['t3'] = $ff['t2']; 
  485. unset($ff['a2']); 
  486. unset($ff['p2']); 
  487. unset($ff['t2']); 
  488. $ff['src'] = '1'; 
  489. } elseif( isset($ff['a1']) && $ff['a1'] != '0.00' ) { 
  490. $ff['a3'] = $ff['a1']; 
  491. $ff['p3'] = $ff['p1']; 
  492. $ff['t3'] = $ff['t1']; 
  493. unset($ff['a1']); 
  494. unset($ff['p1']); 
  495. unset($ff['t1']); 
  496. $ff['src'] = '1'; 
  497. } else { 
  498. $ff['a3'] = apply_filters('membership_amount_' . $M_options['paymentcurrency'], number_format($price['amount'], 2, '.' , '')); 
  499. $ff['p3'] = $price['period']; 
  500. $ff['t3'] = strtoupper($price['unit']); 
  501. $ff['src'] = '1'; 
  502.  
  503. break; 
  504.  
  505. if(!empty($ff)) { 
  506. foreach($ff as $key => $value) { 
  507. $form .= '<input type="hidden" name="' . $key . '" value="' . $value . '">'; 
  508.  
  509. $form .= '<input type="hidden" name="custom" value="' . $this->build_custom($user_id, $subscription->id, $ff['a3'], $fromsub_id) .'">'; 
  510.  
  511. // Remainder of the easy bits 
  512.  
  513. $form .= '<input type="hidden" name="return" value="' . apply_filters( 'membership_return_url_' . $this->gateway, M_get_returnurl_permalink()) . '">'; 
  514. $form .= '<input type="hidden" name="cancel_return" value="' . apply_filters( 'membership_cancel_url_' . $this->gateway, M_get_subscription_permalink()) . '">'; 
  515.  
  516.  
  517. $form .= '<input type="hidden" name="lc" value="' . esc_attr(get_option( $this->gateway . "_paypal_site" )) . '">'; 
  518. $form .= '<input type="hidden" name="notify_url" value="' . trailingslashit(get_option('home')) . 'paymentreturn/' . esc_attr($this->gateway) . '">'; 
  519.  
  520. $form .= '<input type="hidden" name="modify" value="2">'; 
  521.  
  522. $button = get_option( $this->gateway . "_paypal_upgrade_button", 'https://www.paypal.com/en_US/i/btn/btn_subscribe_LG.gif' ); 
  523.  
  524. $form .= '<!-- Display the payment button. --> <input type="image" name="submit" border="0" src="' . $button . '" alt="PayPal - The safer, easier way to pay online">'; 
  525. $form .= '<img alt="" border="0" width="1" height="1" src="https://www.paypal.com/en_US/i/scr/pixel.gif" >'; 
  526. $form .= '</form>'; 
  527.  
  528. return $form; 
  529.  
  530.  
  531. function build_upgrade_button($subscription, $pricing, $user_id, $fromsub_id = false) { 
  532.  
  533. if(!empty($pricing)) { 
  534.  
  535. // check to make sure there is a price in the subscription 
  536. // we don't want to display free ones for a payment system 
  537. $free = true; 
  538. foreach($pricing as $key => $price) { 
  539. if(!empty($price['amount']) && $price['amount'] > 0 ) { 
  540. $free = false; 
  541.  
  542. if(!$free) { 
  543. if(count($pricing) == 1) { 
  544. // A basic price or a single subscription 
  545. if(in_array($pricing[0]['type'], array('indefinite', 'finite'))) { 
  546. // one-off payment 
  547. return $this->single_upgrade_button($pricing, $subscription, $user_id, true, $fromsub_id); 
  548. } else { 
  549. // simple subscription 
  550. return $this->single_upgrade_button($pricing, $subscription, $user_id, false, $fromsub_id); 
  551. } else { 
  552. // something much more complex 
  553. return $this->complex_upgrade_button($pricing, $subscription, $user_id, $fromsub_id); 
  554.  
  555.  
  556.  
  557.  
  558. function display_subscribe_button($subscription, $pricing, $user_id) { 
  559. echo $this->build_subscribe_button($subscription, $pricing, $user_id); 
  560.  
  561.  
  562. function display_upgrade_button($subscription, $pricing, $user_id, $fromsub_id = false) { 
  563. echo $this->build_upgrade_button($subscription, $pricing, $user_id, $fromsub_id); 
  564.  
  565. function display_cancel_button($subscription, $pricing, $user_id) { 
  566.  
  567. if($pricing[0]['amount'] < 1) { 
  568. // a free first level, so we can just cancel without having to go to paypal 
  569. echo '<form class="unsubbutton" action="" method="post">'; 
  570. wp_nonce_field('cancel-sub_' . $subscription->sub_id()); 
  571. echo "<input type='hidden' name='action' value='unsubscribe' />"; 
  572. echo "<input type='hidden' name='gateway' value='" . $this->gateway . "' />"; 
  573. echo "<input type='hidden' name='subscription' value='" . $subscription->sub_id() . "' />"; 
  574. echo "<input type='hidden' name='user' value='" . $user_id . "' />"; 
  575. echo "<input type='submit' name='submit' value=' " . __('Unsubscribe', 'membership') . " ' class='button blue' />"; 
  576. echo "</form>"; 
  577. } else { 
  578. $form = ''; 
  579.  
  580. if (get_option( $this->gateway . "_paypal_status" ) == 'live') { 
  581. $form .= '<a class="unsubbutton" href="https://www.paypal.com/cgi-bin/webscr'; 
  582. } else { 
  583. $form .= '<a class="unsubbutton" href="https://www.sandbox.paypal.com/cgi-bin/webscr'; 
  584.  
  585. $form .= '?cmd=_subscr-find&alias=' . urlencode(esc_attr(get_option( $this->gateway . "_paypal_email" ))) . '">'; 
  586.  
  587. $button = get_option( $this->gateway . "_paypal_cancel_button", 'https://www.paypal.com/en_US/i/btn/btn_unsubscribe_LG.gif' ); 
  588. $form .= '<img border="0" src="' . esc_attr($button) . '">'; 
  589. $form .= '</a>'; 
  590.  
  591. echo $form; 
  592.  
  593.  
  594. function update() { 
  595.  
  596. if(isset($_POST['paypal_email'])) { 
  597. update_option( $this->gateway . "_paypal_email", $_POST[ 'paypal_email' ] ); 
  598. update_option( $this->gateway . "_paypal_site", $_POST[ 'paypal_site' ] ); 
  599. update_option( $this->gateway . "_currency", (isset($_POST[ 'currency' ])) ? $_POST[ 'currency' ] : 'USD' ); 
  600. update_option( $this->gateway . "_paypal_status", $_POST[ 'paypal_status' ] ); 
  601. update_option( $this->gateway . "_paypal_button", $_POST[ 'paypal_button' ] ); 
  602. update_option( $this->gateway . "_paypal_upgrade_button", $_POST[ '_paypal_upgrade_button' ] ); 
  603. update_option( $this->gateway . "_paypal_cancel_button", $_POST[ '_paypal_cancel_button' ] ); 
  604.  
  605. // default action is to return true 
  606. return true; 
  607.  
  608.  
  609. function display_free_upgrade_button($subscription, $pricing, $user_id, $fromsub_id = false) { 
  610.  
  611. echo '<form class="upgradebutton" action="' . M_get_subscription_permalink() . '" method="post">'; 
  612. wp_nonce_field('upgrade-sub_' . $subscription->sub_id()); 
  613. echo "<input type='hidden' name='action' value='upgradesolo' />"; 
  614. echo "<input type='hidden' name='gateway' value='" . $this->gateway . "' />"; 
  615. echo "<input type='hidden' name='subscription' value='" . $subscription->sub_id() . "' />"; 
  616. echo "<input type='hidden' name='user' value='" . $user_id . "' />"; 
  617. echo "<input type='hidden' name='fromsub_id' value='" . $fromsub_id . "' />"; 
  618. echo "<input type='submit' name='submit' value=' " . __('Upgrade', 'membership') . " ' class='button blue' />"; 
  619. echo "</form>"; 
  620.  
  621. function display_upgrade_from_free_button($subscription, $pricing, $user_id, $fromsub_id = false) { 
  622.  
  623. if(!empty($pricing)) { 
  624.  
  625. $free = true; 
  626. foreach($pricing as $key => $price) { 
  627. if(!empty($price['amount']) && $price['amount'] > 0 ) { 
  628. $free = false; 
  629.  
  630. if($free) { 
  631.  
  632. $this->display_free_upgrade_button($subscription, $pricing, $user_id, $fromsub_id); 
  633. } else { 
  634. $this->display_upgrade_button($subscription, $pricing, $user_id, $fromsub_id); 
  635.  
  636.  
  637.  
  638. // IPN stuff 
  639. function handle_paypal_return() { 
  640. // PayPal IPN handling code 
  641.  
  642. if ((isset($_POST['payment_status']) || isset($_POST['txn_type'])) && isset($_POST['custom'])) { 
  643.  
  644. if (get_option( $this->gateway . "_paypal_status" ) == 'live') { 
  645. $domain = 'https://www.paypal.com'; 
  646. } else { 
  647. $domain = 'https://www.sandbox.paypal.com'; 
  648.  
  649. $req = 'cmd=_notify-validate'; 
  650. if (!isset($_POST)) $_POST = $HTTP_POST_VARS; 
  651. foreach ($_POST as $k => $v) { 
  652. if (get_magic_quotes_gpc()) $v = stripslashes($v); 
  653. $req .= '&' . $k . '=' . $v; 
  654.  
  655. $header = 'POST /cgi-bin/webscr HTTP/1.0' . "\r\n" 
  656. . 'Content-Type: application/x-www-form-urlencoded' . "\r\n" 
  657. . 'Content-Length: ' . strlen($req) . "\r\n" 
  658. . "\r\n"; 
  659.  
  660. @set_time_limit(60); 
  661. if ($conn = @fsockopen($domain, 80, $errno, $errstr, 30)) { 
  662. fputs($conn, $header . $req); 
  663. socket_set_timeout($conn, 30); 
  664.  
  665. $response = ''; 
  666. $close_connection = false; 
  667. while (true) { 
  668. if (feof($conn) || $close_connection) { 
  669. fclose($conn); 
  670. break; 
  671.  
  672. $st = @fgets($conn, 4096); 
  673. if ($st === false) { 
  674. $close_connection = true; 
  675. continue; 
  676.  
  677. $response .= $st; 
  678.  
  679. $error = ''; 
  680. $lines = explode("\n", str_replace("\r\n", "\n", $response)); 
  681. // looking for: HTTP/1.1 200 OK 
  682. if (count($lines) == 0) $error = 'Response Error: Header not found'; 
  683. else if (substr($lines[0], -7) != ' 200 OK') $error = 'Response Error: Unexpected HTTP response'; 
  684. else { 
  685. // remove HTTP header 
  686. while (count($lines) > 0 && trim($lines[0]) != '') array_shift($lines); 
  687.  
  688. // first line will be empty, second line will have the result 
  689. if (count($lines) < 2) $error = 'Response Error: No content found in transaction response'; 
  690. else if (strtoupper(trim($lines[1])) != 'VERIFIED') $error = 'Response Error: Unexpected transaction response'; 
  691.  
  692. if ($error != '') { 
  693. echo $error; 
  694. exit; 
  695.  
  696. // handle cases that the system must ignore 
  697. //if ($_POST['payment_status'] == 'In-Progress' || $_POST['payment_status'] == 'Partially-Refunded') exit; 
  698. $new_status = false; 
  699. // process PayPal response 
  700. switch ($_POST['payment_status']) { 
  701. case 'Partially-Refunded': 
  702. break; 
  703.  
  704. case 'In-Progress': 
  705. break; 
  706.  
  707. case 'Completed': 
  708. case 'Processed': 
  709. // case: successful payment 
  710. $amount = $_POST['mc_gross']; 
  711. $currency = $_POST['mc_currency']; 
  712. list($timestamp, $user_id, $sub_id, $key) = explode(':', $_POST['custom']); 
  713.  
  714. $this->record_transaction($user_id, $sub_id, $amount, $currency, $timestamp, $_POST['txn_id'], $_POST['payment_status'], ''); 
  715.  
  716. // Added for affiliate system link 
  717. do_action('membership_payment_processed', $user_id, $sub_id, $amount, $currency, $_POST['txn_id']); 
  718. break; 
  719.  
  720. case 'Reversed': 
  721. // case: charge back 
  722. $note = __('Last transaction has been reversed. Reason: Payment has been reversed (charge back)', 'membership'); 
  723. $amount = $_POST['mc_gross']; 
  724. $currency = $_POST['mc_currency']; 
  725. list($timestamp, $user_id, $sub_id, $key) = explode(':', $_POST['custom']); 
  726.  
  727. $this->record_transaction($user_id, $sub_id, $amount, $currency, $timestamp, $_POST['txn_id'], $_POST['payment_status'], $note); 
  728.  
  729. $member = new M_Membership($user_id); 
  730. if($member) { 
  731. $member->expire_subscription($sub_id); 
  732. if(defined('MEMBERSHIP_DEACTIVATE_USER_ON_CANCELATION') && MEMBERSHIP_DEACTIVATE_USER_ON_CANCELATION == true ) { 
  733. $member->deactivate(); 
  734.  
  735. do_action('membership_payment_reversed', $user_id, $sub_id, $amount, $currency, $_POST['txn_id']); 
  736. break; 
  737.  
  738. case 'Refunded': 
  739. // case: refund 
  740. $note = __('Last transaction has been reversed. Reason: Payment has been refunded', 'membership'); 
  741. $amount = $_POST['mc_gross']; 
  742. $currency = $_POST['mc_currency']; 
  743. list($timestamp, $user_id, $sub_id, $key) = explode(':', $_POST['custom']); 
  744.  
  745. $this->record_transaction($user_id, $sub_id, $amount, $currency, $timestamp, $_POST['txn_id'], $_POST['payment_status'], $note); 
  746.  
  747. $member = new M_Membership($user_id); 
  748. if($member) { 
  749. $member->expire_subscription($sub_id); 
  750.  
  751. do_action('membership_payment_refunded', $user_id, $sub_id, $amount, $currency, $_POST['txn_id']); 
  752. break; 
  753.  
  754. case 'Denied': 
  755. // case: denied 
  756. $note = __('Last transaction has been reversed. Reason: Payment Denied', 'membership'); 
  757. $amount = $_POST['mc_gross']; 
  758. $currency = $_POST['mc_currency']; 
  759. list($timestamp, $user_id, $sub_id, $key) = explode(':', $_POST['custom']); 
  760.  
  761. $this->record_transaction($user_id, $sub_id, $amount, $currency, $timestamp, $_POST['txn_id'], $_POST['payment_status'], $note); 
  762.  
  763. $member = new M_Membership($user_id); 
  764. if($member) { 
  765. $member->expire_subscription($sub_id); 
  766. if(defined('MEMBERSHIP_DEACTIVATE_USER_ON_CANCELATION') && MEMBERSHIP_DEACTIVATE_USER_ON_CANCELATION == true ) { 
  767. $member->deactivate(); 
  768.  
  769. do_action('membership_payment_denied', $user_id, $sub_id, $amount, $currency, $_POST['txn_id']); 
  770. break; 
  771.  
  772. case 'Pending': 
  773. // case: payment is pending 
  774. $pending_str = array( 
  775. 'address' => __('Customer did not include a confirmed shipping address', 'membership'),  
  776. 'authorization' => __('Funds not captured yet', 'membership'),  
  777. 'echeck' => __('eCheck that has not cleared yet', 'membership'),  
  778. 'intl' => __('Payment waiting for aproval by service provider', 'membership'),  
  779. 'multi-currency' => __('Payment waiting for service provider to handle multi-currency process', 'membership'),  
  780. 'unilateral' => __('Customer did not register or confirm his/her email yet', 'membership'),  
  781. 'upgrade' => __('Waiting for service provider to upgrade the PayPal account', 'membership'),  
  782. 'verify' => __('Waiting for service provider to verify his/her PayPal account', 'membership'),  
  783. '*' => '' 
  784. ); 
  785. $reason = @$_POST['pending_reason']; 
  786. $note = __('Last transaction is pending. Reason: ', 'membership') . (isset($pending_str[$reason]) ? $pending_str[$reason] : $pending_str['*']); 
  787. $amount = $_POST['mc_gross']; 
  788. $currency = $_POST['mc_currency']; 
  789. list($timestamp, $user_id, $sub_id, $key) = explode(':', $_POST['custom']); 
  790.  
  791. $this->record_transaction($user_id, $sub_id, $amount, $currency, $timestamp, $_POST['txn_id'], $_POST['payment_status'], $note); 
  792.  
  793. do_action('membership_payment_pending', $user_id, $sub_id, $amount, $currency, $_POST['txn_id']); 
  794. break; 
  795.  
  796. default: 
  797. // case: various error cases 
  798.  
  799. //check for subscription details 
  800. switch ($_POST['txn_type']) { 
  801. case 'subscr_signup': 
  802. // start the subscription 
  803. $amount = $_POST['mc_amount3']; 
  804. list($timestamp, $user_id, $sub_id, $key) = explode(':', $_POST['custom']); 
  805.  
  806. $newkey = md5('MEMBERSHIP' . $amount); 
  807. if($key != $newkey) { 
  808. $member = new M_Membership($user_id); 
  809. if($member) { 
  810. if(defined('MEMBERSHIP_DEACTIVATE_USER_ON_CANCELATION') && MEMBERSHIP_DEACTIVATE_USER_ON_CANCELATION == true ) { 
  811. $member->deactivate(); 
  812. } else { 
  813. // create_subscription 
  814. $member = new M_Membership($user_id); 
  815. if($member) { 
  816. $member->create_subscription($sub_id, $this->gateway); 
  817.  
  818. do_action('membership_payment_subscr_signup', $user_id, $sub_id); 
  819. break; 
  820.  
  821. case 'subscr_modify': 
  822. // modify the subscription 
  823. list($timestamp, $user_id, $sub_id, $key) = explode(':', $_POST['custom']); 
  824.  
  825. // create_subscription 
  826. $member = new M_Membership($user_id); 
  827. if($member) { 
  828. // Remove the old subscription 
  829. $member->drop_subscription($sub_id); 
  830. // Join the new subscription 
  831. $member->create_subscription((int) $_POST['item_number'], $this->gateway); 
  832. // Timestamp the update 
  833. update_user_meta( $user_id, '_membership_last_upgraded', time()); 
  834.  
  835. do_action('membership_payment_subscr_signup', $user_id, $sub_id); 
  836. break; 
  837.  
  838. case 'subscr_cancel': 
  839. // mark for removal 
  840. list($timestamp, $user_id, $sub_id, $key) = explode(':', $_POST['custom']); 
  841.  
  842. $member = new M_Membership($user_id); 
  843. if($member) { 
  844. $member->mark_for_expire($sub_id); 
  845.  
  846. do_action('membership_payment_subscr_cancel', $user_id, $sub_id); 
  847. break; 
  848.  
  849. case 'new_case': 
  850. // a dispute 
  851. if($_POST['case_type'] == 'dispute') { 
  852. // immediately suspend the account 
  853. $member = new M_Membership($user_id); 
  854. if($member) { 
  855. $member->deactivate(); 
  856.  
  857. do_action('membership_payment_new_case', $user_id, $sub_id, $_POST['case_type']); 
  858. break; 
  859.  
  860. } else { 
  861. // Did not find expected POST variables. Possible access attempt from a non PayPal site. 
  862. header('Status: 404 Not Found'); 
  863. echo 'Error: Missing POST variables. Identification is not possible.'; 
  864. exit; 
  865.  
  866.  
  867. M_register_gateway('paypalexpress', 'paypalexpress'); 
  868.  
  869. ?> 
.