Skip to content

Commit

Permalink
Store subscription renewal date
Browse files Browse the repository at this point in the history
  • Loading branch information
clementmas committed May 3, 2024
1 parent 98fa78e commit 7bdbe81
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 2 deletions.
1 change: 1 addition & 0 deletions database/factories/SubscriptionFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public function definition(): array
'stripe_status' => StripeSubscription::STATUS_ACTIVE,
'stripe_price' => null,
'quantity' => null,
'renews_at' => null,
'trial_ends_at' => null,
'ends_at' => null,
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public function up(): void
$table->string('stripe_status');
$table->string('stripe_price')->nullable();
$table->integer('quantity')->nullable();
$table->timestamp('renews_at')->nullable();
$table->timestamp('trial_ends_at')->nullable();
$table->timestamp('ends_at')->nullable();
$table->timestamps();
Expand Down
6 changes: 5 additions & 1 deletion src/Http/Controllers/WebhookController.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ protected function handleCustomerSubscriptionCreated(array $payload)
'stripe_status' => $data['status'],
'stripe_price' => $isSinglePrice ? $firstItem['price']['id'] : null,
'quantity' => $isSinglePrice && isset($firstItem['quantity']) ? $firstItem['quantity'] : null,
'renews_at' => Carbon::createFromTimestamp($data['current_period_end']),
'trial_ends_at' => $trialEndsAt,
'ends_at' => null,
]);
Expand Down Expand Up @@ -163,11 +164,14 @@ protected function handleCustomerSubscriptionUpdated(array $payload)
}
}

// Renewal date...
$subscription->renews_at = Carbon::createFromTimestamp($data['current_period_end']);

// Cancellation date...
if ($data['cancel_at_period_end'] ?? false) {
$subscription->ends_at = $subscription->onTrial()
? $subscription->trial_ends_at
: Carbon::createFromTimestamp($data['current_period_end']);
: $subscription->renews_at;
} elseif (isset($data['cancel_at']) || isset($data['canceled_at'])) {
$subscription->ends_at = Carbon::createFromTimestamp($data['cancel_at'] ?? $data['canceled_at']);
} else {
Expand Down
10 changes: 9 additions & 1 deletion src/Subscription.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ class Subscription extends Model
* @var array
*/
protected $casts = [
'ends_at' => 'datetime',
'quantity' => 'integer',
'renews_at' => 'datetime',
'trial_ends_at' => 'datetime',
'ends_at' => 'datetime',
];

/**
Expand Down Expand Up @@ -705,6 +706,7 @@ public function swap($prices, array $options = [])
'stripe_status' => $stripeSubscription->status,
'stripe_price' => $isSinglePrice ? $firstItem->price->id : null,
'quantity' => $isSinglePrice ? ($firstItem->quantity ?? null) : null,
'renews_at' => Carbon::createFromTimestamp($stripeSubscription->current_period_end),
'ends_at' => null,
])->save();

Expand Down Expand Up @@ -992,6 +994,8 @@ public function cancel()

$this->stripe_status = $stripeSubscription->status;

$this->renews_at = null;

// If the user was on trial, we will set the grace period to end when the trial
// would have ended. Otherwise, we'll retrieve the end of the billing period
// period and make that the end of the grace period for this current user.
Expand Down Expand Up @@ -1027,6 +1031,8 @@ public function cancelAt($endsAt)

$this->stripe_status = $stripeSubscription->status;

$this->renews_at = null;

$this->ends_at = Carbon::createFromTimestamp($stripeSubscription->cancel_at);

$this->save();
Expand Down Expand Up @@ -1078,6 +1084,7 @@ public function markAsCanceled()
{
$this->fill([
'stripe_status' => StripeSubscription::STATUS_CANCELED,
'renews_at' => null,
'ends_at' => Carbon::now(),
])->save();
}
Expand Down Expand Up @@ -1105,6 +1112,7 @@ public function resume()
// no longer "canceled". Then we shall save this record in the database.
$this->fill([
'stripe_status' => $stripeSubscription->status,
'renews_at' => Carbon::createFromTimestamp($stripeSubscription->current_period_end),
'ends_at' => null,
])->save();

Expand Down
1 change: 1 addition & 0 deletions src/SubscriptionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ protected function createSubscription(StripeSubscription $stripeSubscription)
'stripe_status' => $stripeSubscription->status,
'stripe_price' => $isSinglePrice ? $firstItem->price->id : null,
'quantity' => $isSinglePrice ? ($firstItem->quantity ?? null) : null,
'renews_at' => Carbon::createFromTimestamp($stripeSubscription->current_period_end),
'trial_ends_at' => ! $this->skipTrial ? $this->trialExpires : null,
'ends_at' => null,
]);
Expand Down
27 changes: 27 additions & 0 deletions tests/Feature/SubscriptionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ public function test_subscriptions_can_be_created()
$this->assertFalse($user->subscription('main')->onGracePeriod());
$this->assertTrue($user->subscription('main')->recurring());
$this->assertFalse($user->subscription('main')->ended());
$this->assertSame(Carbon::today()->addMonth()->toDateString(), $user->subscription('main')->renews_at->toDateString());

// Cancel Subscription
$subscription = $user->subscription('main');
Expand All @@ -142,6 +143,7 @@ public function test_subscriptions_can_be_created()
$this->assertTrue($subscription->onGracePeriod());
$this->assertFalse($subscription->recurring());
$this->assertFalse($subscription->ended());
$this->assertNull($subscription->renews_at);

// Modify Ends Date To Past
$oldGracePeriod = $subscription->ends_at;
Expand All @@ -163,6 +165,7 @@ public function test_subscriptions_can_be_created()
$this->assertFalse($subscription->onGracePeriod());
$this->assertTrue($subscription->recurring());
$this->assertFalse($subscription->ended());
$this->assertSame(Carbon::today()->addMonth()->toDateString(), $user->subscription('main')->renews_at->toDateString());

// Increment & Decrement
$subscription->incrementQuantity();
Expand Down Expand Up @@ -249,6 +252,29 @@ public function test_swapping_subscription_with_inline_price_data()
$this->assertEquals('exclusive', $subscription->asStripeSubscription()->items->data[0]->price->tax_behavior);
}

public function test_swapping_subscription_and_updating_renewal_date()
{
$user = $this->createCustomer('swapping_subscription_and_updating_renewal_date');
$user->newSubscription('main', static::$priceId)->create('pm_card_visa');
$subscription = $user->subscription('main');

$this->assertSame(Carbon::today()->addMonth()->toDateString(), $subscription->renews_at->toDateString());

$subscription->swap([[
'price_data' => [
'product' => static::$productId,
'tax_behavior' => 'exclusive',
'currency' => 'USD',
'recurring' => [
'interval' => 'year',
],
'unit_amount' => 1100,
],
]]);

$this->assertSame(Carbon::today()->addYear()->toDateString(), $subscription->renews_at->toDateString());
}

public function test_declined_card_during_new_quantity()
{
$user = $this->createCustomer('declined_card_during_new_quantity');
Expand Down Expand Up @@ -936,6 +962,7 @@ public function test_subscriptions_can_be_canceled_at_a_specific_time()
$subscription = $subscription->cancelAt($endsAt = now()->addMonths(3));

$this->assertTrue($subscription->active());
$this->assertNull($subscription->renews_at);
$this->assertSame($endsAt->timestamp, $subscription->ends_at->timestamp);
$this->assertSame($endsAt->timestamp, $subscription->asStripeSubscription()->cancel_at);
}
Expand Down
10 changes: 10 additions & 0 deletions tests/Feature/WebhooksTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public static function setUpBeforeClass(): void
public function test_subscriptions_are_created()
{
$user = $this->createCustomer('subscriptions_are_created', ['stripe_id' => 'cus_foo']);
$renewalDate = Carbon::now()->addMonth();

$this->postJson('stripe/webhook', [
'id' => 'foo',
Expand All @@ -57,6 +58,7 @@ public function test_subscriptions_are_created()
'object' => [
'id' => 'sub_foo',
'customer' => 'cus_foo',
'current_period_end' => $renewalDate->timestamp,
'cancel_at_period_end' => false,
'quantity' => 10,
'items' => [
Expand All @@ -77,6 +79,7 @@ public function test_subscriptions_are_created()
'stripe_id' => 'sub_foo',
'stripe_status' => 'active',
'quantity' => 10,
'renews_at' => $renewalDate->format('Y-m-d H:i:s'),
]);

$this->assertDatabaseHas('subscription_items', [
Expand All @@ -90,6 +93,7 @@ public function test_subscriptions_are_created()
public function test_subscriptions_are_updated()
{
$user = $this->createCustomer('subscriptions_are_updated', ['stripe_id' => 'cus_foo']);
$renewalDate = Carbon::now()->addMonth();

$subscription = $user->subscriptions()->create([
'type' => 'main',
Expand All @@ -112,6 +116,7 @@ public function test_subscriptions_are_updated()
'object' => [
'id' => $subscription->stripe_id,
'customer' => 'cus_foo',
'current_period_end' => $renewalDate->timestamp,
'cancel_at_period_end' => false,
'items' => [
'data' => [[
Expand All @@ -129,6 +134,7 @@ public function test_subscriptions_are_updated()
'user_id' => $user->id,
'stripe_id' => 'sub_foo',
'quantity' => 5,
'renews_at' => $renewalDate->format('Y-m-d H:i:s'),
]);

$this->assertDatabaseHas('subscription_items', [
Expand All @@ -147,6 +153,7 @@ public function test_subscriptions_are_updated()
public function test_subscriptions_on_update_cancel_at_date_is_correct()
{
$user = $this->createCustomer('subscriptions_on_update_cancel_at_date_is_correct', ['stripe_id' => 'cus_foo']);
$renewalDate = Carbon::now()->addMonth();
$cancelDate = Carbon::now()->addMonths(6);

$subscription = $user->subscriptions()->create([
Expand All @@ -170,6 +177,7 @@ public function test_subscriptions_on_update_cancel_at_date_is_correct()
'object' => [
'id' => $subscription->stripe_id,
'customer' => 'cus_foo',
'current_period_end' => $renewalDate->timestamp,
'cancel_at' => $cancelDate->timestamp,
'cancel_at_period_end' => false,
'items' => [
Expand All @@ -188,6 +196,7 @@ public function test_subscriptions_on_update_cancel_at_date_is_correct()
'user_id' => $user->id,
'stripe_id' => 'sub_foo',
'quantity' => 5,
'renews_at' => $renewalDate->format('Y-m-d H:i:s'),
'ends_at' => $cancelDate->format('Y-m-d H:i:s'),
]);

Expand Down Expand Up @@ -218,6 +227,7 @@ public function test_canceled_subscription_is_properly_reactivated()
'object' => [
'id' => $subscription->stripe_id,
'customer' => $user->stripe_id,
'current_period_end' => Carbon::now()->addMonth()->timestamp,
'cancel_at_period_end' => false,
'items' => [
'data' => [[
Expand Down

0 comments on commit 7bdbe81

Please sign in to comment.