Home / Function/ PaymentMethods() — supabase Function Reference

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)}
      />
    </>
  )
}

Subdomains

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free