Failed Webhooks
Webhooks allow payment providers to notify SolydFlow when something happens to a transaction.
In a reliable payment system, however, webhook delivery cannot be treated as guaranteed.
A webhook can fail to arrive, arrive late, be rejected, be duplicated, or fail while being processed.
SolydFlow Recover is designed to handle these situations so that a missed webhook does not automatically become a missed payment.
Payment Provider
↓
Webhook
↓
SolydFlow
↓
Transaction
↓
Entitlement
When the webhook does not complete the expected flow:
Payment Provider
↓
Webhook
X
↓
SolydFlow
↓
Recovery
↓
Verification
↓
Transaction
Why Webhooks Can Fail
Webhook delivery involves multiple systems.
For example:
Payment Provider
↓
Internet
↓
Webhook Endpoint
↓
Application / SolydFlow
↓
Event Processing
A failure can occur at several points.
Possible causes include:
- Temporary network failures
- Provider outages
- Endpoint unavailability
- Request timeouts
- Incorrect webhook configuration
- Authentication or signature failures
- Server errors
- Processing failures
- Duplicate events
- Delayed delivery
A failed webhook therefore does not necessarily mean that the underlying payment failed.
A Missing Webhook Does Not Mean a Failed Payment
Consider this scenario:
Customer
↓
Payment Provider
↓
Payment Successful
The provider then attempts to notify SolydFlow:
Payment Provider
↓
Webhook
X
The provider may still have:
Transaction = Successful
while SolydFlow has:
Transaction = Pending
This is a state synchronization problem, not necessarily a payment failure.
The Recovery Flow
When an expected webhook is not received or cannot be processed, SolydFlow can use recovery mechanisms to determine the current transaction state.
Expected Webhook
↓
Not Received
↓
Recovery Trigger
↓
Provider Verification
↓
Transaction State
↓
Entitlement
The important step is verification.
SolydFlow should not assume:
Webhook Missing
=
Payment Failed
or:
Webhook Missing
=
Payment Successful
Instead:
Webhook Missing
↓
Investigate
↓
Verify
↓
Resolve
Webhook Delivery vs Transaction State
A webhook is an event notification.
The transaction is the underlying payment record.
These should not be treated as the same thing.
Provider Transaction
│
├── Payment State
│
└── Webhook Event
A webhook can fail while the provider transaction remains valid.
For example:
Provider Transaction
└── Successful
Webhook
└── Not Delivered
SolydFlow's recovery process exists to bridge this gap.
Webhook Processing Failures
A webhook can also arrive successfully but fail during processing.
For example:
Provider
↓
Webhook
↓
SolydFlow
↓
Processing
X
The provider may have successfully delivered the event, but the event handler may have encountered an error.
Possible causes include:
- Temporary database failure
- Internal application error
- Invalid event data
- Processing timeout
- Dependency failure
- Unexpected provider response
In such cases, the webhook event itself may need to be retried or recovered.
Delivery Failure vs Processing Failure
These are different failure modes.
Delivery failure
The event never reaches the receiving system.
Provider
↓
Webhook
X
SolydFlow
Processing failure
The event reaches the receiving system but cannot be successfully processed.
Provider
↓
Webhook
↓
SolydFlow
↓
Processing
X
Both can result in a transaction that does not reach the expected state.
Duplicate Webhooks
Providers may retry webhook delivery.
This means the same event can potentially be delivered more than once.
Provider
↓
Webhook
↓
SolydFlow
Provider
↓
Webhook Again
↓
SolydFlow
The application should not interpret this as two separate payments.
The transaction should remain associated with the same underlying provider transaction.
Webhook #1 ──┐
├──→ Same Transaction
Webhook #2 ──┘
Webhook processing should therefore be designed to be safe when events are delivered more than once.
See:
Webhook Ordering
Events may not always arrive in the order in which they were generated.
For example:
Provider generates:
Event A
↓
Event B
↓
Event C
But the receiving system may observe:
Event B
↓
Event A
↓
Event C
This means event order should not automatically be treated as proof of the transaction's final state.
SolydFlow should use transaction information and provider state where necessary to determine the appropriate state.
Webhook Timeouts
A webhook endpoint may fail to respond within the expected time.
Provider
↓
Webhook
↓
SolydFlow
↓
Processing
↓
Timeout
The provider may then retry the event.
This can produce:
Attempt 1
↓
Timeout
Attempt 2
↓
Success
The receiving system must therefore safely handle repeated delivery.
Webhook Signature Failures
A webhook should be authenticated before its contents are trusted.
For example:
Webhook
↓
Signature Verification
↓
┌──────┴──────┐
↓ ↓
Valid Invalid
↓ ↓
Process Reject
An invalid signature should not simply be ignored as a harmless delivery problem.
It may indicate:
- Incorrect configuration
- Incorrect signing secret
- A malformed request
- A provider integration issue
- A potentially untrusted request
See:
Recovery After Signature Failure
An invalid webhook should not be treated as proof that the underlying transaction failed.
For example:
Webhook
↓
Signature Invalid
↓
Reject Event
The transaction may still exist at the provider.
Therefore:
Rejected Webhook
↓
Existing Transaction
↓
Provider Verification
↓
Resolved State
This keeps webhook security separate from transaction resolution.
Recovery After Provider Outage
A provider may temporarily become unavailable when SolydFlow needs to retrieve transaction information.
For example:
Recovery
↓
Provider API
X
Unavailable
SolydFlow should not interpret provider unavailability as payment failure.
Instead, the recovery workflow can wait and retry an appropriate operation.
Provider Unavailable
↓
Wait / Retry
↓
Provider Available
↓
Verify
↓
Resolve
See:
Detecting Missing Webhooks
A missing webhook can be detected when SolydFlow has reason to expect an event but does not observe the expected transaction progress.
For example:
Transaction
↓
Pending
↓
Expected Event
↓
Not Received
↓
Recovery Candidate
The system should account for legitimate provider processing delays before declaring the transaction abnormal.
Conceptually:
Pending
↓
Expected Processing Window
↓
┌──────┴──────┐
↓ ↓
Progress No Progress
↓ ↓
Continue Recover
Webhook Recovery vs Polling
Recovery may require querying the provider directly rather than waiting indefinitely for another webhook.
For example:
Webhook Missing
↓
Provider Query
↓
Current Transaction State
This can help determine what happened to the transaction.
The provider query should be used carefully and according to the provider's capabilities and rate limits.
Avoiding Duplicate Charges
Webhook failure should never automatically result in a new customer charge.
For example:
Payment
↓
Provider
↓
Successful
↓
Webhook Missing
It would be dangerous to respond with:
Charge Again
Instead:
Existing Transaction
↓
Verify
↓
┌─────┴─────┐
↓ ↓
Paid Not Paid
↓ ↓
Resolve New Attempt
This distinction protects against duplicate charges.
Webhook Recovery and Transaction Recovery
Failed webhook recovery is one part of the broader transaction recovery system.
Recover
│
┌───────────┼───────────┐
↓ ↓ ↓
Failed Webhooks Zombie Retries
│ │ │
└───────────┼───────────┘
↓
Transaction
Recovery
See:
Webhook Recovery and Zombie Transactions
A missing webhook can cause a transaction to remain pending long enough to become a zombie transaction.
Payment Successful
↓
Webhook Missing
↓
Transaction Pending
↓
No Progress
↓
Zombie
↓
Recovery
This is why failed webhook handling and zombie transaction detection work together.
See:
Webhook Recovery and Entitlements
The purpose of recovering a successful payment is ultimately to ensure that the customer's entitlement reflects the verified transaction.
Webhook Missing
↓
Recovery
↓
Provider Verification
↓
Successful Transaction
↓
Entitlement
↓
Application Access
The application should therefore derive access from the resulting transaction and entitlement state rather than from whether a particular webhook happened to arrive.
See:
Webhook Recovery and the Transaction Ledger
A recovered webhook event should remain traceable in the transaction history.
For example:
Transaction
├── Created
├── Pending
├── Expected Webhook Missing
├── Recovery Triggered
├── Provider Verified
└── Successful
This provides operational visibility into what happened.
It can also help with:
- Customer support
- Debugging
- Reconciliation
- Auditing
- Payment investigations
See:
Webhook Recovery and Reconciliation
Webhook failures can create differences between provider records and SolydFlow records.
For example:
Provider
└── Successful
SolydFlow
└── Pending
Recovery can resolve the individual transaction:
Provider
└── Successful
SolydFlow
└── Successful
Reconciliation can then help identify and resolve broader differences between systems.
See:
Designing Reliable Webhook Processing
A reliable webhook system should assume that:
Events may be:
✓ Delayed
✓ Duplicated
✓ Out of order
✓ Rejected
✓ Retried
✓ Temporarily unavailable
✓ Processed more than once
Therefore, webhook handling should be designed around transaction identity and state rather than assuming that every event is delivered exactly once and in perfect order.
Recommended Flow
A resilient webhook architecture looks like:
Payment Provider
↓
Webhook
↓
Signature Verification
↓
Event Validation
↓
Idempotent Processing
↓
Transaction Update
↓
Entitlement Update
If the webhook cannot complete the flow:
Webhook Failure
↓
Recovery
↓
Provider Verification
↓
Transaction Update
↓
Entitlement
What SolydFlow Should Protect Developers From
Without a centralized recovery layer, developers may need to implement:
Webhook Endpoint
+
Signature Verification
+
Duplicate Detection
+
Event Ordering
+
Retry Handling
+
Missing Event Detection
+
Provider Verification
+
Transaction Recovery
SolydFlow provides the infrastructure around these concerns so that the application can work with a consistent transaction model.
Key Principle
A webhook is a notification about a transaction, not the transaction itself.
If a webhook is lost, delayed, duplicated, or rejected, the underlying transaction may still exist and have a different state.
The recovery process should therefore be:
Webhook Problem
↓
Find Transaction
↓
Verify Provider State
↓
Resolve Transaction
↓
Update Entitlement
rather than:
Webhook Missing
↓
Assume Payment Failed