Grant mobile plans from verified App Store and Play purchases (#78).
CI / test (pull_request) Successful in 10s
Unit Tests / test (pull_request) Successful in 10s

The app confirms a StoreKit signed transaction or Play purchase token. The backend checks it with Apple or Google before writing the ledger, and the RevenueCat webhook no longer grants access.
This commit is contained in:
westfarn committed 2026-10-19 06:14:27 -05:00
1 parent bb5c43a4e7
commit 74e8a4ad71
14 files changed
+1141 -119

No files matched your search

+1 -51
View File
@@ -2,10 +2,7 @@
from __future__ import annotations
from django.test import TestCase, override_settings
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APIClient
from django.test import TestCase
from chat_backend.tests.factories import make_user
from monetization.models import Invoice, Payment, SubscriptionPlan, UserSubscription
@@ -129,50 +126,3 @@ class RevenueCatDispatchTests(TestCase):
self.assertEqual(sub.status, UserSubscription.Status.CANCELED)
@override_settings(REVENUECAT_WEBHOOK_SECRET="test-rc-secret")
class RevenueCatWebhookViewTests(TestCase):
def setUp(self):
seed_subscription_plans(update_existing=False)
self.client = APIClient()
self.url = reverse("finance_revenuecat_webhook")
self.user = make_user(email="rcview@example.com")
founders = SubscriptionPlan.objects.get(slug="founders")
founders.revenuecat_product_id = "hesychia_founders_monthly"
founders.save(update_fields=["revenuecat_product_id", "last_modified"])
def test_missing_secret_config(self):
with override_settings(REVENUECAT_WEBHOOK_SECRET=""):
response = self.client.post(
self.url, {"event": _rc_event()}, format="json"
)
self.assertEqual(response.status_code, status.HTTP_503_SERVICE_UNAVAILABLE)
def test_unauthorized(self):
response = self.client.post(
self.url,
{"event": _rc_event(app_user_id=str(self.user.pk))},
format="json",
HTTP_AUTHORIZATION="Bearer wrong",
)
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
def test_success(self):
response = self.client.post(
self.url,
{"api_version": "1.0", "event": _rc_event(app_user_id=str(self.user.pk))},
format="json",
HTTP_AUTHORIZATION="Bearer test-rc-secret",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertTrue(
UserSubscription.objects.filter(
user=self.user,
source=UserSubscription.Source.REVENUECAT,
status=UserSubscription.Status.ACTIVE,
).exists()
)
self.assertTrue(
Invoice.objects.filter(
user=self.user, provider=Invoice.Provider.REVENUECAT
).exists()
)