The PSP says, “We sent it.”
Your CRM says, “Never got it.”
The client has already sent a screenshot showing the money left their account.
And somewhere in the middle of all this, someone asks the inevitable question:
“Can you check the webhook?”
Welcome to one of the less glamorous corners of payment processing.
Webhooks and callbacks are supposed to keep your payment system, PSP, CRM, and client journey speaking the same language. But when that conversation breaks down, PSP webhook and callback problems can leave successful payments pending, statuses missing, or clients returning to the wrong page.
So, what exactly goes wrong?
Let’s figure out..
First, What Are PSP Webhooks and Callbacks?
Introducing a Webhook
A webhook is usually a server-to-server notification.
Something happens inside the payment provider, such as a payment being approved, declined, refunded, or updated, and the PSP sends an HTTP request to an endpoint configured by your system.
It could sound like this:
-PSP: Payment succeeded.
-Webhook: Hey CRM, thought you should know.
-CRM: Duly noted, thanks.
PSP platforms often describe webhooks this way: event-driven messages sent from their systems to an endpoint on yours.
Introducing A Callback
A callback works a little differently.
In many PSP payment flows, a callback is essentially the return trip for the client’s browser.
When you send a client to a PSP’s payment page, your system also gives the PSP a callback or return URL. Once the client finishes the payment process, the PSP redirects their browser back to that address, sometimes carrying information such as a transaction reference or an indication of the payment result along with it.
It could sound like this:
-Client: Done paying. Where do I go now?
-PSP: Back to the brokerage you came from.
-Callback: This way. I’ve got the return address.
-Broker website: Welcome back.
So, while a webhook is usually the PSP talking directly to your backend, a callback is often the PSP sending the client’s browser back to your website or app.
There is one small catch: payment providers do not all use the word callback in exactly the same way. Some use terms such as return URL, redirect URL, or callback URL for this browser-based journey.
QUICK NOTE
Seeing the client land on a shiny “Payment successful” page does not necessarily mean your CRM received the server-side payment notification.
The callback may have brought the client home safely while the webhook carrying the actual news to your backend is still missing. This topic deserves its own guide.
Now that the two are properly introduced, let’s look at the most common PSP webhook and callback problems and what to check when they happen.
1. The Webhook Was Sent to the Wrong URL
This is the payment-processing equivalent of confidently sending a message to someone's old phone number.
The PSP sends the webhook exactly where it was told to. Unfortunately, that could be an outdated URL, a test endpoint, or one tiny typo away from the right destination.
What to check:
-
the webhook URL configured in the PSP
-
whether it belongs to sandbox or live
-
whether the endpoint is publicly reachable
Sometimes, the boring answer wins.
2. The PSP Knocked, but Nobody Answered
Receiving the webhook is only half the conversation. Your server also needs to acknowledge it with a successful response.
If that response takes too long or fails, the PSP may assume nobody answered and try again.
So yes, your system may have processed the webhook while the PSP still thinks delivery failed.
Congratulations. Both sides can technically be right.
What to check:
-
the HTTP response code and response time
-
PSP and server logs at the same timestamp
-
whether heavy processing is delaying the acknowledgement
3. The Webhook Arrived, but the Signature Failed
Your system should not accept a random internet stranger announcing:
“Hello, this €5,000 deposit definitely succeeded. Trust me.”
That is why PSPs use webhook signatures or HMAC verification to prove the message really came from them.
If verification fails, the webhook may have arrived perfectly well.
Your server simply refused to believe it.
What to check:
-
the webhook secret or HMAC key
-
whether sandbox and live credentials got mixed up
-
whether the request body or signature is being handled correctly
The question here is no longer “Did we receive it?” but “Why didn’t we trust it?”
4. The PSP Sent the Same Webhook Twice
Seeing the same webhook twice does not mean the PSP suddenly developed short-term memory problems.
If an acknowledgement fails or gets delayed, the PSP may retry the event.
Your system therefore needs to recognize:
“I've already dealt with this one.”
That is the basic idea behind idempotent processing: repeated events should not create repeated actions.
What to check:
-
whether the first delivery was acknowledged successfully
-
whether both events carry the same transaction or event ID
-
whether duplicate events are safely ignored
A retry is normal. Processing the same payment twice is not.
5. The Webhooks Arrived in the Wrong Order
Computers are organized.
Networks, less so.
You may expect:
Pending → Authorized → Completed
But a delayed or retried webhook can arrive after a newer one.
If your system simply trusts whichever message appeared last, an older status can accidentally overwrite a newer one.
What to check:
-
event timestamps
-
whether an older webhook was retried later
-
whether your system compares payment states before updating them
The last webhook to arrive is not necessarily the one that deserves the final word.
6. Sandbox and Live Environments Got Mixed Up
Ah, sandbox.
The place where everything works beautifully five minutes before production stops cooperating.
Test and live environments usually have their own credentials, endpoints, signing secrets, and configurations. One leftover test setting can be enough to break a perfectly good live integration.
What to check:
-
the live webhook URL
-
live API credentials and signing secret
-
any leftover sandbox settings that followed you into production
Before questioning the laws of computing, check the environment.
7. A Firewall or Security Layer Blocked the Request
Sometimes the webhook never gets anywhere near your application.
A firewall, access rule, TLS problem, or security service can stop the request somewhere along the way.
The useful clue?
The PSP shows a delivery attempt, but your application has absolutely no record of it.
The message may never have reached the front door.
What to check:
-
whether the endpoint is publicly reachable
-
firewall, access-control, and security rules
-
server or network logs showing where the request stopped
Here, the question is simply: How far did the webhook actually get?
8. You Trusted the Callback Instead of the Webhook
A client completes the payment and lands on your success page.
Great.
But that only tells you where the client's browser ended up.
The callback handles the client journey. The webhook handles the backend payment update.
So:
“The client saw the success page”
and
“The CRM received the payment update”
are related statements.
They are not the same statement.
What to check:
-
whether the webhook for that transaction arrived
-
whether your system relied only on the callback
-
whether the callback and webhook reference the same transaction
When the two stories disagree, follow the payment event, not just the page the client landed on.
Maybe Your PSP Webhook and Callback Problems Need a Better CRM
Avoiding PSP webhook and callback problems takes more than simply connecting a CRM to a PSP. Webhooks, callbacks, verification, retries, logs, and transaction updates all need to work together so your team can see what is happening without playing detective every time a payment status looks suspicious.
With FXBO CRM, brokers can manage payment operations within a connected ecosystem designed to make client activity, transactions, and integrations easier to track and manage.
Because when money is moving, your systems should not be left asking each other:
“Wait... nobody told you?”
Explore FXBO CRM, request a free demo, and see how it can support smoother payment operations across your brokerage.