Home / Function/ BillingCustomerData() — supabase Function Reference

BillingCustomerData() — supabase Function Reference

Architecture documentation for the BillingCustomerData() function in BillingCustomerData.tsx from the supabase codebase.

Entity Profile

Dependency Diagram

graph TD
  a9e7e54d_7b41_3549_2112_ff1656aa2dbc["BillingCustomerData()"]
  1a045fde_de7d_a598_5955_195969fbbafd["useBillingCustomerDataForm()"]
  a9e7e54d_7b41_3549_2112_ff1656aa2dbc -->|calls| 1a045fde_de7d_a598_5955_195969fbbafd
  style a9e7e54d_7b41_3549_2112_ff1656aa2dbc fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

apps/studio/components/interfaces/Organization/BillingSettings/BillingCustomerData/BillingCustomerData.tsx lines 29–186

export const BillingCustomerData = () => {
  const { slug } = useParams()
  const { data: selectedOrganization } = useSelectedOrganizationQuery()

  const { can: canReadBillingCustomerData, isSuccess: isPermissionsLoaded } =
    useAsyncCheckPermissions(PermissionAction.BILLING_READ, 'stripe.customer')
  const { can: canUpdateBillingCustomerData } = useAsyncCheckPermissions(
    PermissionAction.BILLING_WRITE,
    'stripe.customer'
  )

  const {
    data: customerProfile,
    error,
    isPending: isLoading,
    isSuccess,
  } = useOrganizationCustomerProfileQuery({ slug }, { enabled: canReadBillingCustomerData })

  const {
    data: taxId,
    error: errorLoadingTaxId,
    isPending: isLoadingTaxId,
    isSuccess: loadedTaxId,
  } = useOrganizationTaxIdQuery({ slug })

  const initialCustomerData = useMemo<Partial<BillingCustomerDataFormValues>>(
    () => ({
      city: customerProfile?.address?.city ?? undefined,
      country: customerProfile?.address?.country,
      line1: customerProfile?.address?.line1,
      line2: customerProfile?.address?.line2 ?? undefined,
      postal_code: customerProfile?.address?.postal_code ?? undefined,
      state: customerProfile?.address?.state ?? undefined,
      billing_name: customerProfile?.billing_name,
      tax_id_type: taxId?.type,
      tax_id_value: taxId?.value,
      tax_id_name: taxId
        ? TAX_IDS.find(
            (option) => option.type === taxId.type && option.countryIso2 === taxId.country
          )?.name || ''
        : '',
    }),
    [customerProfile, taxId]
  )

  const { mutateAsync: updateCustomerProfile } = useOrganizationCustomerProfileUpdateMutation()
  const { mutateAsync: updateTaxId } = useOrganizationTaxIdUpdateMutation()

  const [isSubmitting, setIsSubmitting] = useState(false)

  const { form, handleSubmit, handleReset, isDirty } = useBillingCustomerDataForm({
    initialCustomerData,
    onCustomerDataChange: async (data) => {
      setIsSubmitting(true)

      try {
        await updateCustomerProfile({
          slug,
          address: data.address,
          billing_name: data.billing_name,
        })

        await updateTaxId({ slug, taxId: data.tax_id })

        toast.success('Successfully updated billing data')

        setIsSubmitting(false)
      } catch (error: any) {
        toast.error(`Failed updating billing data: ${error.message}`)
        setIsSubmitting(false)
      }
    },
  })

  const isSubmitDisabled = !isDirty || !canUpdateBillingCustomerData || isSubmitting

  return (
    <ScaffoldSection>
      <ScaffoldSectionDetail>
        <div className="sticky space-y-2 top-12 pr-3">
          <p className="text-foreground text-base m-0">Billing Address &amp; Tax ID</p>
          <p className="text-sm text-foreground-light m-0">
            Changes will be reflected in every upcoming invoice, past invoices are not affected
          </p>
          <p className="text-sm text-foreground-light m-0">
            A Tax ID is only required for registered businesses.
          </p>
        </div>
      </ScaffoldSectionDetail>
      <ScaffoldSectionContent>
        {selectedOrganization?.managed_by !== undefined &&
        selectedOrganization?.managed_by !== 'supabase' ? (
          <PartnerManagedResource
            managedBy={selectedOrganization?.managed_by}
            resource="Billing Addresses"
            cta={{
              installationId: selectedOrganization?.partner_id,
            }}
          />
        ) : isPermissionsLoaded && !canReadBillingCustomerData ? (
          <NoPermission resourceText="view this organization's billing address" />
        ) : (
          <>
            {(isLoading || isLoadingTaxId) && (
              <div className="space-y-2">
                <ShimmeringLoader />
                <ShimmeringLoader className="w-3/4" />
                <ShimmeringLoader className="w-1/2" />
              </div>
            )}

            {(error || errorLoadingTaxId) && (
              <AlertError
                subject="Failed to retrieve organization customer profile"
                error={(error || errorLoadingTaxId) as any}
              />
            )}

            {isSuccess && loadedTaxId && (
              <Card>
                <Form {...form}>
                  <form onSubmit={form.handleSubmit(handleSubmit)}>
                    <BillingCustomerDataForm
                      className="p-8"
                      form={form}
                      disabled={!canUpdateBillingCustomerData}
                    />
                    <CardFooter className="border-t justify-end px-8">
                      {!canUpdateBillingCustomerData && (
                        <span className="text-sm text-foreground-lighter mr-auto">
                          You need additional permissions to manage this organization's billing
                          address
                        </span>
                      )}
                      <div className="flex items-center gap-2">
                        <Button type="default" onClick={handleReset} disabled={isSubmitDisabled}>
                          Cancel
                        </Button>
                        <Button
                          type="primary"
                          htmlType="submit"
                          disabled={isSubmitDisabled}
                          loading={isSubmitting}
                        >
                          Save
                        </Button>
                      </div>
                    </CardFooter>
                  </form>
                </Form>
              </Card>
            )}
          </>
        )}
      </ScaffoldSectionContent>
    </ScaffoldSection>
  )
}

Subdomains

Frequently Asked Questions

What does BillingCustomerData() do?
BillingCustomerData() is a function in the supabase codebase.
What does BillingCustomerData() call?
BillingCustomerData() calls 1 function(s): useBillingCustomerDataForm.

Analyze Your Own Codebase

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

Try Supermodel Free