/** * Process registration * * @since 2.1 */ public function process_signup() { global $rcp_options; $args = array('USER' => $this->username, 'PWD' => $this->password, 'SIGNATURE' => $this->signature, 'VERSION' => '124', 'METHOD' => $this->auto_renew ? 'CreateRecurringPaymentsProfile' : 'DoDirectPayment', 'AMT' => $this->amount, 'CURRENCYCODE' => strtoupper($this->currency), 'SHIPPINGAMT' => 0, 'TAXAMT' => 0, 'DESC' => $this->subscription_name, 'SOFTDESCRIPTOR' => get_bloginfo('name') . ' - ' . $this->subscription_name, 'SOFTDESCRIPTORCITY' => get_bloginfo('admin_email'), 'CUSTOM' => $this->user_id, 'NOTIFYURL' => add_query_arg('listener', 'EIPN', home_url('index.php')), 'EMAIL' => $this->email, 'CREDITCARDTYPE' => '', 'ACCT' => sanitize_text_field($_POST['rcp_card_number']), 'EXPDATE' => sanitize_text_field($_POST['rcp_card_exp_month'] . $_POST['rcp_card_exp_year']), 'CVV2' => sanitize_text_field($_POST['rcp_card_cvc']), 'ZIP' => sanitize_text_field($_POST['rcp_card_zip']), 'BUTTONSOURCE' => 'EasyDigitalDownloads_SP', 'PROFILESTARTDATE' => date('Y-m-d\\TH:i:s', strtotime('+' . $this->length . ' ' . $this->length_unit, time())), 'BILLINGPERIOD' => ucwords($this->length_unit), 'BILLINGFREQUENCY' => $this->length, 'FAILEDINITAMTACTION' => 'CancelOnFailure', 'TOTALBILLINGCYCLES' => $this->auto_renew ? 0 : 1); if ($this->auto_renew) { $initamt = round($this->amount + $this->signup_fee, 2); if ($initamt >= 0) { $args['INITAMT'] = $initamt; } } $request = wp_remote_post($this->api_endpoint, array('timeout' => 45, 'sslverify' => false, 'httpversion' => '1.1', 'body' => $args)); $body = wp_remote_retrieve_body($request); $code = wp_remote_retrieve_response_code($request); $message = wp_remote_retrieve_response_message($request); if (is_wp_error($request)) { do_action('rcp_paypal_pro_signup_payment_failed', $request, $this); $error = '<p>' . __('An unidentified error occurred.', 'rcp') . '</p>'; $error .= '<p>' . $request->get_error_message() . '</p>'; wp_die($error, __('Error', 'rcp'), array('response' => '401')); } elseif (200 == $code && 'OK' == $message) { if (is_string($body)) { wp_parse_str($body, $body); } if (false !== strpos(strtolower($body['ACK']), 'failure')) { do_action('rcp_paypal_pro_signup_payment_failed', $request, $this); $error = '<p>' . __('PayPal subscription creation failed.', 'rcp') . '</p>'; $error .= '<p>' . __('Error message:', 'rcp') . ' ' . $body['L_LONGMESSAGE0'] . '</p>'; $error .= '<p>' . __('Error code:', 'rcp') . ' ' . $body['L_ERRORCODE0'] . '</p>'; wp_die($error, __('Error', 'rcp'), array('response' => '401')); } else { // Successful signup $member = new RCP_Member($this->user_id); if ($member->just_upgraded() && rcp_can_member_cancel($member->ID)) { $cancelled = rcp_cancel_member_payment_profile($member->ID, false); } if (isset($body['PROFILEID'])) { $member->set_payment_profile_id($body['PROFILEID']); } if (isset($body['PROFILESTATUS']) && 'ActiveProfile' === $body['PROFILESTATUS']) { // Confirm a one-time payment $member->renew($this->auto_renew); } wp_redirect(esc_url_raw(rcp_get_return_url())); exit; exit; } } else { wp_die(__('Something has gone wrong, please try again', 'rcp'), __('Error', 'rcp'), array('back_link' => true, 'response' => '401')); } }
/** * Process registration * * @since 2.3 */ public function process_signup() { Twocheckout::privateKey($this->secret_key); Twocheckout::sellerId($this->seller_id); Twocheckout::sandbox($this->test_mode); $member = new RCP_Member($this->user_id); if (empty($_POST['twoCheckoutToken'])) { rcp_errors()->add('missing_card_token', __('Missing 2Checkout token, please try again or contact support if the issue persists.', 'rcp'), 'register'); return; } $paid = false; if ($this->auto_renew) { $payment_type = 'Credit Card'; $line_items = array(array("recurrence" => $this->length . ' ' . ucfirst($this->length_unit), "type" => 'product', "price" => $this->amount, "productId" => $this->subscription_id, "name" => $this->subscription_name, "quantity" => '1', "tangible" => 'N', "startupFee" => $this->signup_fee)); } else { $payment_type = 'Credit Card One Time'; $line_items = array(array("recurrence" => 0, "type" => 'product', "price" => $this->amount, "productId" => $this->subscription_id, "name" => $this->subscription_name, "quantity" => '1', "tangible" => 'N', "startupFee" => $this->signup_fee)); } try { $charge = Twocheckout_Charge::auth(array('merchantOrderId' => $this->subscription_key, 'token' => $_POST['twoCheckoutToken'], 'currency' => strtolower($this->currency), 'billingAddr' => array('name' => sanitize_text_field($_POST['rcp_card_name']), 'addrLine1' => sanitize_text_field($_POST['rcp_card_address']), 'city' => sanitize_text_field($_POST['rcp_card_city']), 'state' => sanitize_text_field($_POST['rcp_card_state']), 'zipCode' => sanitize_text_field($_POST['rcp_card_zip']), 'country' => sanitize_text_field($_POST['rcp_card_country']), 'email' => $this->email), "lineItems" => $line_items)); if ($charge['response']['responseCode'] == 'APPROVED') { // Look to see if we have an existing subscription to cancel if ($member->just_upgraded() && rcp_can_member_cancel($member->ID)) { $cancelled = rcp_cancel_member_payment_profile($member->ID, false); } $payment_data = array('date' => date('Y-m-d H:i:s', current_time('timestamp')), 'subscription' => $this->subscription_name, 'payment_type' => $payment_type, 'subscription_key' => $this->subscription_key, 'amount' => $this->amount + $this->signup_fee, 'user_id' => $this->user_id, 'transaction_id' => $charge['response']['transactionId']); $rcp_payments = new RCP_Payments(); $rcp_payments->insert($payment_data); $paid = true; } } catch (Twocheckout_Error $e) { wp_die($e->getMessage(), __('Error', 'rcp'), array('response' => '401')); } if ($paid) { // set this user to active $member->renew($this->auto_renew); $member->add_note(__('Subscription started in 2Checkout', 'rcp')); $member->set_payment_profile_id('2co_' . $charge['response']['orderNumber']); if (!is_user_logged_in()) { // log the new user in rcp_login_user_in($this->user_id, $this->user_name, $_POST['rcp_user_pass']); } do_action('rcp_2co_signup', $this->user_id, $this); } // redirect to the success page, or error page if something went wrong wp_redirect($this->return_url); exit; }
/** * Cancel a member's payment profile * * @access public * @since 2.1 */ function rcp_cancel_member_payment_profile( $member_id = 0 ) { global $rcp_options; $success = false; $member = new RCP_Member( $member_id ); if( ! rcp_can_member_cancel( $member_id ) ) { return $success; } if( rcp_is_stripe_subscriber( $member_id ) ) { if( ! class_exists( 'Stripe\Stripe' ) ) { require_once RCP_PLUGIN_DIR . 'includes/libraries/stripe/init.php'; } if ( isset( $rcp_options['sandbox'] ) ) { $secret_key = trim( $rcp_options['stripe_test_secret'] ); } else { $secret_key = trim( $rcp_options['stripe_live_secret'] ); } \Stripe\Stripe::setApiKey( $secret_key ); try { $cu = \Stripe\Customer::retrieve( $member->get_payment_profile_id() ); $cu->cancelSubscription( array( 'at_period_end' => false ) ); $success = true; } catch (\Stripe\Error\InvalidRequest $e) { // Invalid parameters were supplied to Stripe's API $body = $e->getJsonBody(); $err = $body['error']; $error = "<h4>" . __( 'An error occurred', 'rcp' ) . "</h4>"; if( isset( $err['code'] ) ) { $error .= "<p>" . __( 'Error code:', 'rcp' ) . " " . $err['code'] ."</p>"; } $error .= "<p>Status: " . $e->getHttpStatus() ."</p>"; $error .= "<p>Message: " . $err['message'] . "</p>"; wp_die( $error, __( 'Error', 'rcp' ), array( 'response' => 401 ) ); } catch (\Stripe\Error\Authentication $e) { // Authentication with Stripe's API failed // (maybe you changed API keys recently) $body = $e->getJsonBody(); $err = $body['error']; $error = "<h4>" . __( 'An error occurred', 'rcp' ) . "</h4>"; if( isset( $err['code'] ) ) { $error .= "<p>" . __( 'Error code:', 'rcp' ) . " " . $err['code'] ."</p>"; } $error .= "<p>Status: " . $e->getHttpStatus() ."</p>"; $error .= "<p>Message: " . $err['message'] . "</p>"; wp_die( $error, __( 'Error', 'rcp' ), array( 'response' => 401 ) ); } catch (\Stripe\Error\ApiConnection $e) { // Network communication with Stripe failed $body = $e->getJsonBody(); $err = $body['error']; $error = "<h4>" . __( 'An error occurred', 'rcp' ) . "</h4>"; if( isset( $err['code'] ) ) { $error .= "<p>" . __( 'Error code:', 'rcp' ) . " " . $err['code'] ."</p>"; } $error .= "<p>Status: " . $e->getHttpStatus() ."</p>"; $error .= "<p>Message: " . $err['message'] . "</p>"; wp_die( $error, __( 'Error', 'rcp' ), array( 'response' => 401 ) ); } catch (\Stripe\Error\Base $e) { // Display a very generic error to the user $body = $e->getJsonBody(); $err = $body['error']; $error = "<h4>" . __( 'An error occurred', 'rcp' ) . "</h4>"; if( isset( $err['code'] ) ) { $error .= "<p>" . __( 'Error code:', 'rcp' ) . " " . $err['code'] ."</p>"; } $error .= "<p>Status: " . $e->getHttpStatus() ."</p>"; $error .= "<p>Message: " . $err['message'] . "</p>"; wp_die( $error, __( 'Error', 'rcp' ), array( 'response' => 401 ) ); } catch (Exception $e) { // Something else happened, completely unrelated to Stripe $error = "<h4>" . __( 'An error occurred', 'rcp' ) . "</h4>"; $error .= print_r( $e, true ); wp_die( $error, __( 'Error', 'rcp' ), array( 'response' => 401 ) ); } } elseif( rcp_is_paypal_subscriber( $member_id ) ) { if( rcp_has_paypal_api_access() && $member->get_payment_profile_id() ) { // Set PayPal API key credentials. $api_username = isset( $rcp_options['sandbox'] ) ? 'test_paypal_api_username' : 'live_paypal_api_username'; $api_password = isset( $rcp_options['sandbox'] ) ? 'test_paypal_api_password' : 'live_paypal_api_password'; $api_signature = isset( $rcp_options['sandbox'] ) ? 'test_paypal_api_signature' : 'live_paypal_api_signature'; $api_endpoint = isset( $rcp_options['sandbox'] ) ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp'; $args = array( 'USER' => $rcp_options[ $api_username ], 'PWD' => $rcp_options[ $api_password ], 'SIGNATURE' => $rcp_options[ $api_signature ], 'VERSION' => '76.0', 'METHOD' => 'ManageRecurringPaymentsProfileStatus', 'PROFILEID' => $member->get_payment_profile_id(), 'ACTION' => 'Cancel' ); $error_msg = ''; $request = wp_remote_post( $api_endpoint, array( 'body' => $args, 'timeout' => 30 ) ); if ( is_wp_error( $request ) ) { $success = false; $error_msg = $request->get_error_message(); } else { $body = wp_remote_retrieve_body( $request ); if( is_string( $body ) ) { wp_parse_str( $body, $body ); } if( empty( $request['response'] ) ) { $success = false; } if( empty( $request['response']['code'] ) || 200 !== (int) $request['response']['code'] ) { $success = false; } if( empty( $request['response']['message'] ) || 'OK' !== $request['response']['message'] ) { $success = false; } if( isset( $body['ACK'] ) && 'success' === strtolower( $body['ACK'] ) ) { $success = true; } else { $success = false; if( isset( $body['L_LONGMESSAGE0'] ) ) { $error_msg = $body['L_LONGMESSAGE0']; } } } if( ! $success ) { wp_die( sprintf( __( 'There was a problem cancelling the subscription, please contact customer support. Error: %s', 'rcp' ), $error_msg ), array( 'response' => 400 ) ); } } } if( $success ) { $member->cancel(); } return $success; }
function rcp_members_page() { global $rcp_options, $rcp_db_name, $wpdb; $current_page = admin_url('/admin.php?page=rcp-members'); ?> <div class="wrap" id="rcp-members-page"> <?php if (isset($_GET['edit_member']) || isset($_GET['view_member'])) { include 'edit-member.php'; } else { ?> <h2><?php _e(' Paid Subscribers', 'rcp'); ?> </h2> <?php $subscription_id = isset($_GET['subscription']) && $_GET['subscription'] != 'all' ? urldecode($_GET['subscription']) : null; $status = !empty($_GET['status']) ? urldecode($_GET['status']) : 'active'; $order = !empty($_GET['order']) ? urldecode($_GET['order']) : 'DESC'; $recurring = isset($_GET['recurring']) ? absint($_GET['recurring']) : null; $search = !empty($_GET['s']) ? urldecode($_GET['s']) : ''; $base_url = admin_url('admin.php?page=rcp-members'); if ($search) { $base_url = add_query_arg('s', $search, $base_url); } // get subscriber count $active_count = rcp_count_members($subscription_id, 'active', $recurring, $search); $pending_count = rcp_count_members($subscription_id, 'pending', $recurring, $search); $expired_count = rcp_count_members($subscription_id, 'expired', $recurring, $search); $cancelled_count = rcp_count_members($subscription_id, 'cancelled', $recurring, $search); $free_count = rcp_count_members($subscription_id, 'free', $recurring, $search); $current_count = rcp_count_members($subscription_id, $status, $recurring, $search); // pagination variables $page = isset($_GET['p']) ? absint($_GET['p']) : 1; $user = get_current_user_id(); $screen = get_current_screen(); $screen_option = $screen->get_option('per_page', 'option'); $per_page = get_user_meta($user, $screen_option, true); if (empty($per_page) || $per_page < 1) { $per_page = $screen->get_option('per_page', 'default'); } $total_pages = 1; $offset = $per_page * ($page - 1); $total_pages = ceil($current_count / $per_page); ?> <ul class="subsubsub"> <li><?php _e('Status: ', 'rcp'); ?> </li> <li> <a href="<?php echo esc_url(add_query_arg('status', 'active', $base_url)); ?> " title="<?php _e('View all active subscribers', 'rcp'); ?> " <?php echo isset($_GET['status']) && $_GET['status'] == 'active' || !isset($_GET['status']) ? 'class="current"' : ''; ?> > <?php _e('Active', 'rcp'); ?> </a>(<?php echo $active_count; ?> ) </li> <li> <a href="<?php echo esc_url(add_query_arg('status', 'pending', $base_url)); ?> " title="<?php _e('View all pending subscribers', 'rcp'); ?> " <?php echo isset($_GET['status']) && $_GET['status'] == 'pending' ? 'class="current"' : ''; ?> > <?php _e('Pending', 'rcp'); ?> </a>(<?php echo $pending_count; ?> ) </li> <li> <a href="<?php echo esc_url(add_query_arg('status', 'expired', $base_url)); ?> " title="<?php _e('View all expired subscribers', 'rcp'); ?> " <?php echo isset($_GET['status']) && $_GET['status'] == 'expired' ? 'class="current"' : ''; ?> > <?php _e('Expired', 'rcp'); ?> </a>(<?php echo $expired_count; ?> ) </li> <li> <a href="<?php echo esc_url(add_query_arg('status', 'cancelled', $base_url)); ?> " title="<?php _e('View all cancelled subscribers', 'rcp'); ?> " <?php echo isset($_GET['status']) && $_GET['status'] == 'cancelled' ? 'class="current"' : ''; ?> > <?php _e('Cancelled', 'rcp'); ?> </a>(<?php echo $cancelled_count; ?> ) </li> <li> <a href="<?php echo esc_url(add_query_arg('status', 'free', $base_url)); ?> " title="<?php _e('View all free members', 'rcp'); ?> " <?php echo isset($_GET['status']) && $_GET['status'] == 'free' ? 'class="current"' : ''; ?> > <?php _e('Free', 'rcp'); ?> </a>(<?php echo $free_count; ?> ) </li> <?php do_action('rcp_members_page_statuses'); ?> </ul> <form id="rcp-member-search" method="get" action="<?php menu_page_url('rcp-members'); ?> "> <label class="screen-reader-text" for="rcp-member-search-input"><?php _e('Search Members', 'rcp'); ?> </label> <input type="search" id="rcp-member-search-input" name="s" value="<?php echo esc_attr($search); ?> "/> <input type="hidden" name="page" value="rcp-members"/> <input type="hidden" name="status" value="<?php echo esc_attr($status); ?> "/> <input type="submit" name="" id="rcp-member-search-submit" class="button" value="<?php _e('Search members', 'rcp'); ?> "/> </form> <form id="members-filter" action="" method="get"> <?php $levels = rcp_get_subscription_levels('all'); if ($levels) { ?> <select name="subscription" id="rcp-subscription"> <option value="all"><?php _e('All Subscriptions', 'rcp'); ?> </option> <?php foreach ($levels as $level) { echo '<option value="' . $level->id . '" ' . selected($subscription_id, $level->id, false) . '>' . $level->name . '</option>'; } ?> </select> <?php } ?> <select name="recurring" id="rcp-recurring"> <option value="0"><?php _e('Either', 'rcp'); ?> </option> <option value="1"<?php selected(1, $recurring); ?> ><?php _e('Not Recurring', 'rcp'); ?> </option> <option value="2"<?php selected(2, $recurring); ?> ><?php _e('Recurring', 'rcp'); ?> </option> </select> <select name="order" id="rcp-order"> <option value="DESC" <?php selected($order, 'DESC'); ?> ><?php _e('Newest First', 'rcp'); ?> </option> <option value="ASC" <?php selected($order, 'ASC'); ?> ><?php _e('Oldest First', 'rcp'); ?> </option> </select> <input type="hidden" name="page" value="rcp-members"/> <input type="hidden" name="status" value="<?php echo isset($_GET['status']) ? $_GET['status'] : 'active'; ?> "/> <input type="submit" class="button-secondary" value="<?php _e('Filter', 'rcp'); ?> "/> </form> <?php do_action('rcp_members_above_table'); ?> <form id="rcp-members-form" action="<?php echo esc_attr(admin_url('admin.php?page=rcp-members')); ?> " method="post"> <div id="rcp-bulk-action-options"> <label for="rcp-bulk-member-action" class="screen-reader-text"><?php _e('Select bulk action', 'rcp'); ?> </label> <select name="rcp-bulk-action" id="rcp-bulk-member-action"> <option value="-1"><?php _e('Bulk Actions', 'rcp'); ?> </option> <option value="mark-active"><?php _e('Mark as Active', 'rcp'); ?> </option> <option value="mark-expired"><?php _e('Mark as Expired', 'rcp'); ?> </option> <option value="mark-cancelled"><?php _e('Revoke Access', 'rcp'); ?> </option> <option value="delete"><?php _e('Delete', 'rcp'); ?> </option> </select> <input type="text" class="rcp-datepicker" name="expiration" placeholder="<?php esc_attr_e('New Expiration Date', 'rcp'); ?> " id="rcp-bulk-expiration" value=""/> <input type="submit" id="rcp-submit-bulk-action" class="button action" value="<?php _e('Apply', 'rcp'); ?> "/> </div> <?php echo wp_nonce_field('rcp_bulk_edit_nonce', 'rcp_bulk_edit_nonce'); ?> <table class="wp-list-table widefat fixed posts"> <thead> <tr> <th class="rcp-checkbox-col"><input type="checkbox" id="rcp-bulk-select-all"/></th> <th class="rcp-user-col"><?php _e('User', 'rcp'); ?> </th> <th class="rcp-id-col"><?php _e('ID', 'rcp'); ?> </th> <th class="rcp-email-col"><?php _e('Email', 'rcp'); ?> </th> <th class="rcp-sub-col"><?php _e('Subscription', 'rcp'); ?> </th> <th class="rcp-status-col"><?php _e('Status', 'rcp'); ?> </th> <th class="rcp-recurring-col"><?php _e('Recurring', 'rcp'); ?> </th> <th class="rcp-expiration-col"><?php _e('Expiration', 'rcp'); ?> </th> <th class="rcp-role-col"><?php _e('User Role', 'rcp'); ?> </th> <?php do_action('rcp_members_page_table_header'); ?> <th class="rcp-actions-role"><?php _e('Actions', 'rcp'); ?> </th> </tr> </thead> <tfoot> <tr> <th class="rcp-checkbox-col"></th> <th><?php _e('User', 'rcp'); ?> </th> <th><?php _e('ID', 'rcp'); ?> </th> <th><?php _e('Email', 'rcp'); ?> </th> <th><?php _e('Subscription', 'rcp'); ?> </th> <th><?php _e('Status', 'rcp'); ?> </th> <th><?php _e('Recurring', 'rcp'); ?> </th> <th><?php _e('Expiration', 'rcp'); ?> </th> <th><?php _e('User Role', 'rcp'); ?> </th> <?php do_action('rcp_members_page_table_footer'); ?> <th><?php _e('Actions', 'rcp'); ?> </th> </tr> </tfoot> <tbody> <?php if (isset($_GET['signup_method'])) { $method = $_GET['signup_method'] == 'live' ? 'live' : 'manual'; $members = get_users(array('meta_key' => 'rcp_signup_method', 'meta_value' => $method, 'number' => 999999)); $per_page = 999999; } else { $members = rcp_get_members($status, $subscription_id, $offset, $per_page, $order, $recurring, $search); } if ($members) { $i = 1; foreach ($members as $key => $member) { ?> <tr class="rcp_row <?php do_action('rcp_member_row_class', $member); if (rcp_is_odd($i)) { echo ' alternate'; } ?> "> <td> <input type="checkbox" class="rcp-member-cb" name="member-ids[]" value="<?php echo absint($member->ID); ?> "/> </td> <td><a href="<?php echo add_query_arg('user_id', $member->ID, admin_url('user-edit.php')); ?> " title="<?php _e('View User\'s Profile', 'rcp'); ?> "><?php echo $member->user_login; ?> </a></td> <td><?php echo $member->ID; ?> </td> <td><?php echo $member->user_email; ?> </td> <td><?php echo rcp_get_subscription($member->ID); ?> </td> <td><?php echo rcp_print_status($member->ID, false); ?> </td> <td><?php echo rcp_is_recurring($member->ID) ? __('yes', 'rcp') : __('no', 'rcp'); ?> <td><?php echo rcp_get_expiration_date($member->ID); ?> </td> <td><?php echo rcp_get_user_role($member->ID); ?> </td> <?php do_action('rcp_members_page_table_column', $member->ID); ?> <td> <?php if (current_user_can('rcp_manage_members')) { ?> <a href="<?php echo esc_url(add_query_arg('edit_member', $member->ID, $current_page)); ?> "><?php _e('Edit', 'rcp'); ?> </a> <?php if (isset($_GET['status']) && $_GET['status'] == 'cancelled') { ?> | <a href="<?php echo esc_url(add_query_arg('activate_member', $member->ID, $current_page)); ?> " class="rcp_activate"><?php _e('Enable Access', 'rcp'); ?> </a> <?php } elseif (isset($_GET['status']) && $_GET['status'] == 'active' || !isset($_GET['status'])) { ?> | <a href="<?php echo esc_url(add_query_arg('revoke_access', $member->ID, $current_page)); ?> " class="rcp_revoke"><?php _e('Revoke Access', 'rcp'); ?> </a> <?php } ?> <?php if (rcp_can_member_cancel($member->ID)) { ?> | <a href="<?php echo wp_nonce_url(add_query_arg('cancel_member', $member->ID, $current_page), 'rcp-cancel-nonce'); ?> " class="rcp_cancel"><?php _e('Cancel', 'rcp'); ?> </a> <?php } ?> <?php if ($switch_to_url = rcp_get_switch_to_url($member->ID)) { ?> | <a href="<?php echo esc_url($switch_to_url); ?> " class="rcp_switch"><?php _e('Switch to User', 'rcp'); ?> </a> <?php } ?> <?php do_action('rcp_member_row_actions', $member->ID); ?> <?php } ?> </td> </tr> <?php $i++; } } else { ?> <tr><td colspan="9"><?php _e('No subscribers found', 'rcp'); ?> </td></tr> <?php } ?> </table> </form> <?php if ($total_pages > 1 && !isset($_GET['signup_method'])) { ?> <div class="tablenav"> <div class="tablenav-pages alignright"> <?php $query_string = $_SERVER['QUERY_STRING']; $base = 'admin.php?' . remove_query_arg('p', $query_string) . '%_%'; echo paginate_links(array('base' => $base, 'format' => '&p=%#%', 'prev_text' => __('« Previous'), 'next_text' => __('Next »'), 'total' => $total_pages, 'current' => $page, 'end_size' => 1, 'mid_size' => 5)); ?> </div> </div><!--end .tablenav--> <?php } ?> <?php do_action('rcp_members_below_table'); ?> <h3><?php _e('Add New Subscription (for existing user)', 'rcp'); ?> </h3> <form id="rcp-add-new-member" action="" method="post"> <table class="form-table"> <tbody> <tr class="form-field"> <th scope="row" valign="top"> <label for="rcp-username"><?php _e('Username', 'rcp'); ?> </label> </th> <td> <input type="text" name="user" id="rcp-user" autocomplete="off" class="regular-text rcp-user-search" style="width: 120px;"/> <img class="rcp-ajax waiting" src="<?php echo admin_url('images/wpspin_light.gif'); ?> " style="display: none;"/> <div id="rcp_user_search_results"></div> <p class="description"><?php _e('Begin typing the user name to add a subscription to.', 'rcp'); ?> </p> </td> </tr> <tr class="form-field"> <th scope="row" valign="top"> <label for="rcp-level"><?php _e('Subscription Level', 'rcp'); ?> </label> </th> <td> <select name="level" id="rcp-level"> <option value="choose"><?php _e('--choose--', 'rcp'); ?> </option> <?php foreach (rcp_get_subscription_levels() as $level) { echo '<option value="' . $level->id . '">' . $level->name . '</option>'; } ?> </select> <p class="description"><?php _e('Choose the subscription level for this user', 'rcp'); ?> </p> </td> </tr> <tr class="form-field"> <th scope="row" valign="top"> <label for="rcp-expiration"><?php _e('Expiration date', 'rcp'); ?> </label> </th> <td> <input name="expiration" id="rcp-expiration" type="text" style="width: 120px;" class="rcp-datepicker"/> <label for="rcp-unlimited"> <input name="unlimited" id="rcp-unlimited" type="checkbox"/> <span class="description"><?php _e('Never expires?', 'rcp'); ?> </span> </label> <p class="description"><?php _e('Enter the expiration date for this user in the format of yyyy-mm-dd', 'rcp'); ?> </p> </td> </tr> </tbody> </table> <p class="submit"> <input type="hidden" name="rcp-action" value="add-subscription"/> <input type="submit" value="<?php _e('Add User Subscription', 'rcp'); ?> " class="button-primary"/> </p> </form> <?php } ?> </div><!--end wrap--> <?php }
/** * Process registration * * @since 2.1 */ public function process_signup() { \Stripe\Stripe::setApiKey($this->secret_key); $paid = false; $member = new RCP_Member($this->user_id); $customer_exists = false; if (empty($_POST['stripeToken'])) { wp_die(__('Missing Stripe token, please try again or contact support if the issue persists.', 'rcp'), __('Error', 'rcp'), array('response' => 400)); } $customer_id = $member->get_payment_profile_id(); if ($customer_id) { $customer_exists = true; try { // Update the customer to ensure their card data is up to date $customer = \Stripe\Customer::retrieve($customer_id); if (isset($customer->deleted) && $customer->deleted) { // This customer was deleted $customer_exists = false; } // No customer found } catch (Exception $e) { $customer_exists = false; } } if (empty($customer_exists)) { try { $customer_args = array('card' => $_POST['stripeToken'], 'email' => $this->email); $customer = \Stripe\Customer::create(apply_filters('rcp_stripe_customer_create_args', $customer_args, $this)); // A temporary invoice is created to force the customer's currency to be set to the store currency. See https://github.com/restrictcontentpro/restrict-content-pro/issues/549 if (!empty($this->signup_fee)) { \Stripe\InvoiceItem::create(array('customer' => $customer->id, 'amount' => 0, 'currency' => rcp_get_currency(), 'description' => 'Setting Customer Currency')); $temp_invoice = \Stripe\Invoice::create(array('customer' => $customer->id)); } $member->set_payment_profile_id($customer->id); } catch (Exception $e) { $this->handle_processing_error($e); } } else { $customer->source = $_POST['stripeToken']; } $customer->description = 'User ID: ' . $this->user_id . ' - User Email: ' . $this->email . ' Subscription: ' . $this->subscription_name; $customer->metadata = array('user_id' => $this->user_id, 'email' => $this->email, 'subscription' => $this->subscription_name); $customer->save(); if ($this->auto_renew) { // process a subscription sign up if (!($plan_id = $this->plan_exists($this->subscription_name))) { // create the plan if it doesn't exist $plan_id = $this->create_plan($this->subscription_name); } try { // Add fees before the plan is updated and charged if (!empty($this->signup_fee)) { $customer->account_balance = $customer->account_balance + $this->signup_fee * rcp_stripe_get_currency_multiplier(); // Add additional amount to initial payment (in cents) $customer->save(); if (isset($temp_invoice)) { $invoice = \Stripe\Invoice::retrieve($temp_invoice->id); $invoice->closed = true; $invoice->save(); unset($temp_invoice, $invoice); } } // clean up any past due or unpaid subscriptions before upgrading/downgrading foreach ($customer->subscriptions->all()->data as $subscription) { // check if we are renewing an existing subscription. This should not ever be 'active', if it is Stripe // will do nothing. If it is 'past_due' the most recent invoice will be paid and the subscription will become active if ($subscription->plan->id == $plan_id && in_array($subscription->status, array('active', 'past_due'))) { continue; } // remove any subscriptions that are past_due or inactive if (in_array($subscription->status, array('past_due', 'unpaid'))) { $subscription->cancel(); } } // If the customer has an existing subscription, we need to cancel it if ($member->just_upgraded() && rcp_can_member_cancel($member->ID)) { $cancelled = rcp_cancel_member_payment_profile($member->ID, false); } $sub_args = array('plan' => $plan_id, 'prorate' => false); if (!empty($this->discount_code)) { $sub_args['coupon'] = $this->discount_code; } // Set the customer's subscription in Stripe $subscription = $customer->subscriptions->create(array($sub_args)); $member->set_merchant_subscription_id($subscription->id); // subscription payments are recorded via webhook $paid = true; } catch (\Stripe\Error\Card $e) { $this->handle_processing_error($e); } catch (\Stripe\Error\InvalidRequest $e) { // Invalid parameters were supplied to Stripe's API $this->handle_processing_error($e); } catch (\Stripe\Error\Authentication $e) { // Authentication with Stripe's API failed // (maybe you changed API keys recently) $this->handle_processing_error($e); } catch (\Stripe\Error\ApiConnection $e) { // Network communication with Stripe failed $this->handle_processing_error($e); } catch (\Stripe\Error\Base $e) { // Display a very generic error to the user $this->handle_processing_error($e); } catch (Exception $e) { // Something else happened, completely unrelated to Stripe $error = '<p>' . __('An unidentified error occurred.', 'rcp') . '</p>'; $error .= print_r($e, true); wp_die($error, __('Error', 'rcp'), array('response' => 401)); } } else { // process a one time payment signup try { $charge = \Stripe\Charge::create(apply_filters('rcp_stripe_charge_create_args', array('amount' => round(($this->amount + $this->signup_fee) * rcp_stripe_get_currency_multiplier(), 0), 'currency' => strtolower($this->currency), 'customer' => $customer->id, 'description' => 'User ID: ' . $this->user_id . ' - User Email: ' . $this->email . ' Subscription: ' . $this->subscription_name, 'receipt_email' => $this->email, 'metadata' => array('email' => $this->email, 'user_id' => $this->user_id, 'level_id' => $this->subscription_id, 'level' => $this->subscription_name, 'key' => $this->subscription_key)), $this)); $payment_data = array('date' => date('Y-m-d H:i:s', current_time('timestamp')), 'subscription' => $this->subscription_name, 'payment_type' => 'Credit Card One Time', 'subscription_key' => $this->subscription_key, 'amount' => $this->amount + $this->signup_fee, 'user_id' => $this->user_id, 'transaction_id' => $charge->id); $rcp_payments = new RCP_Payments(); $rcp_payments->insert($payment_data); $paid = true; } catch (\Stripe\Error\Card $e) { $this->handle_processing_error($e); } catch (\Stripe\Error\InvalidRequest $e) { // Invalid parameters were supplied to Stripe's API $this->handle_processing_error($e); } catch (\Stripe\Error\Authentication $e) { // Authentication with Stripe's API failed // (maybe you changed API keys recently) $this->handle_processing_error($e); } catch (\Stripe\Error\ApiConnection $e) { // Network communication with Stripe failed $this->handle_processing_error($e); } catch (\Stripe\Error\Base $e) { // Display a very generic error to the user $this->handle_processing_error($e); } catch (Exception $e) { // Something else happened, completely unrelated to Stripe $error = '<p>' . __('An unidentified error occurred.', 'rcp') . '</p>'; $error .= print_r($e, true); wp_die($error, __('Error', 'rcp'), array('response' => 401)); } } if ($paid) { // If this is a one-time signup and the customer has an existing subscription, we need to cancel it if (!$this->auto_renew && $member->just_upgraded() && rcp_can_member_cancel($member->ID)) { $cancelled = rcp_cancel_member_payment_profile($member->ID, false); } // set this user to active $member->set_status('active'); $member->set_recurring($this->auto_renew); if (!is_user_logged_in()) { // log the new user in rcp_login_user_in($this->user_id, $this->user_name, $_POST['rcp_user_pass']); } if (!$this->auto_renew) { $member->set_expiration_date($member->calculate_expiration()); } do_action('rcp_stripe_signup', $this->user_id, $this); } else { wp_die(__('An error occurred, please contact the site administrator: ', 'rcp') . get_bloginfo('admin_email'), __('Error', 'rcp'), array('response' => 401)); } // redirect to the success page, or error page if something went wrong wp_redirect($this->return_url); exit; }
<?php endif; ?> <th><?php _e( 'Actions', 'rcp' ); ?></th> </tr> </thead> <tbody> <tr> <td><?php rcp_print_status(); ?></td> <td><?php echo rcp_get_subscription(); ?></td> <td><?php echo rcp_get_expiration_date(); ?></td> <td> <?php if( ( ( rcp_is_expired( $user_ID ) || ! rcp_is_recurring( $user_ID ) ) || rcp_get_status( $user_ID ) == 'cancelled' ) && rcp_subscription_upgrade_possible( $user_ID ) ) { echo '<a href="' . esc_url( get_permalink( $rcp_options['registration_page'] ) ) . '" title="' . __( 'Renew your subscription', 'rcp' ) . '" class="rcp_sub_details_renew">' . __( 'Renew your subscription', 'rcp' ) . '</a>'; } elseif( ! rcp_is_active( $user_ID ) && rcp_subscription_upgrade_possible( $user_ID ) ) { echo '<a href="' . esc_url( get_permalink( $rcp_options['registration_page'] ) ) . '" title="' . __( 'Upgrade your subscription', 'rcp' ) . '" class="rcp_sub_details_renew">' . __( 'Upgrade your subscription', 'rcp' ) . '</a>'; } elseif( rcp_is_active( $user_ID ) && rcp_can_member_cancel( $user_ID ) ) { echo '<a href="' . rcp_get_member_cancel_url( $user_ID ) . '" title="' . __( 'Cancel your subscription', 'rcp' ) . '">' . __( 'Cancel your subscription', 'rcp' ) . '</a>'; } do_action( 'rcp_subscription_details_action_links' ); ?> </td> </tr> </tbody> </table> <table class="rcp-table" id="rcp-payment-history"> <thead> <tr> <th><?php _e( 'Invoice #', 'rcp' ); ?></th> <th><?php _e( 'Subscription', 'rcp' ); ?></th> <th><?php _e( 'Payment Method', 'rcp' ); ?></th> <th><?php _e( 'Amount', 'rcp' ); ?></th>
function rcp_members_page() { global $rcp_options, $rcp_db_name, $wpdb; $current_page = admin_url('/admin.php?page=rcp-members'); ?> <div class="wrap" id="rcp-members-page"> <?php if (isset($_GET['edit_member']) || isset($_GET['view_member'])) { include 'edit-member.php'; } else { ?> <h2><?php _e(' Paid Subscribers', 'rcp'); ?> </h2> <?php $subscription_id = isset($_GET['subscription']) && $_GET['subscription'] != 'all' ? urldecode($_GET['subscription']) : null; $status = !empty($_GET['status']) ? urldecode($_GET['status']) : 'active'; $order = !empty($_GET['order']) ? urldecode($_GET['order']) : 'DESC'; $search = !empty($_GET['s']) ? urldecode($_GET['s']) : ''; $base_url = admin_url('admin.php?page=rcp-members'); if ($search) { $base_url = add_query_arg('s', $search, $base_url); } // Get subscriber count if (!empty($search) || !empty($subscription_id)) { // Query counts $active_count = rcp_count_members($subscription_id, 'active', null, $search); $pending_count = rcp_count_members($subscription_id, 'pending', null, $search); $expired_count = rcp_count_members($subscription_id, 'expired', null, $search); $cancelled_count = rcp_count_members($subscription_id, 'cancelled', null, $search); $free_count = rcp_count_members($subscription_id, 'free', null, $search); $current_count = rcp_count_members($subscription_id, $status, null, $search); } else { // Retrieve static counts $active_count = rcp_get_member_count('active'); $pending_count = rcp_get_member_count('pending'); $expired_count = rcp_get_member_count('expired'); $cancelled_count = rcp_get_member_count('cancelled'); $free_count = rcp_get_member_count('free'); $current_count = rcp_get_member_count($status); } // pagination variables $page = isset($_GET['p']) ? absint($_GET['p']) : 1; $user = get_current_user_id(); $screen = get_current_screen(); $screen_option = $screen->get_option('per_page', 'option'); $per_page = get_user_meta($user, $screen_option, true); if (empty($per_page) || $per_page < 1) { $per_page = $screen->get_option('per_page', 'default'); } $total_pages = 1; $offset = $per_page * ($page - 1); $total_pages = ceil($current_count / $per_page); ?> <ul class="subsubsub"> <li><?php _e('Status: ', 'rcp'); ?> </li> <li> <a href="<?php echo esc_url(add_query_arg('status', 'active', $base_url)); ?> " title="<?php _e('View all active subscribers', 'rcp'); ?> " <?php echo isset($_GET['status']) && $_GET['status'] == 'active' || !isset($_GET['status']) ? 'class="current"' : ''; ?> > <?php _e('Active', 'rcp'); ?> </a>(<?php echo $active_count; ?> ) </li> <li> <a href="<?php echo esc_url(add_query_arg('status', 'pending', $base_url)); ?> " title="<?php _e('View all pending subscribers', 'rcp'); ?> " <?php echo isset($_GET['status']) && $_GET['status'] == 'pending' ? 'class="current"' : ''; ?> > <?php _e('Pending', 'rcp'); ?> </a>(<?php echo $pending_count; ?> ) </li> <li> <a href="<?php echo esc_url(add_query_arg('status', 'expired', $base_url)); ?> " title="<?php _e('View all expired subscribers', 'rcp'); ?> " <?php echo isset($_GET['status']) && $_GET['status'] == 'expired' ? 'class="current"' : ''; ?> > <?php _e('Expired', 'rcp'); ?> </a>(<?php echo $expired_count; ?> ) </li> <li> <a href="<?php echo esc_url(add_query_arg('status', 'cancelled', $base_url)); ?> " title="<?php _e('View all cancelled subscribers', 'rcp'); ?> " <?php echo isset($_GET['status']) && $_GET['status'] == 'cancelled' ? 'class="current"' : ''; ?> > <?php _e('Cancelled', 'rcp'); ?> </a>(<?php echo $cancelled_count; ?> ) </li> <li> <a href="<?php echo esc_url(add_query_arg('status', 'free', $base_url)); ?> " title="<?php _e('View all free members', 'rcp'); ?> " <?php echo isset($_GET['status']) && $_GET['status'] == 'free' ? 'class="current"' : ''; ?> > <?php _e('Free', 'rcp'); ?> </a>(<?php echo $free_count; ?> ) </li> <?php do_action('rcp_members_page_statuses'); ?> </ul> <form id="rcp-member-search" method="get" action="<?php menu_page_url('rcp-members'); ?> "> <label class="screen-reader-text" for="rcp-member-search-input"><?php _e('Search Members', 'rcp'); ?> </label> <input type="search" id="rcp-member-search-input" name="s" value="<?php echo esc_attr($search); ?> "/> <input type="hidden" name="page" value="rcp-members"/> <input type="hidden" name="status" value="<?php echo esc_attr($status); ?> "/> <input type="submit" name="" id="rcp-member-search-submit" class="button" value="<?php _e('Search members', 'rcp'); ?> "/> </form> <form id="members-filter" action="" method="get"> <?php $levels = rcp_get_subscription_levels('all'); if ($levels) { ?> <select name="subscription" id="rcp-subscription"> <option value="all"><?php _e('All Subscriptions', 'rcp'); ?> </option> <?php foreach ($levels as $level) { echo '<option value="' . $level->id . '" ' . selected($subscription_id, $level->id, false) . '>' . $level->name . '</option>'; } ?> </select> <?php } ?> <select name="order" id="rcp-order"> <option value="DESC" <?php selected($order, 'DESC'); ?> ><?php _e('Newest First', 'rcp'); ?> </option> <option value="ASC" <?php selected($order, 'ASC'); ?> ><?php _e('Oldest First', 'rcp'); ?> </option> </select> <input type="hidden" name="page" value="rcp-members"/> <input type="hidden" name="status" value="<?php echo isset($_GET['status']) ? $_GET['status'] : 'active'; ?> "/> <input type="submit" class="button-secondary" value="<?php _e('Filter', 'rcp'); ?> "/> </form> <?php do_action('rcp_members_above_table'); ?> <form id="rcp-members-form" action="<?php echo esc_attr(admin_url('admin.php?page=rcp-members')); ?> " method="post"> <div id="rcp-bulk-action-options" class="tablenav top"> <label for="rcp-bulk-member-action" class="screen-reader-text"><?php _e('Select bulk action', 'rcp'); ?> </label> <select name="rcp-bulk-action" id="rcp-bulk-member-action"> <option value="-1"><?php _e('Bulk Actions', 'rcp'); ?> </option> <option value="mark-active"><?php _e('Mark as Active', 'rcp'); ?> </option> <option value="mark-expired"><?php _e('Mark as Expired', 'rcp'); ?> </option> <option value="mark-cancelled"><?php _e('Revoke Access', 'rcp'); ?> </option> </select> <input type="text" class="rcp-datepicker" name="expiration" placeholder="<?php esc_attr_e('New Expiration Date', 'rcp'); ?> " id="rcp-bulk-expiration" value=""/> <input type="submit" id="rcp-submit-bulk-action" class="button action" value="<?php _e('Apply', 'rcp'); ?> "/> </div> <?php wp_nonce_field('rcp_bulk_edit_nonce', 'rcp_bulk_edit_nonce'); ?> <table class="wp-list-table widefat"> <thead> <tr> <td id="cb" class="manage-column column-cb check-column"> <label class="screen-reader-text" for="cb-select-all-1"><?php _e('Select All', 'rcp'); ?> </label> <input id="cb-select-all-1" type="checkbox"> </td> <th scope="col" class="rcp-user-col manage-column column-primary"><?php _e('User', 'rcp'); ?> </th> <th scope="col" class="rcp-sub-col manage-column"><?php _e('Subscription', 'rcp'); ?> </th> <th scope="col" class="rcp-status-col manage-column"><?php _e('Status', 'rcp'); ?> </th> <th scope="col" class="rcp-recurring-col manage-column"><?php _e('Recurring', 'rcp'); ?> </th> <th scope="col" class="rcp-expiration-col manage-column"><?php _e('Expiration', 'rcp'); ?> </th> <th scope="col" class="rcp-role-col manage-column"><?php _e('User Role', 'rcp'); ?> </th> <?php do_action('rcp_members_page_table_header'); ?> </tr> </thead> <tbody id="the-list"> <?php if (isset($_GET['signup_method'])) { $method = $_GET['signup_method'] == 'live' ? 'live' : 'manual'; $members = get_users(array('meta_key' => 'rcp_signup_method', 'meta_value' => $method, 'number' => 999999)); $per_page = 999999; } else { $members = rcp_get_members($status, $subscription_id, $offset, $per_page, $order, null, $search); } if ($members) { $i = 1; foreach ($members as $key => $member) { $rcp_member = new RCP_Member($member->ID); // Show pending expiration date for members with a pending status. See https://github.com/restrictcontentpro/restrict-content-pro/issues/708. if ('pending' === $status) { $expiration = $rcp_member->get_expiration_date(true, true); } else { $expiration = $rcp_member->get_expiration_date(true, false); } ?> <tr class="rcp_row <?php do_action('rcp_member_row_class', $member); if (rcp_is_odd($i)) { echo ' alternate'; } ?> "> <th scope="row" class="check-column"> <input type="checkbox" class="rcp-member-cb" name="member-ids[]" value="<?php echo absint($member->ID); ?> "/> </th> <td class="has-row-actions column-primary" data-colname="<?php _e('User', 'rcp'); ?> "> <strong> <a href="<?php echo esc_url(add_query_arg('edit_member', $member->ID, $current_page)); ?> " title="<?php _e('Edit Member', 'rcp'); ?> "><?php echo $member->user_login; ?> </a> <?php if ($member->user_login != $member->user_email) { ?> <?php echo ' – ' . $member->user_email; ?> <?php } ?> </strong> <?php if (current_user_can('rcp_manage_members')) { ?> <div class="row-actions"> <span class="edit"> <a href="<?php echo esc_url(add_query_arg('edit_member', $member->ID, $current_page)); ?> "><?php _e('Edit Member', 'rcp'); ?> </a> <span class="rcp-separator"> | </span> <a href="<?php echo esc_url(add_query_arg('user_id', $member->ID, admin_url('user-edit.php'))); ?> " title="<?php _e('View User\'s Profile', 'rcp'); ?> "><?php _e('Edit User Account', 'rcp'); ?> </a> </span> <?php if (rcp_can_member_cancel($member->ID)) { ?> <span> | <a href="<?php echo wp_nonce_url(add_query_arg('cancel_member', $member->ID, $current_page), 'rcp-cancel-nonce'); ?> " class="trash rcp_cancel"><?php _e('Cancel', 'rcp'); ?> </a></span> <?php } ?> <?php if ($switch_to_url = rcp_get_switch_to_url($member->ID)) { ?> <span> | <a href="<?php echo esc_url($switch_to_url); ?> " class="rcp_switch"><?php _e('Switch to User', 'rcp'); ?> </a></span> <?php } ?> <span class="rcp-separator"> | </span> <span class="id rcp-member-id"><?php echo __('ID:', 'rcp') . ' ' . $member->ID; ?> </span> <?php do_action('rcp_member_row_actions', $member->ID); ?> </div> <?php } ?> <button type="button" class="toggle-row"><span class="screen-reader-text"><?php _e('Show more details', 'rcp'); ?> </span></button> </td> <td data-colname="<?php _e('Subscription', 'rcp'); ?> "><?php echo rcp_get_subscription($member->ID); ?> </td> <td data-colname="<?php _e('Status', 'rcp'); ?> "><?php echo rcp_print_status($member->ID, false); ?> </td> <td data-colname="<?php _e('Recurring', 'rcp'); ?> "><?php echo rcp_is_recurring($member->ID) ? __('yes', 'rcp') : __('no', 'rcp'); ?> </td> <td data-colname="<?php _e('Expiration', 'rcp'); ?> "><?php echo $expiration; ?> </td> <td data-colname="<?php _e('User Role', 'rcp'); ?> "><?php echo rcp_get_user_role($member->ID); ?> </td> <?php do_action('rcp_members_page_table_column', $member->ID); ?> </tr> <?php $i++; } } else { ?> <tr><td colspan="6"><?php _e('No subscribers found', 'rcp'); ?> </td></tr> <?php } ?> </tbody> <tfoot> <tr> <td id="cb" class="manage-column column-cb check-column"> <label class="screen-reader-text" for="cb-select-all-1"><?php _e('Select All', 'rcp'); ?> </label> <input id="cb-select-all-1" type="checkbox"> </td> <th scope="col" class="rcp-user-col manage-column column-primary"><?php _e('User', 'rcp'); ?> </th> <th scope="col" class="rcp-sub-col manage-column"><?php _e('Subscription', 'rcp'); ?> </th> <th scope="col" class="rcp-status-col manage-column"><?php _e('Status', 'rcp'); ?> </th> <th scope="col" class="rcp-recurring-col manage-column"><?php _e('Recurring', 'rcp'); ?> </th> <th scope="col" class="rcp-expiration-col manage-column"><?php _e('Expiration', 'rcp'); ?> </th> <th scope="col" class="rcp-role-col manage-column"><?php _e('User Role', 'rcp'); ?> </th> <?php do_action('rcp_members_page_table_footer'); ?> </tr> </tfoot> </table> </form> <?php if ($total_pages > 1 && !isset($_GET['signup_method'])) { ?> <div class="tablenav bottom"> <div class="tablenav-pages alignright"> <?php $query_string = $_SERVER['QUERY_STRING']; $base = 'admin.php?' . remove_query_arg('p', $query_string) . '%_%'; echo paginate_links(array('base' => $base, 'format' => '&p=%#%', 'prev_text' => __('« Previous', 'rcp'), 'next_text' => __('Next »', 'rcp'), 'total' => $total_pages, 'current' => $page, 'end_size' => 1, 'mid_size' => 5)); ?> </div> </div><!--end .tablenav--> <?php } ?> <?php do_action('rcp_members_below_table'); ?> <h3> <?php _e('Add New Subscription (for existing user)', 'rcp'); ?> <span alt="f223" class="rcp-help-tip dashicons dashicons-editor-help" title="<?php _e('If you wish to create a brand new account, that may be done from Users → Add New. <br/><strong>Note</strong>: this will not create a payment profile for the member. That must be done manually through your merchant account.', 'rcp'); ?> "></span> </h3> <form id="rcp-add-new-member" action="" method="post"> <table class="form-table"> <tbody> <tr class="form-field"> <th scope="row" valign="top"> <label for="rcp-username"><?php _e('Username', 'rcp'); ?> </label> </th> <td> <input type="text" name="user" id="rcp-user" autocomplete="off" class="regular-text rcp-user-search" style="width: 120px;"/> <img class="rcp-ajax waiting" src="<?php echo admin_url('images/wpspin_light.gif'); ?> " style="display: none;"/> <div id="rcp_user_search_results"></div> <p class="description"><?php _e('Begin typing the user name to add a subscription to.', 'rcp'); ?> </p> </td> </tr> <tr class="form-field"> <th scope="row" valign="top"> <label for="rcp-level"><?php _e('Subscription Level', 'rcp'); ?> </label> </th> <td> <select name="level" id="rcp-level"> <option value="choose"><?php _e('--choose--', 'rcp'); ?> </option> <?php foreach (rcp_get_subscription_levels() as $level) { echo '<option value="' . $level->id . '">' . $level->name . '</option>'; } ?> </select> <span alt="f223" class="rcp-help-tip dashicons dashicons-editor-help" title="<?php _e('The subscription level determines the content the member has access to. <strong>Note</strong>: adding a subscription level to a member will not create a payment profile in your merchant account.', 'rcp'); ?> "></span> <p class="description"><?php _e('Choose the subscription level for this user.', 'rcp'); ?> </p> </td> </tr> <tr class="form-field"> <th scope="row" valign="top"> <label for="rcp-expiration"><?php _e('Expiration date', 'rcp'); ?> </label> </th> <td> <input name="expiration" id="rcp-expiration" type="text" style="width: 120px;" class="rcp-datepicker"/> <label for="rcp-unlimited"> <input name="unlimited" id="rcp-unlimited" type="checkbox"/> <span class="description"><?php _e('Never expires?', 'rcp'); ?> </span> </label> <p class="description"><?php _e('Enter the expiration date for this user in the format of yyyy-mm-dd', 'rcp'); ?> </p> </td> </tr> </tbody> </table> <p class="submit"> <input type="hidden" name="rcp-action" value="add-subscription"/> <input type="submit" value="<?php _e('Add User Subscription', 'rcp'); ?> " class="button-primary"/> </p> <?php wp_nonce_field('rcp_add_member_nonce', 'rcp_add_member_nonce'); ?> </form> <?php } ?> </div><!--end wrap--> <?php }
/** * Process PayPal IPN * * @since 2.1 */ public function process_webhooks() { if (!isset($_GET['listener']) || strtoupper($_GET['listener']) != 'IPN') { return; } global $rcp_options; nocache_headers(); if (!class_exists('IpnListener')) { // instantiate the IpnListener class include RCP_PLUGIN_DIR . 'includes/gateways/paypal/paypal-ipnlistener.php'; } $listener = new IpnListener(); $verified = false; if ($this->test_mode) { $listener->use_sandbox = true; } /* if( isset( $rcp_options['ssl'] ) ) { $listener->use_ssl = true; } else { $listener->use_ssl = false; } */ //To post using the fsockopen() function rather than cURL, use: if (isset($rcp_options['disable_curl'])) { $listener->use_curl = false; } try { $listener->requirePostMethod(); $verified = $listener->processIpn(); } catch (Exception $e) { status_header(402); //die( 'IPN exception: ' . $e->getMessage() ); } /* The processIpn() method returned true if the IPN was "VERIFIED" and false if it was "INVALID". */ if ($verified || isset($_POST['verification_override']) || ($this->test_mode || isset($rcp_options['disable_ipn_verify']))) { status_header(200); $user_id = 0; $posted = apply_filters('rcp_ipn_post', $_POST); // allow $_POST to be modified if (!empty($posted['subscr_id'])) { $user_id = rcp_get_member_id_from_profile_id($posted['subscr_id']); } if (empty($user_id) && !empty($posted['custom']) && is_numeric($posted['custom'])) { $user_id = absint($posted['custom']); } if (empty($user_id) && !empty($posted['payer_email'])) { $user = get_user_by('email', $posted['payer_email']); $user_id = $user ? $user->ID : false; } $member = new RCP_Member($user_id); if (!$member || !$member->ID > 0) { die('no member found'); } $subscription_id = $member->get_pending_subscription_id(); if (empty($subscription_id)) { $subscription_id = $member->get_subscription_id(); } if (!$subscription_id) { die('no subscription for member found'); } if (!rcp_get_subscription_details($subscription_id)) { die('no subscription level found'); } $subscription_name = $posted['item_name']; $subscription_key = $posted['item_number']; $amount = number_format((double) $posted['mc_gross'], 2); $amount2 = number_format((double) $posted['mc_amount3'], 2); $payment_status = $posted['payment_status']; $currency_code = $posted['mc_currency']; $subscription_price = number_format((double) rcp_get_subscription_price($subscription_id), 2); $pending_amount = get_user_meta($member->ID, 'rcp_pending_subscription_amount', true); $pending_amount = number_format((double) $pending_amount, 2); // Check for invalid amounts in the IPN data if (!empty($pending_amount) && !empty($amount) && in_array($posted['txn_type'], array('web_accept', 'subscr_payment'))) { if ($amount < $pending_amount) { rcp_add_member_note($member->ID, sprintf(__('Incorrect amount received in the IPN. Amount received was %s. The amount should have been %s. PayPal Transaction ID: %s', 'rcp'), $amount, $pending_amount, sanitize_text_field($posted['txn_id']))); die('incorrect amount'); } else { delete_user_meta($member->ID, 'rcp_pending_subscription_amount'); } } // setup the payment info in an array for storage $payment_data = array('date' => date('Y-m-d H:i:s', strtotime($posted['payment_date'], current_time('timestamp'))), 'subscription' => $posted['item_name'], 'payment_type' => $posted['txn_type'], 'subscription_key' => $subscription_key, 'amount' => $amount, 'user_id' => $user_id, 'transaction_id' => $posted['txn_id']); do_action('rcp_valid_ipn', $payment_data, $user_id, $posted); if ($posted['txn_type'] == 'web_accept' || $posted['txn_type'] == 'subscr_payment') { // only check for an existing payment if this is a payment IPD request if (rcp_check_for_existing_payment($posted['txn_type'], $posted['payment_date'], $subscription_key)) { $log_data = array('post_title' => __('Duplicate Payment', 'rcp'), 'post_content' => __('A duplicate payment was detected. The new payment was still recorded, so you may want to check into both payments.', 'rcp'), 'post_parent' => 0, 'log_type' => 'gateway_error'); $log_meta = array('user_subscription' => $posted['item_name'], 'user_id' => $user_id); $log_entry = WP_Logging::insert_log($log_data, $log_meta); die('duplicate IPN detected'); } if (strtolower($currency_code) != strtolower($rcp_options['currency'])) { // the currency code is invalid $log_data = array('post_title' => __('Invalid Currency Code', 'rcp'), 'post_content' => sprintf(__('The currency code in an IPN request did not match the site currency code. Payment data: %s', 'rcp'), json_encode($payment_data)), 'post_parent' => 0, 'log_type' => 'gateway_error'); $log_meta = array('user_subscription' => $posted['item_name'], 'user_id' => $user_id); $log_entry = WP_Logging::insert_log($log_data, $log_meta); die('invalid currency code'); } } if (isset($rcp_options['email_ipn_reports'])) { wp_mail(get_bloginfo('admin_email'), __('IPN report', 'rcp'), $listener->getTextReport()); } /* now process the kind of subscription/payment */ $rcp_payments = new RCP_Payments(); // Subscriptions switch ($posted['txn_type']) { case "subscr_signup": // when a new user signs up // store the recurring payment ID update_user_meta($user_id, 'rcp_paypal_subscriber', $posted['payer_id']); if ($member->just_upgraded() && rcp_can_member_cancel($member->ID)) { $cancelled = rcp_cancel_member_payment_profile($member->ID, false); } $member->set_payment_profile_id($posted['subscr_id']); do_action('rcp_ipn_subscr_signup', $user_id); die('successful subscr_signup'); break; case "subscr_payment": // when a user makes a recurring payment update_user_meta($user_id, 'rcp_paypal_subscriber', $posted['payer_id']); $member->set_payment_profile_id($posted['subscr_id']); $member->renew(true); // record this payment in the database $rcp_payments->insert($payment_data); do_action('rcp_ipn_subscr_payment', $user_id); die('successful subscr_payment'); break; case "subscr_cancel": if (!$member->just_upgraded()) { // user is marked as cancelled but retains access until end of term $member->set_status('cancelled'); // set the use to no longer be recurring delete_user_meta($user_id, 'rcp_paypal_subscriber'); do_action('rcp_ipn_subscr_cancel', $user_id); die('successful subscr_cancel'); } break; case "subscr_failed": do_action('rcp_ipn_subscr_failed'); die('successful subscr_failed'); break; case "subscr_eot": // user's subscription has reached the end of its term if ('cancelled' !== $member->get_status($user_id)) { $member->set_status('expired'); } do_action('rcp_ipn_subscr_eot', $user_id); die('successful subscr_eot'); break; case "web_accept": switch (strtolower($payment_status)) { case 'completed': if ($member->just_upgraded() && rcp_can_member_cancel($member->ID)) { $cancelled = rcp_cancel_member_payment_profile($member->ID, false); if ($cancelled) { $member->set_payment_profile_id(''); } } // set this user to active $member->renew(); $rcp_payments->insert($payment_data); break; case 'denied': case 'expired': case 'failed': case 'voided': $member->set_status('cancelled'); break; } die('successful web_accept'); break; case "cart": case "express_checkout": default: break; } } else { if (isset($rcp_options['email_ipn_reports'])) { // an invalid IPN attempt was made. Send an email to the admin account to investigate wp_mail(get_bloginfo('admin_email'), __('Invalid IPN', 'rcp'), $listener->getTextReport()); } status_header(400); die('invalid IPN'); } }
/** * Process PayPal IPN * * @since 2.1 */ public function process_webhooks() { if (!isset($_GET['listener']) || strtoupper($_GET['listener']) != 'EIPN') { return; } $user_id = 0; $posted = apply_filters('rcp_ipn_post', $_POST); // allow $_POST to be modified if (!empty($posted['recurring_payment_id'])) { $user_id = rcp_get_member_id_from_profile_id($posted['recurring_payment_id']); } if (empty($user_id) && !empty($posted['custom']) && is_numeric($posted['custom'])) { $user_id = absint($posted['custom']); } if (empty($user_id) && !empty($posted['payer_email'])) { $user = get_user_by('email', $posted['payer_email']); $user_id = $user ? $user->ID : false; } $member = new RCP_Member($user_id); if (!$member || !$member->ID > 0) { die('no member found'); } $subscription_id = $member->get_pending_subscription_id(); if (empty($subscription_id)) { $subscription_id = $member->get_subscription_id(); } if (!$subscription_id) { die('no subscription for member found'); } if (!rcp_get_subscription_details($subscription_id)) { die('no subscription level found'); } $amount = number_format((double) $posted['mc_gross'], 2); // setup the payment info in an array for storage $payment_data = array('date' => date('Y-m-d H:i:s', strtotime($posted['payment_date'])), 'subscription' => $member->get_subscription_name(), 'payment_type' => $posted['txn_type'], 'subscription_key' => $member->get_subscription_key(), 'amount' => $amount, 'user_id' => $user_id, 'transaction_id' => $posted['txn_id']); do_action('rcp_valid_ipn', $payment_data, $user_id, $posted); if (isset($rcp_options['email_ipn_reports'])) { wp_mail(get_bloginfo('admin_email'), __('IPN report', 'rcp'), $listener->getTextReport()); } /* now process the kind of subscription/payment */ $rcp_payments = new RCP_Payments(); // Subscriptions switch ($posted['txn_type']) { case "recurring_payment_profile_created": if (isset($posted['initial_payment_txn_id'])) { $transaction_id = 'Completed' == $posted['initial_payment_status'] ? $posted['initial_payment_txn_id'] : ''; } else { $transaction_id = $posted['ipn_track_id']; } if (empty($transaction_id) || $rcp_payments->payment_exists($transaction_id)) { break; } // setup the payment info in an array for storage $payment_data = array('date' => date('Y-m-d H:i:s', strtotime($posted['time_created'])), 'subscription' => $member->get_subscription_name(), 'payment_type' => $posted['txn_type'], 'subscription_key' => $member->get_subscription_key(), 'amount' => number_format((double) $posted['initial_payment_amount'], 2), 'user_id' => $user_id, 'transaction_id' => sanitize_text_field($transaction_id)); $rcp_payments->insert($payment_data); $expiration = date('Y-m-d 23:59:59', strtotime($posted['next_payment_date'])); $member->renew($member->is_recurring(), 'active', $expiration); break; case "recurring_payment": // when a user makes a recurring payment update_user_meta($user_id, 'rcp_paypal_subscriber', $posted['payer_id']); $member->set_payment_profile_id($posted['recurring_payment_id']); $member->renew(true); // record this payment in the database $rcp_payments->insert($payment_data); do_action('rcp_ipn_subscr_payment', $user_id); die('successful recurring_payment'); break; case "recurring_payment_profile_cancel": if (!$member->just_upgraded()) { // user is marked as cancelled but retains access until end of term $member->set_status('cancelled'); // set the use to no longer be recurring delete_user_meta($user_id, 'rcp_paypal_subscriber'); do_action('rcp_ipn_subscr_cancel', $user_id); die('successful recurring_payment_profile_cancel'); } break; case "recurring_payment_failed": case "recurring_payment_suspended_due_to_max_failed_payment": if ('cancelled' !== $member->get_status($user_id)) { $member->set_status('expired'); } do_action('rcp_ipn_subscr_failed'); die('successful recurring_payment_failed or recurring_payment_suspended_due_to_max_failed_payment'); break; case "web_accept": switch (strtolower($posted['payment_status'])) { case 'completed': if ($member->just_upgraded() && rcp_can_member_cancel($member->ID)) { $cancelled = rcp_cancel_member_payment_profile($member->ID, false); if ($cancelled) { $member->set_payment_profile_id(''); } } $payment_data = array('date' => date('Y-m-d H:i:s', strtotime($posted['payment_date'])), 'subscription' => $member->get_subscription_name(), 'payment_type' => $posted['txn_type'], 'subscription_key' => $member->get_subscription_key(), 'amount' => number_format((double) $posted['mc_gross'], 2), 'user_id' => $user_id, 'transaction_id' => sanitize_text_field($posted['txn_id'])); $rcp_payments->insert($payment_data); // set this user to active $member->renew(); break; case 'denied': case 'expired': case 'failed': case 'voided': $member->set_status('cancelled'); break; } die('successful web_accept'); break; } }