Commit Graph

40 Commits

Author SHA1 Message Date
Ethan Mayer
c12b94aea4 models: Refactor corporate/models.py into models package.
Fixes #34318.

Seperated models file into a package with component files.
2025-04-08 10:16:35 -07:00
Anders Kaseorg
3b84dd3b8c stripe_event_handler: Fix UP038.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2025-01-24 22:59:58 -08:00
Lauryn Menard
1f2f0af257 stripe: Rename remote_server_legacy_plan param in initial upgrade.
Renames the remote_server_legacy_plan parameter in
process_initial_upgrade to instead be complimentary_access_plan,
as well as some relevant code comments in that function.
2024-12-15 09:15:07 -08:00
Lauryn Menard
7a0626aede stripe: Rename get_remote_server_legacy_plan.
Renames get_remote_server_legacy_plan to
get_complimentary_access_plan, as well as
associated variable names.
2024-12-15 09:15:07 -08:00
Lauryn Menard
a0bbc62f2b support: Add fixed-price plan configuration to Cloud support view.
Adds ability to configure a fixed-price plan and to delete a
configured fixed-price plan in the Cloud support view.

Updates the invoice processing to send reminder emails to the
billing support email for these Cloud fixed-price plans about
renewals since we now are able to configure them via our support
panel.

Updates function to get the billing session for stripe webhook
events to handle an intial upgrade for a custom generated invoice
for a fixed-price plan for a Cloud organization, which won't have
a user_id in the invoice metadata.
2024-11-26 12:42:39 -08:00
Anders Kaseorg
05e54a0af2 ruff: Fix E721 Use isinstance() for isinstance checks.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-08-01 16:46:58 -07:00
Anders Kaseorg
48202389b8 ruff: Bump target-version from py38 to py310.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-07-13 22:28:22 -07:00
Anders Kaseorg
0fa5e7f629 ruff: Fix UP035 Import from collections.abc, typing instead.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-07-13 22:28:22 -07:00
Anders Kaseorg
531b34cb4c ruff: Fix UP007 Use X | Y for type annotations.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-07-13 22:28:22 -07:00
Prakhar Pratyush
14415dfa90 invoice_paid_event: Verify invoice before activating fixed-price plan.
Earlier, we were not verifying that the invoice which got paid is
for the fixed-price plan.

That could result in a bug where another support invoice with
collection_method = "send_invoice" got paid while a fixed-price
plam is already configured. The fixed-price plan would be falsely
activated.

This commit verifies the invoice before activating the fixed-price
plan.
2024-04-16 09:49:04 -07:00
Aman Agrawal
ed2de77895 stripe: Send invoice to customer at the start of free trial.
We send customer an invoice at the start of free trial, if customer
pays we upgrade them to the active plan at the end of free trial,
else we downgrade them and show a custom message on the upgrade
page regarding the current status.
2024-04-11 21:57:33 -07:00
Mateusz Mandera
c3caa3ecc8 stripe: Rename @error_handler decorator.
This decorator, among other things, transforms the "event" argument
passed when calling the decorated functions into actually passing
event.content_object.

So e.g. despite having a (before the decorator is applied) signature:

```
def handle_invoice_paid_event(stripe_invoice: stripe.Invoice, invoice: Invoice) -> None:
```

these are called passing an `Event` in the second arg when calling
`handle_invoice_paid_event`:

```
handle_invoice_paid_event(stripe_invoice, event)
```

I found that kind of confusing because the @error_handler decorator
didn't sound like something that would intervene in the arguments like
that. So it feels helpful to rename it something with a less modest
name, that makes it sound like it does more than just pure
error-handling.
2024-03-28 09:10:09 -07:00
Aman Agrawal
c84b9cbc97 upgrade: Allow payment by invoice. 2024-03-14 16:43:52 -07:00
Aman Agrawal
7ca85bed71 stripe: Fix $0 invoices being generated on upgrade.
Instead of charging the customer using the attached payment
method and then creating the invoice, we create an invoice and
force an immediate payment for the invoice via the attached
payment method.
2024-02-12 15:15:56 -08:00
Prakhar Pratyush
2055dfa83e support: Add support to configure fixed-price plan with pay-by-invoice.
* Manually create & send invoice
* Configure a fixed-price plan with sent invoice-id.
* When customer pays, upgrade them to concerned plan.
2024-02-06 18:43:23 -08:00
Anders Kaseorg
45bb8d2580 models: Extract zerver.models.users.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-12-16 22:08:44 -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
Aman Agrawal
f942bbd70f stripe: Show tier information correctly on billing and upgrade page. 2023-12-03 15:15:04 -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
222077804b upgrade: Simplify getting session data for card update. 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
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
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
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
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
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
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
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
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
Anders Kaseorg
ff1971f5ad ruff: Fix SIM105 Use contextlib.suppress instead of try-except-pass.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-01-23 11:18:36 -08:00
Zixuan James Li
6277f09296 corporate: Fix type annotations for payment failed handler.
When being called, the wrapped function is passed `PaymentIntent`
(the `content_object` of `Event`). With that, since `customer` can be
`None`, an assertion is also required.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-07-15 14:56:22 -07:00
Zixuan James Li
4a5043dd6e typing: Add none-checks for miscellaneous cases.
Signed-off-by: Zixuan James Li <359101898@qq.com>
2022-05-31 09:43:55 -07:00
Aman Agrawal
7614f2203a pricing: Replace "Zulip Standard" with "Zulip Cloud Standard".
Case sensitive replace.
2022-02-09 11:00:24 -08:00
Eeshan Garg
7c9f587563 billing: Stop using UserProfile.delivery_email in Stripe handler.
Now that we pass in the UserProfile.id in the metadata to Stripe's
PaymentIntent objects, we no longer need to retrieve the user via
delivery_email. It makes more sense to just fetch the user by ID
and then get the latest delivery_email directly.

Note that an update to Stripe's fixtures is not necessary here
since a previous commit already modified the metadata passed to
both stripe.Session/PaymentIntent objects.
2021-12-03 14:57:30 -08:00
Eeshan Garg
88fd399bec billing: Use UserProfile.id to ascertain customer's email.
Previously, our Stripe webhook event handler code retrieved the
user's email from Stripe using the stripe.Customer.email attribute.
This led to situations such that whenever the email that Stripe had
did not correspond to a UserProfile in Zulip, the payment flow
failed since we couldn't find a UserProfile associated with the
given email.

Now, we pass in the UserProfile.id in the metadata to Stripe's
checkout Session object, so that we can fetch the correct email
in future Stripe requests.
2021-12-03 14:57:30 -08:00
Eeshan Garg
a3095331eb corporate/models: Modify Customer to accommodate self-hosted customers.
This is a part of our efforts to introduce billing for our on-premise
customers.
2021-11-30 15:20:33 -08:00
Vishnu KS
6c06858e02 billing: Migrate to Stripe hosted checkout page. 2021-11-05 17:23:10 -07:00