#gassin_api
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/1308506989386797098
š Have more to share? Add more details, code, screenshots, videos, etc. below.
Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.
- gassin_webhooks, 23 hours ago, 19 messages
app.post("/api/v1/webhook", async (req, res) => {
let event = req.body;
let userId;
let user;
switch (event.type) {
case "invoice.paid":
console.log("[+] INVOICE PAID EVENT!")
userId = event.data.object.customer;
user = await User.findOne({ stripeId: userId }).populate({
path: "purchasedPackage.package",
select: "-__v",
});
// const customer = await stripe.customers.retrieve(userId, {
// apiKey: stripesecret
// });
const customer = await stripe.customers.retrieve(userId,
{}, // empty params
{ // options
apiKey: stripesecret
}
);
if (!user) {
user = await User.findOne({ email: customer.email }).populate({
path: "purchasedPackage.package",
select: "-__v",
});
}
user.purchasedPackage.remainingLines =
user.purchasedPackage.package.lineLimit;
const now = new Date();
const futureDate = new Date(now);
futureDate.setDate(futureDate.getDate() + 30);
user.purchasedPackage.nextPaymentDue = futureDate;
await user.save();
console.log("Paid!");
break;
Hi, which docs are you using?
This is the code I use on NodeJS for how I handle the webhook POST request. And this is what I see on the logs.
Multiple, but I don't think the await stripe.customers.retrieve line is the problem. I believe it's because I don't "respond" to the webhook but the docs don't clarify how I should do that.
Yeah, there seems to be multiple issues here.
1/ You do not include the API within your POST request. We document how you can make that call here: https://docs.stripe.com/api/customers/retrieve:
const stripe = require('stripe')('sk_test_');
const customer = await stripe.customers.retrieve('cus_');
Where do I make the post request? Here const customer = await stripe.customers.retrieve ?
2/ Can you share the event id where you see the error attached on the screenshot?
I already tried doing just this:
const customer = await stripe.customers.retrieve(userId);
It had the same result.
Every single event. the endpoint has 100% failure rate. Here is one for instance evt_1QMZ9CBH8SJ1NP7tDjFXWQPm
Stripe is already defined:
const stripe = require("stripe")(stripesecret);
Yeah, but you're still passing the apiKey: stripesecret on that request and you need to remove that
Yes I did that to see if it would work, I had it without that apiKey initially and it had the same result
From looking at the event id, https://dashboard.stripe.com/events/evt_1QMZ9CBH8SJ1NP7tDjFXWQPm it looks like it timed out. You can look at the Result type. We document how you handle this here: https://support.stripe.com/questions/webhooks-how-to-investigate-and-fix-timed-out
This is what I tried as well š
There is not much we can help here as it's your own code you need to debug
Can you share the request id from that reques where you did omitted the api key? Here's how you can find a request ID: https://support.stripe.com/questions/finding-the-id-for-an-api-request
Find help and support for Stripe. Our support site provides answers on all types of situations, including account information, charges and refunds, and subscriptions information. Get your questions answered and find international support for Stripe.
I understand, but last time I put in a ticket you guys told me to change it to this:
const customer = await stripe.customers.retrieve(userId,
{}, // empty params
{ // options
apiKey: stripesecret
}
);
That does not sound right, do you recall what the reasoning was?
No they just told me to try that
and from one doc I saw it said to include the apiKey.
Not really seeing any notable API requests
These look like outbound API requests going to your servers, not API requests being made to me
Which document?
I think there might be some mix up here, can you share the specific document you're looking at?
Can't seem to find it anymore, sorry
I think the problem is that I'm not responding to the webhook event. I guess my question is - how do I do that?
Oh, actually the status code is statusCode: 401, so it means unauthorized I guess
but then again - how can I authenticate so that it will work ? The logs say I should include it in a bearer authorization token, but the docs you sent me say otherwise.
The events you shared indicated a time out
We document how you can verify your webhook signature here: https://docs.stripe.com/webhooks#verify-webhook-signatures-with-official-libraries
Right - but logically it's timing out because I'm unable to send a valid response back to stripe due to the authentication logs I'm getting, Unless the logs isn't correct? Once again pasted for your convenience.
That is a Stripe Authentication Error and not the same thing as the webhook signature error.
Let's step back. What are you exactly trying to do?
I simply want to verify if a user has made their monthly payment. I am using a subscription model, so it relies on the webhook to tell me if the user payment went through or not for the specific month.
Got it, so you've built your event handler right, https://docs.stripe.com/webhooks#webhooks-summary?
correct
I build the event handler using the switch statements as documented. I then use the stripe.customers.retrieve method to retrieve the customers email so that I can update their account on our database.
It looks like you've set your Connect webhook endpoint correctly. Can you look there and ensure that your code is similar to how you handle the Connect events?
So my best guess is that the stripe.customers.retrieve call is failing because of the unathorization 401 error, and the webhook is timing out because I'm not responding to it.
Ah! Yes, that makes sense now.
Yes, you would want to run that logic after you respond to Stripe with 200. That code will come from your and that is for you to handle so we can't dirently help there. However, I would recommend that you look at how you set your Connect webhook endpoint.
So I would handle this outside of the event handler?
I figured I should somehow respond with 200 in the event handler.
Wait I think on the doc you sent it says to do this:
response.json({received: true});
but I already do that....
But maybe it's not getting to that line because it errors on the stripe.customers.retrieve line.
You would not want to run any logic before you respond to Stripe, https://docs.stripe.com/webhooks#acknowledge-events-immediately
Can you make that request after you repond here?
I believe I could. Let me try that. Can you kindly keep this ticket open?
Will take 5 minutes please.
Yes, it worked!
Awesome @polar geode thanks for your support!
Yay, glad to hear!
If I may, could you give me a hand with that 401 unauthorization error?
I'm following the guideline now but it seems to think I'm unauthenticated.
That is the error you're seeing when you make that GET request right?
I recommend that review this https://docs.stripe.com/api/authentication
yeah when calling const customer = await stripe.customers.retrieve(userId);
Can you share the exact code with me? Where are you setting the API key? (Please redact your key)
the API key is stored in an env variable:
const stripesecret =
process.env.DEVSTATUS === "Production"
? process.env.STRIPE_SECRET_LIVE
: process.env.STRIPE_SECRET_KEY;
const stripe = require("stripe")(stripesecret);
STRIPE_SECRET_LIVE is the live API key which I'm using in this case.
What happens if you hard code the key instead of 'stripesecret'?
Trying to help debug this
Yeah ok let me try, it's always possible it's not getting loaded correctly.
To clarify - I need to place in my secret key not the publishable one right?
That is right
Well that was silly, it worked š¤¦āāļø
Ok, so now you need to debug that on your code
@polar geode you're a real one, best support out there š«”
@valid lily give him a raise
Thanks for the help I will debug the rest on my own. You may close this ticket.
Happy to help!