Stripe checkout #104411

Merged
Anna Sirota merged 61 commits from stripe into main 2024-06-17 18:08:41 +02:00
6 changed files with 28 additions and 44 deletions
Showing only changes of commit 2b29a7ab2a - Show all commits

View File

@ -210,12 +210,6 @@ class PayExistingOrderForm(forms.Form): # TODO
price = forms.CharField(widget=forms.HiddenInput(), required=True)
class ChangePaymentMethodForm(forms.Form): # TODO
"""Add full billing address to the change payment form."""
pass
class CancelSubscriptionForm(forms.Form):
"""Confirm cancellation of a subscription."""

View File

@ -93,10 +93,10 @@
{% if not subscription.is_cancelled %}
<div class="col-auto">
<a class="small"
href="{% url 'subscriptions:payment-method-change' subscription_id=subscription.id %}">
Change
</a>
<form method="POST" action="{% url 'subscriptions:payment-method-change' subscription_id=subscription.id %}">
{% csrf_token %}
<button type="submit" class="small">Change</button>
</form>
</div>
{% endif %}
</div>

View File

@ -41,9 +41,17 @@ urlpatterns = [
),
path(
'subscription/<int:subscription_id>/payment-method/change/',
settings.PaymentMethodChangeView.as_view(),
looper_settings.PaymentMethodChangeView.as_view(
success_url='subscriptions:payment-method-change-done',
cancel_url='user-settings-billing', # FIXME: go back to subscription manage instead
),
name='payment-method-change',
),
path(
'subscription/<int:subscription_id>/payment-method/change/<stripe_session_id>/',
settings.PaymentMethodChangeDoneView.as_view(),
name='payment-method-change-done',
),
path(
'subscription/order/<int:order_id>/pay/',
settings.PayExistingOrderView.as_view(),

View File

@ -5,7 +5,7 @@ import logging
from django.shortcuts import redirect
from django.views.generic import FormView
from looper.views.checkout_braintree import AbstractPaymentView
from looper.views.checkout_stripe import CheckoutStripeView
import looper.gateways
import looper.middleware
import looper.models
@ -20,7 +20,7 @@ logger.setLevel(logging.DEBUG)
class _PlanSelectorMixin:
get_currency = AbstractPaymentView.get_currency
get_currency = CheckoutStripeView.get_currency
select_team_plans = False
plan_variation = None
plan = None

View File

@ -1,6 +1,7 @@
"""Views handling subscription management."""
import logging
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from django.http import HttpResponseForbidden
from django.shortcuts import get_object_or_404
@ -14,7 +15,6 @@ import looper.views.settings_braintree
from subscriptions.forms import (
CancelSubscriptionForm,
ChangePaymentMethodForm,
PayExistingOrderForm,
TeamForm,
)
@ -47,35 +47,17 @@ class CancelSubscriptionView(SingleSubscriptionMixin, FormView):
return super().form_valid(form)
class PaymentMethodChangeView(looper.views.settings_braintree.PaymentMethodChangeView):
"""Use the Braintree drop-in UI to switch a subscription's payment method."""
class PaymentMethodChangeDoneView(looper.views.settings.PaymentMethodChangeDoneView):
"""Change payment method in response to a successful payment setup."""
template_name = 'subscriptions/payment_method_change.html'
form_class = ChangePaymentMethodForm
success_url = reverse_lazy('user-settings-billing')
subscription: looper.models.Subscription
def get_initial(self) -> dict:
"""Modify initial form data."""
initial = super().get_initial()
initial['next_url_after_done'] = self.success_url
# Looper's view uses customer full_name, we don't
initial.pop('full_name', None)
# Only set initial values if they aren't already saved to the billing address.
# Initial values always override form data, which leads to confusing issues with views.
if not (self.customer and self.customer.billing_address.full_name):
# Fall back to user's full name, if no full name set already in the billing address:
if self.request.user.full_name:
initial['full_name'] = self.request.user.full_name
return initial
def form_invalid(self, form):
"""Temporarily log all validation errors."""
logger.exception('Validation error in ChangePaymentMethodForm: %s', form.errors)
return super().form_invalid(form)
@property
def success_url(self):
"""Return to this subscription's manage page."""
messages.add_message(self.request, messages.INFO, 'Payment method updated')
return reverse(
'subscriptions:manage',
kwargs={'subscription_id': self.kwargs['subscription_id']},
)
class PayExistingOrderView(looper.views.checkout_braintree.CheckoutExistingOrderView):

View File

@ -2,7 +2,7 @@
from collections import defaultdict
from django.views.generic.base import TemplateView
from looper.views.checkout_braintree import AbstractPaymentView
from looper.views.checkout_stripe import CheckoutStripeView
import looper.models
import subscriptions.models
@ -11,7 +11,7 @@ import subscriptions.models
class TeamsLanding(TemplateView):
"""Display a selection of team plans and existing sponsors."""
get_currency = AbstractPaymentView.get_currency
get_currency = CheckoutStripeView.get_currency
template_name = 'subscriptions/teams_landing.html'
@staticmethod