Skip to content
This repository was archived by the owner on Jun 13, 2025. It is now read-only.

Commit 0d80364

Browse files
add end to end ach items
1 parent 058e85f commit 0d80364

File tree

6 files changed

+50
-8
lines changed

6 files changed

+50
-8
lines changed

api/internal/owner/serializers.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,17 @@ class StripeCardSerializer(serializers.Serializer):
108108
last4 = serializers.CharField()
109109

110110

111+
class StripeUSBankAccountSerializer(serializers.Serializer):
112+
account_holder_type = serializers.CharField()
113+
account_type = serializers.CharField()
114+
bank_name = serializers.CharField()
115+
last4 = serializers.CharField()
116+
routing_number = serializers.CharField()
117+
118+
111119
class StripePaymentMethodSerializer(serializers.Serializer):
112120
card = StripeCardSerializer(read_only=True)
121+
us_bank_account = StripeUSBankAccountSerializer(read_only=True)
113122
billing_details = serializers.JSONField(read_only=True)
114123

115124

api/internal/owner/views.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ def update_email(self, request, *args, **kwargs):
8585
raise ValidationError(detail="No new_email sent")
8686
owner = self.get_object()
8787
billing = BillingService(requesting_user=request.current_owner)
88-
billing.update_email_address(owner, new_email)
88+
should_propagate = request.data.get("should_propagate_to_payment_methods", False)
89+
billing.update_email_address(owner, new_email, should_propagate_to_payment_methods=should_propagate)
8990
return Response(self.get_serializer(owner).data)
9091

9192
@action(detail=False, methods=["patch"])

billing/views.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ def customer_subscription_created(self, subscription: stripe.Subscription) -> No
312312
self._log_updated([owner])
313313

314314
def customer_subscription_updated(self, subscription: stripe.Subscription) -> None:
315+
print("CUSTOMER SUBSCRIPTION UPDATED", subscription)
315316
owners: QuerySet[Owner] = Owner.objects.filter(
316317
stripe_subscription_id=subscription.id,
317318
stripe_customer_id=subscription.customer,
@@ -408,6 +409,8 @@ def customer_subscription_updated(self, subscription: stripe.Subscription) -> No
408409
)
409410

410411
def customer_updated(self, customer: stripe.Customer) -> None:
412+
print("CUSTOMER UPDATED", customer)
413+
411414
new_default_payment_method = customer["invoice_settings"][
412415
"default_payment_method"
413416
]

codecov/settings_base.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,7 @@
9898
"setup", "graphql", "query_cost_threshold", default=10000
9999
)
100100

101-
GRAPHQL_RATE_LIMIT_ENABLED = get_config(
102-
"setup", "graphql", "rate_limit_enabled", default=True
103-
)
101+
GRAPHQL_RATE_LIMIT_ENABLED = get_config("setup", "graphql", "rate_limit_enabled", default=True)
104102

105103
GRAPHQL_RATE_LIMIT_RPM = get_config("setup", "graphql", "rate_limit_rpm", default=300)
106104

@@ -428,6 +426,8 @@
428426
SHELTER_PUBSUB_PROJECT_ID = get_config("setup", "shelter", "pubsub_project_id")
429427
SHELTER_PUBSUB_SYNC_REPO_TOPIC_ID = get_config("setup", "shelter", "sync_repo_topic_id")
430428

429+
STRIPE_PAYMENT_METHOD_CONFIGURATION_ID = get_config("setup", "stripe", "payment_method_configuration", default=None)
430+
431431
# Allows to do migrations from another module
432432
MIGRATION_MODULES = {
433433
"codecov_auth": "shared.django_apps.codecov_auth.migrations",

graphql_api/types/invoice/invoice.graphql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ type Card {
4343
last4: String
4444
}
4545

46+
type BankAccount {
47+
accountHolderType: String
48+
accountType: String
49+
bankName: String
50+
last4: String
51+
routingNumber: String
52+
}
53+
4654
type BillingDetails {
4755
address: Address
4856
email: String

services/billing.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -516,8 +516,8 @@ def create_checkout_session(self, owner: Owner, desired_plan):
516516
)
517517

518518
session = stripe.checkout.Session.create(
519+
payment_method_configuration=settings.STRIPE_PAYMENT_METHOD_CONFIGURATION_ID,
519520
billing_address_collection="required",
520-
payment_method_types=["card"],
521521
payment_method_collection="if_required",
522522
client_reference_id=str(owner.ownerid),
523523
success_url=success_url,
@@ -601,7 +601,7 @@ def update_payment_method(self, owner: Owner, payment_method):
601601
)
602602

603603
@_log_stripe_error
604-
def update_email_address(self, owner: Owner, email_address: str):
604+
def update_email_address(self, owner: Owner, email_address: str, should_propagate_to_payment_methods: bool = False):
605605
if not re.fullmatch(r"[^@]+@[^@]+\.[^@]+", email_address):
606606
return None
607607

@@ -616,6 +616,27 @@ def update_email_address(self, owner: Owner, email_address: str):
616616
f"Stripe successfully updated email address for owner {owner.ownerid} by user #{self.requesting_user.ownerid}"
617617
)
618618

619+
if should_propagate_to_payment_methods:
620+
try:
621+
default_payment_method = stripe.Customer.retrieve(
622+
owner.stripe_customer_id
623+
).invoice_settings.default_payment_method
624+
625+
stripe.PaymentMethod.modify(
626+
default_payment_method,
627+
billing_details={"email": email_address},
628+
)
629+
log.info(
630+
f"Stripe successfully updated billing email for payment method {default_payment_method}"
631+
)
632+
except Exception:
633+
log.error(
634+
"Unable to update billing email for payment method",
635+
extra=dict(
636+
payment_method=default_payment_method,
637+
),
638+
)
639+
619640
@_log_stripe_error
620641
def update_billing_address(self, owner: Owner, name, billing_address):
621642
log.info(f"Stripe update billing address for owner {owner.ownerid}")
@@ -786,14 +807,14 @@ def update_payment_method(self, owner, payment_method):
786807
"""
787808
return self.payment_service.update_payment_method(owner, payment_method)
788809

789-
def update_email_address(self, owner: Owner, email_address: str):
810+
def update_email_address(self, owner: Owner, email_address: str, should_propagate_to_payment_methods: bool = False):
790811
"""
791812
Takes an owner and a new email. Email is a string coming directly from
792813
the front-end. If the owner has a payment id and if it's a valid email,
793814
the payment service will update the email address in the upstream service.
794815
Otherwise returns None.
795816
"""
796-
return self.payment_service.update_email_address(owner, email_address)
817+
return self.payment_service.update_email_address(owner, email_address, should_propagate_to_payment_methods)
797818

798819
def update_billing_address(self, owner: Owner, name: str, billing_address):
799820
"""

0 commit comments

Comments
 (0)