· 6 years ago · Nov 05, 2019, 12:20 AM
1@login_required
2def PaymentView(request):
3 user = request.user
4 try:
5 address = profile.address.get(address_type="home")
6 except:
7 address = None
8 user_membership = get_user_membership(request)
9 try:
10 selected_membership = get_selected_membership(request)
11 except:
12 return redirect(reverse("memberships:select"))
13 publishKey = settings.STRIPE_PUBLISHABLE_KEY
14 if request.method == "POST":
15 # try:
16 payment_method_id = request.POST.get('PaymentMethod', "")
17 amend = request.POST.get('amend', '')
18
19 '''
20 First we need to add the source for the customer
21 '''
22 if amend == "true":
23 customer = stripe.Customer.modify(
24 user_membership.stripe_customer_id,
25 stripe.PaymentMethod.attach(payment_method_id,customer=user_membership.stripe_customer_id),
26 )
27 customer.save()
28 else:
29 customer = stripe.Customer.retrieve(
30 user_membership.stripe_customer_id)
31
32 try:
33 stripe.PaymentMethod.attach(payment_method_id,customer=user_membership.stripe_customer_id) # 4242424242424242
34 customer.save()
35 except:
36 messages.warning(
37 request, "Your card has been failed or declined, Please try a different card")
38 context = {
39 'publishKey': publishKey,
40 'selected_membership': selected_membership,
41 'address': address,
42 'profile': profile,
43 'amend': "true"
44 }
45 return render(request, "membership/membership_payment.html", context)
46
47 '''
48 before we make any subscriptions, we need to make sure there isn't any current active subscriptions for the customer.
49 Without this, we could get duplicates payment
50 We first fetch the customer to make sure we have the latest update
51 '''
52 customer = stripe.Customer.retrieve(user_membership.stripe_customer_id)
53 if customer.subscriptions.total_count > 0:
54 for i in customer.subscriptions.data:
55 if i.plan['id'] == selected_membership.stripe_plan_id and i.plan['active'] == True:
56 messages.info(
57 request, "Your have already subscribed to this plan")
58 return redirect(reverse('memberships:update-transactions',
59 kwargs={
60 'subscription_id': i.id
61 }))
62 else:
63 pass # Maybe we can check if users have a subscription that needs renewing
64 else:
65 '''
66 Now we can create the subscription using only the customer as we don't need to pass their
67 credit card source anymore
68 '''
69
70 stripe_subscription = stripe.Subscription.create(
71 customer=user_membership.stripe_customer_id,
72 items=[
73 {"plan": selected_membership.stripe_plan_id},
74 ],
75 # billing="charge_automatically", #billing is depricated
76 collection_method="charge_automatically",
77 expand=['latest_invoice.payment_intent'],
78 default_payment_method=payment_method_id,
79 # idempotency_key='FXZMav7BbtEui1Z3', # we can add a random idempotency key too
80 )
81 '''
82 Here we check three different status of the subscription object according to API and if
83 secure 3D payment is required, we redirect them for the necessary payments.
84 '''
85 if stripe_subscription.status == "active":
86 return redirect(reverse('memberships:update-transactions',
87 kwargs={
88 'subscription_id': stripe_subscription.id
89 }))
90 elif stripe_subscription.status == "incomplete":
91 payment_intent = stripe_subscription.latest_invoice.payment_intent
92 if payment_intent.status == "requires_action":
93 messages.info(
94 request, "Your bank requires extra authentication")
95 context = {
96 "client_secret": payment_intent.client_secret,
97 "STRIPE_PUBLIC_KEY": settings.STRIPE_PUBLISHABLE_KEY,
98 "subscription_id": stripe_subscription.id
99 }
100 return render(request, "memberships/3d-secure-checkout.html", context)
101 elif payment_intent.status == "requires_payment_method":
102 messages.warning(
103 request, "Your card has been failed or declined, Please try a different card")
104 context = {
105 'publishKey': publishKey,
106 'selected_membership': selected_membership,
107 # 'client_secret': client_secret,
108 'address': address,
109 'profile': profile,
110 'amend': "true"
111 }
112 return render(request, "memberships/membership_payment.html", context)
113 else:
114 messages.info(
115 request, "Something went wrong. Please report to the website admin.")
116
117
118
119 context = {
120 'publishKey': publishKey,
121 'selected_membership': selected_membership,
122 # 'client_secret': client_secret,
123 'address': address,
124 'user': user,
125 'amend': "false"
126 }
127
128 return render(request, "memberships/membership_payment.html", context)