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.
107 lines
3.1 KiB
Python
107 lines
3.1 KiB
Python
from rest_framework import serializers
|
|
|
|
from monetization.models import Invoice, Payment, SubscriptionPlan
|
|
|
|
|
|
class InvoiceSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Invoice
|
|
fields = [
|
|
"id",
|
|
"provider",
|
|
"status",
|
|
"currency",
|
|
"amount_due",
|
|
"amount_paid",
|
|
"period_start",
|
|
"period_end",
|
|
"stripe_invoice_id",
|
|
"stripe_checkout_session_id",
|
|
"stripe_subscription_id",
|
|
"revenuecat_event_id",
|
|
"revenuecat_store",
|
|
"hosted_invoice_url",
|
|
"description",
|
|
"created",
|
|
"last_modified",
|
|
]
|
|
read_only_fields = fields
|
|
|
|
|
|
class PaymentSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Payment
|
|
fields = [
|
|
"id",
|
|
"invoice",
|
|
"provider",
|
|
"status",
|
|
"currency",
|
|
"amount",
|
|
"stripe_payment_intent_id",
|
|
"stripe_charge_id",
|
|
"revenuecat_transaction_id",
|
|
"paid_at",
|
|
"failure_message",
|
|
"created",
|
|
"last_modified",
|
|
]
|
|
read_only_fields = fields
|
|
|
|
|
|
class CheckoutSessionSerializer(serializers.Serializer):
|
|
success_url = serializers.URLField(required=False, allow_blank=False)
|
|
cancel_url = serializers.URLField(required=False, allow_blank=False)
|
|
plan_slug = serializers.SlugField(required=False, allow_blank=False)
|
|
|
|
|
|
class PortalSessionSerializer(serializers.Serializer):
|
|
return_url = serializers.URLField(required=False, allow_blank=False)
|
|
|
|
|
|
class StorePurchaseConfirmSerializer(serializers.Serializer):
|
|
store = serializers.ChoiceField(choices=("app_store", "play_store"))
|
|
product_id = serializers.CharField(max_length=255)
|
|
transaction_id = serializers.CharField(
|
|
max_length=255, required=False, allow_blank=True
|
|
)
|
|
purchase_token = serializers.CharField(
|
|
max_length=4096, required=False, allow_blank=True
|
|
)
|
|
signed_transaction = serializers.CharField(required=False, allow_blank=True)
|
|
|
|
|
|
class SubscriptionPlanSerializer(serializers.ModelSerializer):
|
|
features = serializers.SerializerMethodField()
|
|
store_product_id = serializers.CharField(
|
|
source="revenuecat_product_id", read_only=True
|
|
)
|
|
|
|
class Meta:
|
|
model = SubscriptionPlan
|
|
fields = [
|
|
"slug",
|
|
"name",
|
|
"description",
|
|
"price_cents",
|
|
"currency",
|
|
"interval",
|
|
"is_public",
|
|
"is_selectable",
|
|
"features",
|
|
"prompt_quota_per_window",
|
|
"prompt_window_hours",
|
|
"monthly_token_quota",
|
|
"sort_order",
|
|
"store_product_id",
|
|
]
|
|
read_only_fields = fields
|
|
|
|
def get_features(self, obj):
|
|
return {
|
|
"text_generation": obj.allows_feature("text_generation"),
|
|
"image_generation": obj.allows_feature("image_generation"),
|
|
"rag": obj.allows_feature("rag"),
|
|
"all_future_features": obj.allows_all_future_features,
|
|
}
|