#mangle8582
1 messages · Page 1 of 1 (latest)
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.
- mangle8582, 32 minutes ago, 41 messages
- mangle8582, 8 hours ago, 20 messages
- mangle-subscription-previewchanges, 19 hours ago, 116 messages
- mangle-subscription-refund, 1 day ago, 92 messages
- mangle8582, 2 days ago, 77 messages
- mangle8582, 5 days ago, 36 messages
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
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?
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
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).
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?
If you cancel the schedule : https://stripe.com/docs/api/subscription_schedules/cancel it cancels the subscription immediately
If you cancel the subscription directly: https://stripe.com/docs/api/subscriptions/cancel that will cancel the schedule
Perfect
Now from_subscription is used only when a subscription is not inside a schedule right?
when you create a schedule
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
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
Yup, that is how it will behave
Thank you for helping!
Happy to shed what 💡 I can 🙂
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?
?
Yep, test clock customers are limited to 3 active subscriptions and 3 scheduled ones
oh, but a normal customer is not right?
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
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?
?
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
You can get it back as part of your finalize call by expanding payment_intent in your finalize call https://stripe.com/docs/api/expanding_objects
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
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
You should re-use the client secret from the first invoice, don't create more subscriptions or schedules
Intents are a state machine designed to handle multiple attempts at payment for something https://stripe.com/docs/payments/paymentintents/lifecycle
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?
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
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
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?
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
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.
Can you send me the request ID for that call? (req_123) I can look in to that as well
It will be in your logs if you don't have it on hand https://dashboard.stripe.com/test/logs
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.
req_napcI1zI4SOUn1
It seems i'm taking the payment_intent and trying to update the subscription with it, with await stripe.subscriptions.update
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
But before it was attaching automatically, i wasn't calling any attach
Oh I do see that before that you confirmed an intent from a subscription from a schedule https://dashboard.stripe.com/test/logs/req_PBhZb8WizDcE6t
Not sure why that did not attach. Looking in to it
Apologies, still looking in to the subscription and the request
Sure
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
It messes up a bit for beeing active
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
if the invoice is paid it Subscription should be active right?
Subscription won't be active if the invoice is open i hope right?
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
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.
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
Where can i handle this? on the webhook directly? on invoice.paid?
I think it would be on the invoice.created webook. Consulting my colleagues to confirm that makes sense as a workaround
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.
So it looks like you can wait for invoice.finalized and can then make an update payment intent call to set setup_future_usage: offline on the payment intent https://stripe.com/docs/api/payment_intents/update#update_payment_intent-setup_future_usage
Can you send me the ID of that charge succeeded event?
sure
Is it possible that the customer already has a valid payment method saved to them?
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
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
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
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
yes
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
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"
setup_future_usage: offline as quoted from your message
HI 👋
I'm stepping in as @sudden wedge needs to go.
Can you share the request ID for the API request that returned that error? It will start with req_
Here's how you can find a request ID: https://support.stripe.com/questions/finding-the-id-for-an-api-request
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.
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
@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
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
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
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
Did you do what I recommend and try to use Test Clocks? If not, please pause and try this on your own first
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
I'm sorry, none of this makes any sense
Give me a concrete example so that we look at the same thing
Sure
- I buy Monthly, I pay 5.99$.
- 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.
- I Upgrade after 16 days to Yearly, i will pay like 57$ for that upgrade right?
- 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.
- 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.
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
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
that doesn't really make sense
Why would they "trigger a refund"? They cancel their subscription right? The refund is a side effect
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
I'm really sorry but all of this is so unclear
Showing the user how much money he can get back if he refunds and cancel the subscription is unclear?
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?
- Modal Opens
- GET call to invoicesUpcoming
- Loader finishes, i show the refund amount on UI
- User looks at the amount he then presses the refund button
- 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',
}
);
okay now I get it. So what's the problem?
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
okay now share an exact invoice id so that I can look
Give me 1-2 minutes to reproduce this please
yep no problem
req_9AZskmKhdmiHCw
5.99$ pi_3ODEFFDmVlmqORBI1FLZDogd
54.00$ pi_3ODEFPDmVlmqORBI0RrW1gZ1
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
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
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
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
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.
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
the user paid $54 AND $5.99
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
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
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.
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.
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$.
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?
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$
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
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
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
req_zIuBukMYnbn93S
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
Yea, so conclusion is to refund both Monthly and Yearly payment intents?
When he refunds?
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
- Cancel Subscription
- Look at resulting balance on the Invoice
- Look at most recently paid Invoice, look at the amount paid, refund MIN(balance, invoice amount)
- Continue looping over invoices until you have refunded the full balance.
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.
- this is done
- balance on invoice is 59.99$ after you upgraded with 54.00$
- recently paid invoice is 54.00$, i need to prorate because user used the app
- 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.
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
Sure. Thanks @cunning narwhal for your time and understanding