def process_stripe_webhook_view(request): payload = request.body sig_header = request.META["HTTP_STRIPE_SIGNATURE"] event = None logger.info("In process webhook.") try: logger.info("Constructing event.") event = stripe.Webhook.construct_event(payload, sig_header, settings.STRIPE_WEBHOOK_SECRET) except ValueError: logger.warning("Invalid payload from Stripe webhook request") return Response(data={"error": "Invalid payload"}, status=status.HTTP_400_BAD_REQUEST) except stripe.error.SignatureVerificationError: logger.warning( "Invalid signature on Stripe webhook request. Is STRIPE_WEBHOOK_SECRET set correctly?" ) return Response(data={"error": "Invalid signature"}, status=status.HTTP_400_BAD_REQUEST) try: logger.info("Processing event.") processor = StripeWebhookProcessor(event) processor.process() except ValueError as e: logger.error(e) except Contribution.DoesNotExist: logger.error( "Could not find contribution matching provider_payment_id") return Response(status=status.HTTP_200_OK)
def test_unknown_event_logs_helpful_message(self, mock_logger): self._create_contribution(ref_id="abcd") fake_event_object = "criminal_activiy" processor = StripeWebhookProcessor( MockPaymentIntentEvent(object_type=fake_event_object, intent_id="1234")) processor.process() mock_logger.warning.assert_called_with( f'Recieved un-handled Stripe object of type "{fake_event_object}"')
def test_payment_intent_succeeded_webhook(self, mock): ref_id = "1234" contribution = self._create_contribution(ref_id=ref_id) processor = StripeWebhookProcessor( MockPaymentIntentEvent(event_type="payment_intent.succeeded", intent_id=ref_id)) processor.process() contribution.refresh_from_db() self.assertEqual(contribution.status, ContributionStatus.PAID)
def test_payment_intent_fraudulent(self): ref_id = "1234" contribution = self._create_contribution(ref_id=ref_id) processor = StripeWebhookProcessor( MockPaymentIntentEvent(event_type="payment_intent.canceled", intent_id=ref_id, cancellation_reason="fraudulent")) processor.process() contribution.refresh_from_db() self.assertEqual(contribution.status, ContributionStatus.REJECTED)
def test_canceled_subscription_gets_updated(self, mock_fetch_pm): ref_id = "1234" contribution = self._create_contribution(ref_id=ref_id) self.assertNotEqual(contribution.status, ContributionStatus.CANCELED) processor = StripeWebhookProcessor( MockSubscriptionEvent(event_type="customer.subscription.deleted", intent_id=ref_id)) processor.process() mock_fetch_pm.assert_not_called() contribution.refresh_from_db() self.assertEqual(contribution.status, ContributionStatus.CANCELED)
def test_updated_subscription_gets_updated(self, mock_fetch_pm): ref_id = "1234" previous_payment_method_id = "testing-previous-pm-id" new_payment_method = "testing-new-pm-id" contribution = self._create_contribution( ref_id=ref_id, provider_payment_method_id=previous_payment_method_id) processor = StripeWebhookProcessor( MockSubscriptionEvent( event_type="customer.subscription.updated", intent_id=ref_id, new_payment_method=new_payment_method, previous_attributes={ "default_payment_method": previous_payment_method_id }, )) processor.process() mock_fetch_pm.assert_called() contribution.refresh_from_db() self.assertEqual(contribution.provider_payment_method_id, new_payment_method)
def test_handle_subscription_canceled_handles_event( self, mock_handle_subscription_canceled): processor = StripeWebhookProcessor( MockSubscriptionEvent(event_type="customer.subscription.deleted")) processor.process() mock_handle_subscription_canceled.assert_called_once()
def test_process_subscription_handles_event(self, mock_process_subscription): processor = StripeWebhookProcessor( MockSubscriptionEvent(event_type="customer.subscription.updated")) processor.process() mock_process_subscription.assert_called_once()