diff --git a/src/pretix/base/middleware.py b/src/pretix/base/middleware.py index 7f633eee52..4d80d97c37 100644 --- a/src/pretix/base/middleware.py +++ b/src/pretix/base/middleware.py @@ -155,10 +155,11 @@ class SecurityMiddleware: resp['X-XSS-Protection'] = '1' h = { 'default-src': "{static}", - 'script-src': '{static} https://js.stripe.com', + 'script-src': '{static} https://checkout.stripe.com https://js.stripe.com', 'object-src': "'none'", - 'frame-src': '{static} https://js.stripe.com', + 'frame-src': '{static} https://checkout.stripe.com https://js.stripe.com', 'style-src': "{static}", + 'connect-src': "{dynamic} https://checkout.stripe.com", 'img-src': "{static} data: https://*.stripe.com", # form-action is not only used to match on form actions, but also on URLs # form-ations redirect to. In the context of e.g. payment providers or diff --git a/src/pretix/plugins/stripe/payment.py b/src/pretix/plugins/stripe/payment.py index bea5a3a16f..69196092b9 100644 --- a/src/pretix/plugins/stripe/payment.py +++ b/src/pretix/plugins/stripe/payment.py @@ -32,6 +32,14 @@ class Stripe(BasePaymentProvider): ('publishable_key', forms.CharField( label=_('Publishable key'), + )), + ('ui', + forms.ChoiceField( + label=_('User interface'), + choices=( + ('pretix', _('Simple (pretix design)')), + ('checkout', _('Stripe Checkout')), + ) )) ] ) @@ -60,7 +68,11 @@ class Stripe(BasePaymentProvider): return True def payment_form_render(self, request) -> str: - template = get_template('pretixplugins/stripe/checkout_payment_form.html') + ui = self.settings.get('ui', default='pretix') + if ui == 'checkout': + template = get_template('pretixplugins/stripe/checkout_payment_form_stripe_checkout.html') + else: + template = get_template('pretixplugins/stripe/checkout_payment_form.html') ctx = {'request': request, 'event': self.event, 'settings': self.settings} return template.render(ctx) diff --git a/src/pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe-checkout.js b/src/pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe-checkout.js new file mode 100644 index 0000000000..39b7da976f --- /dev/null +++ b/src/pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe-checkout.js @@ -0,0 +1,75 @@ +/*global $, stripe_pubkey, stripe_loadingmessage, gettext */ +'use strict'; + +var Stripe = null; +var pretixstripe = { + 'load': function () { + $.ajax( + { + url: 'https://checkout.stripe.com/checkout.js', + dataType: 'script', + success: function () { + pretixstripe.handler = StripeCheckout.configure({ + key: $.trim($("#stripe_pubkey").html()), + locale: 'auto', + token: function(token) { + var $form = $("#stripe-checkout").parents("form"); + $("#stripe_token").val(token.id); + $("#stripe_card_brand").val(token.card.brand); + $("#stripe_card_last4").val(token.card.last4); + $form.get(0).submit(); + }, + shippingAddress: false, + allowRememberMe: false, + billingAddress: false + }); + } + } + ); + }, + + handler: null +}; +$(function () { + if (!$("#stripe-checkout").length) { // Not on the checkout page + return; + } + + if ($("input[name=payment][value=stripe]").is(':checked') || $(".payment-redo-form").length) { + pretixstripe.load(); + } else { + $("input[name=payment]").change(function() { + if ($(this).val() == 'stripe') { + pretixstripe.load(); + } + }) + } + + $(".checkout-button-row .btn-primary").click( + function (e) { + if (($("input[name=payment][value=stripe]").prop('checked') || $("input[name=payment]").length === 0) + && $("#stripe_token").val() == "") { + var amount = Math.round( + parseFloat( + $("#stripe-checkout").parents("[data-total]").attr("data-total").replace(",", ".") + ) * 100 + ); + pretixstripe.handler.open({ + name: $("#organizer_name").val(), + description: $("#event_name").val(), + currency: $("#stripe_currency").val(), + email: $("#stripe_email").val(), + amount: amount, + }); + e.preventDefault(); + return false; + } + } + ); + + $(window).on('popstate', function () { + if (pretixstripe.handler) { + pretixstripe.handler.close(); + } + }); +}); diff --git a/src/pretix/plugins/stripe/templates/pretixplugins/stripe/checkout_payment_form_stripe_checkout.html b/src/pretix/plugins/stripe/templates/pretixplugins/stripe/checkout_payment_form_stripe_checkout.html new file mode 100644 index 0000000000..2b25d036f0 --- /dev/null +++ b/src/pretix/plugins/stripe/templates/pretixplugins/stripe/checkout_payment_form_stripe_checkout.html @@ -0,0 +1,29 @@ +{% load i18n %} + +
+ +

+ {% blocktrans trimmed %} + Please continue below to start the credit card payment. + {% endblocktrans %} +

+

+ {% blocktrans trimmed %} + Your payment will be processed by Stripe, Inc. Your credit card data will be transmitted directly to + Stripe and never touches our servers. + {% endblocktrans %} +

+ + + + + + + + +
+ diff --git a/src/pretix/plugins/stripe/templates/pretixplugins/stripe/presale_head.html b/src/pretix/plugins/stripe/templates/pretixplugins/stripe/presale_head.html index 57e1f02104..dbf0a95f1b 100644 --- a/src/pretix/plugins/stripe/templates/pretixplugins/stripe/presale_head.html +++ b/src/pretix/plugins/stripe/templates/pretixplugins/stripe/presale_head.html @@ -2,8 +2,14 @@ {% load compress %} {% load i18n %} -{% compress js %} - -{% endcompress %} +{% if settings.ui == "checkout" %} + {% compress js %} + + {% endcompress %} +{% else %} + {% compress js %} + + {% endcompress %} +{% endif %} diff --git a/src/pretix/presale/checkoutflow.py b/src/pretix/presale/checkoutflow.py index 50331953f6..0163334a7f 100644 --- a/src/pretix/presale/checkoutflow.py +++ b/src/pretix/presale/checkoutflow.py @@ -234,6 +234,7 @@ class PaymentStep(QuestionsViewMixin, CartMixin, TemplateFlowStep): providers.append({ 'provider': provider, 'fee': fee, + 'total': self._total_order_value + fee, 'form': provider.payment_form_render(self.request) }) return providers diff --git a/src/pretix/presale/templates/pretixpresale/event/checkout_payment.html b/src/pretix/presale/templates/pretixpresale/event/checkout_payment.html index a82d4f36f1..28468f0a2e 100644 --- a/src/pretix/presale/templates/pretixpresale/event/checkout_payment.html +++ b/src/pretix/presale/templates/pretixpresale/event/checkout_payment.html @@ -9,7 +9,7 @@ {% csrf_token %}
{% for p in providers %} -
+