Skip to content

Commit

Permalink
subscriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
hhartwell committed Dec 28, 2023
1 parent e0afde3 commit c35fb15
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 8 deletions.
36 changes: 35 additions & 1 deletion ckc/serializers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import stripe
from djstripe.models import PaymentMethod, Customer
from djstripe.models import PaymentMethod, Customer, Price, Product

from rest_framework import serializers

Expand Down Expand Up @@ -74,3 +74,37 @@ def create(self, validated_data):
raise serializers.ValidationError(e)

return payment_method


class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = (
'id',
'name',
'description',
'type',
)
read_only_fields = (
'id',
'name',
'description',
'type',
)


class PriceSerializer(serializers.ModelSerializer):
class Meta:
model = Price
fields = (
'id',
'unit_amount',
'currency',
'recurring',
)
read_only_fields = (
'id',
'unit_amount',
'currency',
'recurring',
)
18 changes: 14 additions & 4 deletions ckc/views.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from djstripe.models import PaymentMethod
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated
from djstripe.models import PaymentMethod, Price, Plan
from rest_framework import viewsets, mixins
from rest_framework.permissions import IsAuthenticated, AllowAny

from ckc.serializers import PaymentMethodSerializer
from ckc.serializers import PaymentMethodSerializer, PriceSerializer


class PaymentMethodViewSet(viewsets.ModelViewSet):
Expand All @@ -13,3 +13,13 @@ class PaymentMethodViewSet(viewsets.ModelViewSet):
def get_queryset(self):
qs = PaymentMethod.objects.filter(customer__subscriber=self.request.user)
return qs


class PriceViewSet(viewsets.GenericViewSet, mixins.RetrieveModelMixin, mixins.ListModelMixin):
queryset = Price.objects.all()
serializer_class = PriceSerializer
permission_classes = [AllowAny]

def get_queryset(self):
qs = Price.objects.all()
return qs
4 changes: 3 additions & 1 deletion testproject/urls.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.urls import path
from rest_framework import routers

from ckc.views import PaymentMethodViewSet
from ckc.views import PaymentMethodViewSet, PriceViewSet
from testapp.views import TestExceptionsViewSet
from testapp.viewsets import TestModelWithACreatorViewSet, TestModelWithADifferentNamedCreatorViewSet, BModelViewSet

Expand All @@ -11,6 +11,8 @@
router.register(r'creators-alternative', TestModelWithADifferentNamedCreatorViewSet)
router.register(r'bmodel', BModelViewSet)
router.register(r'payment-methods', PaymentMethodViewSet, basename='payment-methods')
# router.register(r'subscription-plans', SubscriptionPlanViewSet, basename='subscription-plans')
router.register(r'prices', PriceViewSet, basename='prices')

urlpatterns = router.urls + [
path('test-exceptions/', TestExceptionsViewSet.as_view(), name='test-exceptions'),
Expand Down
36 changes: 34 additions & 2 deletions tests/integration/test_payment_processing.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import json

import stripe
from django.urls import reverse
from djstripe.models import PaymentMethod, Customer
from djstripe.models import PaymentMethod, Customer, Price, Product
# from djstripe.core import Price
from rest_framework.test import APITestCase

from django.contrib.auth import get_user_model

from ckc.utils.payments import create_checkout_session, create_payment_intent, confirm_payment_intent
from tests.integration.utils import create_subscription_plan

User = get_user_model()


class TestExceptions(APITestCase):
class TestPaymentProcessing(APITestCase):
def setUp(self):
self.user = User.objects.create_user(username="test", password="test")
self.client.force_authenticate(user=self.user)
Expand Down Expand Up @@ -77,4 +80,33 @@ def test_payment_intents(self):
assert intent is not None
assert intent.status == "succeeded"

def test_subscriptions(self):
# create the subscription plan through dj stripe price object
price = create_subscription_plan(2000, "month", product_name="Sample Product Name: 0", currency="usd")
assert price is not None
assert price.id is not None

customer, created = Customer.get_or_create(subscriber=self.user)
customer.add_payment_method("pm_card_visa")
# subscribe the customer to the plan
subscription = customer.subscribe(price=price.id)

stripe_sub = stripe.Subscription.retrieve(subscription.id)
assert stripe_sub is not None
assert stripe_sub.status == "active"
assert stripe_sub.customer == customer.id

# cancel the subscription
subscription.cancel()
stripe_sub = stripe.Subscription.retrieve(subscription.id)
assert stripe_sub is not None
assert stripe_sub.status == "canceled"

def test_subscription_plan_list(self):
for i in range(3):
create_subscription_plan(2000 + i, "month", product_name=f"Sample Product Name: {i}", currency="usd")

url = reverse('prices-list')
resp = self.client.get(url)
assert resp.status_code == 200
assert len(resp.data) == 3
40 changes: 40 additions & 0 deletions tests/integration/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import stripe
from djstripe.models import Product, Price, Plan


def create_subscription_plan(amount, interval, interval_count=1, currency="usd", product_name="Sample Product Name"):
# product, created = Product.get_or_create(
# name=product_name,
# description="Sample Description",
# type="service",
# )
stripe_product = stripe.Product.create(
name=product_name,
description="Sample Description",
)
product = Product.sync_from_stripe_data(stripe_product)

price = Price.create(
unit_amount=amount,
currency=currency,
recurring={
"interval": interval,
"interval_count": interval_count,
},
product=product,
active=True,
)
from pprint import pprint
pprint(price)

# print(price)
# print(created)
# plan, created = Plan.objects.get_or_create(
# active=True,
# amount=amount,
# interval=interval,
# interval_count=interval_count,
# product=product,
# currency=currency,
# )
return price

0 comments on commit c35fb15

Please sign in to comment.