Skip to content

Commit

Permalink
feat: add stripe subscription remaining endpoints (#468)
Browse files Browse the repository at this point in the history
  • Loading branch information
vncsna authored Oct 28, 2023
1 parent 8396e2e commit 282705d
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 55 deletions.
15 changes: 0 additions & 15 deletions bd_api/apps/payment/signals.py
Original file line number Diff line number Diff line change
@@ -1,15 +0,0 @@
# -*- coding: utf-8 -*-
from django.db.models.signals import post_save
from django.dispatch import receiver
from djstripe.models import Customer as DJStripeCustomer

from bd_api.apps.account.models import Account
from bd_api.utils import is_prod


@receiver(post_save, sender=Account)
def create_stripe_customer(sender, instance, created, **kwargs):
"""Create stripe customer from after registration"""

if created and is_prod():
DJStripeCustomer.create(subscriber=instance)
17 changes: 0 additions & 17 deletions bd_api/apps/payment/tests.py
Original file line number Diff line number Diff line change
@@ -1,17 +0,0 @@
# -*- coding: utf-8 -*-
from unittest.mock import MagicMock, patch

import pytest

from bd_api.apps.account.models import Account


@pytest.mark.django_db
@patch("bd_api.apps.payment.signals.DJStripeCustomer")
@patch("bd_api.apps.payment.signals.is_prod", new=lambda: True)
def test_create_stripe_customer_signal(mock: MagicMock):
Account.objects.create(
username="john.doe",
email="[email protected]",
)
assert mock.create.called
28 changes: 25 additions & 3 deletions bd_api/apps/payment/urls.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,34 @@
# -*- coding: utf-8 -*-
from django.urls import include, path

from bd_api.apps.payment.views import StripeCustomerView, StripeSubscriptionView
from bd_api.apps.payment.views import (
StripeCustomerSubscriptionView,
StripeCustomerView,
StripeSubscriptionView,
)

urlpatterns = [
path("", include("djstripe.urls", namespace="payment")),
path("customer/<account_id>/", StripeCustomerView, name="payment_customer"),
path("customer/", StripeCustomerView.as_view(), name="payment_customer"),
path("customer/<account_id>/", StripeCustomerView.as_view(), name="payment_customer"),
path(
"subscription/<account_id>/<price_id>/", StripeSubscriptionView, name="payment_subscription"
"customer/<account_id>/subscription/",
StripeCustomerSubscriptionView.as_view(),
name="payment_subscription",
),
path(
"customer/<account_id>/subscription/<subscription_id>",
StripeCustomerSubscriptionView.as_view(),
name="payment_subscription",
),
path(
"subscription/",
StripeSubscriptionView.as_view(),
name="payment_subscription",
),
path(
"subscription/<subscription_id>/",
StripeSubscriptionView.as_view(),
name="payment_subscription",
),
]
100 changes: 80 additions & 20 deletions bd_api/apps/payment/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
from json import JSONDecodeError, loads

from django.http import JsonResponse
from django.contrib.auth.decorators import login_required
from django.http import HttpRequest, JsonResponse
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from djstripe.models import Customer as DJStripeCustomer
Expand All @@ -12,20 +13,51 @@
from bd_api.apps.account.models import Account


@csrf_exempt
class StripeCustomerView(View):
"""Update stripe customer fields:
- name
- email
- address
- line1: "Rua Augusta, 100"
- city: "São Paulo"
- state: "SP"
- country: "BR"
- postal_code: "01304-000"
"""

def put(self, request, account_id):
@csrf_exempt
@login_required
def post(self, request: HttpRequest):
"""Create a stripe customer
- name
- email
- address
- line1: "Rua Augusta, 100"
- city: "São Paulo"
- state: "SP"
- country: "BR"
- postal_code: "01304-000"
"""
try:
body = loads(request.body)
assert "name" in body
assert "email" in body
assert "address" in body

account = Account.objects.get(id=body.account_id)
customer = DJStripeCustomer.create(account)
customer = StripeCustomer.modify(customer.id, **body)

return JsonResponse(customer.values())
except (JSONDecodeError, KeyError) as e:
logger.error(e)
return JsonResponse({}, status=400)
except Exception as e:
logger.error(e)
return JsonResponse({"error": str(e)}, status=422)

@csrf_exempt
@login_required
def put(self, request: HttpRequest, account_id: str):
"""Update a stripe customer
- name
- email
- address
- line1: "Rua Augusta, 100"
- city: "São Paulo"
- state: "SP"
- country: "BR"
- postal_code: "01304-000"
"""
try:
body = loads(request.body)
assert "name" in body
Expand All @@ -45,16 +77,17 @@ def put(self, request, account_id):
return JsonResponse({"error": str(e)}, status=422)


@csrf_exempt
class StripeSubscriptionView(View):
"""Create a stripe subscription"""

def post(self, request, account_id, price_id):
@csrf_exempt
@login_required
def post(self, request: HttpRequest):
"""Create a stripe subscription"""
try:
account = Account.objects.get(id=account_id)
body = loads(request.body)
account = Account.objects.get(id=body.account_id)
customer: DJStripeCustomer = account.djstripe_customers[0]
subscription: DJStripeSubscription = customer.subscribe(
price=price_id,
price=body.price_id,
payment_behaviour="default_incomplete",
payment_settings={"save_default_payment_method": "on_subscription"},
)
Expand All @@ -71,6 +104,33 @@ def post(self, request, account_id, price_id):
logger.error(e)
return JsonResponse({"error": str(e)}, status=422)

@csrf_exempt
@login_required
def delete(self, request: HttpRequest, subscription_id: str):
"""Delete a stripe subscription"""

try:
subscription = DJStripeSubscription.objects.get(id=subscription_id)
subscription = subscription.cancel()
return JsonResponse({})
except Exception as e:
logger.error(e)
return JsonResponse({"error": str(e)}, status=422)


class StripeCustomerSubscriptionView(View):
@csrf_exempt
@login_required
def post(self, request: HttpRequest, account_id: str, subscription_id: str):
"""Add a customer to a stripe subscription"""
...

@csrf_exempt
@login_required
def delete(self, request: HttpRequest, account_id: str, subscription_id: str):
"""Remove a customer from a stripe subscription"""
...


# Reference
# https://stripe.com/docs/billing/subscriptions/build-subscriptions?ui=elementsf

0 comments on commit 282705d

Please sign in to comment.