Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Subscription quantity at the end of the cycle #250

Open
wants to merge 5 commits into
base: v3_develop
Choose a base branch
from

Conversation

ignaciocunado
Copy link
Contributor

Description

This PR adds functionality to update the subscription count at the end of the cycle. This is needed because if a user wants to decrease their subscription count, there is currently no way to make the billing and downgrading of the count to happen at the end of the cycle.

Additional Information

I believe this PR would not break any existing functionality, but is probably considered a major release as a new column needs to be added to the database.


Thank you for reviewing my PR!

@Naoray
Copy link
Collaborator

Naoray commented Jun 24, 2024

Hi @ignaciocunado,

thank you for your contribution!

I don't think another property next_quantity is needed to be able to achieve what you want!

If I am not mistaken - @sandervanhooft, please correct me if I am wrong - you could create an OrderItemObserver that reacts to an OrderItem who is being created.

<?php

namespace App\Observers;

use Laravel\Cashier\Order\OrderItem;
use Laravel\Cashier\Subscription;

class OrderItemObserver
{
    public function creating(OrderItem $orderItem): void
    {
        $orderItem->quantity -= 1;

        if (!$orderItem->orderableIsSet()) {
            return;
        }

        // we only want to decrement the quantity of subscriptions
        // that are set to process in the future
        if ($orderItem->process_at->lessThanOrEqualTo(now())) {
            return;
        }

        /** @var Subscription $subscription */
        $subscription = $orderItem->orderable;

        if ($subscription->quantity === 1) {
            // quantity would be 0 now
            // you can cancel the subscription or do something else
            return;
        }

        $subscription->decrement('quantity');   
    }
}

// in AppServiceProvider
use App\Observers\OrderItemObserver;
use Laravel\Cashier\Order\OrderItem;

// ...

public function boot(): void
{
        OrderItem::observe(OrderItemObserver::class);
}

You could also scope this functionality to a specific plan, by checking the $subscription->plan before decrementing.


I am aware that this is just a workaround and is far from ideal. The solution you proposed seems to be okaish, but I am not convinced this is the best path forward. I believe in future versions of this library we are able to expose more events before and after processing order items which may result in an easier implementation for this scenario!

If you have any further questions, please feel free to submit an Issue!

@ignaciocunado
Copy link
Contributor Author

Thank you for your response and suggestion @Naoray.

However, I do not understand how this would allow a user to choose if they want to change (usually downgrade) their subscription count at the end of the cycle. Wouldn't this decrease the quantity for all subscriptions when a new order item is created?

@sandervanhooft
Copy link
Collaborator

Thanks @ignaciocunado !

@Naoray 's suggestion is valid in the sense that it takes care of the swapping and billing. However, the subscription quantity will be out of sync for the remainder of the cycle.

I have to agree with @ignaciocunado that adding columns similar to swap-next-cycle is desirable here.

I consider it to breaking, so best to consider this PR for next major release.

@sandervanhooft sandervanhooft added the major release The issue describes something that will be implemented in a future major release label Jun 25, 2024
@ignaciocunado
Copy link
Contributor Author

Hi @sandervanhooft!

Do we have an ETA for the next major release?

Thanks

@sandervanhooft
Copy link
Collaborator

Not as of yet

@sandervanhooft sandervanhooft mentioned this pull request Jan 6, 2025
10 tasks
@sandervanhooft sandervanhooft changed the base branch from main to v3_develop January 6, 2025 12:38
@sandervanhooft
Copy link
Collaborator

Switched to target v3_develop branch

$quantity < 1,
new LogicException('Subscription quantity must be at least 1.')
);
return DB::transaction(function () use ($quantity) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll also need to make sure the subscription doesn't get restarted if it has ended.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
major release The issue describes something that will be implemented in a future major release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Changing subscription count at the end of cycle
3 participants