Skip to content

Commit da1e685

Browse files
authored
Merge pull request #7983 from readthedocs/humitos/donate-stripe-checkout
2 parents 6171dbf + 6031bdc commit da1e685

File tree

6 files changed

+48
-29
lines changed

6 files changed

+48
-29
lines changed

media/css/core.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ form p label { font-weight: normal; }
104104
form p.required label { font-weight: bold; }
105105
textarea, input, button, .button, select { display: block; padding: 5px; color: #444; background-color: #fff; border: 1px solid #BFBFBF; border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; }
106106
textarea, input, .button { box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.5) inset; -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.5) inset; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.5) inset; }
107-
input[type="text"], input[type="password"] { width: 250px; height: 20px; margin-bottom: 5px; background: #fff; }
107+
input[type="text"], input[type="password"], input[type="email"] { width: 250px; height: 20px; margin-bottom: 5px; background: #fff; }
108108
input::-webkit-input-placeholder { color: #ccc; }
109109
input:-moz-placeholder { color: #ccc; opacity: 1; }
110110
input::-moz-placeholder { color: #ccc; opacity: 1; }

readthedocs/gold/static-src/gold/js/checkout.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ function StripeCheckoutView(config) {
1515
// Avoid submitting the form
1616
event.preventDefault();
1717

18-
var priceId = document.getElementById(self.levelId).value;
19-
self.createCheckoutSession(priceId).then(function (result) {
18+
self.createCheckoutSession().then(function (result) {
2019
// Call Stripe.js method to redirect to the new Checkout page
2120
result.json().then(function (data) {
2221
self.stripe
@@ -28,15 +27,28 @@ function StripeCheckoutView(config) {
2827
});
2928
};
3029

31-
self.createCheckoutSession = function (priceId) {
30+
self.createCheckoutSession = function () {
31+
var priceId = document.getElementById(self.levelId).value;
32+
// One-time donation fields
33+
var name = document.getElementById('id_name');
34+
var email = document.getElementById('id_email');
35+
var logoUrl = document.getElementById('id_logo_url');
36+
var siteUrl = document.getElementById('id_site_url');
37+
var public = document.getElementById('id_public');
38+
3239
return fetch(self.checkoutSessionUrl, {
3340
method: "POST",
3441
headers: {
3542
"Content-Type": "application/json",
3643
"X-CSRFToken": self.csrfToken
3744
},
3845
body: JSON.stringify({
39-
priceId: priceId
46+
priceId: priceId,
47+
name: name ? name.value : null,
48+
email: email ? email.value : null,
49+
logoUrl: logoUrl ? logUrl.value : null,
50+
siteUrl: siteUrl ? siteUrl.value : null,
51+
public: public ? public.checked : null,
4052
})
4153
});
4254
};

readthedocs/gold/static/gold/js/checkout.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

readthedocs/gold/tests/test_webhooks.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ class GoldStripeWebhookTests(TestCase):
2323
"client_reference_id": "golduser",
2424
"customer": "cus_a1b2c3",
2525
"customer_email": "[email protected]",
26-
"subscription": "sub_a1b2c3"
26+
"subscription": "sub_a1b2c3",
27+
"mode": "subscription"
2728
}
2829
},
2930
"type": "checkout.session.completed"

readthedocs/gold/views.py

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -226,15 +226,34 @@ def post(self, request, format=None):
226226

227227
if event.type == self.EVENT_CHECKOUT_COMPLETED:
228228
username = event.data.object.client_reference_id
229-
subscription = stripe.Subscription.retrieve(event.data.object.subscription)
230-
231-
user = User.objects.get(username=username)
232-
GoldUser.objects.create(
233-
user=user,
234-
level=subscription.plan.id,
235-
stripe_id=stripe_customer,
236-
subscribed=True,
237-
)
229+
mode = event.data.object.mode
230+
if mode == 'subscription':
231+
# Gold Membership
232+
user = User.objects.get(username=username)
233+
subscription = stripe.Subscription.retrieve(event.data.object.subscription)
234+
GoldUser.objects.create(
235+
user=user,
236+
level=subscription.plan.id,
237+
stripe_id=stripe_customer,
238+
subscribed=True,
239+
)
240+
elif mode == 'payment':
241+
# One-time donation
242+
try:
243+
# TODO: find a better way to extend this view for one-time donations.
244+
from readthedocsext.donate.utils import handle_payment_webhook
245+
stripe_session = event.data.object.id
246+
price_in_cents = event.data.object.amount_total
247+
handle_payment_webhook(
248+
username,
249+
stripe_customer,
250+
stripe_session,
251+
price_in_cents,
252+
)
253+
except ImportError:
254+
log.warning(
255+
'Not able to import handle_payment_webhook for one-time donation.',
256+
)
238257
# TODO: add user notification saying it was successful
239258

240259
elif event.type == self.EVENT_CHECKOUT_PAYMENT_FAILED:

readthedocs/payments/mixins.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,3 @@ def get_context_data(self, **kwargs):
1313
context = super().get_context_data(**kwargs)
1414
context['stripe_publishable'] = settings.STRIPE_PUBLISHABLE
1515
return context
16-
17-
def get_form(self, data=None, files=None, **kwargs):
18-
"""
19-
Pass in copy of POST data to avoid read only QueryDicts on form.
20-
21-
This is used to be able to reset some important credit card fields if
22-
card validation fails. In this case, the Stripe token was valid, but the
23-
card was rejected during the charge or subscription instantiation.
24-
"""
25-
if self.request.method == 'POST':
26-
data = self.request.POST.copy()
27-
cls = self.get_form_class()
28-
return cls(data=data, files=files, **kwargs)

0 commit comments

Comments
 (0)