#albion_code

1 messages · Page 1 of 1 (latest)

ornate finchBOT
#

👋 Welcome to your new thread!

⏲️ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.

⏱️ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.

🔗 This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1349984616471330826

📝 Have more to share? Add more details, code, screenshots, videos, etc. below.

fluid stump
pliant burrow
#

Understood, I appreciate the prompt reply

fluid stump
#

No problem. Can you decribe the behaviour that you wish to achieve, so that I can design a solution for you?

pliant burrow
#

I just added yearly pricing, and I have a lot of customers on monthly plan that would like to switch to a yearly plan.

Ideally, I think the customers would want the price of the monthly plan subtracted from the yearly price and have their subscription 'extended' to a year.

example:

  • Customer is on a $10 monthly plan that let's say started Jan 1st
  • Halfway through the month, they want to switch to $96 yearly plan
  • They get redirected to a checkout session for $86
  • They subscription is switched to annual pricing but the billing_cycle_anchor stays on Jan 1

In this example, the customer ends up with the same result as if they had just subscribed to the yearly price on Jan 1st to begin with.

It is to my understanding that this is not possible for a few reasons

  1. As you mentioned, the customer gets invoiced automatically when the billing period changes
  2. When you switch billing periods, you cannot retain that billing cycle anchor

Because Stripe always invoices on billing period changes, it seems like I have to rely on this automatic billing to collect payment instead of my custom flow of redirecting them to a checkout session and then handling the update in the webhook. In that case I either set proration_behavior to "create_prorations" or "none".

#

The issue with prorations is that they are time based and my service is credit based and users receive the entire credit amount up front (as soon as the subscription starts). Therefore this can be abused.

A simple example is let's say tier 1 is $10 and you get 8,000 credits and tier 2 is $25 and you get 30,000 credits. With prorations enabled, the user can buy tier 1, and then on the last day of their subscription, update for a very small price and get an additional 22,000.

Similarly, monthly -> yearly upgrades can also be abused. For example, the user can subscribe to the $10 monthly plan and then instantly upgrade to the $96 yearly plan. Stripe will only charge $86 because the value of that subscription based on time is $10 (it just started). But, the user effectively got 8,000 credits for free since they paid $96 total for a yearly subscription and also got their credits when they first subscribed to the monthly plan.

But then the alternative is to have "proration_behavior": "none" which would just charge the full amount but this isn't great either because although the main product is credit based, there are other products that have a monthly limit so the user may be upset that they paid $10 for a month and now that month is getting cut short. Also, could possibly be upset that they have to pay the full yearly price after having already paid for a month and they would have wanted to just pay yearly to begin with.

fluid stump
#

Ok so basically you want your customer to pay only $86 for the first invoice, what happen if they continue the subscription in the 2nd year, will it be $96 or $86?

pliant burrow
#

$96

Tier 1 Pricing is
Monthly: $10
Yearly: $96

So ideal situation would be

  • Jan 1 2025: Subscribe monthly, $10
  • Jan 14 2025: Switch to yearly, pay $86
  • Jan 1 2026: Yearly sub recurs, pay $96
#

Not sure if this is possible though, when you switch from monthly to yearly, doesn't it always create a new billing cycle at that time, meaning when you switch to yearly you can't say that the yearly plan 'started' earlier. Or in other words, 'extend' the monthly plan into yearly.

fluid stump
#

The billing_cycle_anchor will be reset when you change the billing interval. A workaround will be cancle the monthly subscription, and create a annual subscription with backdate_start_date set to 1 Jan 2025

#

You can apply a coupon to the annual subscription so that you customer only need to pay $86 for the first invoice

pliant burrow
#

Interesting, that's a great suggestion actually I might go with this. I think I would want to also include my 'custom' checkout flow because that is what my users are used too plus it gives them a chance to review the payment amount and add whatever payment method they want. So the end to end flow would be

  1. User starts on a monthly plan
  2. They want to switch or upgrade to a yearly plan
  3. Create a checkout session with the calculated price
  4. In my webhook, get the user's subscription and the start date of the subscription.
  5. Cancel this subscription
  6. Create a new subscription with the yearly priceId

Is this a good implementation?

And for step 6, I would need to make it so that the user does not get charged when I create that subscription since they were already charged in the checkout session. Is there a way to set it so that it doesn't charge or do I need to add a discount/coupon?

fluid stump
#

pass proration_behavior: 'none' when you create the subscription, and your customer won't be charged for the backdated period

pliant burrow
#

Thank you for the guidance!
I just tested this code here, and it is still charging the full amount and the backdate isn't working (the subscription period is starting when it gets created). Do you know what is wrong?

      const subscription = (
        await stripe.subscriptions.list({
          customer: user.customerId,
        })
      ).data[0];

      await stripe.subscriptions.cancel(subscription.id);
      await stripe.subscriptions.create({
        customer: user.customerId,
        items: [
          { price: PLANS[subscriptionId][billingInterval].priceId[stripeEnv] },
        ],
        proration_behavior: "none",
        backdate_start_date: subscription.start_date,
        default_payment_method: subscription.default_payment_method,
      });
fluid stump
#

What's the subscription ID?

pliant burrow
#

This is all in test mode

customer id:
cus_RwLNrgNONfQNTB

subscription id monthly (the cancelled one):
sub_1R2SgVGKtlMNJUno20KpoytN

subscription id yearly:
sub_1R2SlzGKtlMNJUnoBCrQqAHe

fluid stump
#

Can you tell me the behaviour that you expect?

pliant burrow
#

Yeah, I want to the yearly subscription to ‘start’ when that monthly subscription started so it’s like we are ‘extending’ the monthly subscription into a yearly one.

fluid stump
#

If your example, you create and change the subscription on the same day. Perhaps you want to advance the test clock and change the subscription a few days later?

ornate finchBOT
pliant burrow
#

I just tried advancing and running it again, and I'm getting the same behavior. It is both charging for the full amount, and the period is not starting on the backdate

woeful walrus
#

Hey! Taking over for my colleague. Let me catch up.

#

Sorry, I'm not sure I understand the latest issue you are facing, could you please summarize the latest follow up questino ?

pliant burrow
#

yes, i am trying to create a new subscription but i want to make its start time in the past so that its as if it also started at a previous date, and i also dont want to charge the customer

woeful walrus
#

There'll be no invoice generated untill reaching the billing cycle anchor