Skip to content

Commit

Permalink
feat: Add stripe setupIntent api
Browse files Browse the repository at this point in the history
  • Loading branch information
suejung-sentry committed Jan 7, 2025
1 parent b07a010 commit 9f023ab
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
17 changes: 17 additions & 0 deletions api/internal/owner/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,23 @@ def update_billing_address(self, request, *args, **kwargs):
return Response(self.get_serializer(owner).data)


@action(detail=False, methods=["get"])
@stripe_safe
def setup_intent(self, request, *args, **kwargs):
"""
GET a Stripe setupIntent clientSecret for updating payment method
"""
try:
billing = BillingService(requesting_user=request.current_owner)
client_secret = billing.get_setup_intent(self.owner)
return Response({"client_secret": client_secret})
except Exception as e:
log.error(
f"Error getting setup intent for owner {self.owner.ownerid}",
extra={"error": str(e)},
)
raise ValidationError(detail="Unable to create setup intent")

class UsersOrderingFilter(filters.OrderingFilter):
def get_valid_fields(self, queryset, view, context=None):
fields = super().get_valid_fields(queryset, view, context=context or {})
Expand Down
24 changes: 24 additions & 0 deletions services/billing.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ def modify_subscription(self, owner, plan):
def create_checkout_session(self, owner, plan):
pass

@abstractmethod
def create_setup_intent(self, owner):
pass

@abstractmethod
def get_subscription(self, owner):
pass
Expand Down Expand Up @@ -539,6 +543,23 @@ def create_checkout_session(self, owner: Owner, desired_plan):
)
return session["id"]

@_log_stripe_error
def create_setup_intent(self, owner: Owner):
log.info(
"Stripe create setup intent for owner",
extra=dict(
owner_id=owner.ownerid,
user_id=self.requesting_user.ownerid,
subscription_id=owner.stripe_subscription_id,
customer_id=owner.stripe_customer_id,
),
)
setup_intent = stripe.SetupIntent.create(
payment_method_types=['card', 'us_bank_account'],
customer=owner.stripe_customer_id,
)
return setup_intent.client_secret

@_log_stripe_error
def update_payment_method(self, owner: Owner, payment_method):
log.info(
Expand Down Expand Up @@ -722,6 +743,9 @@ def __init__(self, payment_service=None, requesting_user=None):
def get_subscription(self, owner):
return self.payment_service.get_subscription(owner)

def get_setup_intent(self, owner):
return self.payment_service.create_setup_intent(owner)

def get_schedule(self, owner):
return self.payment_service.get_schedule(owner)

Expand Down
10 changes: 10 additions & 0 deletions services/tests/test_billing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1825,6 +1825,15 @@ def test_apply_cancellation_discount_existing_coupon(
assert not customer_modify_mock.called
assert not coupon_create_mock.called

@patch("services.billing.stripe.SetupIntent.create")
def test_get_setup_intent(self, setup_intent_create_mock):
owner = OwnerFactory(stripe_customer_id="test-customer-id")
setup_intent_create_mock.return_value = {"client_secret": "test-client-secret"}
resp = self.stripe.get_setup_intent(owner)
self.stripe.payment_service.get_setup_intent.assert_called_once_with(owner)

assert resp.client_secret == "test-client-secret"


class MockPaymentService(AbstractPaymentService):
def list_filtered_invoices(self, owner, limit=10):
Expand Down Expand Up @@ -2022,3 +2031,4 @@ def test_get_invoice(self, get_invoice_mock):
owner = OwnerFactory()
self.billing_service.get_invoice(owner, "abc")
get_invoice_mock.assert_called_once_with(owner, "abc")

0 comments on commit 9f023ab

Please sign in to comment.