VIDEO 9:42
Stripe payment succeeded but the order is still pending: the webhook nobody set up
Published
Length 9:42
Spoken in English
Short answer
When a payment succeeds but the order stays pending, the payment provider took the money and your app was never told. A common cause in the AI-built and vibe-coded apps we reviewed is a webhook that was never registered in the provider’s dashboard. The next causes are duplicate or out-of-order events, fake unsigned requests, timeouts nobody handled, and silent errors. Kevin Riedl, who runs Wavect, walks through each one in a ten-minute video: Wavect has reviewed over 50 vibe-coded products in 2026. The failures shown were reproduced in a simulated shop (Wavect lab simulation), not in a client system.What the video covers
Stripe payment succeeded but the order never arrived
The money arrived, the order is still pending and nobody got an error. The bugs that hurt most in the products we reviewed sat at the edges, where your code meets someone else’s code. Watch from 0:00Why isn’t my Stripe webhook arriving? It was never registered
The endpoint must be configured in the provider’s dashboard, not only in your code, and it must be checked in production. Watch from 0:38What happens when Stripe sends the same webhook twice?
Retries mean the same event can arrive several times, late or out of order; handlers must be idempotent. Watch from 2:26How do I stop fake webhooks? Verify the signature
A public endpoint needs signature verification, and the AI often has to be told to add it. Watch from 3:25Request timed out: did the payment go through?
A timeout does not say whether the payment happened. Watch from 4:44Silent errors and expired API keys: how to notice them
Failures that nobody sees, including expired keys, show up as lost customers. Watch from 5:345 questions to ask before you call an integration done
What can go wrong, how do we notice, how do we recover, who gets alerted, how do we test. Watch from 7:20Frequently asked questions
Full transcript
Verbatim transcript of the spoken audio, matching the video captions.
Stripe payment succeeded but the order never arrived
Watch on YouTube · 0:00This customer paid but the shop never found out.
The money arrived, the order is still pending and nobody got an error or something remotely similar. So nobody actually knows that something is wrong.
Hi, I’m Kevin, I run Wavect and we have reviewed over 50 vibe-coded products this year alone.
And the bugs that really did hurt the most were the ones where it wasn’t about the code itself but rather about the edges when your code interacted with someone else’s code.
Why isn’t my Stripe webhook arriving? It was never registered
Watch on YouTube · 0:38In many cases, for example, just a webhook wasn’t properly configured when you, for example, have some kind of a payment flow or something like that and the payment event just doesn’t or didn’t arrive.
And a lot of these applications that we have reviewed, especially the fintech ones, for example, there were webhooks when you, for example, pay for a product or service and your application then usually redirects you to an external payment provider. And that payment provider, once the payment has been completed, sends a webhook, basically the notification to your own backend, to your own server that the payment has been completed or that it didn’t complete or any other state in between. And your application then usually reacts to that.
But oftentimes these vibe coders just forget that they have to configure stuff outside of their own application, their own infrastructure as well, for example, on the dashboard from Stripe or PayPal or whatever, just to make sure that they’re actually sending you that notification to your own web application.
So even though everything seems to work locally, you have your tests, you even might have end-to-end testing and all that stuff, still in production, when you actually have real users, it might not arrive.
And you basically have a serious bug because there’s no worse experience on earth than when you buy something and you think you don’t get it. That’s pretty shit, you know.
And also not to forget is that when you test, you usually test the happy path, or that’s basically where your main attention goes.
What happens when Stripe sends the same webhook twice?
Watch on YouTube · 2:26And the next part is like if one of these payments, for example, or these notifications are not successfully delivered, for example, by Stripe or any other payment provider, they usually keep retrying. So just in case you might have configured everything correctly, but then you receive a notification and for whatever reason your server returns an error code or something didn’t work the way it was supposed to, and Stripe sends another notification, another, another.
And if your backend or your algorithm isn’t idempotent, then you basically register that as multiple payments, even though it’s actually just one payment. And that’s, for obvious reasons, a problem.
And it even gets worse, these notifications might not be in the correct order or in the order that you assumed, it might come late, it might come, as mentioned, multiple times.
How do I stop fake webhooks? Verify the signature
Watch on YouTube · 3:25And just sticking with that example a little bit, for example, Stripe sends that notification to your backend. If you think about it, that means that endpoint where Stripe sends that notification needs to be public in some sort at least, because otherwise how could an external service on the internet call, send you that notification to your application?
To make sure that not unauthorized or fake payment providers or a malicious user can send you these fake notifications to act as if they’re paid, which is just as bad, just the other way around. And for that, you do have different mechanisms to avoid that, from IP, whitelisting, or webhook signatures, and so on.
But these are things that AI sometimes does, because AI is very smart in applying best practices. But oftentimes, you also have to point these things out explicitly, because your judgment tells you, hey, I need to do that, otherwise I’m going to be fucked or I’m going to be wrecked.
Request timed out: did the payment go through?
Watch on YouTube · 4:44And there are also oftentimes, let’s say, ambivalent or confusing errors that you get in your application. Let’s say a timeout, great example. For example, if you send a request on external service or external backend, which can be anything, and you get a timeout, you just have the information, okay, the request timed out, like I didn’t get the response, at least not in time.
Which means, in theory, your action, what you actually wanted to do, might have been executed successfully, it failed, or it might be executed at some later point in time, whatever. And these are things, certain edge cases that you have to deal with, and there are many more than you usually imagine.
Silent errors and expired API keys: how to notice them
Watch on YouTube · 5:34And the worst thing of all, when you build applications, is silent errors. Things that don’t scream at you. Because when your server crashes, you notice, at least when you have users or you use your application yourself. But when something just fails silently, you might not notice at all.
But oftentimes, it might be something that shows off in a different way, which might be users are just not using your service anymore. They’re not registering. They’re not coming back. They’re not buying from your e-commerce store because maybe the payment fails and they just give up on it, whatever.
And these are silent errors which can kill businesses, which can have huge implications in whatever regard of the context of the bug.
So, when you deal with secrets, you obviously want these passwords, API keys, whatever, especially as a vibe coder, or in general it’s just best practice, to expire at some point oftentimes, or most of the time. Because when they are leaked, when they get into the false hands, when they leak into the internet in some capacity, they obviously can be used, and that’s a problem. So when they expire, your application also won’t work, so you have to maintain that as well. So these are also possibly cryptic errors that you might get, like why is something not working anymore? It used to work for weeks, months, years. That’s maintenance.
5 questions to ask before you call an integration done
Watch on YouTube · 7:20So I like to think about it, let’s say, about four or five key things that you always should think about when you call a feature or product done. The first one would be, what actually could go wrong here, right? When I pay for something, what could go wrong? Well, it could go wrong that the payment doesn’t go through, it goes through twice.
And the next one is, when one of these bad situations is actually happening, how do we notice that? Do we have some kind of monitoring? Do we get a notification? Do we get user feedback in some way, which is also always a great thing to do in general?
And the next one is, how do we recover when something actually goes wrong? When data is corrupted, when we lost data, or when we are not just sure what the true state of the application is. Did the person pay?
What’s right? And these are all things that are real problems in the real world.
The next thing is, maybe you do have all these things, but who gets alerted? Who is responsible for that? Who is responding in time and fixing it and handling it and doing what?
And the last one is, how do we test actually all of that?
And that’s also something vibe coders oftentimes do wrong, especially the ones that came to us. We oftentimes weren’t aware that they launched this thing already with the client. And when they fixed something, they immediately pushed it to production and didn’t even test it. And things were just broken.
So to recap, connecting an API is just the first step at the real work as often is in the boring stuff, which means everything that comes afterwards in the maintenance, in the testing, in the monitoring, everything that makes sure this thing actually works under real pressure.