#nikivi

1 messages ยท Page 1 of 1 (latest)

manic forumBOT
fossil kettle
#

Hi ๐Ÿ‘‹ can you tell me more about what you're trying to do, and what you're seeing?

sturdy bough
#

is my test buy url

#

I have a web hook endpoint

#

running

#

I ran this

#

stripe listen --forward-to localhost:8787/personal-product-bought

#

to pipe requests to it locally

#

but as you see there are no logs that reach the endpoint

#

the url is correct

#

the thing is im not sure how to get PERSONAL_STRIPE_WEBHOOK_SECRET

#

maybe thats why its not working right

#

i thought for local its ignored

#

i would get the secret once i deploy

fossil kettle
# sturdy bough

The signing secret you're looking for is printed to the console when you run stripe listen, it's in the line that starts with Ready! in this screenshot.

sturdy bough
#

ok perfect

#

one final thing

#

as the web hook from my understanding

#

covers all the products under account

#

how do I know which product was paid for

#

I remember asking this question and I was told i have to do something like pass it as metadata

#

or something

#

is there like a nice way to know which product id was paid for

#

the goal of the web hook is to put customer emails mapped to product they paid for in my own db

#

im looking to see if price_id is included perhaps

#

i can do a switch on it

#

that would probably be best actually

fossil kettle
#

How are you integrated/what type of Events are you listening for?

The Event that you listen for controls what context it provides. For instance, if you're listening for Invoice or Checkout Session related Events, those are more likely to have Price and Product references, but Paymnt Intent Events will not as Payment Intents don't reference Price/Product objects at all.

sturdy bough
#

so i only care about case "checkout.session.completed":

#

which is when user completes the purchase

#

its single purchase, not a sub

#

const checkoutSessionCompleted = event.data.object

#

so this is what i work with

#

but thats for creation

#

it seems

#

const checkoutSessionCompleted = event.data.object

#

basically somewhere inside this

#

i need to know which product was paid for

#

and email of person who bought it

#

if i log it truncates

fossil kettle
#

Gotcha, so those Events will contain Checkout Sessions then, depening on your API version the line items likely won't be in the Checkout Session object by default, you'll want to use this endpoint to retrieve those using the ID of the session:
https://stripe.com/docs/api/checkout/sessions/line_items

sturdy bough
#

maybe a good question to ask

#

whether i should use another event

#

to make this easier?

#

like payment intent completed or something

#

or invoice paid it was

#

that would have all the necessary data

#

Retrieve a Checkout Session's line items because this is bit confusing to me

#

there is like one line item for me

#

or well i guess i can try it

#

im surprised though

#

there has to be an easier way to just get the event on payment with all the necessary details

#

without doing cross stripe requests

#

like payment succesful with price_id and customer_email included in the object

fossil kettle
#

It'll be easier to converse if you send complete messages instead of fragments of messages.

fossil kettle
fossil kettle
sturdy bough
#

ok I need a web hook that will listen on user completing payment

this web hook should include price_id and customer_email inside the object so I can easily access it and do things with the data

sturdy bough
fossil kettle
sturdy bough
#

ok will try that

#

should be easy enough

#

cs_test_a1sZ3321BhXIKGR

#

this string

#

is that secret key

#

it looks like a product id

#

or something

#

trying to do this now

#

yea its confusing, I imagine i need to have it dynamic

#

or wait it should come from event.data.object i think

fossil kettle
sturdy bough
#
      const checkoutSessionCompleted = event.data.object

      stripe.checkout.sessions.listLineItems(
        checkoutSessionCompleted.id,
#

ok trying with this

#

think thats the id

#

not sure if session completed id is same as what it expects

#

it just says Unique identifier for the object

#

and in here it does not even say what id it expects

#

just prefills it for you

#
completed!
Context is not finalized. You may forget returning Response object or `await next()`
#

callback never gets called

#

not sure perhaps it wants this await stripe.checkout.sessions.listLineItems( but even then i expect a log

#

perhaps the way i did arrow function is wrong but i think it should be ok

fossil kettle
#

What is your code trying to do? You seem to be making a request to list the Line Items for the Checkout Session, but you aren't storing the results in a variable. Does your Event handling code send a response back when it receives a request?

sturdy bough
#

so this is web hook that gets called if any product in personal account gets bought /personal-product-bought

case "checkout.session.completed":

I use this to know that user has completed payment

I now need to know the product that user bought and the email of the user

you said I can use stripe.checkout.sessions.listLineItems to get this info

so I tried to do

      stripe.checkout.sessions.listLineItems(
        checkoutSessionCompleted.id,
        { limit: 5 },
        (err, lineItems) => {
          console.log(err, "err")
          console.log(lineItems)
          // asynchronously called
        }
      )

I thought this would get me the price id AND the email of the customer, not sure

once I get that I have everything I need

#

its not even reaching the console logs

#
      const checkoutSessionCompleted = event.data.object

      let customerEmail
      let productBought

      stripe.checkout.sessions.listLineItems(
        checkoutSessionCompleted.id,
        { limit: 1 },
        (err, lineItems) => {
          console.log(err, "err")
          console.log(lineItems)
          if (lineItems.data[0].price.id === c.env.WIKI_STRIPE_PRICE) {
            productBought = "wiki"
          } else if (lineItems.data[0].price.id === c.env.COURSE_STRIPE_PRICE) {
            productBought = "course"
          }
        }
      )
#

something like this I guess, looks ugly

#

and not sure where email is

fossil kettle
sturdy bough
#

the callback never runs

#

it just gets ignored

#

no log for err or lineItems

#

thus the productBought variable never is filled with value

fossil kettle
#

Are you seeing an associated GET request being logged in the logs for your Stripe account? Are you saving/deploying the code as you're making changes to it so your endpoint is using the new code? Does adding a console.log line before the call to retrieve the Checkout Session line items result in an additional line being printed?

sturdy bough
#

no GET request here

#

if you mean this

#

i make sure to deploy new local version when i change code

#

so server has latest code

fossil kettle
#

I don't, I mean here, to see if you're able to see if a call is actually being made to retrieve the line items for the Checkout Session:
https://dashboard.stripe.com/test/logs?showIP=false

But taking another look at your code, I think the problem may be that you're using the fat arrow syntax inside of the parameter list for the call to listeLineItems.

#

What happens if you change this:

        checkoutSessionCompleted.id,
        { limit: 1 },
        (err, lineItems) => {
          console.log(err, "err")
          console.log(lineItems)
          if (lineItems.data[0].price.id === c.env.WIKI_STRIPE_PRICE) {
            productBought = "wiki"
          } else if (lineItems.data[0].price.id === c.env.COURSE_STRIPE_PRICE) {
            productBought = "course"
          }
        }
      )```
to:
```      stripe.checkout.sessions.listLineItems(
        checkoutSessionCompleted.id,
         { limit: 1 },
        ).then((err, lineItems) => {
    console.log(err, "err")
    console.log(lineItems)
    if (lineItems.data[0].price.id === c.env.WIKI_STRIPE_PRICE) {
      productBought = "wiki"
    } else if (lineItems.data[0].price.id === c.env.COURSE_STRIPE_PRICE) {
      productBought = "course"
    }
  })```
sturdy bough
#

did not work

fossil kettle
#

What did it do? What errors were thrown?

sturdy bough
#

as you see nothing

#

logs were not reached

#

it just skipped it

#

logs are on the right

#

going to try wrap it in a try catch

#
      try {
      stripe.checkout.sessions
        .listLineItems(checkoutSessionCompleted.id, { limit: 1 })
        .then((err, lineItems) => {
          console.log(err, "err")
          console.log(lineItems)
          if (lineItems.data[0].price.id === c.env.WIKI_STRIPE_PRICE) {
            productBought = "wiki"
          } else if (lineItems.data[0].price.id === c.env.COURSE_STRIPE_PRICE) {
            productBought = "course"
          }
        })
      } catch (err) {
        console.log(err)
      }
fossil kettle
#

Does adding await to the function call help?

sturdy bough
#

await stripe.checkout.sessions

#

here?

fossil kettle
#

Yup

sturdy bough
#

yep nothing

#

no error

#

just callback never called

fossil kettle
#

My suggestion, start by seeing what you're actually getting when you retrieve the Checkout Sessoin's line items. Start by removing your if else blocks that are looking for specific values, capture the result of the function call in a variable, and then log that variable to the console to see what you are working with

sturdy bough
#

thats not the issue though

#

it does not even go inside the callback

#

it does not reach the if else

#

what should i log

#

this seems complex

#

will try pass metadata

#

maybe that works

#

or maybe i miss something ๐Ÿค”

#

like i reread what you said again and still don't get it, the issue is calback is just not called, whats inside of it

so no point moving stuff inside

#

Start by removing your if else blocks

#

i mean i can try it

#

but it just doesn't make sense

#

in any way, going to go with metadata approach

#
  const data = await stripe.checkout.sessions.create({
    success_url: c.env.WIKI_STRIPE_SUCCESS_URL!,
    line_items: [
      {
        price: c.env.WIKI_STRIPE_PRICE!,
        quantity: 1,
      },
    ],
    metadata: {
      product: "wiki"
    },
    mode: "payment",
  })
#

its actually going to be clean approach too

#

i assume i can do this

fossil kettle
#

Yup, but I have no idea why the callback wasn't being called and was trying to see what your debugging of that was uncovering.

sturdy bough
#
      const checkoutSessionCompleted = event.data.object
      const product = checkoutSessionCompleted.metadata.product.trim()
manic forumBOT
sturdy bough
#

ok yea i made it work with metadata