Commit Graph

811 Commits

Author SHA1 Message Date
Aman Agrawal 0d3c68cefb stripe: Rearrange code. 2023-12-06 12:04:10 -08:00
Aman Agrawal 74ef619412 stripe: Active plans always have last_ledger_entry. 2023-12-06 12:04:10 -08:00
Aman Agrawal f99214e866 stripe: Plan is always defined for get_billing_page_context calls. 2023-12-06 12:04:10 -08:00
Aman Agrawal f381fb1afd billing_page: Check for live plan before redirecting to upgrade page.
Instead of checking for any `CustomerPlan`, we need to check if
the customer has any live plan.
2023-12-06 12:04:10 -08:00
Aman Agrawal b8c0265d3a billing_page: Directly used billing_session method get base url. 2023-12-06 12:04:10 -08:00
Lauryn Menard 906e667a70 corporate: Implement support_url for all BillingSession child classes.
Adds a helper since there are only a few different parameters for
all BillingSession child clases, `build_support_url`.

Also, renames `get_support_url` to more explicitly note that it
is for realms: `get_realm_support_url`.
2023-12-06 11:04:54 -08:00
Lauryn Menard 46dab1beb9 emails: Replace string_id from sponsorship request email context.
Use of `string_id` in the sponsorship request email content was
removed in commit d3834f8b9, but it is still used in the email
subject.

Updates the email subject to use the billing_entity_display_name,
which is still the Realm.string_id for Zulip Cloud organizations.

Sets this string as "billing_entity" in the context and subject
template.
2023-12-06 11:04:54 -08:00
Lauryn Menard ea725aaaf3 support: Handle missing current licenses data for support views. 2023-12-06 11:01:26 -08:00
Lauryn Menard d079a13760 support: Use shared template for current plan details on support views.
Moves the section in support views for any current plan details
to a new template: `templates/analytics/current_plan_details.html`.

Also, updates the PlanData dataclass to have a boolean that checks
if the current plan tier is the self-hosted legacy plan.
2023-12-06 11:01:26 -08:00
Aman Agrawal ca3569165a billing_page: Fix redirect URLs for remote_realm billing page. 2023-12-05 23:44:29 -08:00
Aman Agrawal 34730203b3 plans: Show special text for legacy orgs scheduled for upgrade. 2023-12-05 23:44:29 -08:00
Aman Agrawal 8d9a7679bc plans: Show buttons as per current context.
Also show correct tab based on remote / cloud user.
2023-12-05 23:44:29 -08:00
Aman Agrawal 49908ba166 sponsorship: Populate sponsorship page with correct context.
Fixes sponsorship page to work for remote realm and server.
2023-12-05 23:44:29 -08:00
Aman Agrawal 044cb820f8 stripe: Fix legacy server upgrade to business plan.
I had pushed a similar change in #28017 but seems to have been lost.
2023-12-05 23:44:29 -08:00
Prakhar Pratyush e5d71fe5ac stripe: Move `update_license_ledger_if_needed` to BillingSession.
This commit moves the 'update_license_ledger_if_needed' and its
helper function 'update_license_ledger_for_automanaged_plan'
to the 'BillingSession' abstract class.

This refactoring will help in minimizing duplicate code while
supporting both realm and remote_server customers.
2023-12-05 12:51:41 -08:00
Prakhar Pratyush 133291ec2d stripe: Move `update_license_ledger_for_manual_plan` to BillingSession.
Moves the 'update_license_ledger_for_manual_plan' function
to the 'BillingSession' abstract class.

This refactoring will help in minimizing duplicate code while
supporting both realm and remote_server customers.
2023-12-05 12:51:41 -08:00
Lauryn Menard 6c5b419267 support: Add downgrade current plan actions to remote servers. 2023-12-05 12:48:42 -08:00
Anders Kaseorg 8a7916f21a python: Consistently use from…import for datetime.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-12-05 12:01:18 -08:00
Mateusz Mandera 250b52e3dc remote_billing: Add a "confirm login" page in RemoteRealm auth flow. 2023-12-05 11:34:57 -08:00
Mateusz Mandera 04bb60a05e remote_billing: Increase signed link validity to 2 hours.
This cannot be so short if we're adding an intermittent "check your
details, agree to ToS and confirm login" page. We're also considering
having users potentially share these links.
2023-12-05 11:34:57 -08:00
Mateusz Mandera c23339f295 remote_billing: Rename the _billing_entry and _finalize_login functions.
These names were picked when I still thought these endpoints would serve
both the RemoteRealm and RemoteZulipServer based flows. Now that it's
known these are RemoteRealm-only endpoints, the _server in the names no
longer makes sense.
2023-12-05 11:34:57 -08:00
Aman Agrawal 201a2bb9c8 urls: Add `/` to `_page` URLs to avoid redirects. 2023-12-04 12:36:24 -08:00
Aman Agrawal 00f4f8cb04 billing: Use PATCH requests for update plan for remote instances.
This fixes the update requests for billing frequency and other
requests not working on billing page for cloud customers.
2023-12-04 12:36:24 -08:00
Aman Agrawal 1a063986e3 billing: Render page for legacy server scheduled for upgrade. 2023-12-04 12:36:24 -08:00
Aman Agrawal cd45b6f6f8 upgrade: Allow legacy servers to upgrade to business plan. 2023-12-04 12:36:24 -08:00
Aman Agrawal 9935f002ec stripe: Fill `get_type_of_plan_tier_change` for remote realm/server. 2023-12-04 12:36:24 -08:00
Aman Agrawal f22ccd3125 stripe: Render upgrade page for remote servers on legacy plan. 2023-12-04 12:36:24 -08:00
Aman Agrawal 7d83508235 commands: Add script to create servers on legacy plan.
Also adds `SWITCH_PLAN_TIER_AT_PLAN_END` for `CustomerPlan`
which will be used to mark status of remote server legacy
plans which are scheduled for an upgrade.
2023-12-04 12:36:24 -08:00
Lauryn Menard 45df5750ae corporate: Remove now unused is_sponsored_realm.
This has been replaced with the is_sponsored method in
the RealmBillingSession class.
2023-12-04 07:15:15 -08:00
Lauryn Menard 5eabd51702 corporate: Make is_sponsored_or_pending not abstract in BillingSession.
The logic for BillingSession.is_sponsored_or_pending would be the
same for all three child classes of BillingSession, so this should
be a method on the BillingSession abstract class.
2023-12-04 07:15:15 -08:00
Aman Agrawal 8a1630ee42 remote_billing_page: Redirect servers to correct URL after login. 2023-12-03 15:15:04 -08:00
Aman Agrawal a59245e932 billing: Make various buttons on billing page work.
We pass billing_base_url to the template and use it to construct
session specific URLs. Also, add corresponding function on server
to support them.
2023-12-03 15:15:04 -08:00
Aman Agrawal 7e7af6266d stripe: Rename get_metadata to use for both billing and upgrade. 2023-12-03 15:15:04 -08:00
Aman Agrawal f942bbd70f stripe: Show tier information correctly on billing and upgrade page. 2023-12-03 15:15:04 -08:00
Aman Agrawal 785444b2b8 test_stripe: Keep same context after seat_count change during upgrade.
We need to emulate seat_count change after we rendered
the upgrade page. To do that, we need to render the upgrade
page with old seat count.
2023-12-03 15:15:04 -08:00
Aman Agrawal 36532e9180 models: Rename tiers to pass stripe 22 character limit. 2023-12-03 15:15:04 -08:00
Aman Agrawal 5835ef44fe stripe: Add session specific get_email method.
This looks nicer and it will help us have a common method for
get_data_for_stripe_payment_intent.
2023-12-03 15:15:04 -08:00
Lauryn Menard 69f6d3dcb1 support: Approve sponsorship for remote server customer.
Adds ability to approve a sponsorship request for a customer
attached to a remote server via the remote server support view.
2023-12-03 14:27:07 -08:00
Lauryn Menard 6d66248d3d support: Get plan data via BillingSession for support views. 2023-12-03 14:27:07 -08:00
Lauryn Menard 8d992405a6 analytics: Get customer discount for support views. 2023-12-03 14:27:07 -08:00
Lauryn Menard 5135acd9e3 support: Use process_support_view_request for plan modifications.
Updates the support view to use process_support_view_request to
process upgrade or downgrade modifications currently implemented
for active plans.
2023-12-03 14:27:07 -08:00
Lauryn Menard 4fb564026d corporate: Move void_all_open_invoices to BillingSession. 2023-12-03 14:27:07 -08:00
Lauryn Menard 97d33a4363 support: Update billing modality via process_support_view_request. 2023-12-03 14:27:07 -08:00
Lauryn Menard 5d25cab42b analytics: Create process_support_view_request BillingSession method.
Creates a process_support_view_request method for BillingSession
to process the various support requests that relate to the billing
system.

Moves approve_realm_sponsorship, update_realm_sponsorship_status,
and attach_discount_to_realm to this new BillingSession method.

Adds a new abstract property to BillingSession to have a string
value, billing_entity_display_name, to use for support messages
sent when these requests are processed.
2023-12-03 14:27:07 -08:00
Lauryn Menard 0679bc044a corporate: Make references to billing modality consistent.
The "send_invoice" and "charge_automatically" strings used by stripe
for the `collection_method` are referred to both as the "billing
method" and "billing modality" in the billing code.

Because we send this as data to stripe as either `collection_method`
or `billing_modality`, renames any references that are any form of
"billing method".
2023-12-03 14:27:07 -08:00
Mateusz Mandera 544482eefb remote_billing: Add tests for the legacy server flow.
This doesn't provide 100% coverage, but does test the important cases.
2023-12-03 10:39:56 -08:00
Mateusz Mandera 134e3bfa68 remote_billing: Add redirects to login for unauthed user in legacy flow.
Analogical to the more complex mechanism implemented for the RemoteRealm
flow in a previous commit in
authenticated_remote_realm_management_endpoint.

As explained in the code comment, this is much easier because:

In this flow, we can only redirect to our local "legacy server flow
login" page. That means that we can do it universally whether the user
has an expired
identity_dict, or just lacks any form of authentication info at all -
there are no security concerns since this is just a local redirect.
2023-12-03 10:39:56 -08:00
Mateusz Mandera 44ac99b8fc remote_billing: Redirect via next_page param in legacy server flow.
Analogical to 1df8e00d7c which implemented
this for the RemoteRealm auth flow.
Except here we don't need to add next_page to the IdentityDict
(LegacyServerIdentityDict in this flow), because the redirect happens
immediately at remote_billing_legacy_server_login upon login - so no
need to have a structure to carry the info through intermediate steps.
2023-12-03 10:39:56 -08:00
Mateusz Mandera 3d6863b5b9 remote_billing_legacy_server_login: Only accept credentials via POST.
This is an obvious standard practice.
2023-12-03 10:39:56 -08:00
Mateusz Mandera ec7245d4e1 remote_billing: Add redirect flow for users with expired session.
Implements a nice redirect flow to give a good UX for users attempting
to access a remote billing page with an expired RemoteRealm session e.g.
/realm/some-uuid/sponsorship - perhaps through their browser
history or just their session expired while they were doing things in
this billing system.

The logic has a few pieces:
1. get_remote_realm_from_session, if the user doesn't have a
   identity_dict will raise RemoteBillingAuthenticationError.
2. If the user has an identity_dict, but it's expired, then
   get_identity_dict_from_session inside of get_remote_realm_from_session
   will raise RemoteBillingIdentityExpiredError.
3. The decorator authenticated_remote_realm_management_endpoint
   catches that exception and uses some general logic, described in more
   detail in the comments in the code, to figure out the right URL to
   redirect them to. Something like:
   https://theirserver.example.com/self-hosted-billing/?next_page=...
   where the next_page param is determined based on parsing request.path
   to see what kind of endpoint they're trying to access.
4. The remote_server_billing_entry endpoint is tweaked to also send
   its uri scheme to the bouncer, so that the bouncer can know whether
   to do the redirect on http or https.
2023-12-03 10:39:56 -08:00
Mateusz Mandera c9b0602320 tests: Create default RemoteRealms in populate_db.
This default setup will be more realistic, matching the ordinary
conditions for a modern server.
Especially needed as we add bouncer code that will expect to have
RemoteRealm entries for realm_uuid values for which it receives
requests.
2023-12-03 09:51:45 -08:00
Aman Agrawal 5d49e54d33 upgrade: Show tier corresponding to session on upgrade page. 2023-12-01 08:55:58 -08:00
Aman Agrawal 6b70be38b3 models: Add method to get `CustomerPlan` name from tier. 2023-12-01 08:55:58 -08:00
Aman Agrawal b35ea18829 stripe: Make get_price_per_license more readable. 2023-12-01 08:55:58 -08:00
Aman Agrawal 8500eae87e billing_page: Successfully render for remote realms and server. 2023-12-01 08:55:58 -08:00
Aman Agrawal 42c0e2ca3e billing_page: Use URL name redirect instead of importing it. 2023-12-01 08:55:58 -08:00
Aman Agrawal 0888608fcc billing_page: Remove completed TODO.
See 003b29ba14
2023-12-01 08:55:58 -08:00
Aman Agrawal e949fb47ff billing: Rename billing_home to billing_page. 2023-12-01 08:55:58 -08:00
Aman Agrawal c822e953be urls: Rename function names to match naming syntax of remote pages. 2023-12-01 08:55:58 -08:00
Aman Agrawal a2c1a2f4bb urls: Use /billing URL to direct user to upgrade page.
This is more about keeping the same syntax for all the pages.
2023-12-01 08:55:58 -08:00
Aman Agrawal d0c0b11fbf upgrade: Make purchase upgrade work for remove servers and realms.
We are upgrading them to cloud standard right now, we can easily
change tiers in future while adding pricing and configuration for
them.
2023-12-01 08:55:58 -08:00
Aman Agrawal e9bbb67035 upgrade: Make card add / update work for remote servers. 2023-12-01 08:55:58 -08:00
Aman Agrawal 9889dc38fe event_status: Pass billing_base_url to calculate realm specific URLs. 2023-12-01 08:55:58 -08:00
Aman Agrawal bb7b0b6731 upgrade: Provide billing_base_url in page_params.
This makes it cleaner to calculate URLs for the current session type.
2023-12-01 08:55:58 -08:00
Aman Agrawal 222077804b upgrade: Simplify getting session data for card update. 2023-12-01 08:55:58 -08:00
Aman Agrawal 0286f10816 stripe: Move non class specific function outside.
Doesn't seem to benefit from being defined inside the class.
2023-12-01 08:55:58 -08:00
Aman Agrawal 25cf0f71a3 event_status: Remove unused variables in context. 2023-12-01 08:55:58 -08:00
Aman Agrawal 953f0f436e stripe_event_handler: Rename get_billing_session. 2023-12-01 08:55:58 -08:00
Mateusz Mandera 7fad8f1f54 remote_billing: Implement session expiry mechanism.
We still need to add better UX than these JSON errors. We'll want to
utilize the next parameter and redirect the user back to login.
2023-11-30 15:51:10 -08:00
Mateusz Mandera ea9e2ece49 remote_billing: Extract RemoteBillingUserDict sub-dict. 2023-11-30 15:51:10 -08:00
Mateusz Mandera 5a198c639e remote_billing: Sort out remote_billing_identities typing.
This does two important things:
1. Fix return type of get_identity_dict_from_session to correctly be
   Optional[Union[RemoteBillingIdentityDict, LegacyServerIdentityDict]].
   RemoteBillingIdentityDict is the type in the 8.0+ auth flow,
   LegacyServerIdentityDict is the type in old servers flow, where only
   the server uuid info is available.
2. The uuid key used in request.session["remote_billing_identities"]
   should be explicitly namespaced depending on which flow and type
   we're
   dealing with - to avoid confusion in case of collisions between a
   realm and server that have the same UUID. Such a situation should not
   occur naturally and I haven't come up with any actual exploitation
   ideas that could utilize this by manipulating your server/realm
   uuids, but it's much easier to just not think about such collision
   security implications by making them impossible.
2023-11-30 15:51:10 -08:00
Aman Agrawal 8d485726e4 upgrade: Make add card workflow functional.
Add / update card for remote realms on /upgrade page works now.
2023-11-30 11:22:19 -08:00
Aman Agrawal a39cb2bda3 session: Migrate to typed endpoint. 2023-11-30 11:22:19 -08:00
Aman Agrawal d05315b051 event_status: Migrate to typed_endpoint. 2023-11-30 11:22:19 -08:00
Aman Agrawal 05f2ad5299 event_status: Migrate to typed_endpoint. 2023-11-30 11:22:19 -08:00
Aman Agrawal 4d60c3a96c models: Allow realm_id to be blank.
We cannot provide realm_id for some remote session logs.
2023-11-30 11:22:19 -08:00
Aman Agrawal 5c9a10da31 stripe: Call log create method once.
Makes it easier to look at.
2023-11-30 11:22:19 -08:00
Tim Abbott cab0215f3f decorator: Pass RemoteServerBillingSession to views. 2023-11-30 11:22:19 -08:00
Aman Agrawal 7540e70cc8 decorator: Pass remote billing session instead of remote realm.
Since endpoints using the
`authenticated_remote_realm_management_endpoint` decorator
want to initialize a billing session and if need be remote_realm
is accessible to via the session variable.
2023-11-30 11:22:19 -08:00
Aman Agrawal 1df8e00d7c remote_billing: Redirect to upgrade/sponsorship page based on next.
We pass `next` parameter with /self-hosted-billing to redirect
users to the intended page after login.

Fixed realm_uuid incorrectly required in remote_realm_upgrade_page.
2023-11-30 11:22:19 -08:00
Lauryn Menard 2c34dcf7dc corporate: Use enum value for type of plan tier change.
Updates do_change_plan_to_new_tier in BillingSession to use an
enum for the value returned when checking for a valid change
between two plan tier types. This makes it more explicit that
the implementation for a valid upgrade in plan tier will be
different from a valid downgrade in plan tier.
2023-11-30 09:43:55 -08:00
Lauryn Menard 4eea4d4717 corporate: Move invoice_plan to BillingSession abstract class. 2023-11-30 09:43:55 -08:00
Tim Abbott ebb02bad8f billing: Add INVOICING_STATUS_ prefix to values. 2023-11-29 23:32:56 -08:00
Tim Abbott 610338d192 billing: Add BILLING_SCHEDULE_ prefix to values. 2023-11-29 23:32:56 -08:00
Tim Abbott 5d6b635efe billing: Use better variable names for plan tiers.
The existing values didn't have our standard type-prefixing naming
scheme.

Add some extra unused placeholder values while we're at it.
2023-11-29 23:32:56 -08:00
Tim Abbott a01618d633 billing: Add BillingSession support for requesting sponsorship. 2023-11-29 19:04:32 -08:00
Tim Abbott 1691205306 billing: Remove unnecessary sponsorship request variables. 2023-11-29 19:04:32 -08:00
Aman Agrawal e43b51b01e stripe: Extract common helper function. 2023-11-29 19:04:32 -08:00
Tim Abbott 405c28252a decorator: Don't pass processed args/kwargs onwards.
We've already processed the only URL parameters we intend to support
to determine which RemoteRealm or RemoteZulipServer is involved, so
there should be nothing further to do here.

And it's cleaner to not have to write the downstream code to expect
these unnecessary parameters.
2023-11-29 19:04:32 -08:00
Aman Agrawal ba11d0fe5d decorator: Add decorator to provide remote_server to endpoint. 2023-11-29 19:04:32 -08:00
Aman Agrawal 5277ebb268 decorator: Remove wrong positional argument remote_realm.
Not sure how this even worked with this required argument.
2023-11-29 19:04:32 -08:00
Aman Agrawal d8f8152f9b models: Make requested_by optional in sponsorship request model.
`requested_by` needs to be a UserProfile which is not available
for remote server sponsorship requests.
2023-11-29 19:04:32 -08:00
Aman Agrawal d999d18476 upgrade: Use valid form data to fill email context. 2023-11-29 19:04:32 -08:00
Aman Agrawal cd7893b1bf sponsorship: Use `organization_type` as field name for simplification. 2023-11-29 19:04:32 -08:00
Mateusz Mandera 2765c63f56 remote_billing: Add flow for legacy servers. 2023-11-29 14:40:27 -08:00
Prakhar Pratyush 44d8dc66d2 send_email: Update 'from_name' for non user-facing emails.
This commit performs a minor update in 'from_name' text for
'support' and 'sponsorship' emails.

Removes capitalization and adds a comment specifying that the
emails are not user-facing.
2023-11-29 14:20:01 -08:00
Alex Vandiver 61fc838179 python: Switch mocking of timezone_now to time_machine. 2023-11-28 15:10:39 -08:00
Alex Vandiver f4cbb494ac test_remote_counts: Insert in date order.
Inserting these in order means that they have dates which ascend with
their ids and remote_ids, for a more accurate simulation.
2023-11-28 09:46:48 -08:00
Aman Agrawal e8fed998ce test_stripe: Add method to better mock stripe invoice creation. 2023-11-28 08:58:19 -08:00
Aman Agrawal 28a49be161 get_initial_upgrade_context: Use tier passed as part of request. 2023-11-28 08:58:19 -08:00
Alya Abbott fcd0783202 upgrade: Simplify free trial upgrade page. 2023-11-28 08:57:27 -08:00
Alya Abbott 9788e7514f billing: Edit text of free trial upgrade page. 2023-11-27 14:17:18 -08:00
Aman Agrawal b35a792623 billing: Allow free trial orgs to switch billing frequency.
Fixes #27855
2023-11-27 14:17:18 -08:00
Aman Agrawal 1f8d3fc48f stripe: Extract method to get next billing cycle. 2023-11-27 14:17:18 -08:00
Aman Agrawal 482b5d8871 upgrade: Minor text changes to free trial page.
Fixes #27684
2023-11-27 14:17:18 -08:00
Aman Agrawal fe1a40279c billing: Downgrade realm at the end of free trial.
Fixes #27875

Instead of immediately ending the free trial, we end the free trial
at the end of the cycle.
2023-11-27 14:17:18 -08:00
Aman Agrawal 22c333d135 stripe: Don't allow free trial users to have paid plan states.
Free trial users can only switch to `ACTIVE` or `ENDED`
as possible states. To switch to any other state, they need to
be `ACTIVE` first.
2023-11-27 14:17:18 -08:00
Aman Agrawal d43a60eb9d models: Add status text for some plan status states. 2023-11-27 14:17:18 -08:00
Tim Abbott 7de061cf10 billing: Inline is_realm_on_paid_plan.
This helps simplify the BillingSession interface to have less
realm-specific functions outside RealmBillingSesssion.
2023-11-27 09:01:56 -08:00
Prakhar Pratyush f8b0e16ff2 stripe: Add get_sponsorship_request_context method to BillingSession.
This commit refactors 'sponsorship_request' view and adds
'BillingSession.get_sponsorship_request' method.

This refactoring will help in minimizing duplicate code
while supporting both realm and remote_Server customers.
2023-11-27 09:01:56 -08:00
Prakhar Pratyush 1b17626327 stripe: Add 'is_sponsored' method to 'BillingSession' class.
This prep commit adds a 'is_sponsored' method as we need
to explicitly check this in 'event_status' view.
2023-11-27 09:01:56 -08:00
Prakhar Pratyush 29f77bfd31 stripe: Add 'get_event_status' method to the 'BillingSession' class.
This commit refactors 'event_status' view and adds
'BillingSession.get_event_status' method.

This refactoring will help in minimizing duplicate code
while supporting both realm and remote_server customers.
2023-11-27 09:01:56 -08:00
Aman Agrawal 20cae359d1 sponsorship: Show correct plan for sponsored without CustomerPlan.
For users on limited plan, if approved for full sponsorship
via support page, we don't create a CustomerPlan for them, but
they are fully sponsored.
2023-11-27 08:23:36 -08:00
Aman Agrawal 3615fa4745 sponsorship: Use customer instead of realm to store sponsorship data.
Since Customer already stores the realm it is linked to and
customer is always created to store sponsorship request, we directly
use customer to link to the sponsorship data for the realm.
2023-11-27 08:23:36 -08:00
Aman Agrawal ede73fc2c6 decorator: Add wrapper to directly pass remote_realm to view_func. 2023-11-26 20:23:24 -08:00
Aman Agrawal 354330d81b decorator: Move self_hosting_management_endpoint wrapper to corporate. 2023-11-26 20:23:24 -08:00
Mateusz Mandera c79d116f8c tests: Add basic tests for remote billing auth flow. 2023-11-26 19:57:12 -08:00
Lauryn Menard b167eeff08 corporate: Create change plan tier function for BillingSession.
Moves and generalizes `switch_realm_from_standard_to_plus_plan`
in stripe.py to be a more general function for changing a
CustomerPlan to a new and valid tier, `do_change_plan_to_new_tier`.

Adds a helper function with the previous function name to be used
for the support view and management command for changing a realm
from the Standard plan tier to the Plus plan tier.
2023-11-26 19:39:52 -08:00
Lauryn Menard a00e687d02 corporate: Update stripe create_balance_transaction description. 2023-11-26 19:39:52 -08:00
Lauryn Menard 1f1f1b913b corporate: Simplify initial plan tier switch check.
Simplifies the initial check for switching a customer plan tier
for an existing and active plan, so that it is more generic.
2023-11-26 19:39:52 -08:00
Lauryn Menard 39bfab0ec4 corporate: Move plan tier change to separate helper function.
Renames CustomerPlan.SWITCH_NOW_FROM_STANDARD_TO_PLUS to be more
generic, CustomerPlan.SWITCH_PLAN_TIER_NOW.

Because the plan tier change is immediate, moves the code to end
the current plan with the old tier and create the new plan with
the new tier from `make_end_of_cycle_updates_if_needed` to instead
be in a separate helper function, `switch_plan_tier`.
2023-11-26 19:39:52 -08:00
Lauryn Menard 30f0005799 corporate: Extract calculation of amount to credit for tier change. 2023-11-26 19:39:52 -08:00
Aman Agrawal 3cfcd0efee remote_upgrade_page: Add /upgrade URL for self hosted realms. 2023-11-24 09:22:02 -08:00
Aman Agrawal caf2b7da26 stripe: Use remote_billing_url for redirecting to sponsorship page.
The will make redirects to sponsorship page work for all
BillingSession child classes.
2023-11-24 09:22:02 -08:00
Aman Agrawal 6ad9217fbf stripe: Set discount to None for 0 discount. 2023-11-24 09:22:02 -08:00
Aman Agrawal 6040ffb94b stripe: Verify context via TypedDict for upgrade page. 2023-11-24 09:22:02 -08:00
Aman Agrawal e3abd57dce stripe: Rename update_context_initial_upgrade. 2023-11-24 09:22:02 -08:00
Aman Agrawal 053f30ca25 stripe: Sort upgrade page context keys.
This will help us verify changes easily.
2023-11-24 09:22:02 -08:00
Aman Agrawal 4844ef9810 upgrade: Pass customer_name instead of realm object to upgrade context.
This will help simplify things for remote realms.
2023-11-24 09:22:02 -08:00
Aman Agrawal ace14e5a7d remote_billing_page: Extract method to get RemoteBillingIdentityDict.
This will likely be used in other files.
2023-11-24 09:22:02 -08:00
Aman Agrawal f006be0cdf initial_upgrade: Rename to upgrade_page.
Replaced for "(initial_upgrade)", " initial_upgrade"
`'initial_upgrade'` and `"initial_upgrade"`.
2023-11-24 09:22:02 -08:00
Aman Agrawal 95f5d8bdb8 billing: Note applied discount on upgrade and billing pages.
Fixes #27526
2023-11-23 10:32:39 -08:00
Aman Agrawal 07d29126fd sponsorship: Improve page for sponsorship pending orgs.
Fixes #27686
2023-11-23 10:32:39 -08:00
Aman Agrawal 003b29ba14 billing_page: Redirect orgs on paid plans with sponsorship pending.
Redirect sponsorship pending realms on a paid plan to billing page
with banner which reflects the current status of their request.
2023-11-23 10:32:39 -08:00
Aman Agrawal 74d8a050e4 billing_page: Extract method to check if realm is on paid plan. 2023-11-23 10:32:39 -08:00
Aman Agrawal 5422dd3661 sponsorship: Improve sponsorship page for sponsored realms. 2023-11-23 10:32:39 -08:00
Prakhar Pratyush 51b39cb682 stripe: Add 'do_update_plan' method to the 'BillingSession' class.
This commit moves a major portion of the 'update_plan`
view to a new shared 'BillingSession.do_update_plan' method.

This refactoring will help in minimizing duplicate code
while supporting both realm and remote_server customers.
2023-11-23 09:01:45 -08:00
Tim Abbott efa423395f billing: Make support_session an explicit parameter. 2023-11-23 09:01:45 -08:00
Mateusz Mandera 3958743b33 corporate: Add prototype authentication system for self-hosters.
This makes it possible for a self-hosted realm administrator to
directly access a logged-page on the push notifications bouncer
service, enabling billing, support contacts, and other administrator
for enterprise customers to be managed without manual setup.
2023-11-22 17:03:47 -08:00
Aman Agrawal d82efbd503 free_trial: Remove extra onboarding flow.
We still redirect free trial users to upgrade page on first
signup but no longer pass the onboarding param.
2023-11-22 08:06:22 -08:00
Aman Agrawal 2218c49244 billing: Minor changes to text for free trial.
Fixes #27685
2023-11-22 08:06:22 -08:00
Prakhar Pratyush 476b44ae67 stripe: Use 'get_price_per_license' in 'get_initial_upgrade_context'.
This commit updates the 'get_initial_upgrade_context' method
to use 'get_price_per_license' for determining 'annual_price'
and 'monthly_price' based on tier and discount instead of hardcoding.

Also, removed the 'percent_off' page_params as
'get_price_per_license' already performs the price calculation
taking discount into consideration.
2023-11-21 23:39:18 -08:00
Aman Agrawal de267b964c event_status: Return user back to same license management after session.
If the update / add card session is successful, return user to
manual license management page if user was on it before clicking
the add / update card button.
2023-11-21 11:44:04 -08:00
Aman Agrawal 69d8442ab4 billing: Allow user to switch between billing frequencies. 2023-11-21 10:42:12 -08:00
Tim Abbott e3a3f36225 billing: Rename do_initial_upgrade.
This function gets context without doing anything, and so deserves a
name that hints that.
2023-11-20 12:04:56 -08:00
Aman Agrawal 09009ab03a upgrade: Separate add card and purchase upgrade flow.
We now let user add / update card in a separate session and then
charge users after clicking on the purchase button.
2023-11-20 12:04:56 -08:00
Prakhar Pratyush 26c5149d31 stripe: Add 'do_initial_upgrade' method to the 'BillingSession' class.
This commit moves a major portion of the 'initial_upgrade`
view to a new shared 'BillingSession.do_initial_upgrade' method.

This refactoring will help in minimizing duplicate code
while supporting both realm and remote_server customers.
2023-11-20 08:00:05 -08:00
Lauryn Menard 11cb37c9a4 billing: Add prototype remote billing sessions.
These new models are incomplete and totally untested, but merging this
will provide valuable scaffolding for doing smaller PRs working on
individual gaps, and reveals a clear set of TODOs/refactoring/model
changes needed to support where want to end up.

Co-authored-by: Tim Abbott <tabbott@zulip.com>
2023-11-17 12:58:37 -08:00
Tim Abbott f916385cab corporate: Adjust models for RemoteRealm customers. 2023-11-17 12:58:37 -08:00
Tim Abbott c5940bd68f zilencer: Make plan types less weird. 2023-11-17 12:58:37 -08:00
Prakhar Pratyush 135d7c03cc stripe: Add 'get_billing_page_context' method to 'BillingSession'.
This commit moves the main context creation part of the
'billing_home` view to a new shared
'BillingSession.get_billing_page_context' method.

This refactoring will help in minimizing duplicate code
while supporting both realm and remote_server customers.
2023-11-16 09:48:43 -08:00
Mateusz Mandera 1819b85b85 management: Allow changing is_billing_admin using change_user_role. 2023-11-15 18:36:07 -08:00
Anders Kaseorg f4e7a11c35 requirements: Upgrade Python requirements.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-11-15 15:27:54 -08:00
Anders Kaseorg 7a4ca3135d stripe: Prepare to switch to stripe inline annotations.
https://github.com/stripe/stripe-python/wiki/Inline-type-annotations

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-11-15 15:27:54 -08:00
Prakhar Pratyush f8a0035215 stripe: Move `make_end_of_cycle_updates_if_needed` to BillingSession.
Moves the 'make_end_of_cycle_updates_if_needed' function to
the 'BillingSession' abstract class.

This refactoring will help in minimizing duplicate code while
supporting both realm and remote_server customers.

Since the function is called from our main daily billing cron job
as well, we have changed 'RealmBillingSession' to accept 'user=None'
(our convention for automated system jobs).
2023-11-15 09:26:41 -08:00
Aman Agrawal 27ffcc6576 bililng: Fix incorrect price per license on billing page.
There is a discrepancy between price per license shown on billing
and upgrade page for annual billing frequency due to difference
in methods used to calculate the amount.

To fix it, we use the same method on both the pages.

I didn't use the helpers.format_money directly here since that would
create a visual delay in showing the price per license which will
not be nice considering that will be the only thing on this page
being updated that way.

The stripe fixture used is same as
free_trial_upgrade_by_card--Customer.retrieve.3.json
2023-11-15 15:59:26 +05:30
Prakhar Pratyush fb9e258a65 stripe: Add 'do_upgrade' method to the 'BillingSession' class.
This commit moves a major portion of the 'upgrade`
view to a new shared 'BillingSession.do_upgrade' method.

This refactoring will help in minimizing duplicate code
while supporting both realm and remote_server customers.
2023-11-14 12:07:26 -08:00
Aman Agrawal 67bddb3d72 billing: Show success message for license change after page reload. 2023-11-13 10:35:39 -08:00
Aman Agrawal 2997c269e1 billing: Show breakdown of renewal amount if not fixed_price. 2023-11-13 10:35:39 -08:00
Aman Agrawal 775a90771e stripe: Modify error message for less than min licenses. 2023-11-13 10:35:39 -08:00
Aman Agrawal 5f0969f52b session: Remove unnecessary has_request_variables wrapper. 2023-11-13 10:35:39 -08:00
Aman Agrawal 2570f7ce23 upgrade: Control automatic / manual license management via URL. 2023-11-13 10:35:39 -08:00
Aman Agrawal 395cafcf46 sponsorship: Add extra input fields to get more org info.
Fixes #27600
2023-11-13 08:52:13 -08:00
Prakhar Pratyush b5a6742adc stripe: Move `process_initial_upgrade` to BillingSession.
Moves the 'process_initial_upgrade' function to the
'BillingSession' abstract class.

This refactoring will help in minimizing duplicate code while
supporting both realm and remote_server customers.
2023-11-13 08:11:27 -08:00
Lauryn Menard 928cb7e09e corporate: Pass plan_tier parameter to process_initial_upgrade.
Updates `process_initial_upgrade` to take a plan_tier parameter,
so that information can be specific to the type of BillingSession.

Note that ideally the plan tier would be passed as metadata to the
stripe.checkout.Session, but in order to do so, we need to be able
to update the generated stripe fixtures for tests. So for now, we
set the plan tier directly in the stripe event handler code.
2023-11-10 11:26:18 -08:00
Lauryn Menard 3e550364c6 corporate: Use plan.name for stripe.Invoice statement descriptor.
Instead of hard coding the string for the stripe.InvoiceItem and
stripe.Invoice statement_descriptor, we use the name of the plan
that was just created.
2023-11-10 11:26:18 -08:00
Lauryn Menard d29c454e80 corporate: Make BillingSession abstract method for changing plan type.
Creates `do_change_plan_type` as a BillingSession abstract method
as an alias for updating the plan_type for a realm (and eventually
remote server).

This removes the last direct reference to a customer's realm in
`process_initial_upgrade`.
2023-11-10 11:26:18 -08:00
Lauryn Menard 26ad2e29c6 corporate: Make BillingSession alias for latest seat count.
Creates `current_count_for_billed_licenses` as an abstract method
in BillingSession class, to get the latest seat count for the realm
(and eventually remote server) connected to the customer.
2023-11-10 11:26:18 -08:00
Prakhar Pratyush 31f048d054 stripe: Move `setup_upgrade_checkout_session_and...` to BillingSession.
Moves the 'setup_upgrade_checkout_session_and_payment_intent'
function to the 'BillingSession' abstract class.

This refactoring will help in minimizing duplicate code while
supporting both realm and remote_server customers.
2023-11-10 09:15:10 -08:00
Aman Agrawal b0fb5c33e9 test_stripe: Fix tests related to text changes on billing page. 2023-11-10 05:17:52 +05:30
Aman Agrawal 9a186ac8d5 billing_page: Redirect users on free plan to `/plans`.
Fixes #27379
2023-11-10 05:17:52 +05:30
Aman Agrawal 56eec2734c billing_page: Add capitalization format of various common cards. 2023-11-10 05:17:52 +05:30
Aman Agrawal f85bd0234a billing: Minor changes. 2023-11-10 05:17:52 +05:30
Aman Agrawal caa40ad2c6 billing_page: Remove unused context. 2023-11-10 05:17:52 +05:30
Aman Agrawal 2f532e49d1 billing: Add field to show billing frequency. 2023-11-10 05:17:52 +05:30
Aman Agrawal 5b97eb0445 billing: Modify title. 2023-11-10 05:17:52 +05:30
Lauryn Menard 6a53005074 corporate: Update generated stripe fixtures for test_stripe.
Generated with both parellel=1 and generate-stripe-fixtures params
on test-backend locally.

Note that the previous series of commits need these test fixtures
to pass CI. If those are changed, then this commit should be updated
or dropped and replaced with a commit that updates the fixtures
based on the new changes.
2023-11-09 12:03:33 -08:00
Lauryn Menard 717d40475e corporate: Use the stripe checkout session metadata for free trials.
Instead of using the data from the stripe.SetupIntent for processing
an initial upgrade for the free trial session types, use the metadata
from the stripe.checkout.Session that was returned.

The metadata is the same for both the checkout session and the setup
intent.
2023-11-09 12:03:33 -08:00
Lauryn Menard c09bfc136e corporate: Update generate stripe fixtures to not use test cc numbers.
Updates generate stripe fixtures to use test credit card strings from
Stripe, instead of creating fake stripe.PaymentMethods for the tests
with the test credit card numbers provided by Stripe.
2023-11-09 12:03:33 -08:00
Lauryn Menard 1f28837bd7 corporate: Update create_stripe_customer to not attach payment method.
According to stripe's documentation for attaching payment methods to
customers (see https://stripe.com/docs/api/payment_methods/attach),
payment methods should be attached to customers through a SetupIntent
or PaymentIntent, which is what we do as we process new customers
and accounts.

Updates create_stripe_customer so that it is clear that the payment
method should not be added when we directly create a new  stripe
customer.
2023-11-09 12:03:33 -08:00
Lauryn Menard 4dd6f105a0 coporate: Change statement descriptor for Zulip Cloud Credit.
There is a 22 char limit on the stripe.Invoice.statement_descriptor
field. The current value for that field in this error case, "Zulip
Cloud Standard Credit" is 27 chars.

Updates the value for this error case to be "Cloud Standard Credit".
2023-11-09 12:03:33 -08:00
Mateusz Mandera 3cafdbdc1e counts: Add function compute_max_monthly_messages for remote servers.
This calculates the largest amount of messages sent within a month for
the last 3 months. The query is targeted for the specific use-case in
this function - for finding the count for a specific server. For
calculating this in bulk for a large number of remote server an
adapted, bulk query will be needed - rather than running this one in a
loop, which would likely be very inefficient.
2023-11-08 09:45:49 -08:00
Lauryn Menard 2da1b3307a corporate: Rename billable_user variables to billing_session in tests. 2023-11-07 12:57:20 -08:00
Lauryn Menard b6fa00d4fd corporate: Set realm strings for test of downgrade small realms.
Instead of randomly generating an integer for the realm string_id
and realm name use a counter to increment the string ids by one.
This way if a particular realm fails the test, it will be easier
to identify which one failed.

Also, removes unused Customer objects that were being returned on
realm creation in the test, as these were not being checked/used
in the test.
2023-11-07 12:57:20 -08:00
Lauryn Menard c3fd7d837b corporate: Add billing admin check to approve sponsorship test.
In commit a3093fad9, we made Hamlet a billing admin for testing.

Because the approve sponsorship flow sends messages from the
notification bot to both organization owners and billing admins,
we need to update that test to cover both of those user types.
2023-11-07 09:13:50 -08:00
Aman Agrawal 0012a52e88 billing: Don't redirect to sponsorship page for orgs on paid plan. 2023-11-06 14:55:14 -08:00
Aman Agrawal 0ffa207118 sponsorship: Use this organization instead of your organization. 2023-11-06 14:55:14 -08:00
Aman Agrawal a3093fad97 billing: Show sponsorship status on /sponsorship page.
We redirect users from billing and upgrade page to sponsorship page if the
org has requested for sponsorship or is already sponsored.
2023-11-06 14:55:14 -08:00
Aman Agrawal 00df9c6c18 urls: Show sponsorship page on a new URL.
Fixes #27377

Replaced #sponsorship links with sponsorship/ links and in other
places liking gear menu.
2023-11-06 14:55:14 -08:00
Lauryn Menard 6f7b75c9a3 corporate: Add `create_stripe_payment_intent` to BillingSession class.
Adds `create_stripe_payment_intent` to the BillingSession abstract
class for the initial upgrade process, which is used only in
`setup_upgrade_checkout_session_and_payment_intent`.

Adds a helper dataclass for the data used to create the stripe
payment intent, StripePaymentIntentData, for the implementation of
more than one child class of BillingSession.

Also adds two abstract helper functions for getting the above stripe
payment intent data as well as updating that data for a stripe
checkout session that is associated with a payment intent:
update_data_for_checkout_session_and_payment_intent,
get_data_for_stripe_payment_intent.
2023-11-06 14:39:36 -08:00
Lauryn Menard 600fea23bb corporate: Add create_stripe_checkout_session to BillingSession class.
Adds `create_stripe_checkout_session` to BillingSession abstract
class, which is then used in all places where a stripe.checkout.Session
and Session were created: start_retry_payment_intent_session,
start_card_update_stripe_session, and
setup_upgrade_checkout_session_and_payment_intent.

Adds a `billing_session_url`  abstract property to the BillingSession
abstract class and for the RealmBillingSession child class sets that
value to `self.realm.uri`.
2023-11-06 14:39:36 -08:00
Lauryn Menard 227645ab65 corporate: Update setup upgrade checkout to only get price per license.
setup_upgrade_checkout_session_and_payment_intent was not using the
datetime values that were being returned by compute_plan_parameters,
so just get the price per license directly.
2023-11-06 14:39:36 -08:00
Lauryn Menard ec2b00e8c4 corporate: Move `update_billing_method...` to BillingSession class.
Moves `update_billing_method_of_current_plan` to the BillingSession
abstract class.

Adds a helper function for support views for the realm case:
`update_realm_billing_method`.
2023-11-04 17:20:49 -07:00
Lauryn Menard 5d07666362 corporate: Move `update_sponsorship_status` to BillingSession class.
Moves `update_sponsorship_status` to BillingSession abstract class
as `update_customer_sponsorship_status`.

Updates the support views to have a helper for updating this on a
realm: `update_realm_sponsorship_status`.
2023-11-04 17:20:49 -07:00
Lauryn Menard d06062c179 corporate: Move `approve_sponsorship` to BillingSession class.
Makes `approve_sponshorship` an abstract method in BillingSession
abstract base class and moves the implementation for realms to the
RealmBillingSession child class.

Adds `approve_realm_sponsorship` helper function that's used in
the support view and initiates the billing session.
2023-11-04 17:20:49 -07:00
Lauryn Menard c8021925c8 corporate: Create AuditLogEventType enum for BillingSession audit logs.
Creates an enum class, AuditLogEventType, and an abstract method in
BillingSession, get_audit_log_event, so that we have an abstraction
for getting the audit log event type since it might be different for
Customer objects with a realm vs a remote_server.
2023-11-04 17:20:49 -07:00
Lauryn Menard ee19a9c274 corporate: Move `attach_realm_discount` to BillingSession class.
This moves the logic for `attach_realm_discount`, which is used in
the support view, to be in the BillingSession class.

Updates the function name to be `attach_discount_to_customer` so
that the context is generalized vs realm specific.

Updates RealmBillingSession implementation to account for actions
that are initiated by a support admin user.

Also moves the helper function `get_discount_for_realm` that is
only used in support views to `corporate/lib/support.py`.
2023-11-04 17:20:49 -07:00
Lauryn Menard 63abf063b7 corporate: Use StripeCustomerData dataclass to create stripe Customer.
So that all child classes of BillingSession generate the same data
structure for customers that are created in Stripe, revise
`get_data_for_stripe_customer` to return a specific dataclass:
StripeCustomerData.
2023-11-04 17:20:49 -07:00
Lauryn Menard ce6f1f8c18 stripe: Create BillingSession class for different customer types.
So that `update_or_create_stripe_customer` can work for Customer
objects with either a realm or remote_server, we create an abstract
base class, BillingSession, and implement a child class for the
current implementation of Customer objects with a realm.

Refactoring `update_or_create_stripe_customer` also moves
`create_stripe_customer` and `replace_payment_method` to the
BillingSession class.
2023-11-04 17:20:49 -07:00
Lauryn Menard d1e2e2d857 corporate: Check for no CustomerPlan on Customer instead of Realm.
In ensure_customer_does_not_have_active_plan, we were already going
through the Customer table to get/check for an active CustomerPlan.

Now we directly get/check for an active CustomerPlan with via the
Customer, which allows for reusing this function for Customer
objects without a Realm set.
2023-10-30 16:09:52 -07:00