Example #1
0
	function withdraw( $blog_id, $withdraw = false, $domain = false ) {
		global $wpdb;

		$blog_expire = $this->get_expire( $blog_id );

		if ( $withdraw ) {
			if ( $withdraw == '1' ) {
				$withdraw = 2629744;
			} else if ( $withdraw == '3' ) {
				$withdraw = 7889231;
			} else if ( $withdraw == '12' ) {
				$withdraw = 31556926;
			}
			$new_expire = $blog_expire - $withdraw;
		} else {
			$new_expire = strtotime('-1 day', time() );
		}
		$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->base_prefix}pro_sites SET expire = %s WHERE blog_ID = %d", $new_expire, $blog_id ) );

		unset( $this->pro_sites[ $blog_id ] ); //clear cache
		wp_cache_delete( 'is_pro_site_' . $blog_id, 'psts' ); //clear object cache

		$this->log_action( $blog_id, __( 'Pro Site status has been withdrawn.', 'psts' ) );

		do_action( 'psts_withdraw', $blog_id, $new_expire );

		//flip flag after action fired
		update_blog_option( $blog_id, 'psts_withdrawn', 1 );
		ProSites_Helper_Registration::set_trial( $blog_id, 0 );

		//force to checkout screen next login
		if ( $new_expire <= time() ) {
			update_blog_option( $blog_id, 'psts_signed_up', 1 );
		}
	}
Example #2
0
 /**
  * The heart of the Stripe API integration
  *
  * Everything that Stripe does gets communicated back here.
  *
  * @return bool
  */
 public static function webhook_handler()
 {
     global $wpdb, $psts, $current_site;
     $site_name = $current_site->site_name;
     $domain = '';
     $blog_id = false;
     try {
         // retrieve the request's body and parse it as JSON
         $body = @file_get_contents('php://input');
         $event_json = json_decode($body);
         if (!isset($event_json->data->object->customer)) {
             return false;
         }
         $event_type = $event_json->type;
         $customer_id = $event_json->data->object->customer;
         $subscription = self::get_subscription($event_json);
         if ('invoice.payment_succeeded' == $event_type) {
             self::record_transaction($event_json);
         }
         //If invoice has been created, activate user blog trial
         if ('invoiceitem.updated' == $event_type || 'invoiceitem.created' == $event_type || 'invoice.created' == $event_type || 'invoice.payment_succeeded' == $event_type) {
             // Create generic class from Stripe\Subscription class
             // Convert 3.4 -> 3.5+
             if (!isset($subscription->metadata->blog_id)) {
                 $blog_id = ProSites_Gateway_Stripe::get_blog_id($customer_id);
                 self::set_subscription_blog_id($subscription, $customer_id, $blog_id, $blog_id);
                 $subscription->blog_id = $blog_id;
                 self::set_subscription_meta($subscription, $customer_id);
             }
             if (!empty($subscription->blog_id)) {
                 $blog_id = (int) $subscription->blog_id;
             } else {
                 if (!empty($subscription)) {
                     // activate to get ID
                     $result = ProSites_Helper_Registration::activate_blog($subscription->activation, $subscription->is_trial, $subscription->period, $subscription->level, $subscription->trial_end);
                     $blog_id = $result['blog_id'];
                     // set new ID
                     self::set_subscription_blog_id($subscription, $customer_id, $blog_id);
                 }
             }
             //Set Customer data
             if (!empty($blog_id) && isset($subscription->id) && !empty($subscription->id)) {
                 self::set_customer_data($blog_id, $customer_id, $subscription->id);
             }
         }
         if (empty($blog_id) && isset($subscription) && isset($subscription->blog_id) && !empty($subscription->blog_id)) {
             $blog_id = $subscription->blog_id;
         }
         if ($blog_id || $domain) {
             // In case the blog has since been removed from the database, just exit
             $details = get_blog_details($blog_id);
             if (empty($details)) {
                 return false;
             }
             $date = date_i18n(get_option('date_format'), $event_json->created);
             $amount = $amount_formatted = $plan_amount = 0;
             $level = $period = $plan = '';
             $is_trial = false;
             $plan_end = false;
             switch ($event_type) {
                 case 'invoice.payment_succeeded':
                 case 'invoice.payment_failed':
                     $plan = $subscription->plan->id;
                     $is_trial = $subscription->is_trial;
                     $plan_end = $subscription->period_end;
                     $plan_amount = $subscription->plan_amount;
                     $amount = $subscription->subscription_amount;
                     $invoice_items = $subscription->invoice_items;
                     $setup_fee_amt = $subscription->setup_fee;
                     $has_setup_fee = $subscription->has_setup_fee;
                     $plan_change_amount = $subscription->plan_change_amount;
                     $has_plan_change = $subscription->plan_change;
                     $plan_change_mode = $subscription->plan_change_mode;
                     $discount_amount = $subscription->discount_amount;
                     $has_discount = $subscription->has_discount;
                     break;
                 case 'customer.subscription.created':
                 case 'customer.subscription.updated':
                     $plan = $subscription->plan->id;
                     $amount = $plan_amount = $subscription->plan->amount / 100;
                     $is_trial = $subscription->is_trial;
                     $plan_end = $is_trial ? $subscription->trial_end : $subscription->period_end;
                     break;
             }
             // Should be Stripe regardless if its a trial, we need the proper information returned later
             $gateway = self::get_slug();
             // ... but we should record that it is a trial.
             if ($is_trial) {
                 ProSites_Helper_Registration::set_trial($blog_id, 1);
             }
             $amount_formatted = $psts->format_currency(false, $amount);
             $charge_id = isset($event_json->data->object->charge) ? $event_json->data->object->charge : $event_json->data->object->id;
             if (!empty($plan)) {
                 $plan_parts = explode('_', $plan);
                 $period = array_pop($plan_parts);
                 $level = array_pop($plan_parts);
             }
             if (!empty($blog_id)) {
                 /* 	reset the waiting status (this is used on the checkout screen to display a
                 				notice to customers that actions are pending on their account) */
                 update_blog_option($blog_id, 'psts_stripe_waiting', 0);
             } elseif (!empty($domain)) {
                 /**
                  * @todo redundant now
                  */
                 //Update signup meta
                 //					$signup_meta                        = $psts->get_signup_meta( $domain );
                 //					$signup_meta['psts_stripe_waiting'] = 0;
                 //					$psts->update_signup_meta( $signup_meta, $domain );
             }
             switch ($event_type) {
                 case 'invoice.payment_succeeded':
                     $psts->log_action($blog_id, sprintf(__('Stripe webhook "%s" received: The %s payment was successfully received. Date: "%s", Charge ID "%s"', 'psts'), $event_type, $amount_formatted, $date, $charge_id));
                     $charge_amount = $plan_amount;
                     $args = array();
                     //						if ( $has_setup_fee ) {
                     //							$args['setup_amount'] = $setup_fee_amt;
                     //						}
                     //						if( $has_discount ) {
                     //							$args['discount_amount'] = $discount_amount;
                     //						}
                     //						if( $has_plan_change ) {
                     //							$args['plan_change_amount'] = $plan_change_amount;
                     //							$args['plan_change_mode'] = $plan_change_mode;
                     //						}
                     if ($invoice_items) {
                         $args['items'] = $invoice_items;
                     }
                     self::maybe_extend($blog_id, $period, $gateway, $level, $charge_amount, $plan_end, true, true, $args);
                     break;
                 case 'customer.subscription.created':
                     $period_string = $period == 1 ? 'month' : 'months';
                     $psts->record_stat($blog_id, 'signup');
                     $psts->log_action($blog_id, sprintf(__('Stripe webhook "%1$s" received: Customer successfully subscribed to %2$s %3$s: %4$s every %5$s %6$s.', 'psts'), $event_type, $site_name, $psts->get_level_setting($level, 'name'), $psts->format_currency(false, $plan_amount), number_format_i18n($period), $period_string), $domain);
                     self::maybe_extend($blog_id, $period, $gateway, $level, $plan_amount, $plan_end);
                     break;
                 case 'customer.subscription.updated':
                     $period_string = $period == 1 ? 'month' : 'months';
                     $current_plan = self::get_current_plan($blog_id);
                     $plan_parts = explode('_', $current_plan);
                     $current_plan_period = array_pop($plan_parts);
                     $current_plan_level = array_pop($plan_parts);
                     if ($current_plan_period != $period || $current_plan_level != $level) {
                         if ($current_plan_level < $level) {
                             $psts->record_stat($blog_id, 'upgrade');
                         } else {
                             $psts->record_stat($blog_id, 'modify');
                         }
                     }
                     $psts->log_action($blog_id, sprintf(__('Stripe webhook "%s" received. The customer\'s subscription was successfully updated to %2$s %3$s: %4$s every %5$s %6$s.', 'psts'), $event_type, $site_name, $psts->get_level_setting($level, 'name'), $psts->format_currency(false, $plan_amount), number_format_i18n($period), $period_string));
                     self::maybe_extend($blog_id, $period, $gateway, $level, $plan_amount, $plan_end);
                     break;
                 case 'invoice.payment_failed':
                     $psts->log_action($blog_id, sprintf(__('Stripe webhook "%s" received: The %s payment has failed. Date: "%s", Charge ID "%s"', 'psts'), $event_type, $amount_formatted, $date, $charge_id));
                     $psts->email_notification($blog_id, 'failed');
                     break;
                 case 'charge.disputed':
                     $psts->log_action($blog_id, sprintf(__('Stripe webhook "%s" received: The customer disputed a charge with their bank (chargeback), Charge ID "%s"', 'psts'), $event_type, $charge_id));
                     $psts->withdraw($blog_id);
                     break;
                 case 'customer.subscription.deleted':
                     update_blog_option($blog_id, 'psts_stripe_canceled', 1);
                     $psts->log_action($blog_id, sprintf(__('Stripe webhook "%s" received: The subscription has been canceled', 'psts'), $event_type));
                     break;
                 default:
                     $text = sprintf(__('Stripe webhook "%s" received', 'psts'), $event_type);
                     if ($customer_id) {
                         $text .= sprintf(__(': Customer ID: %s', 'psts'), $customer_id);
                     }
                     $psts->log_action($blog_id, $text);
                     break;
             }
         }
         die(1);
     } catch (Exception $ex) {
         $message = $ex->getMessage();
         die($message);
     }
 }
Example #3
0
 public static function ajax_check_prosite_blog()
 {
     global $psts, $current_site;
     $blog_data = array();
     // Add ajax session var
     ProSites_Helper_Session::session('psts_ajax_session_activated', true);
     // Introduce a fake error because we don't want to actually create the blog yet.
     add_filter('registration_errors', array('ProSites_Model_Registration', 'prosite_blog_check_only'), 10, 3);
     // replace $_POST with array data
     $params = array();
     parse_str($_POST['data'], $params);
     $period = (int) $_POST['period'];
     $level = 'free' == $_POST['level'] ? $_POST['level'] : (int) $_POST['level'];
     $_POST = $params;
     $doing_ajax = defined('DOING_AJAX') && DOING_AJAX ? true : false;
     $ajax_response = array();
     if ($doing_ajax) {
         $user_name = sanitize_text_field($_POST['user_name']);
         $user_email = sanitize_email($_POST['user_email']);
         $blogname = sanitize_text_field($_POST['blogname']);
         $blog_title = sanitize_text_field(urldecode($_POST['blog_title']));
         // Process some cleaning up if needed
         do_action('prosite_register_blog_pre_validation', $user_name, $user_email, $blogname);
         $blog_validation = wpmu_validate_blog_signup($blogname, $blog_title);
         // Attempt to create a new user (knowing that it will fail, but it should only have our error)
         if (!isset($_POST['new_blog'])) {
             $validation = wpmu_validate_user_signup($user_name, $user_email);
             // nicer errors, but doesn't deal with custom fields
             $user_check = register_new_user($user_name, $user_email);
             // checks custom fields, but ugly errors
             $user_check->errors = array_merge($user_check->errors, $validation['errors']->errors);
             $user_check->errors = array_merge($user_check->errors, $blog_validation['errors']->errors);
         } else {
             $user_check = new WP_Error();
             $user_check->errors = array_merge($user_check->errors, $blog_validation['errors']->errors);
         }
         // Replaced session vars to make it semi-stateless, will pick these up in a session later
         $blog_data['new_blog_details'] = array();
         $blog_data['new_blog_details']['username'] = $user_name;
         $blog_data['new_blog_details']['email'] = $user_email;
         $blog_data['new_blog_details']['blogname'] = $blogname;
         $blog_data['new_blog_details']['title'] = $blog_title;
         $blog_data['new_blog_details']['level'] = $level;
         $blog_data['new_blog_details']['period'] = $period;
         $username_available = true;
         $email_available = true;
         $blogname_available = true;
         $blogtitle_available = true;
         // Checking passed...
         if (!empty($user_check->errors) && 1 == count($user_check->errors) && !isset($_POST['new_blog']) || 0 == count($user_check->errors) && isset($_POST['new_blog'])) {
             $keys = array_keys($user_check->errors);
             if ($keys && !in_array('availability_check_only', $keys) && !isset($_POST['new_blog'])) {
                 // Something went wrong!
                 $ajax_response['user_available'] = false;
             } else {
                 // All good!  We're ready to create the user/site
                 /** User is validated using register_new_user so that we can use the hooks and make them available,
                  * but we still need to actually create and activate the signup to get the $user_id. */
                 $blog = $blog_validation;
                 $domain = $blog['domain'];
                 $path = $blog['path'];
                 $blogname = $blog['blogname'];
                 $blog_title = $blog['blog_title'];
                 $errors = $blog['errors'];
                 // Privacy setting
                 $public = (int) $_POST['blog_public'];
                 $signup_meta = array('lang_id' => 1, 'public' => $public);
                 // Create the signup
                 $meta = apply_filters('add_signup_meta', $signup_meta);
                 $result = ProSites_Helper_Registration::signup_blog($domain, $path, $blog_title, $user_name, $user_email, $meta);
                 $blog_data['activation_key'] = $result['activation_key'];
                 if (isset($result['user_pass']) && !empty($result['user_pass'])) {
                     $blog_data['new_blog_details']['user_pass'] = $result['user_pass'];
                 }
                 $trial_days = $psts->get_setting('trial_days', 0);
                 $trial_active = !empty($trial_days);
                 $site_name = '';
                 if (!is_subdomain_install()) {
                     $site_name = $current_site->domain . $current_site->path . $blogname;
                 } else {
                     $site_name = $blogname . '.' . ($site_domain = preg_replace('|^www\\.|', '', $current_site->domain));
                 }
                 if ($trial_active) {
                     $recurring = $psts->get_setting('recurring_subscriptions', 1);
                     if ($recurring) {
                         $blog_data['new_blog_details']['reserved_message'] = sprintf('<div class="reserved_msg"><h2>' . __('Activate your site', 'psts') . '</h2>' . __('<p>Your site <strong>(%s)</strong> has been reserved but is not yet activated.</p><p>Once payment information has been verified your trial period will begin. When your trial ends you will be automatically upgraded to your chosen plan. Your reservation only last for 48 hours upon which your site name will become available again.</p><p>Please use the form below to setup your payment information.</p>', 'psts') . '</div>', $site_name);
                     } else {
                         // Non-recurring sites really should not do anything at checkout other than activate.
                         $result = ProSites_Helper_Registration::activate_blog($blog_data, true, $period, $level);
                         $blog_id = $result['blog_id'];
                         if (isset($result['password'])) {
                             $blog_data['new_blog_details']['user_pass'] = $result['password'];
                         }
                         ProSites_Helper_Registration::set_trial($blog_id, 1);
                         //Update Activation Key for blog
                         ProSites_Helper_Registration::update_activation_key($blog_id, $blog_data['activation_key']);
                         $psts->record_stat($blog_id, 'signup');
                         $ajax_response['show_finish'] = true;
                         $ajax_response['finish_content'] = ProSites_View_Front_Gateway::render_payment_submitted($blog_data, true);
                     }
                 } else {
                     $blog_data['new_blog_details']['reserved_message'] = sprintf('<div class="reserved_msg"><h2>' . __('Activate your site', 'psts') . '</h2>' . __('<p>Your site <strong>(%s)</strong> has been reserved but is not yet activated.</p><p>Once payment has been processed your site will become active with your chosen plan. Your reservation only last for 48 hours upon which your site name will become available again.</p><p>Please use the form below to setup your payment information.</p>', 'psts') . '</div>', $site_name);
                 }
                 // FREE basic site
                 if ('free' == $blog_data['new_blog_details']['level']) {
                     if (isset($blog_data['new_blog_details']['reserved_message'])) {
                         unset($blog_data['new_blog_details']['reserved_message']);
                     }
                     $result = ProSites_Helper_Registration::activate_blog($blog_data, false, false, false);
                     $blog_data['new_blog_details']['blog_id'] = $result['blog_id'];
                     if (isset($result['password'])) {
                         $blog_data['new_blog_details']['user_pass'] = $result['password'];
                     }
                     $ajax_response['show_finish'] = true;
                     $ajax_response['finish_content'] = ProSites_View_Front_Gateway::render_free_confirmation($blog_data);
                 }
                 if (isset($blog_data['new_blog_details']['reserved_message'])) {
                     $ajax_response['reserved_message'] = $blog_data['new_blog_details']['reserved_message'];
                 }
             }
             // If WP 4.0+ and user is logged in it will use WP_Session_Tokens, else $_SESSION
             ProSites_Helper_Session::session('new_blog_details', $blog_data['new_blog_details']);
             ProSites_Helper_Session::session('activation_key', $blog_data['activation_key']);
             $ajax_response['gateways_form'] = ProSites_View_Front_Gateway::render_checkout($blog_data);
         } else {
             // We had registration errors, redraw the form displaying errors
             if (!empty($user_check) && isset($user_check->errors)) {
                 $ajax_response['form'] = ProSites_View_Front_Registration::render_signup_form($blog_data, $user_check);
                 $ajax_response['user_available'] = false;
             }
             // Isolate which standard fields are valid
             $error_keys = array_keys($user_check->errors);
             foreach ($error_keys as $key) {
                 if (preg_match('/username|user_name/', $key)) {
                     $username_available = false;
                 }
                 if (preg_match('/email/', $key)) {
                     $email_available = false;
                 }
                 if (preg_match('/blogname/', $key)) {
                     $blogname_available = false;
                 }
                 if (preg_match('/blog_title/', $key)) {
                     $blogtitle_available = false;
                 }
             }
         }
         $ajax_response['username_available'] = $username_available;
         $ajax_response['email_available'] = $email_available;
         $ajax_response['blogname_available'] = $blogname_available;
         $ajax_response['blog_title_available'] = $blogtitle_available;
         $response = array('what' => 'response', 'action' => 'check_prosite_blog', 'id' => 1, 'data' => json_encode($ajax_response));
         // No longer need ajax session
         ProSites_Helper_Session::unset_session('psts_ajax_session_activated');
         // Buffer used to isolate AJAX response from unexpected output
         @ob_end_clean();
         ob_start();
         $xmlResponse = new WP_Ajax_Response($response);
         $xmlResponse->send();
         ob_end_flush();
     }
 }