我有一个Django视图,该视图通过Stripe对用户进行免费试用。当视图发出POST请求时,它会发出两次。
在entries = soup.find_all("tr", {"valign" : "top"})
links = ['https://web.archive.org{}'.format(entry.contents[0].a['href']) for entry in entries]
names = [entry.contents[0].text for entry in entries]
nationalities = [entry.contents[1] for entry in entries]
行之后和视图的初始呈现中,我都尝试了幂等键。 Stripe中的客户总是以两个相同的付款来源和两个相同的计划订阅结束。
if request.method == 'POST'
数据总是在Stripe中两次结束。日志显示:
def start_trial(request):
title = 'get started'
description = title
form = MembershipForm()
key = settings.STRIPE_PUBLISHABLE_KEY
trial_days = 30
coupon = None
custom_message = ''
subscription_idempotency = str(uuid.uuid4())
source_idempotency = str(uuid.uuid4())
try:
vendor = Vendor.objects.get(user=request.user)
custom_message = vendor.message
coupon = Coupon.objects.get(vendor.coupon)
coupon = coupon.stripe_coupon_id
trial_days = vendor.trial_days
except Vendor.DoesNotExist:
pass
try:
partner = Partner.objects.get(user=request.user)
custom_message = partner.message
coupon = Coupon.objects.get(partner.coupon)
coupon = coupon.stripe_coupon_id
trial_days = partner.trial_days
except Partner.DoesNotExist:
pass
if request.method == 'POST':
form = MembershipForm(request.POST)
if form.is_valid():
user = request.user
plan = Membership.objects.get(type_of=form.cleaned_data['plan'])
# stripe needs to attempt to create a customer
# TODO what if there's already a membership/subscription?
user_membership = UserMembership.objects.get(user=request.user)
stripe_subscription = stripe.Subscription.create(
customer=user_membership.stripe_customer_id,
items=[
{"plan": plan.stripe_plan_id}
],
trial_period_days=trial_days,
coupon=coupon,
idempotency_key=subscription_idempotency,
)
subscription = Subscription.objects.create(
user_membership=user_membership, stripe_subscription_id=stripe_subscription.id)
subscription.save()
stripe.Customer.create_source(user_membership.stripe_customer_id,
source=request.POST.get('stripeToken'),
idempotency_key=source_idempotency)
user_membership.membership = plan
user_membership.save()
user.is_subscriber = True
user.save()
# if subscription status is incomplete, display error.
# if passes, redirect to onboarding
message = 'yay'
messages.success(request, message=message)
return HttpResponseRedirect('/onboarding/')
return render(request, 'memberships/free_trial.html',
{'title': title, 'description': description, 'form': form,
'key': key, 'custom_message': custom_message})