diff --git a/src/pretix/plugins/stripe/payment.py b/src/pretix/plugins/stripe/payment.py index 923a1ba896..b87a4efdb7 100644 --- a/src/pretix/plugins/stripe/payment.py +++ b/src/pretix/plugins/stripe/payment.py @@ -137,7 +137,7 @@ logger = logging.getLogger('pretix.plugins.stripe') # Real-time payments # - Swish: ✓ # - PayNow: ✗ -# - PromptPay: ✗ +# - PromptPay: ✓ # - Pix: ✗ # # Vouchers @@ -440,6 +440,14 @@ class StripeSettingsHolder(BasePaymentProvider): 'before they work properly.'), required=False, )), + ('method_promptpay', + forms.BooleanField( + label='PromptPay', + disabled=self.event.currency != 'THB', + help_text=_('Some payment methods might need to be enabled in the settings of your Stripe account ' + 'before they work properly.'), + required=False, + )), ('method_swish', forms.BooleanField( label=_('Swish'), @@ -1880,6 +1888,30 @@ class StripeSwish(StripeRedirectMethod): } +class StripePromptPay(StripeRedirectMethod): + identifier = 'stripe_promptpay' + verbose_name = _('PromptPay via Stripe') + public_name = 'PromptPay' + method = 'promptpay' + confirmation_method = 'automatic' + explanation = _( + 'This payment method is available to PromptPay users in Thailand. Please have your app ready.' + ) + + def is_allowed(self, request: HttpRequest, total: Decimal=None) -> bool: + return super().is_allowed(request, total) and request.event.currency == "THB" + + def _payment_intent_kwargs(self, request, payment): + return { + "payment_method_data": { + "type": "promptpay", + "billing_details": { + "email": payment.order.email, + }, + }, + } + + class StripeTwint(StripeRedirectMethod): identifier = 'stripe_twint' verbose_name = _('TWINT via Stripe') diff --git a/src/pretix/plugins/stripe/signals.py b/src/pretix/plugins/stripe/signals.py index e968fa54c0..05f5b45f87 100644 --- a/src/pretix/plugins/stripe/signals.py +++ b/src/pretix/plugins/stripe/signals.py @@ -46,15 +46,17 @@ def register_payment_provider(sender, **kwargs): from .payment import ( StripeAffirm, StripeAlipay, StripeBancontact, StripeCC, StripeEPS, StripeGiropay, StripeIdeal, StripeKlarna, StripeMobilePay, - StripeMultibanco, StripePayByBank, StripePayPal, StripePrzelewy24, - StripeRevolutPay, StripeSEPADirectDebit, StripeSettingsHolder, - StripeSofort, StripeSwish, StripeTwint, StripeWeChatPay, + StripeMultibanco, StripePayByBank, StripePayPal, StripePromptPay, + StripePrzelewy24, StripeRevolutPay, StripeSEPADirectDebit, + StripeSettingsHolder, StripeSofort, StripeSwish, StripeTwint, + StripeWeChatPay, ) return [ StripeSettingsHolder, StripeCC, StripeGiropay, StripeIdeal, StripeAlipay, StripeBancontact, - StripeSofort, StripeEPS, StripeMultibanco, StripePrzelewy24, StripeRevolutPay, StripeWeChatPay, - StripeSEPADirectDebit, StripeAffirm, StripeKlarna, StripePayByBank, StripePayPal, StripeSwish, StripeTwint, StripeMobilePay + StripeSofort, StripeEPS, StripeMultibanco, StripePayByBank, StripePrzelewy24, StripePromptPay, StripeRevolutPay, + StripeWeChatPay, StripeSEPADirectDebit, StripeAffirm, StripeKlarna, StripePayPal, StripeSwish, + StripeTwint, StripeMobilePay ] diff --git a/src/pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.css b/src/pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.css index 3ff086fc48..1887236c9d 100644 --- a/src/pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.css +++ b/src/pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.css @@ -79,3 +79,9 @@ .vcenter { margin: auto; } + +.stripe-qr-code { + max-width: 80%; + width: 200px; + height: auto; +} \ No newline at end of file diff --git a/src/pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js b/src/pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js index 85b6784594..cf71266f80 100644 --- a/src/pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js +++ b/src/pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js @@ -325,6 +325,8 @@ $(function () { } else if ($("#stripe_payment_intent_next_action_redirect_url").length) { let payment_intent_next_action_redirect_url = $.trim($("#stripe_payment_intent_next_action_redirect_url").html()); pretixstripe.handlePaymentRedirectAction(payment_intent_next_action_redirect_url); + } else if ($.trim($("#stripe_payment_intent_action_type").html()) === "promptpay_display_qr_code") { + waitingDialog.hide(); } else if ($.trim($("#stripe_payment_intent_action_type").html()) === "wechat_pay_display_qr_code") { let payment_intent_client_secret = $.trim($("#stripe_payment_intent_client_secret").html()); pretixstripe.handleWechatAction(payment_intent_client_secret); diff --git a/src/pretix/plugins/stripe/templates/pretixplugins/stripe/sca.html b/src/pretix/plugins/stripe/templates/pretixplugins/stripe/sca.html index 47ad0e929a..5ca7403721 100644 --- a/src/pretix/plugins/stripe/templates/pretixplugins/stripe/sca.html +++ b/src/pretix/plugins/stripe/templates/pretixplugins/stripe/sca.html @@ -27,9 +27,21 @@
-
- -
+ {% if payment_intent_promptpay_image_url %} +
+

{% blocktrans trimmed %} + Please scan the QR code below to complete your PromptPay payment. + Once you have completed your payment, you can refresh this page. + {% endblocktrans %}

+
+ {% trans 'PromptPay QR code' %} +
+
+ {% else %} +
+
+ {% endif %}
diff --git a/src/pretix/plugins/stripe/views.py b/src/pretix/plugins/stripe/views.py index b5334a5d40..f997a67b10 100644 --- a/src/pretix/plugins/stripe/views.py +++ b/src/pretix/plugins/stripe/views.py @@ -613,7 +613,7 @@ class ScaView(StripeOrderView, View): if intent.status == 'requires_action' and intent.next_action.type in [ 'use_stripe_sdk', 'redirect_to_url', 'alipay_handle_redirect', 'wechat_pay_display_qr_code', - 'swish_handle_redirect_or_display_qr_code', 'multibanco_display_details', + 'swish_handle_redirect_or_display_qr_code', 'multibanco_display_details', 'promptpay_display_qr_code', ]: ctx = { 'order': self.order, @@ -631,6 +631,8 @@ class ScaView(StripeOrderView, View): elif intent.next_action.type == 'multibanco_display_details': ctx['payment_intent_next_action_redirect_url'] = intent.next_action.multibanco_display_details['hosted_voucher_url'] ctx['payment_intent_redirect_action_handling'] = 'iframe' + elif intent.next_action.type == 'promptpay_display_qr_code': + ctx['payment_intent_promptpay_image_url'] = intent.next_action.promptpay_display_qr_code['image_url_svg'] r = render(request, 'pretixplugins/stripe/sca.html', ctx) r._csp_ignore = True diff --git a/src/pretix/static/pretixcontrol/img/auth-b.svg b/src/pretix/static/pretixcontrol/img/auth-b.svg new file mode 100644 index 0000000000..76b60b6b2f --- /dev/null +++ b/src/pretix/static/pretixcontrol/img/auth-b.svg @@ -0,0 +1,536 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +