Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dev: Upgrade stripe version to latest and add typings #569

Merged
merged 12 commits into from
May 17, 2024

Conversation

ajay-sentry
Copy link
Contributor

@ajay-sentry ajay-sentry commented May 16, 2024

Purpose/Motivation

This initiative stemmed from upgrading python to version 3.12, where in the process we bumped up our stripe version from 2.55.2 -> 8.9. This represented ~6.5 years of stripe versions and associated model updates in the process. Change log from stripe's website can be found here.

After the initial merge of that PR, @adrian-codecov and I noticed that there were some issues coming in from sentry; which we thought to have fixed in #563. However, this didn't quell the issues; and in fact surfaced other issues in sentry where certain webhooks around subscription schedules were no longer being processed. Upon doing some additional investigation in the stripe dashboard, we realized that Stripe itself was using the 2017 version of their API when generating webhooks for us to process.

This meant then that we now had a mismatch between our local version of stripe; the local implementation of stripe, and the dashboard version of stripe, each returning or expecting slightly different objects between them. This PR then hoped to tackle the differing versions once and for all; putting us on the latest version of stripe for API, with version updates for Gazebo and Worker soon to follow. Because API is where the "meat" of our stripe integration is, we believe that even with this single PR and using stripe's "native" dashboard API version update tool we should be good. But for sanity, we will be merging codecov/gazebo#2884 and codecov/worker#456 as well.

Things that were broken at some point or another:

  • Invoice payment succeeded
  • Updating a customer subscription
  • Creating a subscription schedule
  • Updating a subscription schedule
  • Deleting a subscription

Links to relevant tickets

Related ticket for tracking codecov/engineering-team#1754

What does this PR do?

Fixes:

  • Checkout Session input params to match latest stripe object
  • Subscription schedule object keys to pull off plan name correctly
  • Stripe errors are now on the stripe object itself from package

Updates:

  • Removes unnecessary segment stuff in checkout_session_completed
  • Removes interpolated logs in favor of dictionary params
  • Adds types for all webhook functions
  • Adds a new set of keys in the settings mapping stripe values to plan names (TBD if we should remove the original mapping)
  • Uses stripe version 9.6 (latest) from 8.9 -- This will match the dashboard version once we upgrade

Notes to Reviewer

I have been working heavily with @adrian-codecov to test this locally throughout. We feel confident in this PR having flipped the dashboard version to latest and doing quick tests and then flipping back. We will be monitoring this post merge to confirm successful webhooks in the console before we breathe a final sigh of relief.

Legal Boilerplate

Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. In 2022 this entity acquired Codecov and as result Sentry is going to need some rights from me in order to utilize my contributions in this PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.

Copy link

codecov bot commented May 16, 2024

Codecov Report

Attention: Patch coverage is 96.36364% with 2 lines in your changes are missing coverage. Please review.

Project coverage is 95.84%. Comparing base (d5ebabe) to head (ca9c30d).

✅ All tests successful. No failed tests found.

Files Patch % Lines
codecov/settings_prod.py 0.00% 1 Missing ⚠️
codecov/settings_staging.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##            main    #569     +/-   ##
=======================================
+ Coverage   95.83   95.84   +0.01     
=======================================
  Files        777     777             
  Lines      17286   17292      +6     
=======================================
+ Hits       16565   16573      +8     
+ Misses       721     719      -2     
Flag Coverage Δ
unit 91.36% <96.36%> (+0.01%) ⬆️
unit-latest-uploader 91.36% <96.36%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@codecov-staging
Copy link

codecov-staging bot commented May 16, 2024

Codecov Report

Attention: Patch coverage is 96.36364% with 2 lines in your changes are missing coverage. Please review.

✅ All tests successful. No failed tests found.

Files Patch % Lines
codecov/settings_prod.py 0.00% 1 Missing ⚠️
codecov/settings_staging.py 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@codecov-qa
Copy link

codecov-qa bot commented May 16, 2024

Codecov Report

Attention: Patch coverage is 96.36364% with 2 lines in your changes are missing coverage. Please review.

Project coverage is 91.36%. Comparing base (d5ebabe) to head (ca9c30d).

✅ All tests successful. No failed tests found.

Files Patch % Lines
codecov/settings_prod.py 0.00% 1 Missing ⚠️
codecov/settings_staging.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #569      +/-   ##
==========================================
+ Coverage   91.34%   91.36%   +0.01%     
==========================================
  Files         599      599              
  Lines       15968    15974       +6     
==========================================
+ Hits        14586    14594       +8     
+ Misses       1382     1380       -2     
Flag Coverage Δ
unit 91.36% <96.36%> (+0.01%) ⬆️
unit-latest-uploader 91.36% <96.36%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

codecov-public-qa bot commented May 16, 2024

Codecov Report

Attention: Patch coverage is 96.36364% with 2 lines in your changes are missing coverage. Please review.

Project coverage is 91.36%. Comparing base (d5ebabe) to head (ca9c30d).

✅ All tests successful. No failed tests found ☺️

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #569      +/-   ##
==========================================
+ Coverage   91.34%   91.36%   +0.01%     
==========================================
  Files         599      599              
  Lines       15968    15974       +6     
==========================================
+ Hits        14586    14594       +8     
+ Misses       1382     1380       -2     
Flag Coverage Δ
unit 91.36% <96.36%> (+0.01%) ⬆️
unit-latest-uploader 91.36% <96.36%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
billing/views.py 96.94% <100.00%> (+2.33%) ⬆️
codecov/settings_dev.py 100.00% <100.00%> (ø)
plan/service.py 97.05% <100.00%> (+0.79%) ⬆️
services/billing.py 92.48% <100.00%> (ø)
services/decorators.py 100.00% <100.00%> (ø)
codecov/settings_prod.py 0.00% <0.00%> (ø)
codecov/settings_staging.py 0.00% <0.00%> (ø)

Impacted file tree graph

Copy link
Contributor

@adrian-codecov adrian-codecov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments but otherwise looks good!

@@ -18,7 +18,7 @@

class MockSubscriptionPlan(object):
def __init__(self, params):
self.name = params["new_plan"]
self.id = params["new_plan"] or "price_1OCM2cGlVGuVgOrkMWUFjPFz"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this price?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope we don't! Removed in ca9c30d

@@ -29,7 +29,7 @@ def __init__(self, owner):

class MockSubscription(object):
def __init__(self, owner, params):
self.metadata = MockOboOrg(owner)
self.metadata = {"obo_organization": owner.ownerid, "obo": 15}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmm, I'm curious what made this change, afaik the metadata object didn't change on our end. Can we confirm we're setting the metadata correctly in stripe? This would be under the customer object

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screenshot 2024-05-17 at 9 58 36 AM
Screenshot 2024-05-17 at 10 00 35 AM
Screenshot 2024-05-17 at 10 00 44 AM

Yep, we are! Here are a few screenshots

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a quick followup, does subscription.metadata.obo_organization work over subscription.metadata["obo_organization"]? Trying to see if we need to make this + test changes related to this in the first place, or if this was when we were unsure about the dot/bracket notation

@@ -301,7 +301,7 @@ def test_customer_subscription_updated_does_not_change_subscription_if_not_paid_
"object": {
"id": self.owner.stripe_subscription_id,
"customer": self.owner.stripe_customer_id,
"plan": {"id": "fieown4", "name": "users-free"},
"plan": {"id": "fieown4"},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency, shouldn't this be id: ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, changed all instances to '?' in ca9c30d

extra=dict(
stripe_customer_id=subscription.customer,
stripe_subscription_id=subscription.id,
ownerid=subscription.metadata.obo_organization,
ownerid=subscription.metadata["obo_organization"],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh do you think we changed the test because we changed this part? Did we have to change this part in the end after seeing object/class notation worked fine?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may be able to swap to . notation, but that makes pylance upset; and we'd have to rerun all our local tests. I don't think the cost is worth it tbh.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll let you make the call, just trying to not change things we don't have to + keep consistency with the rest of the objects and not wonder in the future why we changed this/why it's different 👍

@@ -281,7 +311,7 @@ def post(self, request, *args, **kwargs):
self.request.META.get(StripeHTTPHeaders.SIGNATURE),
settings.STRIPE_ENDPOINT_SECRET,
)
except stripe.error.SignatureVerificationError as e:
except stripe.SignatureVerificationError as e:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we never have tests for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope we didn't haha, added in ca9c30d

if name not in USER_PLAN_REPRESENTATIONS:
raise ValueError("Unsupported plan")
if not user_count:
raise ValueError("Quantity Needed")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably need a test for this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, we didn't have tests for any of that function so added in ca9c30d

Copy link
Contributor

@adrian-codecov adrian-codecov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Post the comments you're gtg

@ajay-sentry ajay-sentry added this pull request to the merge queue May 17, 2024
Merged via the queue into main with commit 18722b4 May 17, 2024
21 of 22 checks passed
@ajay-sentry ajay-sentry deleted the stripe-upgrade-latest branch May 17, 2024 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants