billing: Add billing_modality to upgrade form.

This commit is contained in:
Rishi Gupta
2018-11-23 22:26:00 -08:00
parent 08daefa4a3
commit 6afbc2726f
3 changed files with 34 additions and 16 deletions

View File

@@ -286,7 +286,8 @@ class StripeTest(ZulipTestCase):
'stripeToken': stripe_create_token().id, 'stripeToken': stripe_create_token().id,
'signed_seat_count': self.get_signed_seat_count_from_response(response), 'signed_seat_count': self.get_signed_seat_count_from_response(response),
'salt': self.get_salt_from_response(response), 'salt': self.get_salt_from_response(response),
'plan': Plan.CLOUD_ANNUAL}) 'plan': Plan.CLOUD_ANNUAL,
'billing_modality': 'charge_automatically'})
# Check that we correctly created Customer and Subscription objects in Stripe # Check that we correctly created Customer and Subscription objects in Stripe
stripe_customer = stripe_get_customer(Customer.objects.get(realm=user.realm).stripe_customer_id) stripe_customer = stripe_get_customer(Customer.objects.get(realm=user.realm).stripe_customer_id)
@@ -347,7 +348,8 @@ class StripeTest(ZulipTestCase):
self.client_post("/upgrade/", {'stripeToken': stripe_create_token().id, self.client_post("/upgrade/", {'stripeToken': stripe_create_token().id,
'signed_seat_count': self.signed_seat_count, 'signed_seat_count': self.signed_seat_count,
'salt': self.salt, 'salt': self.salt,
'plan': Plan.CLOUD_ANNUAL}) 'plan': Plan.CLOUD_ANNUAL,
'billing_modality': 'charge_automatically'})
# Check that the non-admin hamlet can still access /billing # Check that the non-admin hamlet can still access /billing
response = self.client_get("/billing/") response = self.client_get("/billing/")
self.assert_in_success_response(["for billing history or to make changes"], response) self.assert_in_success_response(["for billing history or to make changes"], response)
@@ -372,7 +374,8 @@ class StripeTest(ZulipTestCase):
'stripeToken': stripe_create_token().id, 'stripeToken': stripe_create_token().id,
'signed_seat_count': self.get_signed_seat_count_from_response(response), 'signed_seat_count': self.get_signed_seat_count_from_response(response),
'salt': self.get_salt_from_response(response), 'salt': self.get_salt_from_response(response),
'plan': Plan.CLOUD_ANNUAL}) 'plan': Plan.CLOUD_ANNUAL,
'billing_modality': 'charge_automatically'})
# Check that the subscription call used the old quantity, not new_seat_count # Check that the subscription call used the old quantity, not new_seat_count
stripe_customer = stripe_get_customer( stripe_customer = stripe_get_customer(
Customer.objects.get(realm=get_realm('zulip')).stripe_customer_id) Customer.objects.get(realm=get_realm('zulip')).stripe_customer_id)
@@ -406,7 +409,8 @@ class StripeTest(ZulipTestCase):
self.client_post("/upgrade/", {'stripeToken': stripe_create_token('4000000000000341').id, self.client_post("/upgrade/", {'stripeToken': stripe_create_token('4000000000000341').id,
'signed_seat_count': self.signed_seat_count, 'signed_seat_count': self.signed_seat_count,
'salt': self.salt, 'salt': self.salt,
'plan': Plan.CLOUD_ANNUAL}) 'plan': Plan.CLOUD_ANNUAL,
'billing_modality': 'charge_automatically'})
# Check that we created a Customer object with has_billing_relationship False # Check that we created a Customer object with has_billing_relationship False
customer = Customer.objects.get(realm=get_realm('zulip')) customer = Customer.objects.get(realm=get_realm('zulip'))
self.assertFalse(customer.has_billing_relationship) self.assertFalse(customer.has_billing_relationship)
@@ -431,7 +435,8 @@ class StripeTest(ZulipTestCase):
self.client_post("/upgrade/", {'stripeToken': stripe_create_token().id, self.client_post("/upgrade/", {'stripeToken': stripe_create_token().id,
'signed_seat_count': self.signed_seat_count, 'signed_seat_count': self.signed_seat_count,
'salt': self.salt, 'salt': self.salt,
'plan': Plan.CLOUD_ANNUAL}) 'plan': Plan.CLOUD_ANNUAL,
'billing_modality': 'charge_automatically'})
customer = Customer.objects.get(realm=get_realm('zulip')) customer = Customer.objects.get(realm=get_realm('zulip'))
# Impossible to create two Customers, but check that we didn't # Impossible to create two Customers, but check that we didn't
# change stripe_customer_id and that we updated has_billing_relationship # change stripe_customer_id and that we updated has_billing_relationship
@@ -462,7 +467,8 @@ class StripeTest(ZulipTestCase):
'stripeToken': self.token, 'stripeToken': self.token,
'signed_seat_count': "randomsalt", 'signed_seat_count': "randomsalt",
'salt': self.salt, 'salt': self.salt,
'plan': Plan.CLOUD_ANNUAL 'plan': Plan.CLOUD_ANNUAL,
'billing_modality': 'charge_automatically',
}) })
self.assert_in_success_response(["Upgrade to Zulip Standard"], response) self.assert_in_success_response(["Upgrade to Zulip Standard"], response)
self.assertEqual(response['error_description'], 'tampered seat count') self.assertEqual(response['error_description'], 'tampered seat count')
@@ -473,7 +479,8 @@ class StripeTest(ZulipTestCase):
'stripeToken': self.token, 'stripeToken': self.token,
'signed_seat_count': self.signed_seat_count, 'signed_seat_count': self.signed_seat_count,
'salt': self.salt, 'salt': self.salt,
'plan': "invalid" 'plan': "invalid",
'billing_modality': 'charge_automatically',
}) })
self.assert_in_success_response(["Upgrade to Zulip Standard"], response) self.assert_in_success_response(["Upgrade to Zulip Standard"], response)
self.assertEqual(response['error_description'], 'tampered plan') self.assertEqual(response['error_description'], 'tampered plan')
@@ -485,7 +492,8 @@ class StripeTest(ZulipTestCase):
'invoiced_seat_count': self.quantity, 'invoiced_seat_count': self.quantity,
'signed_seat_count': self.signed_seat_count, 'signed_seat_count': self.signed_seat_count,
'salt': self.salt, 'salt': self.salt,
'plan': Plan.CLOUD_ANNUAL 'plan': Plan.CLOUD_ANNUAL,
'billing_modality': 'send_invoice',
}) })
self.assert_in_success_response(["Upgrade to Zulip Standard", self.assert_in_success_response(["Upgrade to Zulip Standard",
"at least %d users" % (MIN_INVOICED_SEAT_COUNT,)], response) "at least %d users" % (MIN_INVOICED_SEAT_COUNT,)], response)
@@ -496,7 +504,8 @@ class StripeTest(ZulipTestCase):
'invoiced_seat_count': self.quantity - 1, 'invoiced_seat_count': self.quantity - 1,
'signed_seat_count': self.signed_seat_count, 'signed_seat_count': self.signed_seat_count,
'salt': self.salt, 'salt': self.salt,
'plan': Plan.CLOUD_ANNUAL 'plan': Plan.CLOUD_ANNUAL,
'billing_modality': 'send_invoice',
}) })
self.assert_in_success_response(["Upgrade to Zulip Standard", self.assert_in_success_response(["Upgrade to Zulip Standard",
"at least %d users" % (self.quantity,)], response) "at least %d users" % (self.quantity,)], response)
@@ -510,7 +519,8 @@ class StripeTest(ZulipTestCase):
'stripeToken': self.token, 'stripeToken': self.token,
'signed_seat_count': self.signed_seat_count, 'signed_seat_count': self.signed_seat_count,
'salt': self.salt, 'salt': self.salt,
'plan': Plan.CLOUD_ANNUAL 'plan': Plan.CLOUD_ANNUAL,
'billing_modality': 'charge_automatically',
}) })
self.assert_in_success_response(["Upgrade to Zulip Standard", self.assert_in_success_response(["Upgrade to Zulip Standard",
"Something went wrong. Please contact"], response) "Something went wrong. Please contact"], response)
@@ -526,7 +536,8 @@ class StripeTest(ZulipTestCase):
'invoiced_seat_count': 123, 'invoiced_seat_count': 123,
'signed_seat_count': self.signed_seat_count, 'signed_seat_count': self.signed_seat_count,
'salt': self.salt, 'salt': self.salt,
'plan': Plan.CLOUD_ANNUAL}) 'plan': Plan.CLOUD_ANNUAL,
'billing_modality': 'send_invoice'})
process_all_billing_log_entries() process_all_billing_log_entries()
# Check that we correctly created a Customer in Stripe # Check that we correctly created a Customer in Stripe
@@ -658,7 +669,8 @@ class StripeTest(ZulipTestCase):
self.client_post("/upgrade/", {'invoiced_seat_count': 123, self.client_post("/upgrade/", {'invoiced_seat_count': 123,
'signed_seat_count': self.signed_seat_count, 'signed_seat_count': self.signed_seat_count,
'salt': self.salt, 'salt': self.salt,
'plan': Plan.CLOUD_ANNUAL}) 'plan': Plan.CLOUD_ANNUAL,
'billing_modality': 'send_invoice'})
stripe_customer = stripe_get_customer(Customer.objects.get(realm=user.realm).stripe_customer_id) stripe_customer = stripe_get_customer(Customer.objects.get(realm=user.realm).stripe_customer_id)
self.assertEqual('Billed by invoice', payment_method_string(stripe_customer)) self.assertEqual('Billed by invoice', payment_method_string(stripe_customer))
@@ -670,7 +682,9 @@ class StripeTest(ZulipTestCase):
self.client_post("/upgrade/", {'stripeToken': stripe_create_token().id, self.client_post("/upgrade/", {'stripeToken': stripe_create_token().id,
'signed_seat_count': self.signed_seat_count, 'signed_seat_count': self.signed_seat_count,
'salt': self.salt, 'salt': self.salt,
'plan': Plan.CLOUD_ANNUAL}, HTTP_HOST=realm.host) 'plan': Plan.CLOUD_ANNUAL,
'billing_modality': 'charge_automatically'},
HTTP_HOST=realm.host)
with patch('corporate.lib.stripe.preview_invoice_total_for_downgrade', return_value=1): with patch('corporate.lib.stripe.preview_invoice_total_for_downgrade', return_value=1):
process_downgrade(user) process_downgrade(user)
stripe_customer = stripe_get_customer(Customer.objects.get(realm=user.realm).stripe_customer_id) stripe_customer = stripe_get_customer(Customer.objects.get(realm=user.realm).stripe_customer_id)
@@ -684,7 +698,9 @@ class StripeTest(ZulipTestCase):
self.client_post("/upgrade/", {'invoiced_seat_count': 123, self.client_post("/upgrade/", {'invoiced_seat_count': 123,
'signed_seat_count': self.signed_seat_count, 'signed_seat_count': self.signed_seat_count,
'salt': self.salt, 'salt': self.salt,
'plan': Plan.CLOUD_ANNUAL}, HTTP_HOST=realm.host) 'plan': Plan.CLOUD_ANNUAL,
'billing_modality': 'send_invoice'},
HTTP_HOST=realm.host)
with patch('corporate.lib.stripe.preview_invoice_total_for_downgrade', return_value=1): with patch('corporate.lib.stripe.preview_invoice_total_for_downgrade', return_value=1):
process_downgrade(user) process_downgrade(user)
stripe_customer = stripe_get_customer(Customer.objects.get(realm=user.realm).stripe_customer_id) stripe_customer = stripe_get_customer(Customer.objects.get(realm=user.realm).stripe_customer_id)
@@ -829,7 +845,8 @@ class StripeTest(ZulipTestCase):
self.client_post("/upgrade/", {'stripeToken': self.token, self.client_post("/upgrade/", {'stripeToken': self.token,
'signed_seat_count': self.signed_seat_count, 'signed_seat_count': self.signed_seat_count,
'salt': self.salt, 'salt': self.salt,
'plan': Plan.CLOUD_ANNUAL}) 'plan': Plan.CLOUD_ANNUAL,
'billing_modality': 'charge_automatically'})
check_billing_processor_update(RealmAuditLog.STRIPE_PLAN_QUANTITY_RESET, new_seat_count) check_billing_processor_update(RealmAuditLog.STRIPE_PLAN_QUANTITY_RESET, new_seat_count)
# Test USER_CREATED # Test USER_CREATED

View File

@@ -77,7 +77,7 @@ def initial_upgrade(request: HttpRequest) -> HttpResponse:
try: try:
plan, seat_count = unsign_and_check_upgrade_parameters( plan, seat_count = unsign_and_check_upgrade_parameters(
user, request.POST['plan'], request.POST['signed_seat_count'], request.POST['salt']) user, request.POST['plan'], request.POST['signed_seat_count'], request.POST['salt'])
if 'invoiced_seat_count' in request.POST: if request.POST['billing_modality'] == 'send_invoice':
min_required_seat_count = max(seat_count, MIN_INVOICED_SEAT_COUNT) min_required_seat_count = max(seat_count, MIN_INVOICED_SEAT_COUNT)
if int(request.POST['invoiced_seat_count']) < min_required_seat_count: if int(request.POST['invoiced_seat_count']) < min_required_seat_count:
raise BillingError( raise BillingError(

View File

@@ -29,6 +29,7 @@
<input type="hidden" name="seat_count" value="{{ seat_count }}"> <input type="hidden" name="seat_count" value="{{ seat_count }}">
<input type="hidden" name="signed_seat_count" value="{{ signed_seat_count }}"> <input type="hidden" name="signed_seat_count" value="{{ signed_seat_count }}">
<input type="hidden" name="salt" value="{{ salt }}"> <input type="hidden" name="salt" value="{{ salt }}">
<input type="hidden" name="billing_modality" value="charge_automatically">
<div class="payment-schedule"> <div class="payment-schedule">
<h3>{{ _("Payment schedule") }}</h3> <h3>{{ _("Payment schedule") }}</h3>
<label> <label>