#mangle8582

1 messages · Page 1 of 1 (latest)

ivory steppeBOT
#

Hello! We'll be with you shortly. Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.

plush chasm
#

Hi 👋

For Subscription Schedules, you would apply the coupon to the phase

#

In the Dashboard, subscription schedules are in the Subscription section and also linked to Customer.

#

They aren't represented in a different way

stray glen
#

I've looked for them, coudn't find them

#

What happens when i have a schedule, but i remove the subscription? The Schedule will remove as well?

plush chasm
#

That doesn't make sense to me

#

What are you trying to do here?

stray glen
#

Well create Monthly or Yealy Subscriptions using Stripe Schedules

#

Ability to update subscription with Stripe Schedules to cancel on period end

#

Remove Subscription for good

#

Refund and Remove Subscription

#

Upgrade to yearly while having Monthly, but Yearly should start on the end of the Monthly subscription end time

plush chasm
#

These words are not complete sentences and don't fit together into a flow. But when a Schedule ends, such as setting a Schedule to cancel the susbcription on period end, the schedule also is removed (since it has nothing to schedule).

stray glen
#

I'm saying about the fact that i just cancel the subscription

#

What happens to Stripe Schedule?

#

Is it canceled as well?

#

Or now i cancel the subscription by deleting the schedule?

plush chasm
stray glen
#

Perfect

#

Now from_subscription is used only when a subscription is not inside a schedule right?

#

when you create a schedule

plush chasm
#

That is if you want to create a Schedule from an existing subscription

#

If the subscription does not exist yet, creating the Schedule will create the subscription too

stray glen
#

Nice, then after i create the Monthly with Stripe Schedule, and if they upgrade to Yearly, i will just update the Schedule with a new phase item right? That starts on the end of the current active subscription

plush chasm
#

Yup, that is how it will behave

stray glen
#

Thank you for helping!

plush chasm
#

Happy to shed what 💡 I can 🙂

stray glen
#

Oh

#

Test clock customer cus_OwiXXKWfKcmlBm already has the maximum 3 current and scheduled subscriptions.

#

One small error here

#

Before i was creating subscriptions, and passing the clientSecret to frontend to pay, and if user didn't had money or something, that subscription will become incomplete in 1 day i suppose

#

Now i have a limit of schedules?

ivory steppeBOT
stray glen
#

?

sudden wedge
#

Yep, test clock customers are limited to 3 active subscriptions and 3 scheduled ones

stray glen
#

oh, but a normal customer is not right?

sudden wedge
#

Correct, I don't think there is a limit on how many subscriptions they can have but I will have to double check

#

If they do have a limit it is definitely higher than 3

stray glen
#

Please take a look at this implementation of creating a Subscription Monthly with Stripe Schedules.

In neither of those responses i get clientSecret so i can send it back to frontend. So i can pass it to Stripe Client so it can pay with clientSecret with await stripe.confirmCardPayment

const subscriptionSchedule = await stripe.subscriptionSchedules.create({
customer: customerId,
start_date: 'now',
end_behavior: 'release',
phases: [
{
items: [{
price: priceId,
}],
},
],
});

  const createdSubscription = await stripe.subscriptions.retrieve(subscriptionSchedule?.subscription);

  const nextInvoice = await stripe.invoices.finalizeInvoice(
    createdSubscription?.latest_invoice
  );
#

You still here?

#

?

sudden wedge
#

Yes apologies, the server is a bit busy

#

Also the live limit for subscriptions is 500 per customer

#

looking at your code

#

After the invoice is finalized it should have a payment_intent property and that payment intent will have a client secret

stray glen
#

nice, also, why it's creating an active subscription when creating a schedule if the invoice isn't paid?

#

If the user gets wrong something on client side in Stripe elements and tries to pay 3 times, it creates 3 active subscriptions

#

that will have next invoices

sudden wedge
#

You should re-use the client secret from the first invoice, don't create more subscriptions or schedules

#

Good question about why it is active. If there is a payment upfront the subscription should be incomplete as far as I know

#

Can you send me the ID of that subscription?

stray glen
#

sub_1ODC0YDmVlmqORBIS5Sic8BS

#

Is there another way to not reuse that? I'm not sure how and where to store the clientSecret for multiple reuse. And how much time? When it does expire?

#

On the previous implementation i was creating the subscription and in 1 day was becoming incomplete, but was not active by any means

#

in_1ODBW1DmVlmqORBIjGGux6Cs

This is the invoice id for the invoice that is not paid yet

sudden wedge
#

It would be valid for 24 hours before the subscription moved from incomplete to expired_incomplete

#

And you don't need to store it for 24 hours like that but definitely re-use the secret when it is a user in a single session trying to pay you

stray glen
#

Yea, i could store it on frontend while customer is there paying and not making the call again

#

But why is it active the subscription if invoice is not paid?

sudden wedge
#

It looks like the invoice was paid prety much immediately but it looks like the subscription started as active before that

#

Figuring it out and will get back to you

stray glen
#

Sure, thanks

#

Also i receive this error.

The customer does not have a payment method with the ID pm_1ODCI2DmVlmqORBInAC8lfpK. The payment method must be attached to the customer.

sudden wedge
#

Can you send me the request ID for that call? (req_123) I can look in to that as well

#

I am forgetting something about how that active subscription is working. Will ask my colleagues and get back to you with what I can find.

stray glen
#

req_napcI1zI4SOUn1

#

It seems i'm taking the payment_intent and trying to update the subscription with it, with await stripe.subscriptions.update

sudden wedge
#

So that req_napcI1zI4SOUn1 error is exactly what it says. Before you make that call to create the subscription with pm_1ODCI2DmVlmqORBInAC8lfpK as the default payment method, you need to attach it to a customer https://stripe.com/docs/api/payment_methods/attach

stray glen
#

But before it was attaching automatically, i wasn't calling any attach

sudden wedge
#

Not sure why that did not attach. Looking in to it

sudden wedge
#

Apologies, still looking in to the subscription and the request

stray glen
#

Sure

sudden wedge
#

I think the subscription status is a result of how charge_automatically subscriptions work with subscription schedules:

Unlike when you create a subscription directly, the first invoice of a subscription schedule with collection_method set to charge_automatically behaves like a recurring invoice and isn’t immediately finalized at the time the schedule’s subscription is created. The invoice begins in a draft status and is finalized by Stripe about 1 hour after creation.

This means that, for example, creating a charge-automatically subscription schedule with start_date=now also creates a subscription and an invoice in the draft status. This gives you a 1-hour window to make edits to the invoice. Later, the invoice is auto-advanced into the open or paid status depending on the outcome of the asynchronous payment attempt at finalization time.
https://stripe.com/docs/billing/subscriptions/subscription-schedules#managing

#

Basically while the initial invoice is in a draft state, the subscription is expected to be in an active state, but I think once that invoice was finalized it should have moved to an incomplete state

stray glen
#

It messes up a bit for beeing active

sudden wedge
#

How so?

#

It is looking like that is expected behavior

stray glen
#

Because if user is putting wrong a card

#

It creates the Subscription and activates it

sudden wedge
#

In that case you may want to also check the status of the first invoice and make sure that it is paid before provisioning access to your subscription content

stray glen
#

if the invoice is paid it Subscription should be active right?

#

Subscription won't be active if the invoice is open i hope right?

sudden wedge
#

Not when it is open though unfortunately the server has been a bit too busy for me to test

#

Would you be able to create a subscription with a schedule on a test clock, advance time by 1 hour so that the invoice finalizes, and then check your subscription's status? I think it should go to incomplete

stray glen
#

without finalizeInvoice?

#

I'm still blocked by this.

The customer does not have a payment method with the ID pm_1ODD7ADmVlmqORBITERvAMee. The payment method must be attached to the customer.

sudden wedge
#

Yes, without finalize invoice.

#

The payment method error looks to be a bug that we are looking to address. Basically if you already have a default payment method on the Customer, invoices created for that customer won't have setup_future_usage set to true on them when they are created

#

I think the workaround is to set setup_future_usage to true manually after the invoice has been created

stray glen
#

Where can i handle this? on the webhook directly? on invoice.paid?

sudden wedge
#

I think it would be on the invoice.created webook. Consulting my colleagues to confirm that makes sense as a workaround

stray glen
#

Sure, thanks

#

Something very stange is happening.

I've added the wrong card, it made a request, it created the subscription and it's active, the invoice was open, and then after I advanced the clock, I receive charge succeeded.

sudden wedge
#

Can you send me the ID of that charge succeeded event?

stray glen
#

sure

sudden wedge
#

Is it possible that the customer already has a valid payment method saved to them?

stray glen
#

It has yes, but it shoudn't invoice them if they tried to add another card right? Maybe they added a wrong card and then left, and then they will be charged? It will be a dispute

#

in_1ODDJjDmVlmqORBI5dhZIvQM

#

req_ANgnPdjYP4bdcr

sudden wedge
#

If you have a card saved to the customer and the subscription's collection_method is set to charge_automatically, we will attempt to charge that default payment method as soon as the invoice finalizes

stray glen
#

Yea but it's weird, payment didn't succeed the first time the client tried to create a subscription, it should only charge if it succeeds with the card they introduce

sudden wedge
#

If they still have a valid card as their default payment method, it is expected that it will be charged for any subscription that does not have a default payment method set on it

#

So it actually sounds like you want to set these payment methods as the default for the subscription not the customer

stray glen
#

Invalid setup_future_usage: must be one of on_session or off_session for customerId: cus_OwiXXKWfKcmlBm with priceId: price_1NuGOSDmVlmqORBIFPO0AcjN'

setup_future_usage can be only on_session and off_session

sudden wedge
#

Do you know what value you passed in instead? As the error says, you should only be setting that param to either "on_session" or "off_session"

stray glen
plush chasm
stray glen
#

Hello, sure

#

req_aiOzcGjvZ7rQkO

plush chasm
#

Thanks, looking

#

Okay so the correct value to pass in that instance is off_session, since you likely mean the customer will not be directly interfacing with your UI when you later charge the payment method.

stray glen
#

Now it works, it creates the subscription with stripe schedules

#

But the issue remains when you make request that fails and it creates the subscription but it's active

#

This is the whole flow when user hit pay.
The subscription schedule creates and then i send the clientSecret back to frontend, but then if stripe client says card invalid, the subscription is created and unfortunately it's active

const subscriptionSchedule = await stripe.subscriptionSchedules.create({
customer: customerId,
start_date: 'now',
end_behavior: 'release',
phases: [
{
items: [{
price: priceId,
}],
},
],
});

  const createdSubscription = await stripe.subscriptions.retrieve(subscriptionSchedule?.subscription);
  const nextInvoice = await stripe.invoices.finalizeInvoice(
    createdSubscription?.latest_invoice,
    {
      expand: ['payment_intent']
    }
  );

 await stripe.paymentIntents.update(
    nextInvoice?.payment_intent?.id,
    {
      setup_future_usage: 'off_session'
    }
  );
#

Before using Stripe Schedules, i was creating subscriptions but they were pending and becoming incomplete after 1 day

#

In case the user did not add the card correctly or he did not have money on card etc

cunning narwhal
#

@stray glen SubscriptionSchedules don't really work that way. I assume you're back trying to do the exact same thing we spent hours on yesterday? If so Schedules are mostly a bad fit for your usecase

stray glen
#

Hi @cunning narwhal . Sorry to bother again. Yea, i just want to start Yearly after Monthly with no prorations or anything. And it seems pretty hard

cunning narwhal
#

It's not hard, but it doesn't really make sense

#

you're deferring the yearly payment to the end of the month, you're going to get a huge increase in payment failure and lost revenue when you should make the change right now and guarantee they paid.

#

I'm sorry but I seeyou've been here for almost 3 more full hours on the same exact discussion

#

You have to pick between what I recommended or just doing the entire proration yourself. Everything else is just going to be a worse experience for you and your customers

stray glen
#

True, the thing is that i'm still confused about that proration thing. I really want to rollback this Stripe Schedule and do what you say, but if you can take 1-2 mins and explain to me again how can i handle that proration, i would appreciate it a lot, i'm like 90% finished with this

cunning narwhal
#

Did you do what I recommend and try to use Test Clocks? If not, please pause and try this on your own first

stray glen
#

I'm using TestClocks yes. But i'm confused about what it should be done.

If user upgrades to Yearly and it's prorated it's 54.00$, from 59.99$. When i try to refund him prorated, and create a refund, i can only create a refund for 54$. But the invoice is telling me it's 59.99$ dollars and getting lower by the time i advance time with test clock

cunning narwhal
#

I'm sorry, none of this makes any sense

#

Give me a concrete example so that we look at the same thing

stray glen
#

Sure

#
  1. I buy Monthly, I pay 5.99$.
  2. By law I need to offer users the ability to refund for 14 days, but if they want to refund, i will need to charge them for how much they used my app in 14 days. This functionality is done and working correctly on Monthly only.
  3. I Upgrade after 16 days to Yearly, i will pay like 57$ for that upgrade right?
  4. Then on Refund, i need to make a call to invoiceUpcoming and show the user on UI the amount of refund he will get by refunding that Yearly after 1 day let's say. And also create a refund for it.
  5. Not sure how can i handle that prorated refund to not lose money. Because stripe.invoiceProrated is showing me from 59.99$ not from 57$ that i've upgraded and even if i want to refund him 59.99$ it will throw error from Stripe telling me that i cannot refund him more than the last charge.
cunning narwhal
#

I remember all of this sorry. I am asking about a real example in your Stripe account so that we talk about the exact same thing

#

Then on Refund, i need to make a call to invoiceUpcoming and show the user on UI the amount of refund he will get by refunding that Yearly after 1 day let's say. And also create a refund for it.
no I explained this in details. You can use that API to preview the refund. Not to create it. The Refund creation happens after you make the Subscription update when you have a Customer credit balance

stray glen
#

Yea i'm using it to preview the refund. and show it to user, the user has another button to refund that will trigger stripe.refund.create

cunning narwhal
#

that doesn't really make sense

#

Why would they "trigger a refund"? They cancel their subscription right? The refund is a side effect

stray glen
#

You hit a Refund button, it opens a modal, it makes the GET call to invoiceUpcoming to show the user the amount of money he will get back on refund, the subscription is canceled yes

#

On that Modal after the loader is finished, user will see a Refund button

cunning narwhal
#

I'm really sorry but all of this is so unclear

stray glen
#

Showing the user how much money he can get back if he refunds and cancel the subscription is unclear?

cunning narwhal
#

No, just the way you frame the overall flow. I'm really struggling to follow your train of thoughts unfortunately.

#

You hit a Refund button, it opens a modal, it makes the GET call to invoiceUpcoming to show the user the amount of money he will get back on refund, the subscription is canceled yes
like that last bit, what does that mean? When is it canceled? Before the GET call? After?

stray glen
#
  1. Modal Opens
  2. GET call to invoicesUpcoming
  3. Loader finishes, i show the refund amount on UI
  4. User looks at the amount he then presses the refund button
  5. Refund button triggers the canceling of subscription and refunding afterwards with

const deletedSubscriptionFromStripe = await stripe.subscriptions.cancel(
subscriptionId,
{
invoice_now: true,
prorate: true
}
);

const nextInvoice = await stripe.invoices.finalizeInvoice(
deletedSubscriptionFromStripe?.latest_invoice
);

const refund = await stripe.refunds.create({
payment_intent: subscriptionToDeleteAndRefund?.payment_intent,
amount: nextInvoice.ending_balance ? Math.abs(nextInvoice.ending_balance) : 0,
});

await stripe.customers.createBalanceTransaction(
subscriptionToDeleteAndRefund?.dataValues?.customer_id,
{
amount: -nextInvoice.ending_balance,
currency: 'usd',
}
);

cunning narwhal
#

okay now I get it. So what's the problem?

stray glen
#

On Monthly it works perfectly

#

On Yearly..

#

when i finalize invoice, i get 59.99$ instead of prorated amount, let's say 57$ if i upgraded at the middle of the Monthly subscription

cunning narwhal
#

okay now share an exact invoice id so that I can look

stray glen
#

Give me 1-2 minutes to reproduce this please

cunning narwhal
#

yep no problem

stray glen
#

req_9AZskmKhdmiHCw

#

5.99$ pi_3ODEFFDmVlmqORBI1FLZDogd
54.00$ pi_3ODEFPDmVlmqORBI0RrW1gZ1

cunning narwhal
#

okay so it's literally the same thing as yesterday 😦

#

Error message: Refund amount ($59.99) is greater than charge amount ($54.00)

You are refunding $59.99. Your PaymentIntent is for $54. You can not refund more than the amount of the PaymentIntent.

#

You have to refund both PaymentIntents separately. I'm really sorry but I told you this 3 separate times over 2 hours yesterday

stray glen
#

I know you did, but i'm still confused about the handling of this.

If i'm doing prorated refunding, and i'm getting 59.99$ on the invoiceUpcoming and i have the last charge of 54.00$ and the user is past due on 14 days refund on the Monthly, it's a case in the middle that is not good

#

I can't refund him Monthly anymore, i can only refund him from 54.00$

#

and if i'm getting 59.99$ from invoiceUpcoming what can i do

cunning narwhal
#

nothing is in the middle. you never used your TestClock to advance time, it's all at the same first second

#

the upcoming Invoice is entirely irrelevant we also discussed this

#
          payment_intent: subscriptionToDeleteAndRefund?.payment_intent,
          amount: nextInvoice.ending_balance ? Math.abs(nextInvoice.ending_balance) : 0,
        });``` even your own code knows that. This isn't the **upcoming Invoice**. This is the Invoice that was created during the monthly to yearly upgrade
stray glen
#

But the user will still use the app and i need to prorate him and show him on UI the money he will get for refund, money that will decrease while he usees the app

cunning narwhal
#

Yeah I get your confusion I'm just not sure how to lift it, your understanding of the steps doesn't match the code you wrote

#

The upcoming Invoice is not relevant anymore at this point. The upgrade happened, the Invoice with proration happened.

stray glen
#

Correct, it happaned, so user paid 54.00$ right? He has 14 days to refund this 54.00$, and if he uses the server i need to give him 52 dollars if 10 days pass after upgrade

#

If he refunds

cunning narwhal
#

the user paid $54 AND $5.99

stray glen
#

for 5.99$ 14 days have passed, he lost by law the ability to refund that. He already used the servers for 15 days

#

I cannot refund him even prorated

#

only 54$ dollars remain

cunning narwhal
#

lol

#

I'm really sorry I don't know what to do I have explained this so many times

#

Just yesterday ```[3:57 PM]koopajah: I'm really sorry @Mangle but we're really running in circles at this point
[3:57 PM]koopajah: You did not pay $54. You paid $59.99 across two separate Invoices seconds apart
[3:58 PM]koopajah: 00:00 UTC I pay $5.99
00:01 UTC I realize I should have subscribed to the yearly Price, I upgrade and pay $54
01:00 UTC Irealize my partner paid already so I change my mind and cancel

I should get the full amount back it's been barely an hour```

#

you unfortunately are really so set on your own way of calculations and you refuse to hear what I am saying

stray glen
#

No @cunning narwhal , i understand what you are saying.

I understand the user paid two seperate invoices and he paid 59.99$.
The important thing is WHEN he paid.
Because if 14 days have passed since his first invoice of 5.99$, the law gives me the ability to hide him the button for refund and not give him his money back for Monthly.
Because if he upgrades to Yearly and he has the ability to get the money back from Monthly, then that button and the functionality is useless.

Please think of it as a timeline and when i can deny him the refund by law.

cunning narwhal
#

First none of what you are doing simulates 14 days. You never changed the TestClock. It's all the same day.
Second, I explained your way is impossible.

stray glen
#

Please tell me your conclusions, how much would you refund the customer if he upgrades to Yearly almost at the end of the Monthly with 57$.

cunning narwhal
#

Conceptually, what you want is reasonable. We just do not support this at all.
Personally, I completely disagree with your take and your read of the "rules" and what is reasonable as a business. It's like splitting hair trying to save $3 from the previous month in case someone abuses the system. We also discussed this at length yesterday over and over and over

#

if he upgrades to Yearly almost at the end of the Monthly with 57$.
I'm sorry I have no idea what those words mean. What does "with 57$" mean?

stray glen
#

57$ meaning prorated Upgrade to Yearly

#

5.99$ Monthly
54.00$ Yearly

He upgrades with 10 days before the ending of Monthly, it's aprox 57$

cunning narwhal
#

I worry you're not understanding TestClocks at all. You can simulate all of this in seconds. That's the whole point of the feature: to simulate time passing
Just try it. Create a Subscription, advance by 16 days and then upgrade

#
54.00$ Yearly```
I thought your yearly was $59.99
stray glen
#

Yearly is 59.99$, but default way on upgrade is to prorate right, and user is charged with 54$ is he already has a 5.99$ Monthly

#

pi_3ODEYqDmVlmqORBI1GwLPOjn

Look at this payment intent

#

55.55$

#

Prorated Upgrade, i've used Test Clock

cunning narwhal
#

I fully understand the situation. I just don't get what you don't understand. Your way is impossible. I don't get why you don't want to hear this

#

Also: please try to focus on Invoices when doing this work not PaymentIntent. The Invoice has the full information about what is being billed, that's what you use to make sense of things

stray glen
#

req_zIuBukMYnbn93S

cunning narwhal
#

this is a random request id for a GET request that has no info

#

@stray glen I'm really sorry, at this point we need to stop. It's been 10+ hours of back and forth saying the exact same thing. This is clearly not working

stray glen
#

Yea, so conclusion is to refund both Monthly and Yearly payment intents?

#

When he refunds?

cunning narwhal
#
Refund $54
Do $59.97 - $54 => $4.97 left
Find the previous Invoice and refund
[4:06 PM]koopajah: It's unfortunately crucial that you take the time to understand the overall products, the objects involved at each step, etc. Here you had 2 separate Invoices, each with their own PaymentIntent and successful Charge separately and you have to handle that in your Refund logic
[4:06 PM]koopajah: It can get even more complex if discounts or multiple sequential upgrade/downgrade are involved```
#

what I explained in details yesterday

#
  1. Cancel Subscription
  2. Look at resulting balance on the Invoice
  3. Look at most recently paid Invoice, look at the amount paid, refund MIN(balance, invoice amount)
  4. Continue looping over invoices until you have refunded the full balance.
stray glen
#

It's easier to just remove Upgrading functionality and he can cancel subscription and buy Yearly afterwards.
In this way it works on both Monthly and Yearly, if they buy the subscription, the invoice prorated starts from 59.99$ or 5.99$ and i can refund him for 14 days based on how much they used the product.

  1. this is done
  2. balance on invoice is 59.99$ after you upgraded with 54.00$
  3. recently paid invoice is 54.00$, i need to prorate because user used the app
  4. he cannot get money back for monthly

Refunding him based on how much he used the app is default behavior, otherwise users will never pay the product, they will make accounts and pay and then refund on 13th day and you lost money, stripe fee and servers were used.

I thought this was easier to implement. Thank you for your time and help @cunning narwhal . Really appreciate it.

cunning narwhal
#

Sounds good. I would ask that you make sure to work with our spport team moving forward @stray glen. I'm sorry but this is not really suitable for Discord at this point and isnt really scalable while helping others. Just reading through the other threads I see it was the same questions over and over. So please moving forward work directly with 1:1 support on https://support.stripe.com/contact as they will be better equipped to help you and keep context on what you are doing

stray glen
#

Sure. Thanks @cunning narwhal for your time and understanding