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.

218 lines
6.1 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. period = "monthly"
  33. if sub and sub.plan_id.startswith("Y"):
  34. period = "annual"
  35. ctx = {
  36. "page": "pricing",
  37. "sub": sub,
  38. "period": period,
  39. "first_charge": request.session.pop("first_charge", False)
  40. }
  41. return render(request, "payments/pricing.html", ctx)
  42. def log_and_bail(request, result):
  43. logged_deep_error = False
  44. for error in result.errors.deep_errors:
  45. messages.error(request, error.message)
  46. logged_deep_error = True
  47. if not logged_deep_error:
  48. messages.error(request, result.message)
  49. return redirect("hc-pricing")
  50. @login_required
  51. @require_POST
  52. def create_plan(request):
  53. plan_id = request.POST["plan_id"]
  54. if plan_id not in ("P5", "P50", "Y48", "Y480"):
  55. return HttpResponseBadRequest()
  56. sub = Subscription.objects.for_user(request.user)
  57. # Cancel the previous plan
  58. if sub.subscription_id:
  59. braintree.Subscription.cancel(sub.subscription_id)
  60. sub.subscription_id = ""
  61. sub.plan_id = ""
  62. sub.save()
  63. # Create Braintree customer record
  64. if not sub.customer_id:
  65. result = braintree.Customer.create({
  66. "email": request.user.email
  67. })
  68. if not result.is_success:
  69. return log_and_bail(request, result)
  70. sub.customer_id = result.customer.id
  71. sub.save()
  72. # Create Braintree payment method
  73. if "payment_method_nonce" in request.POST:
  74. result = braintree.PaymentMethod.create({
  75. "customer_id": sub.customer_id,
  76. "payment_method_nonce": request.POST["payment_method_nonce"]
  77. })
  78. if not result.is_success:
  79. return log_and_bail(request, result)
  80. sub.payment_method_token = result.payment_method.token
  81. sub.save()
  82. # Create Braintree subscription
  83. result = braintree.Subscription.create({
  84. "payment_method_token": sub.payment_method_token,
  85. "plan_id": plan_id,
  86. })
  87. if not result.is_success:
  88. return log_and_bail(request, result)
  89. sub.subscription_id = result.subscription.id
  90. sub.plan_id = plan_id
  91. sub.save()
  92. # Update user's profile
  93. profile = request.user.profile
  94. if plan_id in ("P5", "Y48"):
  95. profile.ping_log_limit = 1000
  96. profile.check_limit = 500
  97. profile.team_limit = 9
  98. profile.sms_limit = 50
  99. profile.sms_sent = 0
  100. profile.save()
  101. elif plan_id in ("P50", "Y480"):
  102. profile.ping_log_limit = 1000
  103. profile.check_limit = 500
  104. profile.team_limit = 500
  105. profile.sms_limit = 500
  106. profile.sms_sent = 0
  107. profile.save()
  108. request.session["first_charge"] = True
  109. return redirect("hc-pricing")
  110. @login_required
  111. @require_POST
  112. def update_payment_method(request):
  113. sub = Subscription.objects.for_user(request.user)
  114. if not sub.customer_id or not sub.subscription_id:
  115. return HttpResponseBadRequest()
  116. if "payment_method_nonce" not in request.POST:
  117. return HttpResponseBadRequest()
  118. result = braintree.PaymentMethod.create({
  119. "customer_id": sub.customer_id,
  120. "payment_method_nonce": request.POST["payment_method_nonce"]
  121. })
  122. if not result.is_success:
  123. return log_and_bail(request, result)
  124. payment_method_token = result.payment_method.token
  125. result = braintree.Subscription.update(sub.subscription_id, {
  126. "payment_method_token": payment_method_token
  127. })
  128. if not result.is_success:
  129. return log_and_bail(request, result)
  130. sub.payment_method_token = payment_method_token
  131. sub.save()
  132. return redirect("hc-pricing")
  133. @login_required
  134. @require_POST
  135. def cancel_plan(request):
  136. sub = Subscription.objects.get(user=request.user)
  137. sub.cancel()
  138. # Revert to default limits--
  139. profile = request.user.profile
  140. profile.ping_log_limit = 100
  141. profile.check_limit = 20
  142. profile.team_limit = 2
  143. profile.sms_limit = 0
  144. profile.save()
  145. return redirect("hc-pricing")
  146. @login_required
  147. def billing(request):
  148. if request.method == "POST":
  149. form = BillToForm(request.POST)
  150. if form.is_valid():
  151. request.user.profile.bill_to = form.cleaned_data["bill_to"]
  152. request.user.profile.save()
  153. return redirect("hc-billing")
  154. sub = Subscription.objects.get(user=request.user)
  155. transactions = braintree.Transaction.search(
  156. braintree.TransactionSearch.customer_id == sub.customer_id)
  157. ctx = {"transactions": transactions}
  158. return render(request, "payments/billing.html", ctx)
  159. @login_required
  160. def invoice(request, transaction_id):
  161. sub = Subscription.objects.get(user=request.user)
  162. transaction = braintree.Transaction.find(transaction_id)
  163. if transaction.customer_details.id != sub.customer_id:
  164. return HttpResponseForbidden()
  165. ctx = {"tx": transaction}
  166. return render(request, "payments/invoice.html", ctx)