Developing a subscription plan for a website
I have been working on a website that has to do with a subscription system where users will have to upgrade from one level to another. Let me explain a bit. There are four plans namely; Basic, Silver, Gold, Platimum. The cost is as follows:
- Basic: $0.00
- Silver: $20.00
- Gold: $30.00
- Platimum: $50.00
The pre-payment options are:
- 1 month
- 3 months
- 6 months
- 12 months.
These are my tables;
plans table:
id name cost
1 Basic 0.00
2 Silver 20.00
3 Gold 30.00
4 Platinum 50.00
plans_period table:
id sub_period
1 1
2 3
3 6
4 12
users table:
user_id plan plan_cost user_plan_period balance plan_expiration
1 2 0.00(default) 0 (default) 0.00 (default) NULL (default)
Now for a user to upgrade the system will check the balance table to see how must the user has left, the cost of the new plan. If the balance is more than the cost of the new plan the user is upgrading to, the upgrade will be successful and redirected to a success page, if not the payment button will be displayed for the user to pay whatever the new cost using any of the payment system integrated. Also if the user is in the middle of a plan and wants to upgrage to a higher plan, the system will also have to pro-rate the new cost and charge the user likewise. I have been trying to do this with the code below.
if ($plan & $period) {
$user = new fncs();
// What plan was chosen?
list($name, $cost) = $db->get_row("select name, cost from plans where id='$plan'", ARRAY_N);
list($sub_period) = $db->get_row("select sub_period from plans_period where sub_period='$period'", ARRAY_N);
list($plan, $user_plan_period, $plan_cost, $plan_expiration) = $db->get_row("select u.plan, u.user_plan_period, u.plan_cost, u.plan_expiration, p.id from users u LEFT JOIN plans p ON p.id=u.plan where u.user_id='{$_SESSION['user_id']}'", ARRAY_N);
$plan_expiration = ($plan_expiration = "NULL") ? '30' : '$plan_expiration';
/*Current Cost of plan chosen */
$totalcost1 = $cost * $sub_period;
/* Cost of the user current plan */
$totalcost2 = $plan_cost * $user_plan_period;
/* Total number of days of the user current plan */
$totaldays1 = 30 * $user_plan_period;
/* Total number of days of the left for the user current plan */
$today = date("m-d-Y");
$dateDiff = strtotime($plan_expiration) - strtotime($today);
$Daysleft = floor($dateDiff/(60*60*24));
$totaldays2 = $totaldays1 - $Daysleft;
$expiredate = strtotime($plan_expiration);
$totalcost = $totalcost1 - ($totalcost2 * ($Daysleft / $totaldays1));
$finalcost = number_format($totalcost, 2);
// sufficient balance?
if ($totalcost > $user->getBalance())
{
$errs[] = 'You have insufficient balance for the upgrade. The total cost is: '.$Daysleft.'';
}
else {
$r = $db->query("update users set plan='$plan', user_plan_period='$period', plan_cost='$cost', plan_expiration=date_add(now(), interval 30 day) where user_id='{$_SESSION['user_id']}'");
// Update balance
$balance = $user->getBalance() - $cost;
$db->query("update users set balance='$balance' where user_id='{$_SESSION['user_id']}'");
// Reset sessions
$user->processLogin($_SESSION['email']);
// Insert into transactions
$txt = "Account upgrade: <strong>$name</strong> for <s>N</s>$cost. Expires ".$_SESSION['plan_expiration'];
$db->query("insert into transactions (user_id, txt, direction, amount, balance, date) values ('{$_SESSION['user_id']}', '$txt', 'd', '$cost', '$balance', now())");
$_SESSION['msg'] = 'Account successfully upgraded. Plan expires on '.$_SESSION['plan_expiration'];
header('location:my-account.php');
exit;
}
}
Below is the form where the user will select the plan to upgrade to
<div class="mainbar">
<h3>Upgrade Account</h3>
<?php
if (isset($errs)) {
echo '<p class="alert">';
foreach($errs as $v){
echo "$v ";
}
echo '</p>';
}
?>
<form class="form" method="post">
<div class="rc">
<p><label>Current Balance</label> <b><s>N</s><?= number_format($_SESSION['balance'], 2); ?></b></p>
<p><label>Plan</label>
<select class="txt iwdt" name="plan">
<?php
$r = $db->get_results("select id, name, cost from plans where id > 1");
foreach ($r as $v) {
list ($id, $name, $cost) = $v;
echo '<option value="'.$id.'"';
echo $id == $_SESSION['plan'] ? ' selected="selected"' : '';
echo '>'.$name.' for N'.$cost.'</option>';
}
?>
</select>
<select class="txt iwdt" 开发者_StackOverflowname="period">
<option value="">Select Period</option>
<?php
$r = $db->get_results("select id, sub_period from plans_period");
foreach ($r as $v) {
list ($id, $sub_period) = $v;
echo '<option value="'.$id.'"';
echo $id == $_SESSION['period'] ? ' selected="selected"' : '';
echo '>'.$sub_period.' month(s)</option>';
}
?>
</select>
</p>
<p>
<label> </label> <input type="submit" name="submit" class="button" value="Upgrade" /> or <a href="my-account.php">Cancel</a>
</p>
</div>
</form>
</div>
Can somebody point me to the right direction. Is there a tutorial i can learn from on this? Thanks.
Thanks to all that have replied.
Basically this is where i think i'm having some challenge
$plan_expiration = ($plan_expiration = "NULL") ? '30' : '$plan_expiration';
This plan_expiration field is date field in this format Year-month-day such as 2011-06-03. Now the default value for this is "NULL". When a user first signs up into our site, the user is assign a basic membership plan which is $0.00 cost with their expiration date set to "NULL".
If a user wants to upgrade, we have to calculate the days left before their plan will expire because we are going to pro-rate this based on the days left. So i did this
i assigned "30" to $plan_expiration if it is nulled based on the code above. I then calculated the days left using the syntax below
$today = date("m-d-Y");
$dateDiff = strtotime($plan_expiration) - strtotime($today);
$Daysleft = floor($dateDiff/(60*60*24));
First error is that $Daysleft is returning me a negative value
You also need the actual sign-up-date to calculate the missing days.
Lets use this example:
We have a sign-up on the 15th of May (2011-05-15) and an expiration of assumed 30 days (which results in an expiration on 15th of June (2011-06-15).
The PHP calculation could work like this:
$signupDate = strtotime('2011-05-15');
$expiration = 30; //this is in days, lets remember that for later
$expirationDate = $signupDate+($expiration*24*60*60); //calculate the expiration date
$today = time(); //theres no need for using date and strtotime of you just want the timestamp
$daysLeft = floor(($expirationDate-$today)/(60*60*24));
If $daysLeft
now has a negative value (which shouldn't happen) his account has expired some time ago. But since the way your application is working this should normally result in a positive value giving you the days left for the users plan.
精彩评论