#bennydev_bennydev-connect-webhooks-cli
1 messages Β· Page 1 of 1 (latest)
π Welcome to your new thread!
β²οΈ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.
β±οΈ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.
π This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1266437701029204110
π Have more to share? Add more details, code, screenshots, videos, etc. below.
Here is the code for the function:
const stripe = new Stripe(env.STRIPE_TEST_SECRET);
const sig = request.headers.get('stripe-signature');
const cloned = request.clone();
const body = await cloned.text();
console.log(body);
let event;
try {
event = await stripe.webhooks.constructEventAsync(body, sig, env.STRIPE_WEBHOOK_SECRET);
console.log(event);
} catch (err) {
return new Response(Webhook Error: ${err.message}, { status: 400 });
}
const supabase = getSupabase();
switch (event.type) {
case 'invoice.paid':
//...
case 'account.application.authorized':
const account = event.data.object;
const { data: teacherProfiles, error: findError } = await supabase
.from('teacher_profiles')
.select('id')
.eq('stripe_account_id', account.id);
if (findError || teacherProfiles.length === 0) {
return new Response('Error finding teacher record', { status: 500 });
}
const teacherId = teacherProfiles[0].id;
const { error: updateError } = await supabase
.from('teacher_profiles')
.update({
stripe_account_status: 'active',
stripe_charges_enabled: account.charges_enabled,
stripe_details_submitted: account.details_submitted,
stripe_payouts_enabled: account.payouts_enabled
})
.eq('id', teacherId);
if (updateError) {
return new Response('Error updating teacher record', { status: 500 });
}
break;
case 'account.updated':
console.log('\n\n\n\n\nAccount update trigger received.\n\n\n\n\n'); //This doesn't run because the webhook doesn't get sent. It stops at file.created.
Hello
Do you mean you're trying to test connect webhook events?
Hi! Yes.
Are you using the correct flag for connect events?
https://docs.stripe.com/connect/webhooks#test-webhooks-locally
For Connect webhooks, use βforward-connect-to with stripe listen and βstripe-account with stripe trigger.
Yes. There's also a new signing error now: Webhook Error: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?
If a webhook request is being forwarded by a third-party tool, ensure that the exact request body, including JSON formatting and new line style, is preserved.
Learn more about webhook signing and explore webhook integration examples for various frameworks at https://github.com/stripe/stripe-node#webhook-signing
However, I didn't change anything. We're still taking in the same stuff in the routing logic:
case '/api/v1/billing/handle-webhook':
const signature = request.headers.get('stripe-signature');
console.log(signature);
if (method === 'POST') {
response = await handleStripeWebhook(request, env, corsHeaders);
}
break;
And then we go to the handling function:
export async function handleStripeWebhook(request, env, corsHeaders) {
const stripe = new Stripe(env.STRIPE_TEST_SECRET);
const sig = request.headers.get('stripe-signature');
const body = await request.text();
console.log(body);
let event;
try {
event = await stripe.webhooks.constructEventAsync(body, sig, env.STRIPE_WEBHOOK_SECRET);
console.log(event);
It logs several events, including .authorized now:
(log) {
"id": "evt_1PgplRISYn9FtJ4Y6NgaKc45",
"object": "event",
...
"livemode": false,
"pending_webhooks": 1,
"request": {
"id": "req_wN909s5DOHzI2I",
"idempotency_key": "<key is here>"
},
"type": "account.application.authorized"
But the webhook never actually processes those. I'm logged in through the CLI, so I don't know why there would be a signing error.
is your CLI forwarding the event to your webhook endpoint route? if so, your webhook endpoint should use the webhook secret that was logged out in the CLI when you ran stripe listen command
We have this guide that should help with debugging: https://docs.stripe.com/webhooks/signature
Thank you, that helped. We're now getting a success on the dashboard, but it only shows the first event (file.created). But the server logs show it's been pinged multiple times for different event types:
/api/v1/billing/handle-webhook - Ok @ 7/26/2024, 12:09:37 PM
(log) POST
(log) {
"id": "evt_1Pgre9RRXI8X0YC3XwTroi2b",
"object": "event",
"account": "acct_1PgrdTRRXI8X0YC3",
"api_version": "2020-03-02",
"created": 1722013777,
"data": {
"object": {
"id": "<id>",
"object": "application",
"name": "Breeze Lessons"
}
},
"livemode": false,
"pending_webhooks": 2,
"request": {
"id": null,
"idempotency_key": null
},
"type": "account.application.authorized"
}
It also didn't do this logging that was expected when it was hit with this type:
case 'account.application.authorized':
console.log('\n\n\nAuthorized portion hit!!!\n\n\n');
const account = event.data.object;
const { data: teacherProfiles, error: findError } = await supabase
.from('teacher_profiles')
.select('id')
.eq('stripe_account_id', account.id);
if (findError || teacherProfiles.length === 0) {
return new Response('Error finding teacher record', { status: 500 });
}
const teacherId = teacherProfiles[0].id;
const { error: updateError } = await supabase
.from('teacher_profiles')
.update({
stripe_account_status: 'active',
stripe_charges_enabled: account.charges_enabled,
stripe_details_submitted: account.details_submitted,
stripe_payouts_enabled: account.payouts_enabled
})
.eq('id', teacherId);
if (updateError) {
return new Response('Error updating teacher record', { status: 500 });
}
break;
Is there a way to pass a payload of info for the request body to the Stripe trigger?
Hi π
I'm stepping in as my colleague needs to go
π§βπ» How to format code on Discord
Inline code: wrap in single backticks (`)
This:
The variable `foo` contains the value `bar`.
Will turn into this:
The variable
foocontains the valuebar.
Code blocks: wrap in three backticks (```)
Also, you can specify the language after the first three backticks to get syntax highlighting.
This:
```javascript
function foo() {
return 'bar';
}
```
Will turn into this:
function foo() {
return 'bar';
}```
Notes about **code blocks**:
- Specifying the language is optional (e.g., you can omit `javascript` in the example above)
- If you don't specify the language you won't get syntax highlighting
- When you're inside a code block (after you type \`\`\`) the `Return`/`Enter` key will add a new line instead of sending your message
- Once you end the code block `Return`/`Enter` works normally again
You can [read more about message formatting on Discord's website.](https://support.discord.com/hc/en-us/articles/210298617)
You say you are seeing a success messge returned. What is currently confusing you?
Thanks! I am only getting a success message for file.created, which seems to be the first thing to happen in the flow leading to account.updated. Even though I'm getting server logs for the other event types being sent, they're not appearing in my webhook logs. I get this in the terminal:
[200] POST https://<my-url>/api/v1/billing/handle-webhook [evt_1PgraxIBB3AjS7h7p8j6lEcR]
2024-07-26 12:07:34 --> connect account.application.authorized [evt_1PgrcAIBB3AjS7h7kdSwrH4a]
But not in the browser. It only shows me file.created. And the databse logic that I have set to run when the event type is account.application.authorized doesn't run.
When you say "in the browser" are you referring to your Stripe dashboard?
Yes, sorry.
Hmmm okay the first one is an account.updated event: https://dashboard.stripe.com/test/events/evt_1PgraxIBB3AjS7h7p8j6lEcR
And then the second is account.application.authorized
https://dashboard.stripe.com/test/events/evt_1PgrcAIBB3AjS7h7kdSwrH4a
Both should show up in the Events log for the account they are occurring on acct_1PgratIBB3AjS7h7
If you are using the Stripe CLI to forward webhook events, e.g. stripe listen, it will automatically include Connect events (events occurring on other accounts that are connected to your platform account).
That's to make it easier to test but it isn't how webhook events work in general with Stripe.
It looks like that is a sample account that was created using Stripe Connect itself. I don't seem to have access to the logs. So I shouldn't be looking for it in the dashboard, just in the terminal, I suppose?
Correct
Or you could set up a Connect webhook endpoint.
Or you could use the Events List API to retrieve events on the Connect Account using the Stripe header
https://docs.stripe.com/api/events/list
Lots of options
But in the Stripe Dashboard, we show Events that occurred on the account you are viewing. Since events occur on the account where the changes are occurring, this means events related to many Connect flows occur on the Connected Account. So those won't be visible in the Dashboard of the Platform Account.
I realize that's a lot of repetition of the words "change", "event", and "account" so let me know if it's confusing π
Thank you so much. It was a series of mismatches between my own stuff vs. connected accounts + signing keys + me needing to destructure the JSON differently in my backend, and we were off to the races. Thanks so much, you rock!
Great π I'm happy we were able to clarify the situation π
Take good care.
You too π