-
Notifications
You must be signed in to change notification settings - Fork 28
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
feat: Add ACH webhook flows #1106
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
✅ All tests successful. No failed tests found.
Additional details and impacted files@@ Coverage Diff @@
## main #1106 +/- ##
==========================================
- Coverage 96.09% 95.56% -0.54%
==========================================
Files 832 835 +3
Lines 19507 19687 +180
==========================================
+ Hits 18746 18813 +67
- Misses 761 874 +113
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
❌ 47 Tests Failed:
View the top 3 failed tests by shortest run time
To view more test analytics, go to the Test Analytics Dashboard |
❌ 47 Tests Failed:
View the top 3 failed tests by shortest run time
📣 Thoughts on this report? Let Codecov know! | Powered by Codecov |
❌ 47 Tests Failed:
View the top 3 failed tests by shortest run time
To view more test analytics, go to the Test Analytics Dashboard |
❌ 47 Tests Failed:
View the top 3 failed tests by shortest run time
To view more test analytics, go to the Test Analytics Dashboard |
@@ -17,6 +17,8 @@ class StripeWebhookEvents: | |||
"customer.updated", | |||
"invoice.payment_failed", | |||
"invoice.payment_succeeded", | |||
"payment_intent.succeeded", | |||
"setup_intent.succeeded", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO - these need to be turned on in Stripe dashboard
27940a4
to
d163c61
Compare
|
||
def _cleanup_incomplete_subscription(self, subscription, owner): | ||
latest_invoice = subscription.latest_invoice | ||
if not latest_invoice or not latest_invoice.payment_intent: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
may need to do a safe access here incase the attribute doesn't exist
@@ -802,8 +887,18 @@ def update_plan(self, owner, desired_plan): | |||
plan_service.set_default_plan_data() | |||
elif desired_plan["value"] in PAID_PLANS: | |||
if owner.stripe_subscription_id is not None: | |||
# if the existing subscription is incomplete, clean it up and create a new checkout session | |||
subscription = self.payment_service.get_subscription(owner) | |||
if subscription and subscription.status == "incomplete": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here for safe access
@@ -758,6 +837,9 @@ def apply_cancellation_discount(self, owner: Owner): | |||
def create_setup_intent(self, owner): | |||
pass | |||
|
|||
def get_unverified_payment_methods(self, owner): | |||
return [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be a pass?
payment_intents = stripe.PaymentIntent.list( | ||
customer=owner.stripe_customer_id, limit=100 | ||
) | ||
for intent in payment_intents.data: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will this and the below data object always exist?
) | ||
for intent in payment_intents.data: | ||
if ( | ||
hasattr(intent, "next_action") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could maybe do a .get() here instead
) | ||
for intent in setup_intents.data: | ||
if ( | ||
hasattr(intent, "next_action") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similar here
@@ -718,6 +752,51 @@ def create_setup_intent(self, owner: Owner) -> stripe.SetupIntent: | |||
customer=owner.stripe_customer_id, | |||
) | |||
|
|||
def _get_unverified_payment_methods(self, owner): | |||
log.info( | |||
"Getting unverified payment methods", extra=dict(owner_id=owner.ownerid) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we add the customerid to this log too?
unverified_payment_methods = [] | ||
|
||
# Check payment intents | ||
payment_intents = stripe.PaymentIntent.list( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little surprised stripe doesn't have a shared API for these two considering the properties being pulled off of each are the same
Handles ACH microdeposits delayed payment verification flow.
This PR handles the below new logical flows:
unverified_payment_methods
list toGET /account-details
payment_intent.succeeded
setup_intent.succeeded
Other things of note:
Tested end-to-end flows:
codecov/engineering-team#2622