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.

151 lines
4.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
  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.accounts.models import Profile
  9. from .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. sub = Subscription.objects.for_user(request.user)
  27. ctx = {
  28. "page": "pricing",
  29. "sub": sub,
  30. "first_charge": request.session.pop("first_charge", False)
  31. }
  32. return render(request, "payments/pricing.html", ctx)
  33. def log_and_bail(request, result):
  34. for error in result.errors.deep_errors:
  35. messages.error(request, error.message)
  36. else:
  37. messages.error(request, result.message)
  38. return redirect("hc-pricing")
  39. @login_required
  40. @require_POST
  41. def create_plan(request):
  42. plan_id = request.POST["plan_id"]
  43. if plan_id not in ("P5", "P20"):
  44. return HttpResponseBadRequest()
  45. sub = Subscription.objects.for_user(request.user)
  46. # Cancel the previous plan
  47. if sub.subscription_id:
  48. braintree.Subscription.cancel(sub.subscription_id)
  49. sub.subscription_id = ""
  50. sub.plan_id = ""
  51. sub.save()
  52. # Create Braintree customer record
  53. if not sub.customer_id:
  54. result = braintree.Customer.create({
  55. "email": request.user.email
  56. })
  57. if not result.is_success:
  58. return log_and_bail(request, result)
  59. sub.customer_id = result.customer.id
  60. sub.save()
  61. # Create Braintree payment method
  62. if "payment_method_nonce" in request.POST:
  63. result = braintree.PaymentMethod.create({
  64. "customer_id": sub.customer_id,
  65. "payment_method_nonce": request.POST["payment_method_nonce"]
  66. })
  67. if not result.is_success:
  68. return log_and_bail(request, result)
  69. sub.payment_method_token = result.payment_method.token
  70. sub.save()
  71. # Create Braintree subscription
  72. result = braintree.Subscription.create({
  73. "payment_method_token": sub.payment_method_token,
  74. "plan_id": plan_id,
  75. })
  76. if not result.is_success:
  77. return log_and_bail(request, result)
  78. sub.subscription_id = result.subscription.id
  79. sub.plan_id = plan_id
  80. sub.save()
  81. # Update user's profile
  82. profile = Profile.objects.for_user(request.user)
  83. if plan_id == "P5":
  84. profile.ping_log_limit = 1000
  85. profile.save()
  86. elif plan_id == "P20":
  87. profile.ping_log_limit = 10000
  88. profile.save()
  89. request.session["first_charge"] = True
  90. return redirect("hc-pricing")
  91. @login_required
  92. @require_POST
  93. def cancel_plan(request):
  94. sub = Subscription.objects.get(user=request.user)
  95. braintree.Subscription.cancel(sub.subscription_id)
  96. sub.subscription_id = ""
  97. sub.plan_id = ""
  98. sub.save()
  99. return redirect("hc-pricing")
  100. @login_required
  101. def billing(request):
  102. sub = Subscription.objects.get(user=request.user)
  103. transactions = braintree.Transaction.search(
  104. braintree.TransactionSearch.customer_id == sub.customer_id)
  105. ctx = {"transactions": transactions}
  106. return render(request, "payments/billing.html", ctx)
  107. @login_required
  108. def invoice(request, transaction_id):
  109. sub = Subscription.objects.get(user=request.user)
  110. transaction = braintree.Transaction.find(transaction_id)
  111. if transaction.customer_details.id != sub.customer_id:
  112. return HttpResponseForbidden()
  113. ctx = {"tx": transaction}
  114. return render(request, "payments/invoice.html", ctx)