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.

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