/**
  * Render membership payment information.
  *
  * Related Filter Hooks:
  * - the_content
  *
  * @since  1.0.0
  *
  * @param string $content The page content to filter.
  * @return string The filtered content.
  */
 public function payment_table($content)
 {
     $data = array();
     $subscription = null;
     $member = MS_Model_Member::get_current_member();
     $membership_id = 0;
     lib3()->array->equip_request('membership_id', 'move_from_id', 'ms_relationship_id');
     if (!empty($_POST['ms_relationship_id'])) {
         // Error path, showing payment table again with error msg
         $subscription = MS_Factory::load('MS_Model_Relationship', absint(intval($_POST['ms_relationship_id'])));
         $membership = $subscription->get_membership();
         $membership_id = $membership->id;
         if (!empty($_POST['error'])) {
             lib3()->array->strip_slashes($_POST, 'error');
             $data['error'] = $_POST['error'];
         }
     } elseif (!empty($_REQUEST['membership_id'])) {
         // First time loading
         $membership_id = intval($_REQUEST['membership_id']);
         $membership = MS_Factory::load('MS_Model_Membership', $membership_id);
         $move_from_id = absint($_REQUEST['move_from_id']);
         $subscription = MS_Model_Relationship::create_ms_relationship($membership_id, $member->id, '', $move_from_id);
     } else {
         MS_Helper_Debug::log('Error: missing POST params');
         MS_Helper_Debug::log($_POST);
         return $content;
     }
     // Invalid membership ID was specified: Redirect to membership list.
     if (!$subscription) {
         MS_Model_Pages::redirect_to(MS_Model_Pages::MS_PAGE_MEMBERSHIPS);
     }
     $invoice = $subscription->get_current_invoice();
     /**
      * Notify Add-ons that we are preparing payment details for a membership
      * subscription.
      *
      * E.g. Coupon discount is applied by this hook.
      *
      * @since  1.0.0
      */
     $invoice = apply_filters('ms_signup_payment_details', $invoice, $subscription, $membership);
     $invoice->save();
     $data['invoice'] = $invoice;
     $data['membership'] = $membership;
     $data['member'] = $member;
     $data['ms_relationship'] = $subscription;
     $view = MS_Factory::load('MS_View_Frontend_Payment');
     $view->data = apply_filters('ms_view_frontend_payment_data', $data, $membership_id, $subscription, $member, $this);
     return apply_filters('ms_controller_frontend_payment_table', $view->to_html(), $this);
 }
 /**
  * Process purchase using gateway.
  *
  * Related Action Hooks:
  * - ms_controller_frontend_signup_process_purchase
  *
  * @since  1.0.0
  */
 public function process_purchase()
 {
     $fields = array('gateway', 'ms_relationship_id');
     lib2()->array->equip_request('gateway', 'ms_relationship_id');
     $valid = true;
     $nonce_name = $_REQUEST['gateway'] . '_' . $_REQUEST['ms_relationship_id'];
     if (!self::validate_required($fields, 'any')) {
         $valid = false;
         $err = 'GAT-01 (invalid fields)';
     } elseif (!MS_Model_Gateway::is_valid_gateway($_REQUEST['gateway'])) {
         $valid = false;
         $err = 'GAT-02 (invalid gateway)';
     } elseif (!$this->verify_nonce($nonce_name, 'any')) {
         $valid = false;
         $err = 'GAT-03 (invalid nonce)';
     }
     if ($valid) {
         $subscription = MS_Factory::load('MS_Model_Relationship', $_REQUEST['ms_relationship_id']);
         $gateway_id = $_REQUEST['gateway'];
         $gateway = MS_Model_Gateway::factory($gateway_id);
         try {
             $invoice = $gateway->process_purchase($subscription);
             // If invoice is successfully paid, redirect to welcome page.
             if ($invoice->is_paid() || $invoice->uses_trial && MS_Model_Invoice::STATUS_BILLED == $invoice->status) {
                 // Make sure to respect the single-membership rule
                 $this->validate_membership_states($subscription);
                 // Redirect user to the Payment-Completed page.
                 if (!defined('IS_UNIT_TEST')) {
                     MS_Model_Pages::redirect_to(MS_Model_Pages::MS_PAGE_REG_COMPLETE, array('ms_relationship_id' => $subscription->id));
                 }
             } elseif (MS_Gateway_Manual::ID == $gateway_id) {
                 // For manual gateway payments.
                 $this->add_action('the_content', 'purchase_info_content');
             } else {
                 // Something went wrong, the payment was not successful.
                 $this->add_action('the_content', 'purchase_error_content');
             }
         } catch (Exception $e) {
             MS_Helper_Debug::log($e->getMessage());
             switch ($gateway_id) {
                 case MS_Gateway_Authorize::ID:
                     $_POST['auth_error'] = $e->getMessage();
                     // call action to step back
                     do_action('ms_controller_frontend_signup_gateway_form');
                     break;
                 case MS_Gateway_Stripe::ID:
                     $_POST['error'] = sprintf(__('Error: %s', MS_TEXT_DOMAIN), $e->getMessage());
                     // Hack to send the error message back to the payment_table.
                     MS_Plugin::instance()->controller->controllers['frontend']->add_action('the_content', 'payment_table', 1);
                     break;
                 default:
                     do_action('ms_controller_gateway_form_error', $e);
                     $this->add_action('the_content', 'purchase_error_content');
                     break;
             }
         }
     } else {
         MS_Helper_Debug::log('Error Code ' . $err);
         $this->add_action('the_content', 'purchase_error_content');
     }
     // Hack to show signup page in case of errors
     $ms_page = MS_Model_Pages::get_page(MS_Model_Pages::MS_PAGE_REGISTER);
     if ($ms_page) {
         // During unit-testing the $ms_page object might be empty.
         global $wp_query;
         $wp_query->query_vars['page_id'] = $ms_page->ID;
         $wp_query->query_vars['post_type'] = 'page';
     }
     do_action('ms_controller_gateway_process_purchase_after', $this);
 }