From 1033eb3f38b6ea41fe9b9d7878c79e31ef5b2ee4 Mon Sep 17 00:00:00 2001 From: Ivan Date: Tue, 28 Mar 2023 22:18:49 +0200 Subject: [PATCH] Add simple stripe webhook --- README.md | 4 ++++ api/urls.py | 5 +++++ api/v1/__init__.py | 0 api/v1/urls.py | 7 +++++++ api/v1/views.py | 31 +++++++++++++++++++++++++++++++ core/urls.py | 1 + 6 files changed, 48 insertions(+) create mode 100644 api/urls.py create mode 100644 api/v1/__init__.py create mode 100644 api/v1/urls.py create mode 100644 api/v1/views.py diff --git a/README.md b/README.md index efd38d6..75e25e7 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,10 @@ To run unit tests: For migrations, add `BF_ADMIN_USERNAME` and `BF_ADMIN_PASSWORD` to virtual environment to create admin user. +## Stripe + +For a webhook you need to configure stripe settings in a dashboard. + ## Notes ### Methodology diff --git a/api/urls.py b/api/urls.py new file mode 100644 index 0000000..d386b41 --- /dev/null +++ b/api/urls.py @@ -0,0 +1,5 @@ +from django.urls import path, include + +urlpatterns = [ + path('v1/', include('api.v1.urls'), name='v1'), +] diff --git a/api/v1/__init__.py b/api/v1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/v1/urls.py b/api/v1/urls.py new file mode 100644 index 0000000..3afd374 --- /dev/null +++ b/api/v1/urls.py @@ -0,0 +1,7 @@ +from django.urls import path + +from api.v1.views import StripeWebhook + +urlpatterns = [ + path('webhooks/stripe/', StripeWebhook.as_view(), name='stripe_webhook'), +] diff --git a/api/v1/views.py b/api/v1/views.py new file mode 100644 index 0000000..96bcb9f --- /dev/null +++ b/api/v1/views.py @@ -0,0 +1,31 @@ +from http import HTTPStatus +import json + +from django.conf import settings +from django.core.exceptions import PermissionDenied +from django.http import HttpResponse +from django.utils.decorators import method_decorator +from django.views import View +from django.views.decorators.csrf import csrf_exempt + +import stripe + + +@method_decorator(csrf_exempt, name='dispatch') +class StripeWebhook(View): + def post(self, request, *args, **kwargs): + try: + sig_header = request.headers['Stripe-Signature'] + except KeyError: + return HttpResponse(status=HTTPStatus.FORBIDDEN) + + try: + event = stripe.Webhook.construct_event( + request.body, sig_header, settings.STRIPE_ENDPOINT_SECRET + ) + except ValueError as e: + raise PermissionDenied() + except stripe.error.SignatureVerificationError as verification_err: + return HttpResponse(status=HTTPStatus.FORBIDDEN) + + return HttpResponse(status=HTTPStatus.OK) diff --git a/core/urls.py b/core/urls.py index c4506e3..c65e157 100644 --- a/core/urls.py +++ b/core/urls.py @@ -30,6 +30,7 @@ path('robots.txt', TemplateView.as_view(template_name='base/robots.txt', content_type='text/plain'), name='robots'), path('payments/', include('payments.urls')), path('docs/', include('docs.urls')), + path('api/', include('api.urls')), ]