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.

187 lines
5.1 KiB

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