#gagan-invoice-calculation
1 messages · Page 1 of 1 (latest)
sure!
i have a couple questions regarding subscriptions in pringtables
how do i get the subscription's price inside the webhook?
this is what github copilot gave me:
case 'payment_intent.succeeded': const paymentIntent = event.data.object const clientReferenceId = paymentIntent.client_reference_id const subscriptionId = paymentIntent.subscription const subscription = await stripe.subscriptions.retrieve(subscriptionId)
Is payment_intent.succeeded the event you're listening to?
And you need the price id? or just the amount?
You can just get that directly off the payment intent: https://stripe.com/docs/api/payment_intents/object#payment_intent_object-amount
what is a better way to check for that?
is there a way i can get the name of the product?
Recommend listening to invoice.paid. That will have more of the data you're looking for
You can get product id from the invoice object lines.data[0].price.product
Then retrieve the product to get its name: https://stripe.com/docs/api/products/retrieve
But for future reference, you can look at our api spec for each object to see what data you can get back for webhook events. Here's what will be in the invoice object, which you get in an invoice.paid event: https://stripe.com/docs/api/invoices/object
That lines param on the invoice object is an Invoice Line Item, which you can see here: https://stripe.com/docs/api/invoices/line_item
how do i change the api version?
Mage
2019-11-05
because i see this on some of the docs:
Changes since API version 2019-11-05
nice got it upgraded
Did you read the doc though
Uprading the api version can cause side effects, so you need to make sure it won't effect your existing code
i just started using it again so everything is new
i see the price object:
"price": {
"id": "price_1NbLnv2eZvKYlo2CoXJoAaOy",
"object": "price",
"active": true,
"billing_scheme": "per_unit",
"created": 1691147063,
"currency": "usd",
"custom_unit_amount": null,
"livemode": false,
"lookup_key": null,
"metadata": {},
"nickname": null,
"product": "prod_OO848NiJ42ipeS",
"recurring": null,
"tax_behavior": "unspecified",
"tiers_mode": null,
"transform_quantity": null,
"type": "one_time",
"unit_amount": 299,
"unit_amount_decimal": "299"
},
where is the name of the product
I explained how to get that above
Then retrieve the product to get its name: https://stripe.com/docs/api/products/retrieve```
ah got it. i need to make a stripe network call to it
const product = await stripe.products.retrieve(
'product id'
);
i see this in the webhooks docs:
invoice.paid Sent when the invoice is successfully paid. You can provision access to your product when you receive this event and the subscription status is active.
its wise to also check if the subscription status is active, correct?
and thats going to be available on the invoice object?
Yes that's correct
No you'll need to retrieve the subscription to check its status
You can get the subscription id from the invoice though
I dont see subscriptionId but i see lines.data[0].subscription on the invoice object.
will that have the status?
im referring to this
do i even need to do a stripe network call to subscription object if this subcription is here?
Ah yeah
subscription is expandable. You can see that called out here: https://stripe.com/docs/api/invoices/object#invoice_object-subscription
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
That means you'll need to retrieve the invoice and expand that field
You can read more about expansion here; https://stripe.com/docs/expand
interesting
in my case, how do i expand the paymentIntent to include the subscription?
case 'invoice.paid': paymentIntent = event.data.object clientReferenceId = paymentIntent.client_reference_id const productId = paymentIntent.lines.data[0].price.product const product = await stripe.products.retrieve(productId) const status = paymentIntent.lines.data[0].subscription.status const planTier = product.name === 'Affiliate' && status === 'active' ? 1 : 0 await createPlanHelper(request, db, clientReferenceId, planTier) break
It's not a payment intent if the event type is invoice.paid
It's an invoice
So main thing there is to change your variable name
Setting it as paymentintent doesn't make sense
But to expand you need to retrieve the invoice and expand the subscription
See the link I sent you already: https://stripe.com/docs/expand
since we need to expand the subscription, and invoice is already an object inside webhook.
"To access nested values in expandable properties, you must retrieve the object in a separate call within your webhook handler"
Does this mean i need to retrieve invoice using stripe network call and invoiceId and then expand that with the subscription?
That's correct yeah
Unfortunately you'll need to make an additional api call because we don't autoexpand params in webhook events
ok ill give it a shot
case 'invoice.paid': const invoiceId = event.data.object.id const invoice = await stripe.invoice.retrieves(invoiceId, { expand: ['subscription'] }) clientReferenceId = invoice.client_reference_id const productId = invoice.lines.data[0].price.product const product = await stripe.products.retrieve(productId) const status = invoice.lines.data[0].subscription.status const planTier = product.name === 'Affiliate' && status === 'active' ? 1 : 0 await createPlanHelper(request, db, clientReferenceId, planTier) break
Looks fine
One thing you could do to save yourself a network call is to just store product id in your database and compare the id in the webhook event to the one stored
That way you don't have to retrieve the product. Reducing the number of api calls you make is recommended
Will make your application faster
ill just check if amount is more than 0.
that could work too
now my other question that i had in the previous thread is related to unsubscribing or not paying but still allowing the subscription to run the remaining billing plan.
I have this:
case 'customer.subscription.updated': const paymentIntent = event.data.object clientReferenceId = paymentIntent.client_reference_id await createPlanHelper(request, db, clientReferenceId, 0) break
is this the correct event type? i want to cover a few cases. for cancellations
all cancellations.
if they manually cancel before billing period end (should still provide subscription until its over)
if billing period end, and they dont pay for the next period
if they switch from paid plan to free plan (which should be same as the first case)
(if possible) the 3rd scenario i want to prevent users from subscribing to free plan. because thats already applied.
gagan-invoice-calculation
yes that's the right Event in that case