$morder->getMemberOrderByID($morder->id);
 //email the user their invoice
 $pmproemail = new PMProEmail();
 $pmproemail->sendInvoiceEmail($user, $morder);
 $logstr .= "Created new order with ID #" . $morder->id . ". Event ID #" . $event->id . ".";
 /*
 	Checking if there is an update "after next payment" for this user.
 */
 $user_updates = $user->pmpro_stripe_updates;
 if (!empty($user_updates)) {
     foreach ($user_updates as $key => $update) {
         if ($update['when'] == 'payment') {
             //get current plan at Stripe to get payment date
             $last_order = new MemberOrder();
             $last_order->getLastMemberOrder($user_id);
             $last_order->setGateway('stripe');
             $last_order->Gateway->getCustomer();
             if (!empty($last_order->Gateway->customer)) {
                 //find the first subscription
                 if (!empty($last_order->Gateway->customer->subscriptions['data'][0])) {
                     $first_sub = $last_order->Gateway->customer->subscriptions['data'][0]->__toArray();
                     $end_timestamp = $first_sub['current_period_end'];
                 }
             }
             //if we didn't get an end date, let's set one one cycle out
             $end_timestamp = strtotime("+" . $update['cycle_number'] . " " . $update['cycle_period']);
             //build order object
             $update_order = new MemberOrder();
             $update_order->setGateway('stripe');
             $update_order->user_id = $user->ID;
             $update_order->membership_id = $user->membership_level->id;
 /**
  * Cron job for subscription updates.
  *
  * @since 1.8
  */
 static function pmpro_cron_stripe_subscription_updates()
 {
     global $wpdb;
     //get all updates for today (or before today)
     $sqlQuery = "SELECT *\n\t\t\t\t\t\t FROM {$wpdb->usermeta}\n\t\t\t\t\t\t WHERE meta_key = 'pmpro_stripe_next_on_date_update'\n\t\t\t\t\t\t\tAND meta_value IS NOT NULL\n\t\t\t\t\t\t\tAND meta_value <> ''\n\t\t\t\t\t\t\tAND meta_value < '" . date("Y-m-d", strtotime("+1 day")) . "'";
     $updates = $wpdb->get_results($sqlQuery);
     if (!empty($updates)) {
         //loop through
         foreach ($updates as $update) {
             //pull values from update
             $user_id = $update->user_id;
             $user = get_userdata($user_id);
             //if user is missing, delete the update info and continue
             if (empty($user) || empty($user->ID)) {
                 delete_user_meta($user_id, "pmpro_stripe_updates");
                 delete_user_meta($user_id, "pmpro_stripe_next_on_date_update");
                 continue;
             }
             $user_updates = $user->pmpro_stripe_updates;
             $next_on_date_update = "";
             //loop through updates looking for updates happening today or earlier
             if (!empty($user_updates)) {
                 foreach ($user_updates as $key => $update) {
                     if ($update['when'] == 'date' && $update['date_year'] . "-" . $update['date_month'] . "-" . $update['date_day'] <= date("Y-m-d")) {
                         //get level for user
                         $user_level = pmpro_getMembershipLevelForUser($user_id);
                         //get current plan at Stripe to get payment date
                         $last_order = new MemberOrder();
                         $last_order->getLastMemberOrder($user_id);
                         $last_order->setGateway('stripe');
                         $last_order->Gateway->getCustomer($last_order);
                         if (!empty($last_order->Gateway->customer)) {
                             //find the first subscription
                             if (!empty($last_order->Gateway->customer->subscriptions['data'][0])) {
                                 $first_sub = $last_order->Gateway->customer->subscriptions['data'][0]->__toArray();
                                 $end_timestamp = $first_sub['current_period_end'];
                             }
                         }
                         //if we didn't get an end date, let's set one one cycle out
                         $end_timestamp = strtotime("+" . $update['cycle_number'] . " " . $update['cycle_period']);
                         //build order object
                         $update_order = new MemberOrder();
                         $update_order->setGateway('stripe');
                         $update_order->user_id = $user_id;
                         $update_order->membership_id = $user_level->id;
                         $update_order->membership_name = $user_level->name;
                         $update_order->InitialPayment = 0;
                         $update_order->PaymentAmount = $update['billing_amount'];
                         $update_order->ProfileStartDate = date("Y-m-d", $end_timestamp);
                         $update_order->BillingPeriod = $update['cycle_period'];
                         $update_order->BillingFrequency = $update['cycle_number'];
                         //update subscription
                         $update_order->Gateway->subscribe($update_order, false);
                         //update membership
                         $sqlQuery = "UPDATE {$wpdb->pmpro_memberships_users}\n\t\t\t\t\t\t\t\t\t\t\t\tSET billing_amount = '" . esc_sql($update['billing_amount']) . "',\n\t\t\t\t\t\t\t\t\t\t\t\t\tcycle_number = '" . esc_sql($update['cycle_number']) . "',\n\t\t\t\t\t\t\t\t\t\t\t\t\tcycle_period = '" . esc_sql($update['cycle_period']) . "'\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE user_id = '" . esc_sql($user_id) . "'\n\t\t\t\t\t\t\t\t\t\t\t\t\tAND membership_id = '" . esc_sql($last_order->membership_id) . "'\n\t\t\t\t\t\t\t\t\t\t\t\t\tAND status = 'active'\n\t\t\t\t\t\t\t\t\t\t\t\tLIMIT 1";
                         $wpdb->query($sqlQuery);
                         //save order
                         $update_order->status = "success";
                         $update_order->save();
                         //remove update from list
                         unset($user_updates[$key]);
                     } elseif ($update['when'] == 'date') {
                         //this is an on date update for the future, update the next on date update
                         if (!empty($next_on_date_update)) {
                             $next_on_date_update = min($next_on_date_update, $update['date_year'] . "-" . $update['date_month'] . "-" . $update['date_day']);
                         } else {
                             $next_on_date_update = $update['date_year'] . "-" . $update['date_month'] . "-" . $update['date_day'];
                         }
                     }
                 }
             }
             //save updates in case we removed some
             update_user_meta($user_id, "pmpro_stripe_updates", $user_updates);
             //save date of next on-date update to make it easier to query for these in cron job
             update_user_meta($user_id, "pmpro_stripe_next_on_date_update", $next_on_date_update);
         }
     }
 }
Пример #3
0
     //sometimes we need these split up
     $morder->FirstName = $bfirstname;
     $morder->LastName = $blastname;
     $morder->Address1 = $baddress1;
     $morder->Address2 = $baddress2;
     //other values
     $morder->billing->name = $bfirstname . " " . $blastname;
     $morder->billing->street = trim($baddress1 . " " . $baddress2);
     $morder->billing->city = $bcity;
     $morder->billing->state = $bstate;
     $morder->billing->country = $bcountry;
     $morder->billing->zip = $bzipcode;
     $morder->billing->phone = $bphone;
     //$gateway = pmpro_getOption("gateway");
     $morder->gateway = $gateway;
     $morder->setGateway();
     $worked = $morder->updateBilling();
     if ($worked) {
         //send email to member
         $pmproemail = new PMProEmail();
         $pmproemail->sendBillingEmail($current_user, $morder);
         //send email to admin
         $pmproemail = new PMProEmail();
         $pmproemail->sendBillingAdminEmail($current_user, $morder);
     }
 } else {
     $worked = true;
 }
 if ($worked) {
     //update the user meta too
     $meta_keys = array("pmpro_bfirstname", "pmpro_blastname", "pmpro_baddress1", "pmpro_baddress2", "pmpro_bcity", "pmpro_bstate", "pmpro_bzipcode", "pmpro_bphone", "pmpro_bemail", "pmpro_CardType", "pmpro_AccountNumber", "pmpro_ExpirationMonth", "pmpro_ExpirationYear");
function pmproues_wp_ajax()
{
    //make sure the user is an admin
    if (!current_user_can('manage_options')) {
        exit;
    }
    //get values
    $gateway = $_REQUEST['gateway'];
    $level = $_REQUEST['level'];
    $billing_amount = $_REQUEST['billing_amount'];
    $cycle_number = $_REQUEST['cycle_number'];
    $cycle_period = $_REQUEST['cycle_period'];
    $live = $_REQUEST['live'];
    if (empty($_REQUEST['limit'])) {
        $limit = 5;
    } else {
        $limit = intval($_REQUEST['limit']);
    }
    //continue progress?
    $hash = substr(md5($gateway . $level . $billing_amount . $cycle_number . $cycle_period . $live), 0, 16);
    $last_user = get_transient('pmproues_update_last_row_' . $hash);
    if (empty($last_user)) {
        $last_user = 0;
    }
    //find members
    global $wpdb;
    $sqlQuery = "SELECT user_id FROM {$wpdb->pmpro_memberships_users} WHERE user_id > {$last_user} AND membership_id = '" . intval($level) . "' AND status = 'active' ORDER BY user_id LIMIT {$limit}";
    $member_ids = $wpdb->get_col($sqlQuery);
    if (empty($member_ids)) {
        delete_transient('pmproues_update_last_row_' . $hash);
        echo "done";
        exit;
    } else {
        //update subs
        foreach ($member_ids as $member_id) {
            $last_user = $member_id;
            echo "\n----\nMember ID #" . $member_id . ". ";
            //get user
            $user = get_userdata($member_id);
            //no user?
            if (empty($user) || empty($user->ID)) {
                echo "Could not find user. ";
                continue;
            } else {
                echo "User found. (" . $user->user_email . ") ";
            }
            //get order
            $order = new MemberOrder();
            $order->getLastMemberOrder($user->ID);
            //no order?
            if (empty($order->id)) {
                echo "Could not find order. ";
                continue;
            } else {
                echo "Order found. (" . $order->code . ") ";
            }
            //different gateway?
            if ($order->gateway != $gateway) {
                echo "Different gateway. ";
                continue;
            } else {
                echo "Gateway matches. ";
            }
            //okay find the sub
            if (empty($order->subscription_transaction_id)) {
                echo "No subscription transaction ID. ";
                continue;
            } else {
                echo "Subscription ID found. ";
            }
            if (empty($live)) {
                echo "Would have updated the subscription here, but we're just testing. ";
                continue;
            }
            //let's do it live!
            if ($gateway == "stripe") {
                /*
                	Note: This code is copied and modified from the user_profile_fields_save method.
                */
                //get level for user
                $user_level = pmpro_getMembershipLevelForUser($user->ID);
                //get current plan at Stripe to get payment date
                $order->Gateway->getCustomer($order);
                $subscription = $order->Gateway->getSubscription($order);
                if (!empty($subscription)) {
                    $end_timestamp = $subscription->current_period_end;
                    //cancel the old subscription
                    if (!$order->Gateway->cancelSubscriptionAtGateway($subscription)) {
                        echo "Could not cancel the old subscription. Skipping. ";
                        continue;
                    }
                }
                //if we didn't get an end date, let's set one one cycle out
                if (empty($end_timestamp)) {
                    $end_timestamp = strtotime("+" . $cycle_number . " " . $cycle_period, current_time('timestamp'));
                }
                //build order object
                $update_order = new MemberOrder();
                $update_order->setGateway('stripe');
                $update_order->user_id = $user->ID;
                $update_order->Email = $user->user_email;
                $update_order->membership_id = $user_level->id;
                $update_order->membership_name = $user_level->name;
                $update_order->InitialPayment = 0;
                $update_order->PaymentAmount = $billing_amount;
                $update_order->ProfileStartDate = date("Y-m-d", $end_timestamp);
                $update_order->BillingPeriod = $cycle_period;
                $update_order->BillingFrequency = $cycle_number;
                //need filter to reset ProfileStartDate
                add_filter('pmpro_profile_start_date', create_function('$startdate, $order', 'return "' . $update_order->ProfileStartDate . 'T0:0:0";'), 10, 2);
                //update subscription
                $update_order->Gateway->subscribe($update_order, false);
                //update membership
                $sqlQuery = "UPDATE {$wpdb->pmpro_memberships_users}\r\n\t\t\t\t\t\t\t\tSET billing_amount = '" . esc_sql($billing_amount) . "',\r\n\t\t\t\t\t\t\t\t\tcycle_number = '" . esc_sql($cycle_number) . "',\r\n\t\t\t\t\t\t\t\t\tcycle_period = '" . esc_sql($cycle_period) . "',\r\n\t\t\t\t\t\t\t\t\ttrial_amount = '',\r\n\t\t\t\t\t\t\t\t\ttrial_limit = ''\r\n\t\t\t\t\t\t\t\tWHERE user_id = '" . esc_sql($user->ID) . "'\r\n\t\t\t\t\t\t\t\t\tAND membership_id = '" . esc_sql($order->membership_id) . "'\r\n\t\t\t\t\t\t\t\t\tAND status = 'active'\r\n\t\t\t\t\t\t\t\tLIMIT 1";
                $wpdb->query($sqlQuery);
                //save order so we know which plan to look for at stripe (order code = plan id)
                $update_order->status = "success";
                $update_order->saveOrder();
                echo "ORDER UPDATED!";
            }
        }
    }
    set_transient('pmproues_update_last_row_' . $hash, $last_user, 60 * 60 * 24);
    exit;
}
function pmpropbc_recurring_orders()
{
    global $wpdb;
    //make sure we only run once a day
    $now = current_time('timestamp');
    $today = date("Y-m-d", $now);
    //have to run for each level, so get levels
    $levels = pmpro_getAllLevels(true, true);
    if (empty($levels)) {
        return;
    }
    foreach ($levels as $level) {
        //get options
        $options = pmpropbc_getOptions($level->id);
        if (!empty($options['renewal_days'])) {
            $date = date("Y-m-d", strtotime("+ " . $options['renewal_days'] . " days", $now));
        } else {
            $date = $today;
        }
        //need to get all combos of pay cycle and period
        $sqlQuery = "SELECT DISTINCT(CONCAT(cycle_number, ' ', cycle_period)) FROM {$wpdb->pmpro_memberships_users} WHERE membership_id = '" . $level->id . "' AND cycle_number > 0 AND status = 'active'";
        $combos = $wpdb->get_col($sqlQuery);
        if (empty($combos)) {
            continue;
        }
        foreach ($combos as $combo) {
            //check if it's been one pay period since the last payment
            /*
            	- Check should create an invoice X days before expiration based on a setting on the levels page.
            	- Set invoice date based on cycle and the day of the month of the member start date.
            	- Send a reminder email Y days after initial invoice is created if it's still pending.
            	- Cancel membership after Z days if invoice is not paid. Send email.
            */
            //get all check orders still pending after X days
            $sqlQuery = "\r\n\t\t\t\tSELECT o1.id FROM\r\n\t\t\t\t    (SELECT id, user_id, timestamp\r\n\t\t\t\t    FROM {$wpdb->pmpro_membership_orders}\r\n\t\t\t\t    WHERE membership_id = {$level->id}\r\n\t\t\t\t        AND gateway = 'check' \r\n\t\t\t\t        AND status IN('pending', 'success')\r\n\t\t\t\t    ) as o1\r\n\r\n\t\t\t\t\tLEFT OUTER JOIN \r\n\t\t\t\t\t\r\n\t\t\t\t\t(SELECT id, user_id, timestamp\r\n\t\t\t\t    FROM {$wpdb->pmpro_membership_orders}\r\n\t\t\t\t    WHERE membership_id = {$level->id}\r\n\t\t\t\t        AND gateway = 'check' \r\n\t\t\t\t        AND status IN('pending', 'success')\r\n\t\t\t\t    ) as o2\r\n\r\n\t\t\t\t\tON o1.user_id = o2.user_id\r\n\t\t\t\t\tAND o1.timestamp < o2.timestamp\r\n\t\t\t\t\tOR (o1.timestamp = o2.timestamp AND o1.id < o2.id)\r\n\t\t\t\tWHERE\r\n\t\t\t\t\to2.id IS NULL\r\n\t\t\t\t\tAND DATE_ADD(o1.timestamp, INTERVAL {$combo}) <= '" . $date . "'\r\n\t\t\t";
            if (defined('PMPRO_CRON_LIMIT')) {
                $sqlQuery .= " LIMIT " . PMPRO_CRON_LIMIT;
            }
            $orders = $wpdb->get_col($sqlQuery);
            if (empty($orders)) {
                continue;
            }
            foreach ($orders as $order_id) {
                $order = new MemberOrder($order_id);
                $user = get_userdata($order->user_id);
                $user->membership_level = pmpro_getMembershipLevelForUser($order->user_id);
                //check that user still has same level?
                if (empty($user->membership_level) || $order->membership_id != $user->membership_level->id) {
                    continue;
                }
                //create new pending order
                $morder = new MemberOrder();
                $morder->user_id = $order->user_id;
                $morder->membership_id = $user->membership_level->id;
                $morder->InitialPayment = $user->membership_level->billing_amount;
                $morder->PaymentAmount = $user->membership_level->billing_amount;
                $morder->BillingPeriod = $user->membership_level->cycle_period;
                $morder->BillingFrequency = $user->membership_level->cycle_number;
                $morder->subscription_transaction_id = $order->subscription_transaction_id;
                $morder->gateway = "check";
                $morder->setGateway();
                $morder->payment_type = "Check";
                $morder->status = "pending";
                //get timestamp for new order
                $order_timestamp = strtotime("+" . $combo, $order->timestamp);
                //let's skip if there is already an order for this user/level/timestamp
                $sqlQuery = "SELECT id FROM {$wpdb->pmpro_membership_orders} WHERE user_id = '" . $order->user_id . "' AND membership_id = '" . $order->membership_id . "' AND timestamp = '" . date('d', $order_timestamp) . "' LIMIT 1";
                $dupe = $wpdb->get_var("SELECT id FROM {$wpdb->pmpro_membership_orders} WHERE user_id = '" . $order->user_id . "' AND membership_id = '" . $order->membership_id . "' AND timestamp = '" . $order_timestamp . "' LIMIT 1");
                if (!empty($dupe)) {
                    continue;
                }
                //save it
                $morder->process();
                $morder->saveOrder();
                //update the timestamp
                $morder->updateTimestamp(date("Y", $order_timestamp), date("m", $order_timestamp), date("d", $order_timestamp));
                //send emails
                $email = new PMProEmail();
                $email->template = "check_pending";
                $email->email = $user->user_email;
                $email->subject = sprintf(__("New Invoice for %s at %s", "pmpropbc"), $user->membership_level->name, get_option("blogname"));
            }
        }
    }
}
     $end_timestamp = $old_subscription->current_period_end;
     //cancel the old subscription
     if (!$last_order->Gateway->cancelSubscriptionAtGateway($old_subscription)) {
         //email admin that the old subscription could not be canceled
         $pmproemail = new PMProEmail();
         $pmproemail->data = array("body" => "<p>" . sprintf(__("While processing an update to the subscription for %s, we failed to cancel their old subscription in Stripe. Please check that this user's original subscription (%s) is cancelled in the Stripe dashboard.", "pmpro"), $user->display_name . " (" . $user->user_login . ", " . $user->user_email . ")", $old_subscription->id) . "</p>");
         $pmproemail->sendEmail(get_bloginfo("admin_email"));
     }
 }
 //if we didn't get an end date, let's set one one cycle out
 if (empty($end_timestamp)) {
     $end_timestamp = strtotime("+" . $update['cycle_number'] . " " . $update['cycle_period']);
 }
 //build order object
 $update_order = new MemberOrder();
 $update_order->setGateway('stripe');
 $update_order->user_id = $user->ID;
 $update_order->membership_id = $user->membership_level->id;
 $update_order->membership_name = $user->membership_level->name;
 $update_order->InitialPayment = 0;
 $update_order->PaymentAmount = $update['billing_amount'];
 $update_order->ProfileStartDate = date_i18n("Y-m-d", $end_timestamp);
 $update_order->BillingPeriod = $update['cycle_period'];
 $update_order->BillingFrequency = $update['cycle_number'];
 //create new subscription
 $update_order->Gateway->subscribe($update_order);
 //update membership
 $sqlQuery = "UPDATE {$wpdb->pmpro_memberships_users}\n\t\t\t\t\t\t\t\t\t\t\t\tSET billing_amount = '" . esc_sql($update['billing_amount']) . "',\n\t\t\t\t\t\t\t\t\t\t\t\t\tcycle_number = '" . esc_sql($update['cycle_number']) . "',\n\t\t\t\t\t\t\t\t\t\t\t\t\tcycle_period = '" . esc_sql($update['cycle_period']) . "'\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE user_id = '" . esc_sql($user_id) . "'\n\t\t\t\t\t\t\t\t\t\t\t\t\tAND membership_id = '" . esc_sql($last_order->membership_id) . "'\n\t\t\t\t\t\t\t\t\t\t\t\t\tAND status = 'active'\n\t\t\t\t\t\t\t\t\t\t\t\tLIMIT 1";
 $wpdb->query($sqlQuery);
 //save order so we know which plan to look for at stripe (order code = plan id)
 $update_order->status = "success";