-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3592 from open-formulieren/feature/3005-add-confi…
…g-field [#3005] Rework payment flow
- Loading branch information
Showing
11 changed files
with
274 additions
and
2 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,3 +12,4 @@ General configuration | |
oidc | ||
cms_integration | ||
virus_scan | ||
payment_flow |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
.. _configuration_general_payment_flow: | ||
|
||
============ | ||
Payment flow | ||
============ | ||
|
||
For forms where a payment is required, it is possible to configure when the submission should be registered. | ||
The setting **Wait for payment to register** can be found in the admin in the **General configuration**, | ||
under the header **Registration**. | ||
|
||
If **Wait for payment to register** is checked, then a submission will only be sent to the registration backend when | ||
the payment is completed. Note that if the submission should also be co-signed, then it will be registered only when | ||
both the payment and the co-sign are completed. | ||
|
||
If **Wait for payment to register** is NOT checked, then the submission is registered as soon as it is completed (unless | ||
co-sign is also needed). Then, once payment is completed, the payment status will be updated in the registration backend. | ||
This means, that for registration backends that create a zaak (StUF-ZDS and ZGW registration backends), the | ||
status of the zaak will be updated. In the case of the email registration backend, a second email will be sent to notify | ||
that the payment has been received. For the MSGraph backend, the ``payment_status.txt`` file will be updated to say that | ||
the payment was received. |
This file contains 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
This file contains 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
22 changes: 22 additions & 0 deletions
22
src/openforms/config/migrations/0066_globalconfiguration_wait_for_payment_to_register.py
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Generated by Django 3.2.23 on 2023-12-12 08:50 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
("config", "0065_theme_uuid"), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name="globalconfiguration", | ||
name="wait_for_payment_to_register", | ||
field=models.BooleanField( | ||
default=False, | ||
help_text="Should a submission be processed (sent to the registration backend) only after payment has been received?", | ||
verbose_name="wait for payment to register", | ||
), | ||
), | ||
] |
This file contains 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
This file contains 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
4 changes: 4 additions & 0 deletions
4
src/openforms/logging/templates/logging/events/registration_skipped_not_yet_paid.txt
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{% load i18n %} | ||
{% blocktrans trimmed with lead=log.fmt_lead %} | ||
{{ lead }}: Skipped registration, because this submission is waiting for a payment. | ||
{% endblocktrans %} |
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,10 +5,12 @@ | |
from django.utils.translation import gettext_lazy as _ | ||
|
||
from privates.test import temp_private_root | ||
from testfixtures import LogCapture | ||
|
||
from openforms.appointments.exceptions import AppointmentRegistrationFailed | ||
from openforms.appointments.tests.utils import setup_jcc | ||
from openforms.authentication.constants import AuthAttribute | ||
from openforms.config.models import GlobalConfiguration | ||
from openforms.emails.tests.factories import ConfirmationEmailTemplateFactory | ||
from openforms.forms.tests.factories import FormDefinitionFactory | ||
from openforms.payments.constants import PaymentStatus | ||
|
@@ -211,6 +213,10 @@ def test_submission_completed_payment_needed(self): | |
patch( | ||
"openforms.registrations.contrib.email.plugin.EmailRegistration.update_payment_status" | ||
) as mock_payment_status_update, | ||
patch( | ||
"openforms.registrations.tasks.GlobalConfiguration.get_solo", | ||
return_value=GlobalConfiguration(wait_for_payment_to_register=False), | ||
), | ||
): | ||
on_post_submission_event(submission.id, PostSubmissionEvents.on_completion) | ||
|
||
|
@@ -447,6 +453,10 @@ def test_cosign_done_payment_needed_not_done(self): | |
patch( | ||
"openforms.registrations.contrib.email.plugin.EmailRegistration.update_payment_status" | ||
) as mock_payment_status_update, | ||
patch( | ||
"openforms.registrations.tasks.GlobalConfiguration.get_solo", | ||
return_value=GlobalConfiguration(wait_for_payment_to_register=False), | ||
), | ||
): | ||
with self.captureOnCommitCallbacks(execute=True): | ||
on_post_submission_event( | ||
|
@@ -597,6 +607,10 @@ def test_payment_done_cosign_not_needed(self): | |
patch( | ||
"openforms.registrations.contrib.email.plugin.EmailRegistration.update_payment_status" | ||
) as mock_payment_status_update, | ||
patch( | ||
"openforms.registrations.tasks.GlobalConfiguration.get_solo", | ||
return_value=GlobalConfiguration(wait_for_payment_to_register=False), | ||
), | ||
): | ||
with self.captureOnCommitCallbacks(execute=True): | ||
on_post_submission_event( | ||
|
@@ -967,3 +981,175 @@ def test_cosign_not_required_but_filled_in_does_not_proceed_with_registration(se | |
self.assertTrue(submission.cosign_request_email_sent) | ||
self.assertTrue(submission.confirmation_email_sent) | ||
self.assertEqual(submission.auth_info.value, "111222333") | ||
|
||
|
||
@temp_private_root() | ||
@override_settings(CELERY_TASK_ALWAYS_EAGER=True) | ||
class PaymentFlowTests(TestCase): | ||
def test_payment_required_and_not_should_wait_for_registration(self): | ||
""" | ||
The payment is required and has not been completed, and the general configuration says to NOT skip registration if | ||
the payment has not been completed. | ||
""" | ||
submission = SubmissionFactory.from_components( | ||
components_list=[ | ||
{ | ||
"key": "email", | ||
"type": "email", | ||
"label": "Email", | ||
"confirmationRecipient": True, | ||
} | ||
], | ||
completed=True, | ||
form__registration_backend="email", | ||
form__registration_backend_options={"to_emails": ["[email protected]"]}, | ||
form__product__price=10, | ||
form__payment_backend="demo", | ||
) | ||
SubmissionPaymentFactory.create( | ||
submission=submission, amount=10, status=PaymentStatus.started | ||
) | ||
|
||
with ( | ||
patch( | ||
"openforms.registrations.contrib.email.plugin.EmailRegistration.register_submission" | ||
) as mock_registration, | ||
patch( | ||
"openforms.registrations.tasks.GlobalConfiguration.get_solo", | ||
return_value=GlobalConfiguration(wait_for_payment_to_register=True), | ||
), | ||
LogCapture() as logs, | ||
): | ||
on_post_submission_event(submission.id, PostSubmissionEvents.on_completion) | ||
|
||
mock_registration.assert_not_called() | ||
logs.check_present( | ||
( | ||
"openforms.registrations.tasks", | ||
"DEBUG", | ||
f"Skipping registration for submission '{submission}' as the payment hasn't been received yet.", | ||
) | ||
) | ||
|
||
def test_payment_done_and_should_wait_for_payment( | ||
self, | ||
): | ||
""" | ||
The payment is required and has been completed, so registration should not be skipped regardless of the general | ||
configuration setting. | ||
""" | ||
submission = SubmissionFactory.from_components( | ||
components_list=[ | ||
{ | ||
"key": "email", | ||
"type": "email", | ||
"label": "Email", | ||
"confirmationRecipient": True, | ||
} | ||
], | ||
form__registration_backend="email", | ||
form__registration_backend_options={"to_emails": ["[email protected]"]}, | ||
form__product__price=10, | ||
form__payment_backend="demo", | ||
completed=True, | ||
with_completed_payment=True, | ||
) | ||
|
||
with ( | ||
patch( | ||
"openforms.registrations.contrib.email.plugin.EmailRegistration.register_submission" | ||
) as mock_registration, | ||
patch( | ||
"openforms.registrations.tasks.GlobalConfiguration.get_solo", | ||
return_value=GlobalConfiguration(wait_for_payment_to_register=True), | ||
), | ||
patch( | ||
"openforms.payments.tasks.update_submission_payment_registration" | ||
) as mock_update_payment_status, | ||
): | ||
on_post_submission_event(submission.id, PostSubmissionEvents.on_completion) | ||
|
||
mock_registration.assert_called_once() | ||
mock_update_payment_status.assert_not_called() | ||
|
||
def test_payment_done_and_not_should_wait_for_payment( | ||
self, | ||
): | ||
""" | ||
The payment is required and has been completed, so registration should not be skipped regardless of the general | ||
configuration setting. | ||
""" | ||
|
||
submission = SubmissionFactory.create( | ||
form__registration_backend="email", | ||
form__registration_backend_options={"to_emails": ["[email protected]"]}, | ||
form__product__price=10, | ||
form__payment_backend="demo", | ||
completed=True, | ||
with_completed_payment=True, | ||
) | ||
|
||
with ( | ||
patch( | ||
"openforms.registrations.contrib.email.plugin.EmailRegistration.register_submission" | ||
) as mock_registration, | ||
patch( | ||
"openforms.registrations.tasks.GlobalConfiguration.get_solo", | ||
return_value=GlobalConfiguration(wait_for_payment_to_register=False), | ||
), | ||
): | ||
on_post_submission_event(submission.id, PostSubmissionEvents.on_completion) | ||
|
||
mock_registration.assert_called_once() | ||
|
||
def test_payment_not_required_and_should_wait_for_payment( | ||
self, | ||
): | ||
""" | ||
The payment is NOT required, so registration should not be skipped regardless of the general | ||
configuration setting. | ||
""" | ||
submission = SubmissionFactory.create( | ||
form__registration_backend="email", | ||
form__registration_backend_options={"to_emails": ["[email protected]"]}, | ||
completed=True, | ||
) | ||
|
||
with ( | ||
patch( | ||
"openforms.registrations.contrib.email.plugin.EmailRegistration.register_submission" | ||
) as mock_registration, | ||
patch( | ||
"openforms.registrations.tasks.GlobalConfiguration.get_solo", | ||
return_value=GlobalConfiguration(wait_for_payment_to_register=True), | ||
), | ||
): | ||
on_post_submission_event(submission.id, PostSubmissionEvents.on_completion) | ||
|
||
mock_registration.assert_called_once() | ||
|
||
def test_payment_not_required_and_not_should_wait_for_payment( | ||
self, | ||
): | ||
""" | ||
The payment is NOT required, so registration should not be skipped regardless of the general | ||
configuration setting. | ||
""" | ||
submission = SubmissionFactory.create( | ||
form__registration_backend="email", | ||
form__registration_backend_options={"to_emails": ["[email protected]"]}, | ||
completed=True, | ||
) | ||
|
||
with ( | ||
patch( | ||
"openforms.registrations.contrib.email.plugin.EmailRegistration.register_submission" | ||
) as mock_registration, | ||
patch( | ||
"openforms.registrations.tasks.GlobalConfiguration.get_solo", | ||
return_value=GlobalConfiguration(wait_for_payment_to_register=False), | ||
), | ||
): | ||
on_post_submission_event(submission.id, PostSubmissionEvents.on_completion) | ||
|
||
mock_registration.assert_called_once() |