mirror of https://github.com/zulip/zulip.git
billing: Enforce the Stripe API version is in sync with billing system.
This commit is contained in:
parent
6c06858e02
commit
585d98d5a9
|
@ -25,6 +25,7 @@ from corporate.lib.stripe import (
|
||||||
DEFAULT_INVOICE_DAYS_UNTIL_DUE,
|
DEFAULT_INVOICE_DAYS_UNTIL_DUE,
|
||||||
MAX_INVOICED_LICENSES,
|
MAX_INVOICED_LICENSES,
|
||||||
MIN_INVOICED_LICENSES,
|
MIN_INVOICED_LICENSES,
|
||||||
|
STRIPE_API_VERSION,
|
||||||
BillingError,
|
BillingError,
|
||||||
InvalidBillingSchedule,
|
InvalidBillingSchedule,
|
||||||
InvalidTier,
|
InvalidTier,
|
||||||
|
@ -496,6 +497,7 @@ class StripeTestCase(ZulipTestCase):
|
||||||
"object": "event",
|
"object": "event",
|
||||||
"data": {"object": stripe_session_dict},
|
"data": {"object": stripe_session_dict},
|
||||||
"type": "checkout.session.completed",
|
"type": "checkout.session.completed",
|
||||||
|
"api_version": STRIPE_API_VERSION,
|
||||||
}
|
}
|
||||||
|
|
||||||
response = self.client_post(
|
response = self.client_post(
|
||||||
|
@ -3846,9 +3848,27 @@ class StripeWebhookEndpointTest(ZulipTestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(result.status_code, 400)
|
self.assertEqual(result.status_code, 400)
|
||||||
|
|
||||||
|
def test_stripe_webhook_endpoint_invalid_api_version(self) -> None:
|
||||||
|
event_data = {
|
||||||
|
"id": "stripe_event_id",
|
||||||
|
"api_version": "1991-02-20",
|
||||||
|
"type": "event_type",
|
||||||
|
"data": {"object": {"object": "checkout.session", "id": "stripe_session_id"}},
|
||||||
|
}
|
||||||
|
|
||||||
|
expected_error_message = fr"Mismatch between billing system Stripe API version({STRIPE_API_VERSION}) and Stripe webhook event API version(1991-02-20)."
|
||||||
|
with self.assertLogs("corporate.stripe", "ERROR") as error_log:
|
||||||
|
self.client_post(
|
||||||
|
"/stripe/webhook/",
|
||||||
|
event_data,
|
||||||
|
content_type="application/json",
|
||||||
|
)
|
||||||
|
self.assertEqual(error_log.output, [f"ERROR:corporate.stripe:{expected_error_message}"])
|
||||||
|
|
||||||
def test_stripe_webhook_for_session_completed_event(self) -> None:
|
def test_stripe_webhook_for_session_completed_event(self) -> None:
|
||||||
valid_session_event_data = {
|
valid_session_event_data = {
|
||||||
"id": "stripe_event_id",
|
"id": "stripe_event_id",
|
||||||
|
"api_version": STRIPE_API_VERSION,
|
||||||
"type": "checkout.session.completed",
|
"type": "checkout.session.completed",
|
||||||
"data": {"object": {"object": "checkout.session", "id": "stripe_session_id"}},
|
"data": {"object": {"object": "checkout.session", "id": "stripe_session_id"}},
|
||||||
}
|
}
|
||||||
|
@ -3906,6 +3926,7 @@ class StripeWebhookEndpointTest(ZulipTestCase):
|
||||||
valid_session_event_data = {
|
valid_session_event_data = {
|
||||||
"id": stripe_event_id,
|
"id": stripe_event_id,
|
||||||
"type": event_type,
|
"type": event_type,
|
||||||
|
"api_version": STRIPE_API_VERSION,
|
||||||
"data": {"object": {"object": "payment_intent", "id": stripe_payment_intent_id}},
|
"data": {"object": {"object": "payment_intent", "id": stripe_payment_intent_id}},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ from django.contrib.contenttypes.models import ContentType
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
|
||||||
|
from corporate.lib.stripe import STRIPE_API_VERSION
|
||||||
from corporate.lib.stripe_event_handler import (
|
from corporate.lib.stripe_event_handler import (
|
||||||
handle_checkout_session_completed_event,
|
handle_checkout_session_completed_event,
|
||||||
handle_payment_intent_payment_failed_event,
|
handle_payment_intent_payment_failed_event,
|
||||||
|
@ -42,6 +43,11 @@ def stripe_webhook(request: HttpRequest) -> HttpResponse:
|
||||||
except Exception:
|
except Exception:
|
||||||
return HttpResponse(status=400)
|
return HttpResponse(status=400)
|
||||||
|
|
||||||
|
if stripe_event.api_version != STRIPE_API_VERSION:
|
||||||
|
error_message = f"Mismatch between billing system Stripe API version({STRIPE_API_VERSION}) and Stripe webhook event API version({stripe_event.api_version})."
|
||||||
|
billing_logger.error(error_message)
|
||||||
|
return HttpResponse(status=400)
|
||||||
|
|
||||||
if stripe_event.type not in [
|
if stripe_event.type not in [
|
||||||
"checkout.session.completed",
|
"checkout.session.completed",
|
||||||
"payment_intent.succeeded",
|
"payment_intent.succeeded",
|
||||||
|
|
|
@ -320,6 +320,7 @@ class EventData:
|
||||||
|
|
||||||
class Event:
|
class Event:
|
||||||
id: str
|
id: str
|
||||||
|
api_version: str
|
||||||
type: EventTypes
|
type: EventTypes
|
||||||
data: EventData
|
data: EventData
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
Loading…
Reference in New Issue