Reputation: 387
I have two plans in my Stripe subscriptions. The first plan is a plan of 10 euros/month until a specific date say for example it started in 10/2/2021 and I want it to end in 15/7/2021. And I want the subsriber to always pay 10 euros/month even for the last month. So I don't want any proration behaviour. In an attempt to do this I did the following on customer.susbcription.created event [I want to update the newly created subscription] :
$sub->cancel_at = strtotime($my_selected_timestamp);
$sub->save();
The second is a plan of 38 euros/month , to cancel it in 2 months I wrote in the customer.susbcription.created event :
$sub->cancel_at = strtotime("+2 month", $sub->start_date);
$sub->save();
So the subscription started in 12/3/2021 at 4:36 PM and the end date in my dashboard was effectively 12/5/2021 at 4:36 PM however my next invoice will be created in Apr 12, 5:36 PM with an amount of €37.95 instead of 38 ! why ? I read about proration_behavior and tried to update my already existing subscription by setting this behavior to none but that didn't work.
I couldn't find any proration field in the subscription object in order to update it to none, so in an attempt to solve this issue I tried this and It worked (now I have 38 euros for my next invoice):
$expiry_date = strtotime("+2 month", $sub->start_date);
$sub->cancel_at = strtotime("+1 hour", $expiry_date);
$sub->save();
I would like to ask you If what I did is correct or does it have any implications ?? In many previous posts, many have said that there is a way to do this using Subscription Schedules. However in my case I cannot set some accurate number of intervals because I want the same code for both plans and the second plan is cancelled at a specific date.
EDIT : Tried this code but also didn't work:
$final = strtotime("+2 month", $subscription_obj->start_date);
\Stripe\Subscription::update($subscription_obj->id, [
'cancel_at' => $final,
'proration_behavior' => 'none',
]
);
$subscription_obj->save();
Here's my subscription object for a plan of 12 euros/month:
[id] => sub_J75FZOObndggWX
[object] => subscription
[application_fee_percent] =>
[billing_cycle_anchor] => 1615717329
[billing_thresholds] =>
[cancel_at] => 1620984129
[cancel_at_period_end] =>
[canceled_at] => 1615717335
[collection_method] => charge_automatically
[created] => 1615717329
[current_period_end] => 1618395729
[current_period_start] => 1615717329
[customer] => cus_J75Fs7RnQtMBTX
[days_until_due] =>
[default_payment_method] => pm_1IUr5IHEWYmoXN4GjeSdn3aK
[default_source] =>
[default_tax_rates] => Array
(
)
[discount] =>
[ended_at] =>
[items] => Stripe\Collection Object
(
[object] => list
[data] => Array
(
[0] => Stripe\SubscriptionItem Object
(
[id] => si_J75F5QEL5Gnzqf
[object] => subscription_item
[billing_thresholds] =>
[created] => 1615717329
[metadata] => Stripe\StripeObject Object
(
)
[plan] => Stripe\Plan Object
(
[id] => price_1IJes9HEWYmoXN4GiFeNywqa
[object] => plan
[active] => 1
[aggregate_usage] =>
[amount] => 1200
[amount_decimal] => 1200
[billing_scheme] => per_unit
[created] => 1613048777
[currency] => eur
[interval] => month
[interval_count] => 1
[livemode] =>
[metadata] => Stripe\StripeObject Object
(
)
[nickname] =>
[product] => prod_IvVt5EemrpxKcf
[tiers_mode] =>
[transform_usage] =>
[trial_period_days] =>
[usage_type] => licensed
)
[price] => Stripe\Price Object
(
[id] => price_1IJes9HEWYmoXN4GiFeNywqa
[object] => price
[active] => 1
[billing_scheme] => per_unit
[created] => 1613048777
[currency] => eur
[livemode] =>
[lookup_key] =>
[metadata] => Stripe\StripeObject Object
(
)
[nickname] =>
[product] => prod_IvVt5EemrpxKcf
[recurring] => Stripe\StripeObject Object
(
[aggregate_usage] =>
[interval] => month
[interval_count] => 1
[trial_period_days] =>
[usage_type] => licensed
)
[tiers_mode] =>
[transform_quantity] =>
[type] => recurring
[unit_amount] => 1200
[unit_amount_decimal] => 1200
)
[quantity] => 1
[subscription] => sub_J75FZOObndggWX
[tax_rates] => Array
(
)
)
)
[has_more] =>
[total_count] => 1
[url] => /v1/subscription_items?subscription=sub_J75FZOObndggWX
)
[latest_invoice] => in_1IUr5JHEWYmoXN4GTmJ3pJUZ
[livemode] =>
[metadata] => Stripe\StripeObject Object
(
[myID] => 1
)
[next_pending_invoice_item_invoice] =>
[pause_collection] =>
[pending_invoice_item_interval] =>
[pending_setup_intent] =>
[pending_update] =>
[plan] => Stripe\Plan Object
(
[id] => price_1IJes9HEWYmoXN4GiFeNywqa
[object] => plan
[active] => 1
[aggregate_usage] =>
[amount] => 1200
[amount_decimal] => 1200
[billing_scheme] => per_unit
[created] => 1613048777
[currency] => eur
[interval] => month
[interval_count] => 1
[livemode] =>
[metadata] => Stripe\StripeObject Object
(
)
[nickname] =>
[product] => prod_IvVt5EemrpxKcf
[tiers_mode] =>
[transform_usage] =>
[trial_period_days] =>
[usage_type] => licensed
)
[quantity] => 1
[schedule] =>
[start_date] => 1615717329
[status] => active
[transfer_data] =>
[trial_end] =>
[trial_start] =>
)
```
Upvotes: 1
Views: 3145
Reputation: 1587
Have you disabled proration
? You have to specifically disable it:
https://stripe.com/docs/billing/subscriptions/prorations#preview-proration
proration_behavior (optional)
Determines how to handle prorations resulting from the billing_cycle_anchor. Valid values are create_prorations or none.
Passing create_prorations will cause proration invoice items to be created when applicable. Prorations can be disabled by passing none. If no value is passed, the default is create_prorations.
As to why the next invoice is $37.95 instead of $38, likely due to proration being prorated to seconds: https://stripe.com/docs/billing/subscriptions/prorations#preview-proration
You can use this information to confirm the changes with the customer before modifying the subscription. Because Stripe prorates to the second, prorated amounts can change between the time they’re previewed and the time the update is made. To avoid this, pass in a subscription_proration_date to the invoice when you preview a change. When you update the subscription, you can pass the same date using the proration_date parameter on a subscription so that the proration is calculated at the same time.
Upvotes: 2