From a45e537079011249b6f82a722f75ea8cd9868735 Mon Sep 17 00:00:00 2001 From: Sergei Maertens Date: Mon, 16 Dec 2024 15:20:02 +0100 Subject: [PATCH 1/2] :sparkles: [#3457] Support custom templates for Ogone COM and TITLE parameters The COM parameter is sent/displayed in the payment receipts of the merchant and can contain references for the organization's administration. The TITLE is (supposedly) displayed on the payment page, however this seems not to be functioning with the simulator. If no custom templates are specified, we use the legacy behaviour and include a hardcoded description. --- .../forms/tests/test_import_export.py | 7 +- .../payments/contrib/ogone/client.py | 7 +- .../payments/contrib/ogone/plugin.py | 58 ++++- ...ientTest.test_com_title_unicode_chars.yaml | 198 ++++++++++++++++++ .../contrib/ogone/tests/test_client.py | 17 ++ .../contrib/ogone/tests/test_plugin.py | 51 ++++- .../payments/contrib/ogone/typing.py | 2 + src/openforms/variables/service.py | 3 +- 8 files changed, 332 insertions(+), 11 deletions(-) create mode 100644 src/openforms/payments/contrib/ogone/tests/files/vcr_cassettes/OgoneClientTest/OgoneClientTest.test_com_title_unicode_chars.yaml diff --git a/src/openforms/forms/tests/test_import_export.py b/src/openforms/forms/tests/test_import_export.py index d0cad6ee0b..6cdf1ce38e 100644 --- a/src/openforms/forms/tests/test_import_export.py +++ b/src/openforms/forms/tests/test_import_export.py @@ -304,7 +304,12 @@ def test_import(self): self.assertEqual(imported_form.authentication_backends, ["digid"]) self.assertEqual(imported_form.payment_backend, "ogone-legacy") self.assertEqual( - imported_form.payment_backend_options, {"merchant_id": merchant.id} + imported_form.payment_backend_options, + { + "merchant_id": merchant.id, + "com_template": "", + "title_template": "", + }, ) form_definitions = FormDefinition.objects.order_by("pk") diff --git a/src/openforms/payments/contrib/ogone/client.py b/src/openforms/payments/contrib/ogone/client.py index 4591932fde..27f86e536d 100644 --- a/src/openforms/payments/contrib/ogone/client.py +++ b/src/openforms/payments/contrib/ogone/client.py @@ -27,7 +27,8 @@ def get_payment_info( amount_cents: int, return_url: str, return_action_param: str, - description: str = "", + title: str = "", + com: str = "", **extra_params ) -> PaymentInfo: # base params @@ -37,8 +38,8 @@ def get_payment_info( LANGUAGE="nl_NL", ORDERID=order_id, PSPID=self.merchant.pspid, - TITLE=description, # doesnt work?? - COM=description, + TITLE=title, # unsure if this works - doesn't seem to be displayed in simulator? + COM=com, ) # add action variations to base return url url = furl(return_url) diff --git a/src/openforms/payments/contrib/ogone/plugin.py b/src/openforms/payments/contrib/ogone/plugin.py index ffba9e267d..fe6394407d 100644 --- a/src/openforms/payments/contrib/ogone/plugin.py +++ b/src/openforms/payments/contrib/ogone/plugin.py @@ -15,7 +15,10 @@ from openforms.frontend import get_frontend_redirect_url from openforms.logging import logevent from openforms.submissions.tokens import submission_status_token_generator +from openforms.template import render_from_string, sandbox_backend +from openforms.template.validators import DjangoTemplateValidator from openforms.utils.mixins import JsonSchemaSerializerMixin +from openforms.variables.service import get_variables_for_context from ...base import BasePlugin from ...constants import PAYMENT_STATUS_FINAL, UserAction @@ -36,6 +39,38 @@ class OgoneOptionsSerializer(JsonSchemaSerializerMixin, serializers.Serializer): required=True, help_text=_("Merchant to use"), ) + title_template = serializers.CharField( + required=False, + allow_blank=True, + default="", + label=_("TITLE template"), + validators=[ + DjangoTemplateValidator(backend="openforms.template.sandbox_backend") + ], + help_text=_( + "Optional custom template for the title displayed on the payment page. " + "You can use all form variables (using their keys) and the " + "`public_reference` template variable. If unspecified, a default " + "description is used." + ), + ) + com_template = serializers.CharField( + required=False, + allow_blank=True, + default="", + label=_("COM template"), + validators=[ + DjangoTemplateValidator(backend="openforms.template.sandbox_backend") + ], + help_text=_( + "Optional custom template for the description, included in the payment " + "overviews for the backoffice. Use this to link the payment back to a " + "particular process or form. You can use all form variables (using their " + "keys) and the `public_reference` template variable. If unspecified, a " + "default description is used. Note that the length of the result is capped " + "to 100 characters and only alpha-numeric characters are allowed." + ), + ) RETURN_ACTION_PARAM = "action" @@ -57,8 +92,24 @@ def start_payment( return_url = self.get_return_url(request, payment) - description = ( - f"{_('Submission')}: {payment.submission.public_registration_reference}" + public_reference = payment.submission.public_registration_reference + default_description = f"{_('Submission')}: {public_reference}" + + # evaluate custom templates, if specified + template_context = get_variables_for_context(payment.submission) + template_context["public_reference"] = public_reference + + title_value = ( + render_from_string( + title_template, template_context, backend=sandbox_backend + ) + if (title_template := options["title_template"]) + else default_description + ) + com_value = ( + render_from_string(com_template, template_context, backend=sandbox_backend) + if (com_template := options["com_template"]) + else default_description ) info = client.get_payment_info( @@ -66,7 +117,8 @@ def start_payment( amount_cents, return_url, RETURN_ACTION_PARAM, - description, + title=title_value, + com=com_value[:100], ) return info diff --git a/src/openforms/payments/contrib/ogone/tests/files/vcr_cassettes/OgoneClientTest/OgoneClientTest.test_com_title_unicode_chars.yaml b/src/openforms/payments/contrib/ogone/tests/files/vcr_cassettes/OgoneClientTest/OgoneClientTest.test_com_title_unicode_chars.yaml new file mode 100644 index 0000000000..7096f950cd --- /dev/null +++ b/src/openforms/payments/contrib/ogone/tests/files/vcr_cassettes/OgoneClientTest/OgoneClientTest.test_com_title_unicode_chars.yaml @@ -0,0 +1,198 @@ +interactions: +- request: + body: PSPID=maykinmedia&ORDERID=xyz2024%2FOF-123456%2F987654321&AMOUNT=1000&CURRENCY=EUR&LANGUAGE=nl_NL&TITLE=l%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4mp%21+l%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4mp%21+l%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4mp%21+l%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4mp%21+l%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4mp%21+l%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4mp%21+l%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4mp%21+l%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4mp%21+l%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4mp%21+l%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4%C3%A4mp%21&PMLISTTYPE=2&ACCEPTURL=http%3A%2F%2Ffoo.bar%2Freturn%3Fbazz%3Dbuzz%26action%3Daccept&DECLINEURL=http%3A%2F%2Ffoo.bar%2Freturn%3Fbazz%3Dbuzz%26action%3Dcancel&EXCEPTIONURL=http%3A%2F%2Ffoo.bar%2Freturn%3Fbazz%3Dbuzz%26action%3Dexception&CANCELURL=http%3A%2F%2Ffoo.bar%2Freturn%3Fbazz%3Dbuzz%26action%3Dcancel&BACKURL=http%3A%2F%2Ffoo.bar%2Freturn%3Fbazz%3Dbuzz%26action%3Dcancel&COM=br%C3%B8ther+i+desire+l%C3%B6%C3%B6ps&SHASIGN=EF6D7725AC3A447821DB9E5997FDC2A9B8F4A7403E091A45A25146E98950B6BF433EDEC00D1B7B542AF82C3912B64598F5A44493465C3C31070FE4DA4B72809B + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, br + Connection: + - keep-alive + Content-Length: + - '1570' + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - python-requests/2.32.2 + method: POST + uri: https://ogone.test.v-psp.com/ncol/test/orderstandard_utf8.asp + response: + body: + string: "\r\n\r\n\r\n \r\n \r\n + \ \r\n + \ \r\n + \ Payment confirmation\r\n \r\n + \ \r\n\r\n\r\n
\r\n
\r\n \r\n
\r\n
\r\n\r\n\r\n\t\r\n\t

Overzicht van de bestelling

\r\n\t\r\n\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\r\n\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t
Referentie van de bestelling + :xyz2024/OF-123456/987654321
\r\n\t\t\t\t\t\t\tTotale + kostprijs :\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t10.00 + EUR\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t
Begunstigde :Maykin Media B.V.
\r\n\t\r\n\t\t\r\n\t\t\r\n\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\r\n\t\t\r\n\t\r\n\r\n\t\r\n\t\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\r\n\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n + \ \r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\r\n\r\n\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t
\r\n\t\t\t\t\t\t\tKies uw bank en klik op + "Ga verder" om bij uw bank met iDEAL te betalen.\r\n\t\t\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\"iDEAL\"\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\r\n\t\r\n\t\r\n\t\r\n\r\n

Bijkomende informatie / Annuleren

\r\n\r\n\t\r\n\t\t\r\n\t\t\t\t\r\n\r\n\t\t\r\n\t\t\r\n\r\n
\"ING\"\"Betaling
Over Worldline |Veiligheid| Wettelijke informatie
 
\r\n\t\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n\r\n\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t
\r\n\t\t\t\t\t\t
\r\n\t\t\t\t
\r\n
\r\n
\r\n\r\n" + headers: + cache-control: + - private, max-age=0 + content-length: + - '14059' + content-type: + - text/html; Charset=utf-8 + date: + - Mon, 16 Dec 2024 14:42:34 GMT + expires: + - Mon, 16 Dec 2024 14:41:34 GMT + set-cookie: + - sessionTest=a866c2ae-aa5f-4421-8eeb-ccf240ddff73; path=/ncol/test/; Secure; + HttpOnly + strict-transport-security: + - max-age=16000000; includeSubDomains; preload; + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +version: 1 diff --git a/src/openforms/payments/contrib/ogone/tests/test_client.py b/src/openforms/payments/contrib/ogone/tests/test_client.py index d8a0db552d..3505592785 100644 --- a/src/openforms/payments/contrib/ogone/tests/test_client.py +++ b/src/openforms/payments/contrib/ogone/tests/test_client.py @@ -53,6 +53,23 @@ def test_payment_request_invalid_order_id(self): self.assertIn("Er is een fout opgetreden", payment_request.text) + def test_com_title_unicode_chars(self): + client = OgoneClient(self.merchant) + + info = client.get_payment_info( + "xyz2024/OF-123456/987654321", + 1000, + "http://foo.bar/return?bazz=buzz", + RETURN_ACTION_PARAM, + title="läääääääääääääämp! " * 10, # 190 chars + com="brøther i desire lööps", + ) + + payment_request = requests.post(info.url, data=info.data) + + # Response is always a 200, so we assert on the content instead + self.assertNotIn("Er is een fout opgetreden", payment_request.text) + class OgoneGetPaymentInfoTest(TestCase): maxDiff = None diff --git a/src/openforms/payments/contrib/ogone/tests/test_plugin.py b/src/openforms/payments/contrib/ogone/tests/test_plugin.py index 2ffb503e66..45ee3247c3 100644 --- a/src/openforms/payments/contrib/ogone/tests/test_plugin.py +++ b/src/openforms/payments/contrib/ogone/tests/test_plugin.py @@ -11,10 +11,13 @@ from ....registry import register from ....tests.factories import SubmissionPaymentFactory from ..constants import OgoneStatus, PaymentStatus -from ..plugin import RETURN_ACTION_PARAM +from ..plugin import RETURN_ACTION_PARAM, OgoneLegacyPaymentPlugin from ..signing import calculate_sha_out +from ..typing import PaymentOptions from .factories import OgoneMerchantFactory +factory = RequestFactory() + @override_settings( CORS_ALLOW_ALL_ORIGINS=False, @@ -43,7 +46,6 @@ def test_payment(self): plugin = register["ogone-legacy"] # we need an arbitrary request - factory = RequestFactory() request = factory.get("/foo") # start url @@ -147,7 +149,6 @@ def test_webhook(self): plugin = register["ogone-legacy"] # we need an arbitrary request - factory = RequestFactory() request = factory.get("/foo") # start url @@ -203,3 +204,47 @@ def test_apply_status(self): plugin.apply_status(payment, OgoneStatus.payment_requested, "12345") # still registered self.assertEqual(payment.status, PaymentStatus.registered) + + def test_custom_com_and_title_attributes(self): + merchant = OgoneMerchantFactory.create() + submission = SubmissionFactory.from_components( + components_list=[ + { + "type": "textfield", + "key": "inputField", + "label": "Some text input", + } + ], + submitted_data={"inputField": "bröther gib lämp"}, + with_public_registration_reference=True, + public_registration_reference="OF-1234", + form__payment_backend="ogone-legacy", + form__product__price=Decimal("11.35"), + ) + payment = SubmissionPaymentFactory.for_submission(submission) + assert submission.payment_required + assert not submission.payment_user_has_paid + plugin = OgoneLegacyPaymentPlugin("ogone-legacy") + options: PaymentOptions = { + "merchant_id": merchant, + # No length limit applies to the title + "title_template": r"Input: {{ inputField }} - ref: {{ public_reference }}", + # result must be capped at 100 chars, see + # https://support.legacy.worldline-solutions.com/en/help/parameter-cookbook + "com_template": r"Input: {{ inputField }} - ref: {{ public_reference }} " + + "A" * 90, + } + # we need an arbitrary request + request = factory.get("/foo") + + payment_info = plugin.start_payment(request, payment, options) + + assert payment_info.data is not None + self.assertEqual( + payment_info.data["TITLE"], "Input: bröther gib lämp - ref: OF-1234" + ) + self.assertEqual( + payment_info.data["COM"], + "Input: bröther gib lämp - ref: OF-1234 " + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ) diff --git a/src/openforms/payments/contrib/ogone/typing.py b/src/openforms/payments/contrib/ogone/typing.py index c8944d68dd..1334426494 100644 --- a/src/openforms/payments/contrib/ogone/typing.py +++ b/src/openforms/payments/contrib/ogone/typing.py @@ -5,3 +5,5 @@ class PaymentOptions(TypedDict): merchant_id: OgoneMerchant # FIXME: key is badly named in the serializer + title_template: str + com_template: str diff --git a/src/openforms/variables/service.py b/src/openforms/variables/service.py index 6a1877f718..1bef547517 100644 --- a/src/openforms/variables/service.py +++ b/src/openforms/variables/service.py @@ -8,8 +8,9 @@ from .base import BaseStaticVariable from .registry import register_static_variable as static_variables_registry +from .utils import get_variables_for_context -__all__ = ["get_static_variables"] +__all__ = ["get_static_variables", "get_variables_for_context"] type VariablesRegistry = BaseRegistry[BaseStaticVariable] From 034355027c576dedb9713a036850d1f0d5f81461 Mon Sep 17 00:00:00 2001 From: Sergei Maertens Date: Mon, 16 Dec 2024 16:49:16 +0100 Subject: [PATCH 2/2] :sparkles: [#3457] Expose new fields in Ogone payment options Added the com template and title template configuration fields to the configuration options modal. --- src/openforms/js/compiled-lang/en.json | 96 +++++++++++++++++++ src/openforms/js/compiled-lang/nl.json | 96 +++++++++++++++++++ .../ogone_legacy/OgoneLegacyOptionsForm.js | 4 +- .../payments/ogone_legacy/fields.js | 73 ++++++++++++++ src/openforms/js/lang/en.json | 20 ++++ src/openforms/js/lang/nl.json | 20 ++++ 6 files changed, 308 insertions(+), 1 deletion(-) diff --git a/src/openforms/js/compiled-lang/en.json b/src/openforms/js/compiled-lang/en.json index 8ca003173f..ec3df680d7 100644 --- a/src/openforms/js/compiled-lang/en.json +++ b/src/openforms/js/compiled-lang/en.json @@ -2293,6 +2293,60 @@ "value": "The data entered in this component will be removed in accordance with the privacy settings." } ], + "JHQfjZ": [ + { + "type": 0, + "value": "Optional custom template for the the description, included in the payment overviews for the backoffice. Use this to link the payment back to a particular process or form." + }, + { + "children": [ + ], + "type": 8, + "value": "br" + }, + { + "type": 0, + "value": " You can use all form variables (using their keys) and the " + }, + { + "children": [ + { + "type": 0, + "value": "public_reference" + } + ], + "type": 8, + "value": "code" + }, + { + "type": 0, + "value": " template variable. If unspecified, a default description is used." + }, + { + "children": [ + ], + "type": 8, + "value": "br" + }, + { + "type": 0, + "value": " " + }, + { + "children": [ + { + "type": 0, + "value": "Note" + } + ], + "type": 8, + "value": "strong" + }, + { + "type": 0, + "value": ": the length of the result is capped to 100 characters." + } + ], "JKq3TC": [ { "type": 0, @@ -3887,6 +3941,12 @@ "value": "The processing (\"verwerking\") for queries to the BRP Persoon API." } ], + "ZSvQcR": [ + { + "type": 0, + "value": "TITLE parameter" + } + ], "ZdZ2Mb": [ { "type": 0, @@ -4445,6 +4505,12 @@ "value": "'Save row' text" } ], + "eZJFP7": [ + { + "type": 0, + "value": "COM parameter" + } + ], "ee4oWr": [ { "type": 0, @@ -6243,6 +6309,36 @@ "value": "The content of the submission confirmation page. It can contain variables that will be templated from the submitted form data. If not specified, the global template will be used." } ], + "vikURf": [ + { + "type": 0, + "value": "Optional custom template for the title displayed on the payment page." + }, + { + "children": [ + ], + "type": 8, + "value": "br" + }, + { + "type": 0, + "value": " You can use all form variables (using their keys) and the " + }, + { + "children": [ + { + "type": 0, + "value": "public_reference" + } + ], + "type": 8, + "value": "code" + }, + { + "type": 0, + "value": " template variable. If unspecified, a default description is used." + } + ], "vlY36U": [ { "type": 0, diff --git a/src/openforms/js/compiled-lang/nl.json b/src/openforms/js/compiled-lang/nl.json index d452780cad..e28e7035e1 100644 --- a/src/openforms/js/compiled-lang/nl.json +++ b/src/openforms/js/compiled-lang/nl.json @@ -2314,6 +2314,60 @@ "value": "Gegevens opgevoerd in dit component worden geschoond volgens de privacy-instellingen." } ], + "JHQfjZ": [ + { + "type": 0, + "value": "Optional custom template for the the description, included in the payment overviews for the backoffice. Use this to link the payment back to a particular process or form." + }, + { + "children": [ + ], + "type": 8, + "value": "br" + }, + { + "type": 0, + "value": " You can use all form variables (using their keys) and the " + }, + { + "children": [ + { + "type": 0, + "value": "public_reference" + } + ], + "type": 8, + "value": "code" + }, + { + "type": 0, + "value": " template variable. If unspecified, a default description is used." + }, + { + "children": [ + ], + "type": 8, + "value": "br" + }, + { + "type": 0, + "value": " " + }, + { + "children": [ + { + "type": 0, + "value": "Note" + } + ], + "type": 8, + "value": "strong" + }, + { + "type": 0, + "value": ": the length of the result is capped to 100 characters." + } + ], "JKq3TC": [ { "type": 0, @@ -3905,6 +3959,12 @@ "value": "De waarde voor \"verwerking\" die meegestuurd wordt bij het bevragen van de BRP Personen API. Mogelijke waarden hiervoor zijn afhankelijk van je gateway-leverancier." } ], + "ZSvQcR": [ + { + "type": 0, + "value": "TITLE parameter" + } + ], "ZdZ2Mb": [ { "type": 0, @@ -4467,6 +4527,12 @@ "value": "'Groep bewaren'-tekst" } ], + "eZJFP7": [ + { + "type": 0, + "value": "COM parameter" + } + ], "ee4oWr": [ { "type": 0, @@ -6265,6 +6331,36 @@ "value": "De inhoud van bevestigingspagina na het versturen van de inzending. Dit sjabloon mag variabelen bevatten met inzendings-gegevens. Laat dit veld leeg om de standaardinstelling te gebruiken." } ], + "vikURf": [ + { + "type": 0, + "value": "Optional custom template for the title displayed on the payment page." + }, + { + "children": [ + ], + "type": 8, + "value": "br" + }, + { + "type": 0, + "value": " You can use all form variables (using their keys) and the " + }, + { + "children": [ + { + "type": 0, + "value": "public_reference" + } + ], + "type": 8, + "value": "code" + }, + { + "type": 0, + "value": " template variable. If unspecified, a default description is used." + } + ], "vlY36U": [ { "type": 0, diff --git a/src/openforms/js/components/admin/form_design/payments/ogone_legacy/OgoneLegacyOptionsForm.js b/src/openforms/js/components/admin/form_design/payments/ogone_legacy/OgoneLegacyOptionsForm.js index 7bc97308d0..74e83f3859 100644 --- a/src/openforms/js/components/admin/form_design/payments/ogone_legacy/OgoneLegacyOptionsForm.js +++ b/src/openforms/js/components/admin/form_design/payments/ogone_legacy/OgoneLegacyOptionsForm.js @@ -11,7 +11,7 @@ import { import {getChoicesFromSchema} from 'utils/json-schema'; import OptionsConfiguration from '../OptionsConfiguration'; -import {MerchantID} from './fields'; +import {ComTemplate, MerchantID, TitleTemplate} from './fields'; const OgoneLegacyOptionsForm = ({schema, formData, onSubmit}) => { const validationErrors = useContext(ValidationErrorContext); @@ -41,6 +41,8 @@ const OgoneLegacyOptionsForm = ({schema, formData, onSubmit}) => {
+ +
diff --git a/src/openforms/js/components/admin/form_design/payments/ogone_legacy/fields.js b/src/openforms/js/components/admin/form_design/payments/ogone_legacy/fields.js index 785817854b..492f3ae24f 100644 --- a/src/openforms/js/components/admin/form_design/payments/ogone_legacy/fields.js +++ b/src/openforms/js/components/admin/form_design/payments/ogone_legacy/fields.js @@ -1,8 +1,10 @@ +import {useField} from 'formik'; import PropTypes from 'prop-types'; import {FormattedMessage} from 'react-intl'; import Field from 'components/admin/forms/Field'; import FormRow from 'components/admin/forms/FormRow'; +import {TextInput} from 'components/admin/forms/Inputs'; import ReactSelect from 'components/admin/forms/ReactSelect'; export const MerchantID = ({options}) => ( @@ -21,6 +23,7 @@ export const MerchantID = ({options}) => ( defaultMessage="Which merchant should be used for payments related to this form." /> } + required > @@ -35,3 +38,73 @@ MerchantID.propTypes = { }) ).isRequired, }; + +export const TitleTemplate = () => { + const [fieldProps] = useField('titleTemplate'); + return ( + + + } + helpText={ +
+ You can use all form variables (using their keys) and the public_reference + template variable. If unspecified, a default description is used.`} + values={{ + br: () =>
, + code: chunks => {chunks}, + }} + /> + } + > + +
+
+ ); +}; + +TitleTemplate.propTypes = {}; + +export const ComTemplate = () => { + const [fieldProps] = useField('comTemplate'); + return ( + + + } + helpText={ +
+ You can use all form variables (using their keys) and the public_reference + template variable. If unspecified, a default description is used.

+ Note: the length of the result is capped to 100 characters.`} + values={{ + br: () =>
, + code: chunks => {chunks}, + strong: chunks => {chunks}, + }} + /> + } + > + +
+
+ ); +}; + +ComTemplate.propTypes = {}; diff --git a/src/openforms/js/lang/en.json b/src/openforms/js/lang/en.json index cdfe481ba4..b814ef1c8e 100644 --- a/src/openforms/js/lang/en.json +++ b/src/openforms/js/lang/en.json @@ -1079,6 +1079,11 @@ "description": "Modal title API call failed with HTTP 401", "originalDefault": "Authentication failure" }, + "JHQfjZ": { + "defaultMessage": "Optional custom template for the the description, included in the payment overviews for the backoffice. Use this to link the payment back to a particular process or form.

You can use all form variables (using their keys) and the public_reference template variable. If unspecified, a default description is used.

Note: the length of the result is capped to 100 characters.", + "description": "Ogone legacy payment options 'comTemplate' help text", + "originalDefault": "Optional custom template for the the description, included in the payment overviews for the backoffice. Use this to link the payment back to a particular process or form.

You can use all form variables (using their keys) and the public_reference template variable. If unspecified, a default description is used.

Note: the length of the result is capped to 100 characters." + }, "JKq3TC": { "defaultMessage": "Medewerker roltype", "description": "Objects API registration options 'medewerkerRoltype' label", @@ -1839,6 +1844,11 @@ "description": "Form 'BRP Personen processing header value' field help text", "originalDefault": "The processing (\"verwerking\") for queries to the BRP Persoon API." }, + "ZSvQcR": { + "defaultMessage": "TITLE parameter", + "description": "Ogone legacy payment options 'titleTemplate' label", + "originalDefault": "TITLE parameter" + }, "ZdZ2Mb": { "defaultMessage": "Set the registration backend to use for the submission", "description": "action type \"set-registration-backend\" label", @@ -2084,6 +2094,11 @@ "description": "StUF-ZDS registration options 'zdsZaaktypeStatusCode' label", "originalDefault": "Zds zaaktype status code" }, + "eZJFP7": { + "defaultMessage": "COM parameter", + "description": "Ogone legacy payment options 'comTemplate' label", + "originalDefault": "COM parameter" + }, "efsF8+": { "defaultMessage": "{label} {isPublished, select, false {(not published)} other {}}", "description": "Document type option label", @@ -2919,6 +2934,11 @@ "description": "Confirmation template help text", "originalDefault": "The content of the submission confirmation page. It can contain variables that will be templated from the submitted form data. If not specified, the global template will be used." }, + "vikURf": { + "defaultMessage": "Optional custom template for the title displayed on the payment page.

You can use all form variables (using their keys) and the public_reference template variable. If unspecified, a default description is used.", + "description": "Ogone legacy payment options 'titleTemplate' help text", + "originalDefault": "Optional custom template for the title displayed on the payment page.

You can use all form variables (using their keys) and the public_reference template variable. If unspecified, a default description is used." + }, "vng/5K": { "defaultMessage": "Set a key name before you can configure this variable", "description": "JSON editor: object entry has empty key name", diff --git a/src/openforms/js/lang/nl.json b/src/openforms/js/lang/nl.json index 3e3c7a6a61..5946b8db68 100644 --- a/src/openforms/js/lang/nl.json +++ b/src/openforms/js/lang/nl.json @@ -1088,6 +1088,11 @@ "description": "Modal title API call failed with HTTP 401", "originalDefault": "Authentication failure" }, + "JHQfjZ": { + "defaultMessage": "Optional custom template for the the description, included in the payment overviews for the backoffice. Use this to link the payment back to a particular process or form.

You can use all form variables (using their keys) and the public_reference template variable. If unspecified, a default description is used.

Note: the length of the result is capped to 100 characters.", + "description": "Ogone legacy payment options 'comTemplate' help text", + "originalDefault": "Optional custom template for the the description, included in the payment overviews for the backoffice. Use this to link the payment back to a particular process or form.

You can use all form variables (using their keys) and the public_reference template variable. If unspecified, a default description is used.

Note: the length of the result is capped to 100 characters." + }, "JKq3TC": { "defaultMessage": "Medewerkerroltype", "description": "Objects API registration options 'medewerkerRoltype' label", @@ -1857,6 +1862,11 @@ "description": "Form 'BRP Personen processing header value' field help text", "originalDefault": "The processing (\"verwerking\") for queries to the BRP Persoon API." }, + "ZSvQcR": { + "defaultMessage": "TITLE parameter", + "description": "Ogone legacy payment options 'titleTemplate' label", + "originalDefault": "TITLE parameter" + }, "ZdZ2Mb": { "defaultMessage": "Zet registratieplugin voor de inzending", "description": "action type \"set-registration-backend\" label", @@ -2104,6 +2114,11 @@ "description": "StUF-ZDS registration options 'zdsZaaktypeStatusCode' label", "originalDefault": "Zds zaaktype status code" }, + "eZJFP7": { + "defaultMessage": "COM parameter", + "description": "Ogone legacy payment options 'comTemplate' label", + "originalDefault": "COM parameter" + }, "efsF8+": { "defaultMessage": "{label} {isPublished, select, false {(concept)} other {}}", "description": "Document type option label", @@ -2940,6 +2955,11 @@ "description": "Confirmation template help text", "originalDefault": "The content of the submission confirmation page. It can contain variables that will be templated from the submitted form data. If not specified, the global template will be used." }, + "vikURf": { + "defaultMessage": "Optional custom template for the title displayed on the payment page.

You can use all form variables (using their keys) and the public_reference template variable. If unspecified, a default description is used.", + "description": "Ogone legacy payment options 'titleTemplate' help text", + "originalDefault": "Optional custom template for the title displayed on the payment page.

You can use all form variables (using their keys) and the public_reference template variable. If unspecified, a default description is used." + }, "vng/5K": { "defaultMessage": "Er moet een sleutelnaam ingesteld worden voordat deze variabele geconfigureerd kan worden", "description": "JSON editor: object entry has empty key name",