#.crawl
1 messages Β· Page 1 of 1 (latest)
Hi π
It all depends on what you want to do.
Stripe triggers events for changes to Stripe objects
But some actions cause changes to multiple objects which is why you see the events coming together
On my side I just want to have the most basic business logic
recurring saas pricing monthly
user pay => we fulfil in our server
user stop paying => we stop fulfulling
but it seems like
payment_intent.succeeded invoice.paid customer.subscription.resumed
is a repetition causing us to have duplicate in fulfulment
Okay each event includes the object that was changed. So the payment_intent.succeeded includes the Payment Intent, the customer.subscription.resumed includes the Subsciption object
So you need to decide for your business logic, which object has the correct data to verify you are taking the right action
the thing is no matter what we receive we retreive what we need from stripe - but eventually we just need the invoice or the subscription
for exemple :
handlePaymentIntentSucceeded
const invoice = await stripe.invoices.retrieve(paymentIntent.invoice, { expand: ['lines.data.price.product'], });
handleSubcriptionResumed
stripe.subscriptions.retrieve(subscription.id, { expand: ['items.data.price.product'], });
handleInvoicePaid
we use the invoice.subscription
on my side, the goal is to have maybe only the few that are needed, and avoid repetition
Sure you can configure which events your webhook endpoint listens to
so you choose the event that has the data you need so you can make the fewest API calls and then trigger the actions you want
ok, and which one should I focus on ?
From what I understand we just need invoice.paid
but I'm wondering if someone is resuming his subscription we'll still receive invoice.paid ??
They would, once they pay the invoice. But if they are paused in the middle of a billing cycle and then resume you might not know. So including customer.subscription.resumed is a good idea as well
That is entirely up to you
because on our side, we dont really need this 'pause' feature
Wait, NVM
either you have an ongoing subscription , or you dont
Pause is something you can configure in response to a missed payment
correct
currently if a payment is missed more than 3 time, we delete subscription and cancel
So yes you would see the payment
so we are sure that the scenario where customer.subscription.resumed is useful is only when we allow the customer to keep the subscription even if payment are missed, like a grace period, and then the customer pay before cancelation of subscription \
but then if he pay, we receive a invoice.paid too
that's confusing
As I said, we are triggering events based on changes to your Stripe account. These enable a wide variety of use cases. You should review each event, understand why it would fire in your integration, and choose whether it is something that matters to you (listen to it) or not.
okok that make sense
resumed is something that's paused
but because we dont pause we dont need it
Correct. You can see a good description of it here: https://stripe.com/docs/api/subscriptions/resume
We also have a useful guide to the Subscription lifecycle here: https://stripe.com/docs/billing/subscriptions/overview
that might help you decide which events make the most sense to listen to
okok perfect
so
invoice.paid
customer.subscription.deleted
and customer.subscription.paused to be safe
just a quick q
@proud heath
does payement intent succeed being sent on the first payment ? or at every billing cycle ?
The invoice object uses a payment intent to collect funds so any time an invoice is paid you will see payment_intent.succeeded
If you need to know whether an invoice is for the first payment of a subscription or not, you can examine the billing_reason property: https://stripe.com/docs/api/invoices/object#invoice_object-billing_reason
ok perfect
and last question
invoice.paid is sent twice everytime, is there any reason for this ?
π hopping in here since snufkin has to head out - do you have an example event ID I can look at on my end where it's being sent twice?
event: invoice.paid evt_1Nj42dLM4GHVXwuAH0QgKx4b
event: invoice.paid evt_1Nj42fLM4GHVXwuA6t2IkKIk
another pair
event: invoice.paid evt_1Nj44RLM4GHVXwuAxYmRHWdN
event: invoice.paid evt_1Nj44VLM4GHVXwuAww6CL3sc
2023-08-25 13:45:20 --> invoice.paid [evt_1Nj44RLM4GHVXwuAxYmRHWdN]
2023-08-25 13:45:23 --> invoice.paid [evt_1Nj44VLM4GHVXwuAww6CL3sc]
Those invoices are actually from two completely separate subscriptions
not really
this is the same subscription that had a trial
I beleive this is because of this
if (user.hadTrial) {
// Remove the trial from the subscription
await stripe.subscriptions.update(invoice.subscription, {
trial_end: 'now',
});
so because the user already had a trial we cancel the trial and trigger a payment
Yeah let me back up here a mi nute
So the events you initially gave me were definitely from different subscriptions so I was a bit confused, but if I look at a specific subscription I see what you're talking about. Here are the ones from the screenshot you shared:
- $0 - in_1Nj44PLM4GHVXwuATdRTJMIC -> This one was created when your subscrpition was first created because it was trialing at the time
- $30 - in_1Nj44SLM4GHVXwuAzkRQUNoq -> Shortly after it was created you updated the subscription to immediately end the trial, which immediately triggers the invoice
Is there a reason you're creating your subscriptions with a trial if you immediately end the trial right after the subscription is created?
the trial is open to all
but we want to prevent the same customer to take a trial twice
like cancel then try again
the trial is set in the price
If this is what you want to keep doing then these two events for invoice.paid are expected and there isn't really a way around it
But if I were you, I'd change the integration to check for the same customer before allowing them to go through payment again
yup! you can configure this by settings/unsetting subscription_data.trial_period_days when you create the Checkout session
Do i set it to false or 0 ?
You can set it to 0 or just omit it entirely from your request
Error creating checkout session: StripeInvalidRequestError: The minimum number of trial period days is 1.
Ah sorry about that - I thought it would just ignore it if it was 0 π¦
Looks like you'll have to omit it entirely
Ah! I didn't realize you were also setting it on the price as well -yes, it'd probaby be safest to remove it from the price too
Okok now I understand why itβs legacy
Best is to manage this at invoice checkout creation
Yeah, it can get very confusing when it's configurable on the price/plan AND at subscription creation
ok sounds good