From 9b32290964c9e176bf0054e60653e5244522f4e0 Mon Sep 17 00:00:00 2001 From: PCoder <purple.coder@yahoo.co.uk> Date: Sat, 13 Apr 2019 23:52:41 +0200 Subject: [PATCH] Add webhook app and create_webhook management command --- dynamicweb/settings/base.py | 3 ++ webhook/__init__.py | 0 webhook/management/commands/create_webhook.py | 49 +++++++++++++++++++ webhook/models.py | 3 ++ webhook/views.py | 36 ++++++++++++++ 5 files changed, 91 insertions(+) create mode 100644 webhook/__init__.py create mode 100644 webhook/management/commands/create_webhook.py create mode 100644 webhook/models.py create mode 100644 webhook/views.py diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py index a770018f..45018f13 100644 --- a/dynamicweb/settings/base.py +++ b/dynamicweb/settings/base.py @@ -153,6 +153,7 @@ INSTALLED_APPS = ( 'rest_framework', 'opennebula_api', 'django_celery_results', + 'webhook', ) MIDDLEWARE_CLASSES = ( @@ -719,6 +720,8 @@ X_FRAME_OPTIONS = ('SAMEORIGIN' if X_FRAME_OPTIONS_ALLOW_FROM_URI is None else X_FRAME_OPTIONS_ALLOW_FROM_URI.strip() )) +INVOICE_WEBHOOK_SECRET = env('INVOICE_WEBHOOK_SECRET') + DEBUG = bool_env('DEBUG') if DEBUG: diff --git a/webhook/__init__.py b/webhook/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/webhook/management/commands/create_webhook.py b/webhook/management/commands/create_webhook.py new file mode 100644 index 00000000..23960297 --- /dev/null +++ b/webhook/management/commands/create_webhook.py @@ -0,0 +1,49 @@ +import logging +import stripe + +from django.core.management.base import BaseCommand + +logger = logging.getLogger(__name__) + + +class Command(BaseCommand): + help = '''creates webhook with the supplied arguments and returns the + webhook secret + ''' + + def add_arguments(self, parser): + parser.add_argument( + '--webhook_endpoint', + help="The url of the webhook endpoint that accepts the events " + "from stripe", + dest="webhook_endpoint" + ) + parser.add_argument('--events_csv', dest="events_csv") + + def handle(self, *args, **options): + wep_exists = False + try: + we_list = stripe.WebhookEndpoint.list(limit=100) + for wep in we_list.data: + if set(wep.enabled_events) == set(options['events_csv'].split(",")): + if wep.url == options['webhook_endpoint']: + logger.debug("We have this webhook already") + wep_exists = True + break + if wep_exists is False: + logger.debug( + "No webhook exists for {} at {}. Creatting a new endpoint " + "now".format( + options['webhook_endpoint'], options['events_csv'] + ) + ) + wep = stripe.WebhookEndpoint.create( + url=options['webhook_endpoint'], + enabled_events=options['events_csv'].split(",") + ) + self.stdout.write( + self.style.SUCCESS('Creation successful. ' + 'webhook_secret = %s' % wep.secret) + ) + except Exception as e: + print(" *** Error occurred. Details {}".format(str(e))) diff --git a/webhook/models.py b/webhook/models.py new file mode 100644 index 00000000..d49766e4 --- /dev/null +++ b/webhook/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. \ No newline at end of file diff --git a/webhook/views.py b/webhook/views.py new file mode 100644 index 00000000..19587e69 --- /dev/null +++ b/webhook/views.py @@ -0,0 +1,36 @@ +import logging +import stripe + +# Create your views here. +from django.conf import settings +from django.http import HttpResponse +from django.views.decorators.csrf import csrf_exempt +from django.views.decorators.http import require_POST + +logger = logging.getLogger(__name__) + + +@require_POST +@csrf_exempt +def handle_invoice_webhook(request): + payload = request.body + sig_header = request.META['HTTP_STRIPE_SIGNATURE'] + event = None + + try: + event = stripe.Webhook.construct_event( + payload, sig_header, settings.INVOICE_WEBHOOK_SECRET + ) + except ValueError as e: + logger.error("Invalid payload details = " + str(e)) + # Invalid payload + return HttpResponse(status=400) + except stripe.error.SignatureVerificationError as e: + logger.error("SignatureVerificationError details = " + str(e)) + # Invalid signature + return HttpResponse(status=400) + + # Do something with event + logger.debug("Passed invoice signature verification") + + return HttpResponse(status=200) \ No newline at end of file