#MikeD-PHP
1 messages · Page 1 of 1 (latest)
one sec
that's the header comes with the request from Stripe. We includes it when we send the event
you don't need to set it yourself
Invalid Signature is a common error
Have you correctly set the $endpoint_secret?
Yes from your documentation but yeahj
so I am doing it locally
and testing using ngrok
How do I find the webhook secret after I create the webhook just to verify
In your dashboard, look at that webhook endpoint you setup
yes!
Ok. So I can access the header through laravel like the following
$headers = collect($request->header())->transform(function ($item) {
return $item[0];
})->toArray();
$headers['stripe-signature'];
Click on "Reveal" when you are at the page of your endpoint
and I get something that looks like this
it's not letting me paste the photo
but like the documentation
t=1492774577,
v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd,
v0=6ffbb59b2300aae63f272406069a9788598b792a944a07aba816edb039989a39
without the "Stripe-Signature:"
this is the Signature header
Just to verify, have you correctly set the Endpoint secret to your env('STRIPE_LOCAL_ENDPOINT') ?
That's my whsec_ code
Yeah, but it looks for STRIPE_LOCAL_ENDPOINT in your environment variables
right it's there
You have it? If you print out env('STRIPE_LOCAL_ENDPOINT') you have the whsec_xxx value, right?
yes
well I didn't do the payload that may be the problem.
let me try one thing
Ok. So how does it accept it?
Because In Laravel we typically do something like $request->all() $request is everything
So I have tried a couple different ways
If I do
$request all it complains about it being an array
if I do json_encode($request->all()) to basically get it back to the way it was. it doesn't like it either says "invalid signature"
In looking at the webhook I am returning it exactly as it is sent
you are talking about the payload right?
Yes so I basically did this
return json_encode($request->all())
Then when I look at the WebHook the Response and the Request are exactly identical.
It's okay as long as you are returning 200 to our request. Stripe only care if you well received it (we got 200/201)
tested with $payload = @file_get_contents('php://input');1 with same result
right right I understand it is going into success
Becasue I am returning 200
But if I do not return and it go through the rest of the code. it fails at signature
But you're saying that my signature is correct
right but you said that my signature looked valid.
so we have correct endpoint_secret, we have the header, we have the payload
still, it's failing
Can I share what the signature look slike ?
Is the signature even a "secret" without the "secret"
Also, it's test data so. Not really caring too much lol
Can I share what my signature extraction is coming out to?
f it
t=1645071548,v1=45c0d0eb757dc9a473af4202a5065bced4ea71e291ea020a048a3a47f175448e,v0=d2625482a145cb93fcbb56dbbfcb890b8f96ac1b00852d8d59911977743cecb5
That's the string output of my extraction. That looks normal yes?
"t=1645071645,v1=153ec87a5ab59d9235660eb0148ddf2ac09292ef44d6056a0e39b3485c05c328,v0=f5c08aefe31bfb0453547cb8a3c4796cc2f2e890af5f0797b5ded76f7bf20772"
Mine
So it does look like correct format
Plot thickens lol
I know you can echo your endpoint secret, but how about print it inside your program
maybe your program doesn't capture environment variables well...
i'll hard code it for a sec to see
and printout payload as well
Well I printed out payload by responding and reading the payload in your web request response section.
So I hard coded the webhook_secret no change
can you paste here how you payload looks like?
{"id":"evt_1KU1C0GHeMNtzjNmdLP9XAGv","object":"event","api_version":"2020-08-27","created":1645070528,"data":{"object":{"id":"in_1KHrzcGHeMNtzjNmVGodu0mx","object":"invoice","account_country":"US","account_name":"MyTekki, LLC","account_tax_ids":null,"amount_due":127500,"amount_paid":127500,"amount_remaining":0,"application_fee_amount":null,"attempt_count":1,"attempted":true,"auto_advance":false,"automatic_tax":{"enabled":false,"status":null},"billing_reason":"manual","charge":"ch_3KHrzdGHeMNtzjNm00jc97RI","collection_method":"send_invoice","created":1642175228,"currency":"usd","custom_fields":null,"customer":"cus_KW5ZjC1SjHhhJZ","customer_address":{"city":"Westford","country":"United States","line1":"70 Main Street","line2":null,"postal_code":"01886","state":"Massachusetts"},"customer_email":"mike@mytekki.com","customer_name":"Building Science Corporation","customer_phone":null,"customer_shipping":{"address":{"city":null,"country":null,"line1":null,"line2":null,"postal_code":null,"state":null},"name":"Betsy BSC Pettit","phone":null},"customer_tax_exempt":"none","customer_tax_ids":[],"default_payment_method":null,"default_source":null,"default_tax_rates":[],"description":null,"discount":null,"discounts":[],"due_date":1642222799,"ending_balance":0,"footer":null,"hosted_invoice_url":"https:\/\/invoice.stripe.com\/i\/acct_1JhwTvGHeMNtzjNm\/test_YWNjdF8xSmh3VHZHSGVNTnR6ak5tLF9LeG5hYnpSZXUyYmxYeHRyalFLcWkyekx0NUFrbWVYLDM1NjExMzI40200cozLv7yl?s=ap","invoice_pdf":"https:\/\/pay.stripe.com\/invoice\/acct_1JhwTvGHeMNtzjNm\/test_YWNjdF8xSmh3VHZHSGVNTnR6ak5tLF9LeG5hYnpSZXUyYmxYeHRyalFLcWkyekx0NUFrbWVYLDM1NjExMzI40200cozLv7yl\/pdf?s=ap","last_finalization_error":null,"lines":{"object":"list","data":[{"id":"il_1KHrzcGHeMNtzjNmn89Oph6R","object":"line_item","amount":127500,"currency":"usd","description":"$150\/ hr @ 8.50 Hours | test","discount_amounts":[],"discountable":true,"discounts":[],"invoice_item":"ii_1KHrzcGHeMNtzjNmNJ1kxQR7","livemode":false,"metadata":{"entry_type":"TimeEntry","billable_hours":"8.50","cost_rate":"0","bill_rate":"15000","description":"test","notes_public":"false","charge_amount":"127500","billable":"true","out_of_scope":"false","wuwd":"0","entry_date":"2022-01-20 00:00:00","item_id":"1","item_description":"Consulting Services","item_code":"CON150","project_id":"1","project_name":"Betsy BSC Pettit","project_code":"0003"},"period":{"end":1642175228,"start":1642175228},"plan":null,"price":{"id":"price_1KHrzcGHeMNtzjNmUUqCbfH2","object":"price","active":false,"billing_scheme":"per_unit","created":1642175228,"currency":"usd","livemode":false,"lookup_key":null,"metadata":[],"nickname":null,"product":"prod_KxnaVkWkxnREHT","recurring":null,"tax_behavior":"unspecified","tiers_mode":null,"transform_quantity":null,"type":"one_time","unit_amount":127500,"unit_amount_decimal":"127500"},"proration":false,"quantity":1,"subscription":null,"tax_amounts":[],"tax_rates":[],"type":"invoiceitem"}],"has_more":false,"total_count":1,"url":"\/v1\/invoices\/in_1KHrzcGHeMNtzjNmVGodu0mx\/lines"},"livemode":false,"metadata":[],"next_payment_attempt":null,"number":"4D8F9B3B-0037","on_behalf_of":null,"paid":true,"paid_out_of_band":false,"payment_intent":"pi_3KHrzdGHeMNtzjNm0h0kvMzr","payment_settings":{"payment_method_options":null,"payment_method_types":null},"period_end":1642175228,"period_start":1642175228,"post_payment_credit_notes_amount":0,"pre_payment_credit_notes_amount":0,"quote":null,"receipt_number":null,"starting_balance":0,"statement_descriptor":null,"status":"paid","status_transitions":{"finalized_at":1642175229,"marked_uncollectible_at":null,"paid_at":1645070528,"voided_at":null},"subscription":null,"subtotal":127500,"tax":null,"total":127500,"total_discount_amounts":[],"total_tax_amounts":[],"transfer_data":null,"webhooks_delivered_at":1642175228}},"livemode":false,"pending_webhooks":1,"request":{"id":"req_XYSXEFmwbY6pdV","idempotency_key":"407564da-e9c4-41c0-afe9-07ba61f69a67"},"type":"invoice.payment_succeeded"}
Umm looks normal to me
I had some \n
hmm, why didn't you have any \n. Is this how you get your payload?
$payload = @file_get_contents('php://input');
tried both ways
so if I do it the way you just said it comes out on the response screen formatted
if I do it the way I tried json_encoded($request->all())
comesout as one line string. but either way they both fail
So I am presuming your response screen is interpretting the \n
So it would be equivalent to your one that you had.
From my experiences, we have received a lot of similar questions for Signature verification failed. It's normally some middleware tried to modify the request body. (Node.js frameworks is terrible, ie) It's possible that Laravel also has some
Do you have an idea of which Laravel middleware could have done some modification?
no. Because I don't have it blocked by a middleware
I found a video
Going to watch this real fast might explain.
Or go to this page, click on Download to get a working example: https://stripe.com/docs/webhooks/quickstart
Choose PHP and click download
Looks like there is a package
composer require spatie/laravel-stripe-webhooks
Going to explore real quick
hahaha ok. So I have even gone through installing https://github.com/spatie/laravel-stripe-webhooks
Which seems to be well used.
Maybe ngrok is changing something?
No idea about ngrok but hard to think they have changed smth that could affect
So it didn't work with even that library?
Could you try the example PHP project above?
So I got it working. Looks like ngrok is modifying the request a bit. It would probably work without ngrok the way I was doing it. but I ended up using the library above anyways due to the fact that it handles the stripe webhook split out and assigns it to jobs. a little more cleaner then my solution if I want to expand.
Thanks for your time.
Glad to hear it's working!