Repository navigation
[FIX] payment_mollie: don't acknowledge webhook on API failure - #290812
Closed
Josuesp1620 wants to merge 2 commits into
Closed
Josuesp1620 wants to merge 2 commits into
Josuesp1620 wants to merge 2 commits into
Conversation
Contributor
Josuesp1620
force-pushed
the
19.0-fix-mollie-webhook-retry
branch
from
September 28, 2026 15:28
f5d26fd to
c4d6d77
Compare
When fetching the payment from Mollie failed, the webhook still answered 200, so Mollie stopped retrying and the transaction stayed in draft. Answer 503 instead so that Mollie retries later. Unknown references are still acknowledged and the return route is unchanged. Fixes odoo#290678
AntoineVDV
force-pushed
the
19.0-fix-mollie-webhook-retry
branch
from
October 6, 2026 11:21
c4d6d77 to
418b24a
Compare
AntoineVDV
reviewed
Oct 6, 2026
AntoineVDV
left a comment
Contributor
There was a problem hiding this comment.
Hi @Josuesp1620, and thank you for the fix; it's indeed patching a gap in payment_mollie 🙂
To save time in back-and-forths, I allowed myself to push some small changes directly onto your branch, mainly to clarify the behavior to adopt in case of API request failure from the controllers' perspective.
Would you mind checking the diff below and letting me know if that's fine for you? Then we can merge this PR.
diff --git a/addons/payment_mollie/controllers/main.py b/addons/payment_mollie/controllers/main.py
index fa77054b8748..b4e4efeed9a8 100755
--- a/addons/payment_mollie/controllers/main.py
+++ b/addons/payment_mollie/controllers/main.py
@@ -37,7 +37,10 @@ class MollieController(http.Controller):
embedded in the return URL.
"""
_logger.info("handling redirection from Mollie with data:\n%s", pprint.pformat(data))
- self._verify_and_process(data)
+ try:
+ self._verify_and_process(data)
+ except ValidationError:
+ _logger.error("Unable to process the payment data")
return request.redirect('/payment/status')
@http.route(_webhook_url, type='http', auth='public', methods=['POST'], csrf=False)
@@ -48,34 +51,27 @@ class MollieController(http.Controller):
embedded in the return URL
:return: An empty string to acknowledge the notification
:rtype: str
+ :raise ServiceUnavailable: If the payment data could not be fetched from Mollie
"""
_logger.info("notification received from Mollie with data:\n%s", pprint.pformat(data))
- self._verify_and_process(data, from_webhook=True)
+ try:
+ self._verify_and_process(data)
+ except ValidationError as error:
+ _logger.error("Unable to process the payment data")
+ raise ServiceUnavailable from error
return '' # Acknowledge the notification
@staticmethod
- def _verify_and_process(data, from_webhook=False):
+ def _verify_and_process(data):
"""Verify and process the payment data sent by Mollie.
:param dict data: The payment data.
- :param bool from_webhook: Whether the data were sent to the webhook.
:return: None
- :raise ServiceUnavailable: If the payment data could not be fetched from Mollie while
- handling a webhook notification, so that Mollie retries later.
+ :raise ValidationError: If the payment data could not be fetched from Mollie
"""
tx_sudo = request.env['payment.transaction'].sudo()._search_by_reference('mollie', data)
if not tx_sudo:
return
- try:
- verified_data = tx_sudo._send_api_request(
- 'GET', f'/payments/{tx_sudo.provider_reference}'
- )
- except ValidationError:
- _logger.error("Unable to process the payment data")
- if from_webhook:
- # Don't acknowledge the notification: Mollie only retries calling the webhook when
- # it doesn't receive a 2xx response.
- raise ServiceUnavailable()
- else:
- tx_sudo._process('mollie', verified_data)
+ verified_data = tx_sudo._send_api_request("GET", f"/payments/{tx_sudo.provider_reference}")
+ tx_sudo._process("mollie", verified_data)
diff --git a/addons/payment_mollie/tests/test_mollie.py b/addons/payment_mollie/tests/test_mollie.py
index 2fb97fb66575..07bc5bae704a 100644
--- a/addons/payment_mollie/tests/test_mollie.py
+++ b/addons/payment_mollie/tests/test_mollie.py
@@ -40,45 +40,24 @@ class MollieTest(MollieCommon, PaymentHttpCommon):
self._make_http_post_request(url, data=self.payment_data)
self.assertEqual(tx.state, 'done')
- @mute_logger('odoo.addons.payment_mollie.controllers.main')
- def test_webhook_notification_not_acknowledged_when_payment_data_unavailable(self):
- """ Test that the webhook doesn't acknowledge the notification when the payment data can't
- be fetched from Mollie, so that Mollie retries later. """
- tx = self._create_transaction('redirect')
- url = self._build_url(MollieController._webhook_url)
+ @mute_logger("odoo.addons.payment_mollie.controllers.main")
+ def test_return_from_checkout_redirects_when_payment_data_unavailable(self):
+ self._create_transaction("redirect")
+ url = self._build_url(MollieController._return_url)
with patch(
- 'odoo.addons.payment.models.payment_provider.PaymentProvider._send_api_request',
+ "odoo.addons.payment.models.payment_provider.PaymentProvider._send_api_request",
side_effect=ValidationError("Service Unavailable"),
):
- response = self._make_http_post_request(url, data=self.payment_data)
- self.assertEqual(response.status_code, 503)
- self.assertEqual(tx.state, 'draft')
+ response = self._make_http_get_request(url, params=self.payment_data)
+ self.assertTrue(response.url.endswith('/payment/status'))
- @mute_logger('odoo.addons.payment.models.payment_transaction')
- def test_webhook_notification_acknowledged_for_unknown_reference(self):
- """ Test that the webhook acknowledges the notification when no transaction matches the
- reference, as Mollie recommends for unknown ids. """
+ @mute_logger("odoo.addons.payment_mollie.controllers.main")
+ def test_webhook_notification_is_rejected_when_payment_data_unavailable(self):
+ self._create_transaction("redirect")
url = self._build_url(MollieController._webhook_url)
with patch(
- 'odoo.addons.payment.models.payment_provider.PaymentProvider._send_api_request',
- ) as send_api_request_mock:
- response = self._make_http_post_request(
- url, data=dict(self.payment_data, ref='unknown reference'),
- )
- self.assertEqual(response.status_code, 200)
- send_api_request_mock.assert_not_called()
-
- @mute_logger('odoo.addons.payment_mollie.controllers.main')
- def test_return_redirects_to_status_page_when_payment_data_unavailable(self):
- """ Test that the customer is redirected to the status page when the payment data can't be
- fetched from Mollie. """
- tx = self._create_transaction('redirect')
- url = self._build_url(MollieController._return_url)
- with patch(
- 'odoo.addons.payment.models.payment_provider.PaymentProvider._send_api_request',
+ "odoo.addons.payment.models.payment_provider.PaymentProvider._send_api_request",
side_effect=ValidationError("Service Unavailable"),
):
- response = self._make_http_get_request(url, params=self.payment_data)
- self.assertEqual(response.status_code, 200)
- self.assertTrue(response.url.endswith('/payment/status'))
- self.assertEqual(tx.state, 'draft')
+ response = self._make_http_post_request(url, data=self.payment_data)
+ self.assertEqual(response.status_code, 503)
Contributor
Author
|
Thanks @AntoineVDV LGTM, and handling the errors in the controllers is definitely cleaner. Good to go from my side 👍 |
AntoineVDV
approved these changes
Oct 7, 2026
AntoineVDV
left a comment
Contributor
There was a problem hiding this comment.
@robodoo r+ rebase-ff
Contributor
|
Merge method set to rebase and fast-forward. |
robodoo
pushed a commit
that referenced
this pull request
Oct 8, 2026
Part-of: #290812 Signed-off-by: Antoine Vandevenne (anv) <[email protected]>
robodoo
pushed a commit
that referenced
this pull request
Oct 8, 2026
When fetching the payment from Mollie failed, the webhook still answered 200, so Mollie stopped retrying and the transaction stayed in draft. Answer 503 instead so that Mollie retries later. Unknown references are still acknowledged and the return route is unchanged. Fixes #290678 closes #290812 Signed-off-by: Antoine Vandevenne (anv) <[email protected]>
This was referenced Oct 8, 2026
terminalstate
added a commit
to terminalstate/terminalstate.github.io
that referenced
this pull request
Oct 8, 2026
terminalstate
added a commit
to terminalstate/callback-audit
that referenced
this pull request
Oct 8, 2026
terminalstate
added a commit
to terminalstate/callback-audit
that referenced
this pull request
Oct 9, 2026
3 of 4 tasks
This was referenced Oct 12, 2026
mekot-odoo
pushed a commit
to odoo-dev/odoo
that referenced
this pull request
Oct 26, 2026
Part-of: odoo#290812 Signed-off-by: Antoine Vandevenne (anv) <[email protected]>
mekot-odoo
pushed a commit
to odoo-dev/odoo
that referenced
this pull request
Oct 26, 2026
When fetching the payment from Mollie failed, the webhook still answered 200, so Mollie stopped retrying and the transaction stayed in draft. Answer 503 instead so that Mollie retries later. Unknown references are still acknowledged and the return route is unchanged. Fixes odoo#290678 closes odoo#290812 Signed-off-by: Antoine Vandevenne (anv) <[email protected]>
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

When fetching the payment from Mollie failed (connection error, timeout, 503, 429), the webhook still answered 200. Mollie only retries a webhook on a non-2xx response, so it stopped retrying and the transaction stayed in draft.
The webhook now answers 503 in that case so that Mollie retries later. Unknown references are still acknowledged with a 200, as Mollie recommends, and the return route is unchanged.
Fixes #290678
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr