Skip to content

Commit

Permalink
can cancel subscriptions at the end of period instead of immediately
Browse files Browse the repository at this point in the history
  • Loading branch information
Jared King committed Sep 11, 2016
1 parent e58f96f commit 4823391
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
17 changes: 15 additions & 2 deletions src/Libs/BillingSubscription.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,11 @@ public function change($plan, $noTrial = false, array $params = [])
/**
* Cancels the subscription.
*
* @param bool $atPeriodEnd when true, cancels the subscription at the end of the billing period
*
* @return bool
*/
public function cancel()
public function cancel($atPeriodEnd = false)
{
if (!$this->active()) {
return false;
Expand Down Expand Up @@ -193,14 +195,25 @@ public function cancel()
return false;
}

$params = [];
if ($atPeriodEnd) {
$params['cancel_at_period_end'] = true;
}

try {
$subscription = $customer->cancelSubscription();
$subscription = $customer->cancelSubscription($params);

if ($subscription->status == 'canceled') {
$this->model->canceled = true;
$this->model->grantAllPermissions()->save();
$this->model->enforcePermissions();

return true;
} elseif ($subscription->cancel_at_period_end && $atPeriodEnd) {
$this->model->canceled_at = $subscription->canceled_at;
$this->model->grantAllPermissions()->save();
$this->model->enforcePermissions();

return true;
}
} catch (StripeError $e) {
Expand Down
34 changes: 34 additions & 0 deletions tests/BillingSubscriptionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,40 @@ public function testCancel()
$this->assertTrue($member->canceled);
}

public function testCancelAtPeriodEnd()
{
$resultSub = new stdClass();
$resultSub->status = 'active';
$resultSub->cancel_at_period_end = true;
$resultSub->canceled_at = time();

$customer = Mockery::mock('StripeCustomer');
$customer->shouldReceive('cancelSubscription')
->withArgs([['cancel_at_period_end' => true]])
->andReturn($resultSub)
->once();

$member = Mockery::mock('TestBillingModel[stripeCustomer,save]');
$member->shouldReceive('stripeCustomer')
->andReturn($customer)
->once();
$member->shouldReceive('save')->once();

$member->canceled = false;
$member->trial_ends = 0;
$member->renews_next = strtotime('+1 month');
$member->not_charged = false;
$member->plan = 'test';
$member->stripe_customer = 'cust_test';

$subscription = new BillingSubscription($member, 'test', Test::$app);

$this->assertTrue($subscription->cancel(true));

$this->assertFalse($member->canceled);
$this->assertEquals($resultSub->canceled_at, $member->canceled_at);
}

public function testCancelFail()
{
$e = new StripeError('error');
Expand Down

0 comments on commit 4823391

Please sign in to comment.