Skip to content

Commit 152809a

Browse files
committed
Fixed updating of stripe donations
1 parent 01a6e53 commit 152809a

File tree

2 files changed

+31
-7
lines changed

2 files changed

+31
-7
lines changed

fundraising/forms.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import stripe
22
from django import forms
3+
from django.db import transaction
34
from django.utils.safestring import mark_safe
45
from django.utils.translation import gettext_lazy as _
56
from django_recaptcha.fields import ReCaptchaField
@@ -154,17 +155,15 @@ class Meta:
154155
model = Donation
155156
fields = ("subscription_amount", "interval")
156157

158+
@transaction.atomic()
157159
def save(self, commit=True, *args, **kwargs):
158160
donation = super().save(commit=commit)
159-
interval = self.cleaned_data.get("interval")
160-
amount = self.cleaned_data.get("subscription_amount")
161161

162162
# Send data to Stripe
163-
customer = stripe.Customer.retrieve(donation.stripe_customer_id)
164-
subscription = customer.subscriptions.retrieve(donation.stripe_subscription_id)
163+
subscription = stripe.Subscription.retrieve(donation.stripe_subscription_id)
165164
# TODO: Setting the plan is deprecated — use Price API instead.
166-
subscription.plan = interval
167-
subscription.quantity = int(amount)
165+
subscription.plan = self.cleaned_data["interval"]
166+
subscription.quantity = int(self.cleaned_data["subscription_amount"])
168167

169168
subscription.save()
170169

fundraising/tests/test_forms.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
from django.test import TestCase
44
from django_recaptcha.client import RecaptchaResponse
55

6-
from ..forms import PaymentForm
6+
from ..forms import DonationForm, PaymentForm
7+
from ..models import DjangoHero, Donation
78

89

910
class TestPaymentForm(TestCase):
@@ -44,3 +45,27 @@ def test_captcha_token_required(self):
4445
)
4546
self.assertFalse(form.is_valid())
4647
self.assertIn("captcha", form.errors)
48+
49+
@patch("fundraising.forms.stripe.Subscription.retrieve", side_effect=KeyError)
50+
def test_donation_form_save_atomic(self, *mocks):
51+
"""
52+
A stripe error in save() should rollback any change made to the Donation
53+
"""
54+
donation = Donation.objects.create(
55+
interval="monthly",
56+
subscription_amount=50,
57+
donor=DjangoHero.objects.create(),
58+
)
59+
form = DonationForm(
60+
instance=donation,
61+
data={"subscription_amount": 25, "interval": "yearly"},
62+
)
63+
64+
# Save the form, this will trigger a KeyError but we catch it and move on
65+
self.assertTrue(form.is_valid())
66+
self.assertRaises(KeyError, form.save)
67+
68+
# The donation should not have been updated with new data
69+
donation.refresh_from_db()
70+
self.assertEqual(donation.interval, "monthly")
71+
self.assertEqual(donation.subscription_amount, 50)

0 commit comments

Comments
 (0)