forked from CGM_Public/pretix_original
Stripe: Optional support for Stripe checkout
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
{% load i18n %}
|
||||
|
||||
<div class="form-horizontal" id="stripe-checkout">
|
||||
<noscript>
|
||||
<div class="alert alert-warning">
|
||||
{% trans "For a credit card payment, please turn on JavaScript." %}
|
||||
</div>
|
||||
</noscript>
|
||||
<p>
|
||||
{% blocktrans trimmed %}
|
||||
Please continue below to start the credit card payment.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<p>
|
||||
<em>{% 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 %}</em>
|
||||
</p>
|
||||
<input type="hidden" name="stripe_token" value="" id="stripe_token" />
|
||||
<input type="hidden" name="stripe_card_last4" value="" id="stripe_card_last4" />
|
||||
<input type="hidden" name="stripe_card_brand" value="" id="stripe_card_brand" />
|
||||
<input type="hidden" id="organizer_name" value="{{ event.organizer.name }}" />
|
||||
<input type="hidden" id="event_name" value="{{ event.name }}" />
|
||||
<input type="hidden" id="stripe_currency" value="{{ event.currency }}" />
|
||||
<input type="hidden" id="event_name" value="{{ event.name }}" />
|
||||
<input type="hidden" id="stripe_email" value="{{ request.session.email }}" />
|
||||
</div>
|
||||
|
||||
@@ -2,8 +2,14 @@
|
||||
{% load compress %}
|
||||
{% load i18n %}
|
||||
|
||||
{% compress js %}
|
||||
<script type="text/javascript" src="{% static "pretixplugins/stripe/pretix-stripe.js" %}"></script>
|
||||
{% endcompress %}
|
||||
{% if settings.ui == "checkout" %}
|
||||
{% compress js %}
|
||||
<script type="text/javascript" src="{% static "pretixplugins/stripe/pretix-stripe-checkout.js" %}"></script>
|
||||
{% endcompress %}
|
||||
{% else %}
|
||||
{% compress js %}
|
||||
<script type="text/javascript" src="{% static "pretixplugins/stripe/pretix-stripe.js" %}"></script>
|
||||
{% endcompress %}
|
||||
{% endif %}
|
||||
<script type="text/plain" id="stripe_pubkey">{{ settings.publishable_key }}</script>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
{% csrf_token %}
|
||||
<div class="panel-group" id="payment_accordion">
|
||||
{% for p in providers %}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel panel-default" data-total="{{ p.total|floatformat:2 }}">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<label class="radio">
|
||||
|
||||
Reference in New Issue
Block a user