Stripe: Open payment gateways in new window when shown in widget

This commit is contained in:
Raphael Michel
2018-03-20 12:27:17 +01:00
parent 94f5ba7d1a
commit 2db1e6b596
4 changed files with 66 additions and 5 deletions

View File

@@ -1,12 +1,14 @@
import hashlib import hashlib
import json import json
import logging import logging
import urllib.parse
from collections import OrderedDict from collections import OrderedDict
import stripe import stripe
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.core import signing
from django.template.loader import get_template from django.template.loader import get_template
from django.utils.translation import ugettext, ugettext_lazy as _ from django.utils.translation import ugettext, ugettext_lazy as _
@@ -371,7 +373,17 @@ class StripeMethod(BasePaymentProvider):
order.payment_info = str(source) order.payment_info = str(source)
order.save(update_fields=['payment_info']) order.save(update_fields=['payment_info'])
request.session['payment_stripe_order_secret'] = order.secret request.session['payment_stripe_order_secret'] = order.secret
return source.redirect.url return self.redirect(request, source.redirect.url)
def redirect(self, request, url):
if request.session.get('iframe_session', False):
signer = signing.Signer(salt='safe-redirect')
return (
build_absolute_uri(request.event, 'plugins:stripe:redirect') + '?url=' +
urllib.parse.quote(signer.sign(url))
)
else:
return str(url)
class StripeCC(StripeMethod): class StripeCC(StripeMethod):
@@ -436,7 +448,7 @@ class StripeCC(StripeMethod):
if source.status == "pending": if source.status == "pending":
order.payment_info = str(source) order.payment_info = str(source)
order.save(update_fields=['payment_info']) order.save(update_fields=['payment_info'])
return source.redirect.url return self.redirect(request, source.redirect.url)
except stripe.error.StripeError as e: except stripe.error.StripeError as e:
if e.json_body: if e.json_body:
err = e.json_body['error'] err = e.json_body['error']

View File

@@ -0,0 +1,32 @@
{% load compress %}
{% load i18n %}
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
<title>{{ settings.PRETIX_INSTANCE_NAME }}</title>
{% compress css %}
<link rel="stylesheet" type="text/x-scss" href="{% static "pretixbase/scss/cachedfiles.scss" %}"/>
{% endcompress %}
{% compress js %}
<script type="text/javascript" src="{% static "jquery/js/jquery-2.1.1.min.js" %}"></script>
{% endcompress %}
</head>
<body>
<div class="container">
<h1>{% trans "The payment process has started in a new window." %}</h1>
<p>
{% trans "The window to enter your payment data was not opened or was closed?" %}
</p>
<p>
<a href="{{ url }}" target="_blank">
{% trans "Click here in order to open the window." %}
</a>
</p>
<script>
window.open('{{ url|escapejs }}');
</script>
</div>
</body>
</html>

View File

@@ -2,11 +2,12 @@ from django.conf.urls import include, url
from pretix.multidomain import event_url from pretix.multidomain import event_url
from .views import ReturnView, refund, webhook from .views import ReturnView, redirect_view, refund, webhook
event_patterns = [ event_patterns = [
url(r'^stripe/', include([ url(r'^stripe/', include([
event_url(r'^webhook/$', webhook, name='webhook', require_live=False), event_url(r'^webhook/$', webhook, name='webhook', require_live=False),
url(r'^redirect/$', redirect_view, name='redirect'),
url(r'^return/(?P<order>[^/]+)/(?P<hash>[^/]+)/$', ReturnView.as_view(), name='return'), url(r'^return/(?P<order>[^/]+)/(?P<hash>[^/]+)/$', ReturnView.as_view(), name='return'),
])), ])),
] ]

View File

@@ -4,9 +4,10 @@ import logging
import stripe import stripe
from django.contrib import messages from django.contrib import messages
from django.core import signing
from django.db import transaction from django.db import transaction
from django.http import Http404, HttpResponse from django.http import Http404, HttpResponse, HttpResponseBadRequest
from django.shortcuts import get_object_or_404, redirect from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse from django.urls import reverse
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.utils.functional import cached_property from django.utils.functional import cached_property
@@ -28,6 +29,21 @@ from pretix.plugins.stripe.payment import StripeCC
logger = logging.getLogger('pretix.plugins.stripe') logger = logging.getLogger('pretix.plugins.stripe')
@xframe_options_exempt
def redirect_view(request, *args, **kwargs):
signer = signing.Signer(salt='safe-redirect')
try:
url = signer.unsign(request.GET.get('url', ''))
except signing.BadSignature:
return HttpResponseBadRequest('Invalid parameter')
r = render(request, 'pretixplugins/paypal/redirect.html', {
'url': url,
})
r._csp_ignore = True
return r
@csrf_exempt @csrf_exempt
@require_POST @require_POST
def webhook(request, *args, **kwargs): def webhook(request, *args, **kwargs):