Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

TylerW's avatar

Laravel Cashier - Adding Days To Subscription

I am a totally newbie to both Laravel Cashier and BrainTree, and I am trying to figure out how to add days to a person's subscription (meaning offset the day they are charged again by a certain amount of days).

Upon reading the Cashier documentation, I see that there is a feature called 'anchorBillingCycleOn' that allows you to change the anchor date of the subscription, but this is only an option in the Stripe version of Cashier.

What can us BrainTree Cashier users do to make it so our user's subscription is charged a few days late?

0 likes
8 replies
Braunson's avatar

Yes anchorBillingCycleOn is for Stripe only. As for BrainTree it doesn't look like there is an option for what you need in Cashier.

I can suggest another option, is using the 'trial days' instead and requiring CC on setup so they have X many days before they are "subscribed". This however only works on initial sign up but not necessarily when they are/have been subscribed already.

You cannot change the billing date on an existing subscription, you must cancel the subscription and create a new one.

With Braintree, the next billing date is calculated, and so can't be changed unfortunately.

TylerW's avatar

@BRAUNSON - Unfortunately, I only need to use this functionality for users that are already signed up. It is not a feature I will ever need at initial sign up. On the bright side, I don't really need to do this programmatically since it's a one-off thing. Just need to glue this together for a couple of people in this instance.

After speaking to BrainTree, it appears my only option to change the date they are charged is to cancel the existing subscription and create a new subscription with a trial period at the beginning and link it to the same payment method as their original subscription.

This brings me to the second part of the equation, making this work with my Cashier implementation. Does it make sense to simply manually add a subscription to the subscriptions table in Laravel with the relevant braintree_id created on the BrainTree back end from the subscription manually created above, and then set the trial_ends_at to match BrainTree's trial_ends_at? It seems like this would work, but I don't fully understand Cashier so maybe there is something wrong with just manually adding a subscription like this.

So for example, I'm imagining: I have a user whose subscription ends on the 28th, but I want it to end on the 30th. I cancel the existing subscription on the BrainTree back end, and create a new subscription starting now with a trial that lasts until the 30th. Then, in Laravel, I delete the old subscription entry and manually insert a new one with the new ID and set trial_ends_at to the 30th.

Braunson's avatar

Yes that sounds like your best bet. I'm not familiar at all with BrainTree myself but from the flow you've described.

  1. Cancel users existing subscription $user->subscription('fooSub')->cancel();
  2. Create a subscription that ends on X date
  3. Subscribe the user to the new subscription.

On step 2, since Cashier (BrainTree) doesn't seem to have methods to create custom subscriptions, you'll have to do this likely with the BrainTree PHP library @ https://developers.braintreepayments.com/reference/request/subscription/create/php manually. You will want to set the billing day of month to the new date you need.

$result = $gateway->subscription()->create([
  'paymentMethodToken' => $token,
  'planId' => 'custom_plan_foo1234',
  'billingDayOfMonth' => 30,
  // ...
]);

After that you can just re-subscribe your user using Cashier like so: $user->newSubscription('newSub')->create($token); You will need the CC token also to re-subscribe the user.

TylerW's avatar
TylerW
OP
Best Answer
Level 3

@BRAUNSON - This may be a stupid question, but I have no idea how Cashier actually works under the hood so I'll just ask it anyways.

Is there any difference between using the cancel subscription method and just deleting the entry from the database?

Likewise, is there any difference between using the BrainTree PHP library to make the subscription rather than just manually creating the new subscription in the BrainTree back end and just inserting a row manually into the subscription table with an insert statement?

I guess what I'm trying to get at is - are there other things going on under the hood when you call subscription cancel or newSubscription that hook up the two?

Cronix's avatar

Is there any difference between using the cancel subscription method and just deleting the entry from the database?

Yes, one will stop the actual charges from hitting the credit card and the other won't. Just deleting it from your db doens't inform stripe/braintree to no longer charge the card at the regular interval. Don't forget, there are 2 systems that are talking to each other here...yours and the cc processor (stripe/braintree).

Likewise, is there any difference between using the BrainTree PHP library to make the subscription rather than just manually creating the new subscription in the BrainTree back end and just inserting a row manually into the subscription table with an insert statement?

You would be a lot better off just using the cashier methods to 1) communicate with braintree and 2) populate your subscription in your database in one go rather than doing everything on your own. There is just a lot less room for error, and if things change with either api you'd have to implement your fixes manually. There just really isn't a good reason to have all of those points of failure when you are using something like cashier. Let cashier do the work.

TylerW's avatar

@CRONIX - Regarding the first point, about it not communicating with BrainTree - I meant to include that I would manually cancel the subscription on the BrainTree back end.

I agree that using Cashier for all of this functionality makes more sense, but also consider that this is just a one-time use. I need to perform this functionality on three accounts just one time, and will not need to perform it again in the future. For that reason, I'm trying to find the quickest and easiest way to accomplish the task of adding 5 days of credit to 3 of my users.

Is there anything wrong with simply doing this:

  1. Cancel subscription on BrainTree
  2. Delete subscription row from subscriptions table
  3. Assign a new subscription to the user on the BrainTree back-end that has a trial of 5 days
  4. Manually insert a row into subscriptions database with the relevant information (subscription id, etc.)

I'm just trying to figure out if Cashier is doing anything else under the hood, besides the 4 steps above, to make everything work. If that's all it's doing, I would much prefer to manually do this right now than take the time to figure out how to do this programmatically because I will never need to do it again in the future. I would literally delete the methods as soon as I used them on these three accounts.

I'm the last guy to say, 'hey I want to waste time doing this manually risking multiple points of failure when it could be automated,' but it's such an unnecessary thing for me to code at the moment. Not to mention, I'm completely unaware of how to create a subscription for an existing user using Cashier without having to provide a token with their payment details - tried already and realized it was more complicated than I anticipated.

Braunson's avatar

@Tyler The repo is your friend in this case, you can see what happens then you 'cancel' a subscription via the cancel method.

For Stripe: https://github.com/laravel/cashier/blob/707ef5ec28974f74c57461ef25c125c46050d885/src/Subscription.php#L404

The code will cancel the subscription at the end of the billing period. The code will set the cancel_at_period_end field in stripe to true. Stripe will end the subscription at the end of the billing period.

For BrainTree: https://github.com/laravel/cashier-braintree/blob/1b9c2500a030fa7589386d829160d63669ead7fa/src/Subscription.php#L369

You can see the code uses the BraintreeSubscription class to call cancel() which if we dig into the braintree/braintree_php package you'll see here it calls the Braintree API Gateway and calls here to cancel the subscription in Braintree.

So to answer your question simply:

  1. Yes there is a difference in using the cancel subscription method vs deleting the entry from the DB. The subscription is technically stored on the Processor side (Stripe/Braintree), your app's database just keeps reference of it, deleting it in your db will just delete your app's reference, the customer will still be billed by the processor (Stripe/Braintree) since that's where the actual processing/charging magic happenbs.

  2. Cashier-Braintree is just a wrapper to help facilitate the use of BrainTree in Laravel, if you want to use t he direct BrainTree PHP library, go for it, but I'd personally use Cashier and if it doesn't do what I need, to just extend it to suit my needs.

I hope this helps give you more insight and a better idea on how things work under the hood with Laravel's Cashier/Cashier-Braintree :)

TylerW's avatar

@BRAUNSON - I really appreciate you taking the time to write this, but I'm afraid it doesn't answer my question. Let me see if I can rephrase it:

I cancel the user's subscription in BrainTree. Then, I delete the subscription from the subscriptions table. Then, I create a new subscription in BrainTree. Then, I manually add a row to the subscriptions table with all the data. Bam, user has a new subscription now.

I have already done the above and tested to ensure it works (->subscribed returns new subscription). All I am trying to figure out is if I will run into issues in the future (such as when user tries to cancel) by adding a subscription manually like this, or is the process I described above an exact replica of what Cashier is doing when it creates a subscription?

The reason I am suspicious that something may go wrong is because I have no idea how cancellation actually occurs in Cashier. For example, if I cancel my subscription right now, nothing actually happens in the BrainTree back end. The subscription does not show up as cancelled until the billing date is reached. How is this happening? Is there some sort of script being run at the end of each day to check all of the subscriptions in the database to see if they have ended before telling BrainTree to cancel? That is where my confusion lies.

Please or to participate in this conversation.