PaymentMethods() — supabase Function Reference
Architecture documentation for the PaymentMethods() function in PaymentMethods.tsx from the supabase codebase.
Entity Profile
Relationship Graph
Source Code
apps/studio/components/interfaces/Billing/Payment/PaymentMethods/PaymentMethods.tsx lines 32–192
const PaymentMethods = () => {
const { slug } = useParams()
const { data: selectedOrganization } = useSelectedOrganizationQuery()
const [selectedMethodForUse, setSelectedMethodForUse] = useState<any>()
const [selectedMethodToDelete, setSelectedMethodToDelete] = useState<any>()
const [showAddPaymentMethodModal, setShowAddPaymentMethodModal] = useState(false)
const { data: subscription } = useOrgSubscriptionQuery({ orgSlug: slug })
const {
data: paymentMethods,
error,
isPending: isLoading,
isError,
isSuccess,
} = useOrganizationPaymentMethodsQuery({ slug })
const { can: canReadPaymentMethods, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
PermissionAction.BILLING_READ,
'stripe.payment_methods'
)
const { can: canUpdatePaymentMethods } = useAsyncCheckPermissions(
PermissionAction.BILLING_WRITE,
'stripe.payment_methods'
)
return (
<>
<ScaffoldSection>
<ScaffoldSectionDetail>
<div className="sticky space-y-2 top-12">
<p className="text-foreground text-base m-0">Payment Methods</p>
<p className="text-sm text-foreground-light mb-2 pr-4 m-0">
Payments for your subscription are made using the default card.
</p>
</div>
</ScaffoldSectionDetail>
<ScaffoldSectionContent>
{selectedOrganization?.managed_by !== undefined &&
selectedOrganization?.managed_by !== MANAGED_BY.SUPABASE ? (
<PartnerManagedResource
managedBy={selectedOrganization?.managed_by}
resource="Payment Methods"
cta={{
installationId: selectedOrganization?.partner_id,
}}
/>
) : isPermissionsLoaded && !canReadPaymentMethods ? (
<NoPermission resourceText="view this organization's payment methods" />
) : (
<>
{isLoading && (
<div className="space-y-2">
<ShimmeringLoader />
<ShimmeringLoader className="w-3/4" />
<ShimmeringLoader className="w-1/2" />
</div>
)}
{isError && (
<AlertError subject="Failed to retrieve payment methods" error={error as any} />
)}
{isSuccess && (
<>
{subscription?.payment_method_type === 'invoice' && (
<Admonition
type="note"
layout="horizontal"
title="Payment is currently by invoice"
description="You get a monthly invoice and payment link via email. To change your payment
method, please contact us via our support form."
actions={
<Button asChild key="payment-method-support" type="default">
<SupportLink
queryParams={{
category: SupportCategories.BILLING,
subject: 'Request to change payment method',
}}
>
Contact support
</SupportLink>
</Button>
}
/>
)}
<FormPanel
footer={
<div className="flex items-center justify-between py-4 px-8">
{!canUpdatePaymentMethods ? (
<p className="text-sm text-foreground-light">
You need additional permissions to manage payment methods
</p>
) : (
<div />
)}
<Button
type="default"
icon={<Plus />}
disabled={!canUpdatePaymentMethods}
onClick={() => setShowAddPaymentMethodModal(true)}
>
Add new card
</Button>
</div>
}
>
<FormSection>
<FormSectionContent fullWidth loading={false}>
{(paymentMethods?.data?.length ?? 0) === 0 ? (
<div className="flex items-center gap-2 opacity-50">
<CreditCardIcon size={16} strokeWidth={1.5} />
<p className="text-sm">No payment methods</p>
</div>
) : (
<div className="space-y-3">
{paymentMethods?.data?.map((paymentMethod) => (
<CreditCard
key={paymentMethod.id}
paymentMethod={paymentMethod}
canUpdatePaymentMethods={canUpdatePaymentMethods}
paymentMethodType={subscription?.payment_method_type}
setSelectedMethodForUse={setSelectedMethodForUse}
setSelectedMethodToDelete={setSelectedMethodToDelete}
paymentMethodCount={paymentMethods?.data.length ?? 0}
subscriptionPlan={subscription?.plan.id}
/>
))}
</div>
)}
</FormSectionContent>
</FormSection>
</FormPanel>
</>
)}
</>
)}
</ScaffoldSectionContent>
</ScaffoldSection>
<AddNewPaymentMethodModal
visible={showAddPaymentMethodModal}
returnUrl={`${getURL()}/org/${slug}/billing`}
onCancel={() => setShowAddPaymentMethodModal(false)}
onConfirm={() => {
setShowAddPaymentMethodModal(false)
toast.success('Successfully added new payment method')
}}
/>
<ChangePaymentMethodModal
selectedPaymentMethod={selectedMethodForUse}
onClose={() => setSelectedMethodForUse(undefined)}
/>
<DeletePaymentMethodModal
selectedPaymentMethod={selectedMethodToDelete}
onClose={() => setSelectedMethodToDelete(undefined)}
/>
</>
)
}
Domain
Subdomains
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free