Change stripe payments to do server side redirect
authorMagnus Hagander <magnus@hagander.net>
Tue, 26 Aug 2025 09:49:15 +0000 (11:49 +0200)
committerMagnus Hagander <magnus@hagander.net>
Tue, 26 Aug 2025 10:06:03 +0000 (12:06 +0200)
It makes little sense to load a separate page, which loads a third party
javascript, and then executes it inline just to perform a redirect to an
URL that's already in the response from the API.

It does lead to one extra (cheap) stripe api call if the user initates
the payment at stripe, doesn't complete it, and rstarts the process from
the invoice. But in all other (thus, the normal) cases it leads to less
calls, and avoiding to load 3rd party javascript inline in general is a
good thing.

docs/invoices/payment.md
postgresqleu/stripepayment/views.py
template/stripepayment/payment.html [deleted file]

index 875928323867de1a5be55886cc8a1837ef80dd17..9631fe0c91b3534600fbb6e1be6fc43ef6ada636 100644 (file)
@@ -257,8 +257,7 @@ This module requires the Python module `braintree` to be installed.
 #### Stripe Creditcard
 
 This method uses the Stripe creditcard system. This uses the Stripe
-"Checkout" system, which uses a mix of server-side code and hosted
-javascript, with the actual payment form entirely hosted by Stripe.
+"Checkout" system. This uses hosted payment forms at Stripe.
 
 #### Trustly Banktransfer
 
index acbf37644b08c4189c61de2d0c85afab3f88c3db..a91f76c1cbeb22424a7a6341082b35ba2e67a12c 100644 (file)
@@ -43,8 +43,12 @@ def invoicepayment_secret(request, paymentmethod, invoiceid, secret):
             # user has multiple tabs open.
             return HttpResponseRedirect("/invoices/{0}/{1}/".format(invoice.id, invoice.recipient_secret))
 
-        # Else session exists but is not completed, so send it through back to Stripe
-        # again.
+        # Else session exists but is not completed, so fetch the session and send the user
+        # back to Stripe.
+        StripeLog(message="Re-fetching session {0} (id {1}) for another try.".format(co.id, co.sessionid),
+                  paymentmethod=method).save()
+        r = api.secret('checkout/sessions/{}'.format(co.sessionid))
+        sessionurl = r.json()['url']
     except StripeCheckout.DoesNotExist:
         # Create a new checkout session
         co = StripeCheckout(createdat=timezone.now(),
@@ -76,14 +80,12 @@ def invoicepayment_secret(request, paymentmethod, invoiceid, secret):
             return HttpResponse("Unable to create Stripe payment session: {}".format(r.status_code))
         j = r.json()
         co.sessionid = j['id']
+        sessionurl = j['url']
         co.paymentintent = j['payment_intent']
         co.save()
 
-    return render(request, 'stripepayment/payment.html', {
-        'invoice': invoice,
-        'stripekey': pm.config('published_key'),
-        'sessionid': co.sessionid,
-    })
+    # Redirect to the stripe payment URL
+    return HttpResponseRedirect(sessionurl)
 
 
 def invoicepayment_results(request, paymentmethod, invoiceid, secret):
diff --git a/template/stripepayment/payment.html b/template/stripepayment/payment.html
deleted file mode 100644 (file)
index da2c79a..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-{%extends "navbase.html" %}
-{%block title%}Invoice payment{%endblock%}
-{%block extrahead%}
-<script src="https://js.stripe.com/v3/"></script>
-<script type="text/javascript">
-var stripe = Stripe('{{stripekey}}');
-stripe.redirectToCheckout({
-   'sessionId': '{{sessionid}}'
-}).then(function (result) {
-   alert('Redirection to Stripe for payment failed.');
-});
-</script>
-{%endblock%}
-{%block content%}
-<h1>Invoice payment</h1>
-<p>You are being redirected to Stripe to complete the payment.</p>
-
-{%endblock%}