You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
5.9 KiB

9 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. from django.conf import settings
  2. from django.contrib import messages
  3. from django.contrib.auth.decorators import login_required
  4. from django.http import (HttpResponseBadRequest, HttpResponseForbidden,
  5. JsonResponse)
  6. from django.shortcuts import redirect, render
  7. from django.views.decorators.http import require_POST
  8. from hc.payments.forms import BillToForm
  9. from hc.payments.models import Subscription
  10. if settings.USE_PAYMENTS:
  11. import braintree
  12. else:
  13. # hc.payments tests mock this object, so tests should
  14. # still be able to run:
  15. braintree = None
  16. @login_required
  17. def get_client_token(request):
  18. sub = Subscription.objects.for_user(request.user)
  19. client_token = braintree.ClientToken.generate({
  20. "customer_id": sub.customer_id
  21. })
  22. return JsonResponse({"client_token": client_token})
  23. def pricing(request):
  24. if request.user.is_authenticated and request.profile != request.team:
  25. ctx = {"page": "pricing"}
  26. return render(request, "payments/pricing_not_owner.html", ctx)
  27. sub = None
  28. if request.user.is_authenticated:
  29. # Don't use Subscription.objects.for_user method here, so a
  30. # subscription object is not created just by viewing a page.
  31. sub = Subscription.objects.filter(user_id=request.user.id).first()
  32. ctx = {
  33. "page": "pricing",
  34. "sub": sub,
  35. "first_charge": request.session.pop("first_charge", False)
  36. }
  37. return render(request, "payments/pricing.html", ctx)
  38. def log_and_bail(request, result):
  39. for error in result.errors.deep_errors:
  40. messages.error(request, error.message)
  41. else:
  42. messages.error(request, result.message)
  43. return redirect("hc-pricing")
  44. @login_required
  45. @require_POST
  46. def create_plan(request):
  47. plan_id = request.POST["plan_id"]
  48. if plan_id not in ("P5", "P50"):
  49. return HttpResponseBadRequest()
  50. sub = Subscription.objects.for_user(request.user)
  51. # Cancel the previous plan
  52. if sub.subscription_id:
  53. braintree.Subscription.cancel(sub.subscription_id)
  54. sub.subscription_id = ""
  55. sub.plan_id = ""
  56. sub.save()
  57. # Create Braintree customer record
  58. if not sub.customer_id:
  59. result = braintree.Customer.create({
  60. "email": request.user.email
  61. })
  62. if not result.is_success:
  63. return log_and_bail(request, result)
  64. sub.customer_id = result.customer.id
  65. sub.save()
  66. # Create Braintree payment method
  67. if "payment_method_nonce" in request.POST:
  68. result = braintree.PaymentMethod.create({
  69. "customer_id": sub.customer_id,
  70. "payment_method_nonce": request.POST["payment_method_nonce"]
  71. })
  72. if not result.is_success:
  73. return log_and_bail(request, result)
  74. sub.payment_method_token = result.payment_method.token
  75. sub.save()
  76. # Create Braintree subscription
  77. result = braintree.Subscription.create({
  78. "payment_method_token": sub.payment_method_token,
  79. "plan_id": plan_id,
  80. })
  81. if not result.is_success:
  82. return log_and_bail(request, result)
  83. sub.subscription_id = result.subscription.id
  84. sub.plan_id = plan_id
  85. sub.save()
  86. # Update user's profile
  87. profile = request.user.profile
  88. if plan_id == "P5":
  89. profile.ping_log_limit = 1000
  90. profile.check_limit = 500
  91. profile.team_limit = 9
  92. profile.sms_limit = 50
  93. profile.sms_sent = 0
  94. profile.save()
  95. elif plan_id == "P50":
  96. profile.ping_log_limit = 1000
  97. profile.check_limit = 500
  98. profile.team_limit = 500
  99. profile.sms_limit = 500
  100. profile.sms_sent = 0
  101. profile.save()
  102. request.session["first_charge"] = True
  103. return redirect("hc-pricing")
  104. @login_required
  105. @require_POST
  106. def update_payment_method(request):
  107. sub = Subscription.objects.for_user(request.user)
  108. if not sub.customer_id or not sub.subscription_id:
  109. return HttpResponseBadRequest()
  110. if "payment_method_nonce" not in request.POST:
  111. return HttpResponseBadRequest()
  112. result = braintree.PaymentMethod.create({
  113. "customer_id": sub.customer_id,
  114. "payment_method_nonce": request.POST["payment_method_nonce"]
  115. })
  116. if not result.is_success:
  117. return log_and_bail(request, result)
  118. payment_method_token = result.payment_method.token
  119. result = braintree.Subscription.update(sub.subscription_id, {
  120. "payment_method_token": payment_method_token
  121. })
  122. if not result.is_success:
  123. return log_and_bail(request, result)
  124. sub.payment_method_token = payment_method_token
  125. sub.save()
  126. return redirect("hc-pricing")
  127. @login_required
  128. @require_POST
  129. def cancel_plan(request):
  130. sub = Subscription.objects.get(user=request.user)
  131. sub.cancel()
  132. # Revert to default limits--
  133. profile = request.user.profile
  134. profile.ping_log_limit = 100
  135. profile.check_limit = 20
  136. profile.team_limit = 2
  137. profile.sms_limit = 0
  138. profile.save()
  139. return redirect("hc-pricing")
  140. @login_required
  141. def billing(request):
  142. if request.method == "POST":
  143. form = BillToForm(request.POST)
  144. if form.is_valid():
  145. request.user.profile.bill_to = form.cleaned_data["bill_to"]
  146. request.user.profile.save()
  147. return redirect("hc-billing")
  148. sub = Subscription.objects.get(user=request.user)
  149. transactions = braintree.Transaction.search(
  150. braintree.TransactionSearch.customer_id == sub.customer_id)
  151. ctx = {"transactions": transactions}
  152. return render(request, "payments/billing.html", ctx)
  153. @login_required
  154. def invoice(request, transaction_id):
  155. sub = Subscription.objects.get(user=request.user)
  156. transaction = braintree.Transaction.find(transaction_id)
  157. if transaction.customer_details.id != sub.customer_id:
  158. return HttpResponseForbidden()
  159. ctx = {"tx": transaction}
  160. return render(request, "payments/invoice.html", ctx)