#nikivi-webhook-cli

1 messages · Page 1 of 1 (latest)

midnight geodeBOT
rotund warren
#

is this the command i need to run to make it work?

#

stripe listen --forward-to localhost:8787/stripe_webhooks

#

im bit confused

#

my server looks like this

crystal crow
#

sorry that's a lot of pictures here

crystal crow
#

What's your real question, developer to developer?

#

nikivi-webhook-cli

rotund warren
#

basically i have a server running that has a POST on /learn-anything-bought

#

i want stripe to call it with web hook

#

locally

#

if it works locally i will deploy to production

crystal crow
#

okay so what's blocking you?

rotund warren
#

i can't call endpoints myself, it fails these checks

#

Webhook signature verification failed. No stripe-signature header value was provided

rotund warren
#

stripe listen --forward-to localhost:8787/stripe_webhooks

#

or rather what i should call after

#

to trigger checkout.session.completed

#

locally

#

stripe trigger payment_intent.succeeded

#

i think its one of this

crystal crow
#

Okay so this is a webserver you run on your local computer. Are you experienced with that? Do you know how to hit your server and make sure it works?

rotund warren
#

i extracted code from my last app just i didn't document how to do local stripe testing

crystal crow
#

Ignore Stripe for a sec, this is basic web development

rotund warren
#

oh so yes

#

i have web server running

crystal crow
#

I'm trying to figure out what you know

rotund warren
#

right now i have server running on left

crystal crow
#

please no pictures 🙂

rotund warren
#

all right im experienced in web dev

crystal crow
#

we're devs, we can talk in text, share code in text, pictures of your whole computer screen are usually a bad sign of confusion

rotund warren
#

if thats the question

#

im not experienced with stripe web hooks

crystal crow
#

yep I'll get you to the answer in a couple minutes, bear with me

#

okay so if you are experienced with this and know how this works you understand how HTTP requests work right? So you can for example hit localhost:8787 and hit your root route/page right?

rotund warren
#

correct

#

if i do this, it fails on stripe signature verify

#

if i do it myself

#

stripe has to call into that webhook endpoint

#

from my understanding

crystal crow
#

Please ignore Stripe

rotund warren
#

what is the question

crystal crow
#

okay so if you are experienced with this and know how this works you understand how HTTP requests work right? So you can for example hit localhost:8787 and hit your root route/page right?

rotund warren
#

i can't call into this endpoint myself

crystal crow
#

why?

rotund warren
#

if i do, it fails with Webhook signature verification failed. No stripe-signature header value was provided

#

message

crystal crow
#

but then that means you can?

rotund warren
#

ok fair i can

crystal crow
#

Sure your code returns an error but again that's not the question

rotund warren
#
app.post("/learn-anything-bought", async (c: Context) => {
  let event = c.req.body
  const stripe = new Stripe(c.env.LA_STRIPE_SECRET_KEY!, {
    apiVersion: "2023-08-16",
    typescript: true,
  })
  const endpointSecret = c.env.LA_STRIPE_WEBHOOK_SECRET!
  if (endpointSecret) {
    // Get the signature sent by Stripe
    const signature = c.req.header("stripe-signature")
    const textBody = await c.req.text()
    try {
      // @ts-ignore
      event = await stripe.webhooks.constructEventAsync(
        textBody,
        signature!,
        endpointSecret,
      )
    } catch (err) {

crystal crow
#

cool so when you call this yourself what do you do with code?

rotund warren
#

it fails this

crystal crow
#

or which tool do you use?

rotund warren
#
app.post("/learn-anything-bought", async (c: Context) => {
  let event = c.req.body
  const stripe = new Stripe(c.env.LA_STRIPE_SECRET_KEY!, {
    apiVersion: "2023-08-16",
    typescript: true,
  })
  const endpointSecret = c.env.LA_STRIPE_WEBHOOK_SECRET!
  if (endpointSecret) {
    // Get the signature sent by Stripe
    const signature = c.req.header("stripe-signature")
    const textBody = await c.req.text()
    try {
      // @ts-ignore
      event = await stripe.webhooks.constructEventAsync(
        textBody,
        signature!,
        endpointSecret,
      )
    } catch (err) {
      // @ts-ignore
      console.log(`⚠️  Webhook signature verification failed.`, err.message)
      c.status(400)
      return c.json({ err: "failed" })
    }
  }

  // Handle the event
  // @ts-ignore
  switch (event.type) {
    case "checkout.session.completed":
      // @ts-ignore
      const checkoutSessionCompleted = event.data.object

      if (checkoutSessionCompleted.status === "complete") {
        // const subscriptionType =
        //   checkoutSessionCompleted.metadata.subscriptionType.trim()

        const email = checkoutSessionCompleted.metadata.email.trim()

#

is the endpoint

rotund warren
#

can also do it with curl but I am familiar with httpie

#

you said no screenshots so 🙂

crystal crow
#

do you know how to do it with curl?

rotund warren
#

i can look it up

#

1 sec

crystal crow
#

nah it's fine

#

what URL do you put in httpie?

rotund warren
#

localhost:8787/learn-anything-bought

#

POST

#

no body

crystal crow
#

perfect

#

so now bear with me again

#

I know it's annoying that way but it'll click better than if I give you the naswer

rotund warren
#

thank you, I prefer that

crystal crow
#

Why did you think localhost:8787/stripe_webhooks but when you use httpie you thought localhost:8787/learn-anything-bought ?

rotund warren
#

ohh

#

i see what you mean

#

so that command means, forward all stripe requests to this endpoint

#

so I should stripe listen --forward-to localhost:8787/learn-anything-bought

#

and then do stripe trigger checkout.session.completed

#

to emulate checkout.session.completed

crystal crow
#

yup 🙂

#

basically that --forward-to is really just making an HTTP POST request to your local server

#

the same way you would with curl or httpie

rotund warren
#

[mf:inf] POST /learn-anything-bought 400 Bad Request (1ms)
run
⚠️  Webhook signature verification failed. No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?

Learn more about webhook signing and explore webhook integration examples for various frameworks at https://github.com/stripe/stripe-node#webhook-signing

[mf:inf] POST /learn-anything-bought 400 Bad Request (1ms)
run
⚠️  Webhook signature verification failed. No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?

Learn more about webhook signing and explore webhook integration examples for various frameworks at https://github.com/stripe/stripe-node#webhook-signing
#

im still getting bunch of these

#

one thing i changed from code i run in prod already

crystal crow
#

yeah that's totally normal

rotund warren
#

is

#
  const stripe = new Stripe(c.env.LA_STRIPE_SECRET_KEY!, {
    apiVersion: "2023-08-16",
    typescript: true,
  })

#

i updated apiVersion to new number

crystal crow
#

sorry you type really fast but don't breathe in between :p

#

1/ the CLI has a different webhook secret so you need to make sure you use the correct one

rotund warren
#
stripe trigger checkout.session.completed
Setting up fixture for: product
Running fixture for: product
Trigger failed: Post "https://api.stripe.com/v1/products": dial tcp: lookup api.stripe.com: no such host
#

also i am getting this

#

it worked before but now get this

#

ok that was my bad nvm

crystal crow
#

yeah

#

2/ I assume you use node, an node is extremely finicky with this because it tries to be helpful and often messes up with the raw payload we send you which is crucial for us to get exactly what we sent to verify signatures. Node makes this really hard sadly and there are dozens of developers a month that ask about this 😦

rotund warren
#

i dont remember setting any env vars

crystal crow
#

not sure what env vars have to do with this

rotund warren
#

im not sure how to understand what you wrote here

crystal crow
#

Webhook signature requires a webhook endpoint secret to verify the signature, right?

#
        textBody,
        signature!,
        endpointSecret,
      )``` literally from your code earlier
rotund warren
#

oh yes i see

#
app.post("/learn-anything-bought", async (c: Context) => {
  let event = c.req.body
  const stripe = new Stripe(c.env.LA_STRIPE_SECRET_KEY!, {
    apiVersion: "2023-08-16",
    typescript: true,
  })
  const endpointSecret = c.env.LA_STRIPE_WEBHOOK_SECRET!

#

you mean this LA_STRIPE_WEBHOOK_SECRET

crystal crow
#

that endpointSecret is configured on the webhook endpoint and visible in the Dashbord. But when you use the CLI it is a different one

rotund warren
#

thats what i mean with env vars, i guess mine are set incorrectly?

#

what should it be for local use?

#

right now i used these ones

#

i know you said no screens

#

but its just to show you what i use for values of

#

LA_STRIPE_SECRET_KEY

#

LA_STRIPE_WEBHOOK_SECRET

#

and

#
  switch (event.type) {
    case "checkout.session.completed":
      console.log("THIS RUNS!!!!!!!")

#

i added this log

#

and ran stripe trigger checkout.session.completed

#

this log never runs

#

which means it fails verifying the signature

#

at least thats what i understand

crystal crow
#

I'm sorry you type so many words so fast

#

That picture is completely unrelated and about API keys and not about the WebhookEndpoint secret. Also I just explained the CLI has a custom secret and you shouldn't use the normal one right?
When you do stripe listen it tells you the secret right there on the command line

rotund warren
#

oh ok

#

i set it to this

#

and will try again

#

oh nvm

crystal crow
#

please be careful those are important secrets and shouldn't be shared.

rotund warren
#

ok I got my log, thank you

#

1 thing i dont get though is why does it do all this

#
stripe trigger checkout.session.completed
Setting up fixture for: product
Running fixture for: product
Setting up fixture for: price
Running fixture for: price
Setting up fixture for: checkout_session
Running fixture for: checkout_session
Setting up fixture for: payment_page
Running fixture for: payment_page
Setting up fixture for: payment_method
Running fixture for: payment_method
Setting up fixture for: payment_page_confirm
Running fixture for: payment_page_confirm
Trigger succeeded! Check dashboard for event details.
#

can i not just trigger it once

#

or rather only trigger it for checkout.session.completed

crystal crow
#

To trigger a complete session it first need all the additional information. This doesn't really matter at all though

rotund warren
#

all right, thank you again

#

will investigate it further and ask again in #dev-help when stuck

#

❤️