#nikivi

1 messages ยท Page 1 of 1 (latest)

shut knollBOT
pearl mica
#
let date = new Date() // get current date
date.setDate(date.getDate() + 31) // set day of month to current day + 30

let year = date.getFullYear()
let month = date.getMonth() + 1 // getMonth() is zero-indexed, so we add 1
let day = date.getDate()

// padStart(2, '0') ensures that day and month are two digits long, adding a leading zero if necessary
month = month.toString().padStart(2, "0")
day = day.toString().padStart(2, "0")

let dateString = `${year}-${month}-${day}` // template string to format in 'YYYY-MM-DD'
console.log(dateString)
#

we thought of doing this

#

but i think stripe should know

#

when end of subscription is

#
type UserDetails @model {
  paidSubscriptionValidUntilDate: Date
#

in our case we want to update this value on user model

#

and check it on further actions that are supposed to be paid

#

or maybe there is another way to do it

proud barn
pearl mica
#

like this?

proud barn
#

Yes

pearl mica
#

was not sure which object

#

great

proud barn
#

Oh whoops I misread your code

#

That will not be on the Checkout Session, that is a completely different object.

pearl mica
#

can i get it there

#

thats my web hook code

#

case "checkout.session.completed":

#

when users pay

#

this gets triggered

proud barn
#

You will also probably want to listen for customer.subscription.updated events to watch the subscription for when it renews so you can update how long the subscription in your system is valid for

pearl mica
#

oh great

#

forgot about that

#

thanks

#

btw can i type

#

the request in web hook

#

async (request, response) => {

#

in typescript

proud barn
#

Yes I believe so, it is common to make API calls when receiving webhook info

pearl mica
#

where can i get the type

#

@types/stripe?

#

ok i see this

#

ok i got subscription id

#

console.log(details.subscription, "details.subscription")

#

use that to retrieve the subscription object

#

how do i do this

#

because i just have the id

proud barn
pearl mica
#
          stripe.subscription.retrieve(
            details.subscription,
            (err, subscription) => {
              if (err) {
                console.log(err)
                return
              }
              console.log(subscription, "subscription")
            }
          )
#

didnt find it it in docs how to do it via stripe-node

#

hope this is ok

#

the err, part looks wrong to me

#

oh wait you could do this

#

neat

#

current_period_end: 1686839028

#

this right?

#

btw for some reason often times when i click the checkout link

#

that is test it just crashes

#

link like this

#
  try {
    const data = await stripe.checkout.sessions.create({
      success_url: process.env.STRIPE_SUCCESS_URL!,
      mode: "subscription",
      metadata: {
        userDetailsId: userDetailsId,
      },
      line_items: [
        {
          quantity: 1,
          price: process.env.STRIPE_PRICE_ID!,
        },
      ],
    })
    return {
      suggestedTasks: null,
      stripeCheckoutUrl: data.url,
    }
  } catch (error) {
    console.log(error)
  }
}
#

which i get from

#

i worry that in production same will happen

#

actually happens often ๐Ÿ˜ฆ

amber phoenix
#

Hello ๐Ÿ‘‹

#

Apologies for the delay here

pearl mica
#

hey @amber phoenix

#

i got it working

#

aside from stripe page breaking

#

i hope this doesn't happen in prod

#

also

#
      case "customer.subscription.updated":

#

for this case

#
  try {
    const data = await stripe.checkout.sessions.create({
      success_url: process.env.STRIPE_SUCCESS_URL!,
      mode: "subscription",
      metadata: {
        userDetailsId: userDetailsId,
      },
      line_items: [
        {
          quantity: 1,
          price: process.env.STRIPE_PRICE_ID!,
        },
      ],
    })
#

can I get access to userDetailsId

#

subscription.updated

#

because I am not manually triggering it

#

i assume stripe will trigger it when user pays again

amber phoenix
#

So the code sets metadata on the Checkout Session object

customer.subscription.updated event payload is a subscription object

pearl mica
#
      case "checkout.session.completed":
        const details = event.data.object
        if (details.status === "complete") {
          const userDetailsId = details.metadata.userDetailsId.trim()
#

i do this

amber phoenix
pearl mica
#

can i do same

#

or those are diff events

amber phoenix
#

Different events

pearl mica
#

ok nice

#

so its persisted on that object

amber phoenix
#

Yup

pearl mica
#
      case "customer.subscription.updated":
        const details = event.data.object
        if (details.status === "complete") {
          stripe.checkout.sessions.retrieve(details.subscription)
        }
#

if I get it right

#

there was no node example in docs

#

im not sure whats on the object

#

will log it and see

#

also not sure about details.status === "complete"

#

maybe no need for it

#

ohh

#

its actully redeclaring details

#
    switch (event.type) {
      case "checkout.session.completed":
        let details = event.data.object
#
      case "customer.subscription.updated":
        console.log(event.data.object)
        details = event.data.object
        if (details.status === "complete") {
          const subscription = stripe.checkout.sessions.retrieve(
            details.subscription
          )
          console.log(subscription, "subscription")
        }
#

trying this

amber phoenix
#

try

  subscription: ID,
});```
pearl mica
#

ID is not defined tho

#

no?

amber phoenix
#

You'd get the ID from the webhook event

pearl mica
#

async (request, response) => {

#

i get this

amber phoenix
#

look at the details printed by event.data.object

pearl mica
#

not typed

#

so dont know whats inside

#

this is very worrying

#

is just test thats breaking?

#

or will it break for users who visit the payment page too?

amber phoenix
#

try commenting out everything and only print event.data.object

is just test thats breaking?
What errors do you see in your console?

pearl mica
#

like it works 1 time out of 4

#

getting this

#

thats with this code

#

i stripped secret info

#

console.log(event.data.object, "event.data.object")

#

is not logged ๐Ÿ˜ฆ

#
    switch (event.type) {
      case "checkout.session.completed":
        let details = event.data.object
#

i should not call it details i think

#

i guess this is sessionDataObject

#
      case "customer.subscription.updated":
        const subscriptionObjectData = event.data.object
#

and this is like this

#

i guess

#

or im wrong

amber phoenix
#

can you share the complete code you have under switch(event.type)?

pearl mica
#

this is full code i have now

#

as it is now

amber phoenix
#

You don't need

            details.subscription
          )
          console.log(subscription, "subscription")```
pearl mica
#

gone

#

get this

#
      case "customer.subscription.updated":
        details = event.data.object
#

should be fine

#

i think

#

or wait

#
      case "customer.subscription.updated":
        let details = event.data.object
#

i guess i have to do this

#
      case "checkout.session.completed":
        let details = event.data.object
#

on both events

#

or rename

#

i was just not sure

amber phoenix
#

You'll need to debug this on your own ๐Ÿ™‚ I guide you to fix your code but I fix it for you
Trial and error

pearl mica
#

customer.subscription.updated

#

for this event

#

event.data.object

#

returns subscriptionData

#

case "checkout.session.completed":

#

for this

#

event.data.object

#

is sessionData

#

i hope at least

#

going to name vars accordingly

pearl mica
#
      case "customer.subscription.updated":
        let subscriptionData = event.data.object
        if (subscriptionData.status === "complete") {
          const sessions = await stripe.checkout.sessions.list({
            subscription: subscriptionData.ID,
          })
          console.log(sessions, "sessions")
        }
#

i assume you mean this

#

trying it out now

amber phoenix
#

๐Ÿ˜„ glad you figured it out

pearl mica
#

ok now how to trigger it

#

because paying does not

#
      case "customer.subscription.updated":
        let subscriptionData = event.data.object
        if (subscriptionData.status === "complete") {
          const sessions = await stripe.checkout.sessions.list({
            subscription: subscriptionData.ID,
          })
          console.log(sessions, "sessions")
        }
#

there is log

#

got this

#

this is stripe listen --forward-to localhost:4242/webhook

amber phoenix
#

I don't think you need this condition

if (subscriptionData.status === "complete")

pearl mica
#

ok getting this

#

but there is no metadata

#

that i can see

#

checking more

#

or wait

#

it returns all sessions

#

im confused

#

what do i do with sessions

#
          const userDetailsId = sessionData.metadata.userDetailsId.trim()
          const subscription = await stripe.subscriptions.retrieve(
            sessionData.subscription
          )
          const endDateInUnix = subscription.current_period_end
#

i need this info

#

to do graphql call

amber phoenix
#

I believe the list should be sorted, you can either pick the first session object OR the last session object (based on how its sorted)

pearl mica
#

last item has created: 1684161798

#

created: 1684162048

#

one before is this

#

one before is bigger

#

so last one is most recent

#

ok i get last session

#

but i dont see metadata

#

userDetailsId

amber phoenix
#

can you share the event ID?

pearl mica
#

cs_test_a1OVQAfGLJNoUfpXMyEnBMiMMZCM7o416S9d2N1jUaH2u8nyXOrzudpwfi

#

this is id:

shut knollBOT
amber phoenix
#

Can you share the complete Session object that you're seeing in the list?

pearl mica
#
    {
      id: 'cs_test_a1OVQAfGLJNoUfpXMyEnBMiMMZCM7o416S9d2N1jUaH2u8nyXOrzudpwfi',
      object: 'checkout.session',
      after_expiration: null,
      allow_promotion_codes: null,
      amount_subtotal: 1000,
      amount_total: 1000,
      automatic_tax: [Object],
      billing_address_collection: null,
      cancel_url: null,
      client_reference_id: null,
      consent: null,
      consent_collection: null,
      created: 1684161798,
      currency: 'eur',
      currency_conversion: null,
      custom_fields: [],
      custom_text: [Object],
      customer: 'cus_NtqJJbygiImxeP',
      customer_creation: 'always',
      customer_details: [Object],
      customer_email: null,
      expires_at: 1684248198,
      invoice: 'in_1N82ckKmRnbuc3WvF3ILNgrK',
      invoice_creation: null,
      livemode: false,
      locale: null,
      metadata: [Object],
      mode: 'subscription',
      payment_intent: null,
      payment_link: null,
      payment_method_collection: 'always',
      payment_method_options: null,
      payment_method_types: [Array],
      payment_status: 'paid',
      phone_number_collection: [Object],
      recovered_from: null,
      setup_intent: null,
      shipping_address_collection: null,
      shipping_cost: null,
      shipping_details: null,
      shipping_options: [],
      status: 'complete',
      submit_type: null,
      subscription: 'sub_1N82ckKmRnbuc3WvE8ighWN0',
      success_url: 'http://localhost:3000/payment-success',
      total_details: [Object],
      url: null
    }
  ],
  has_more: true,
  url: '/v1/checkout/sessions'
} sessions
#

this is last one

#

can send more

amber phoenix
#

metadata: [Object]

So there's a value
Can you try printing that?

pearl mica
#

console.log(sessions[sessions.length - 1].metadata, "metadata")

#

ok trying this

#

ok guess that was wrong

#

thought it'd get last session

#

oh its not array

#

fk

#

console.log(sessions.data[sessions.length - 1], "session")

#
        console.log(sessions, "sessions")
        console.log(sessions.data[sessions.data.length - 1], "session")
        console.log(sessions.data[sessions.data.length - 1].metadata, "metadata")
#

this actually

#

{ userDetailsId: 'userdetails_01H08W9DMHGEZ41Q726XH2M414' } metadata

#

ok its there

#

amazing

#

thank you lots @amber phoenix

#

final q if I may

#

for my saas app

amber phoenix
#

NP! ๐Ÿ™‚ Happy to help
Sure

pearl mica
#

case "checkout.session.completed":

#

case "customer.subscription.updated":

#

anything else needed?

#

i just want to process payments

#

nothing fancy yet

#

i guess I can do .rejected

#
Unhandled event type charge.succeeded.
Unhandled event type payment_method.attached.
Unhandled event type customer.created.
Unhandled event type customer.updated.
Unhandled event type invoice.created.
Unhandled event type invoice.finalized.
Unhandled event type customer.subscription.created.
Unhandled event type invoice.updated.
Unhandled event type invoice.paid.
Unhandled event type invoice.payment_succeeded.
Unhandled event type payment_intent.succeeded.
Unhandled event type payment_intent.created.
#

i don't see .rejected though