laravel / cashier-stripe

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.
https://laravel.com/docs/billing
MIT License
2.37k stars 667 forks source link

[16.x] Store subscription renewal date #1675

Closed clementmas closed 1 month ago

clementmas commented 3 months ago

I believe there's a real need from the community to store the subscription renewal date to display it to users or use for cron jobs. See: #361, #515, #874, #1054, #1102, Stack Overflow, Laracasts, gist, etc.

The current workaround requires making an extra API request $user->subscription()->asStripeSubscription()->current_period_end that can be avoided if we store the renewal date $subscription->renews_at when creating, updating and swapping subscriptions.

Note: I considered using the ends_at column instead of creating a new renews_at column but they'll have different values when using $subscription->cancelAt().

I understand the need to keep Cashier simple and functional but I think this is a relatively simple change that adds a lot of value.

This PR does not break any existing feature but it does require running this database migration to upgrade:

// php artisan make:migration add_cashier_subscriptions_renews_at_column --table=subscriptions
Schema::table('subscriptions', function (Blueprint $table) {
    $table->timestamp('renews_at')->nullable()->after('quantity');
});
driesvints commented 3 months ago

Tbh, I'd also like to see this in Cashier now.. thanks for the PR! The only downside here is that this is gonna need a new major release because current apps won't have the renews_at column.

sts-ryan-holton commented 3 months ago

Is it better to start using dateTime instead of timestamp nowadays? Especially with the future timestamp issue approaching

driesvints commented 1 month ago

@clementmas I'm sorry but given there's no consensus on how to approach this I believe it's best to let this one go for now. Thank you for your time and work.

clementmas commented 1 month ago

I haven't found any side effects in production from relying on the invoice.payment_succeeded webhook instead of customer.subscription.updated. The renewal date is updated properly and on time.

I updated the webhook code on my fork: https://github.com/clementmas/cashier-stripe/commit/c41246265aaf426b47e7f18070d161f30575eed1

I invite other developers to try it, improve it if necessary, and hopefully we can PR it again.