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

Commit 9f023ab

Browse files
feat: Add stripe setupIntent api
1 parent b07a010 commit 9f023ab

File tree

3 files changed

+51
-0
lines changed

3 files changed

+51
-0
lines changed

api/internal/owner/views.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,23 @@ def update_billing_address(self, request, *args, **kwargs):
113113
return Response(self.get_serializer(owner).data)
114114

115115

116+
@action(detail=False, methods=["get"])
117+
@stripe_safe
118+
def setup_intent(self, request, *args, **kwargs):
119+
"""
120+
GET a Stripe setupIntent clientSecret for updating payment method
121+
"""
122+
try:
123+
billing = BillingService(requesting_user=request.current_owner)
124+
client_secret = billing.get_setup_intent(self.owner)
125+
return Response({"client_secret": client_secret})
126+
except Exception as e:
127+
log.error(
128+
f"Error getting setup intent for owner {self.owner.ownerid}",
129+
extra={"error": str(e)},
130+
)
131+
raise ValidationError(detail="Unable to create setup intent")
132+
116133
class UsersOrderingFilter(filters.OrderingFilter):
117134
def get_valid_fields(self, queryset, view, context=None):
118135
fields = super().get_valid_fields(queryset, view, context=context or {})

services/billing.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ def modify_subscription(self, owner, plan):
5959
def create_checkout_session(self, owner, plan):
6060
pass
6161

62+
@abstractmethod
63+
def create_setup_intent(self, owner):
64+
pass
65+
6266
@abstractmethod
6367
def get_subscription(self, owner):
6468
pass
@@ -539,6 +543,23 @@ def create_checkout_session(self, owner: Owner, desired_plan):
539543
)
540544
return session["id"]
541545

546+
@_log_stripe_error
547+
def create_setup_intent(self, owner: Owner):
548+
log.info(
549+
"Stripe create setup intent for owner",
550+
extra=dict(
551+
owner_id=owner.ownerid,
552+
user_id=self.requesting_user.ownerid,
553+
subscription_id=owner.stripe_subscription_id,
554+
customer_id=owner.stripe_customer_id,
555+
),
556+
)
557+
setup_intent = stripe.SetupIntent.create(
558+
payment_method_types=['card', 'us_bank_account'],
559+
customer=owner.stripe_customer_id,
560+
)
561+
return setup_intent.client_secret
562+
542563
@_log_stripe_error
543564
def update_payment_method(self, owner: Owner, payment_method):
544565
log.info(
@@ -722,6 +743,9 @@ def __init__(self, payment_service=None, requesting_user=None):
722743
def get_subscription(self, owner):
723744
return self.payment_service.get_subscription(owner)
724745

746+
def get_setup_intent(self, owner):
747+
return self.payment_service.create_setup_intent(owner)
748+
725749
def get_schedule(self, owner):
726750
return self.payment_service.get_schedule(owner)
727751

services/tests/test_billing.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,6 +1825,15 @@ def test_apply_cancellation_discount_existing_coupon(
18251825
assert not customer_modify_mock.called
18261826
assert not coupon_create_mock.called
18271827

1828+
@patch("services.billing.stripe.SetupIntent.create")
1829+
def test_get_setup_intent(self, setup_intent_create_mock):
1830+
owner = OwnerFactory(stripe_customer_id="test-customer-id")
1831+
setup_intent_create_mock.return_value = {"client_secret": "test-client-secret"}
1832+
resp = self.stripe.get_setup_intent(owner)
1833+
self.stripe.payment_service.get_setup_intent.assert_called_once_with(owner)
1834+
1835+
assert resp.client_secret == "test-client-secret"
1836+
18281837

18291838
class MockPaymentService(AbstractPaymentService):
18301839
def list_filtered_invoices(self, owner, limit=10):
@@ -2022,3 +2031,4 @@ def test_get_invoice(self, get_invoice_mock):
20222031
owner = OwnerFactory()
20232032
self.billing_service.get_invoice(owner, "abc")
20242033
get_invoice_mock.assert_called_once_with(owner, "abc")
2034+

0 commit comments

Comments
 (0)