290 lines · 11.9 KB
import { accountDb } from "../scoped-db";
import { forgetLocator, locate } from "../scoped-db/locators";
import { claimLocator } from "../metering/directory";
import { badRequest, forbidden, HttpError } from "../errors";
import { publicUrl } from "../events/emit";
import type { BillingAccount } from "../metering/access";
import { clearSiteCap } from "../metering/quota";
import type { Viewer } from "~/lib/types";
import { CUSTOM_DOMAIN_PRICE_CENTS } from "~/lib/pricing";
import { customDomainCount, domainAddon } from "./domain-addon";
import {
  billingNotConfigured,
  checkoutDisabled,
  proPriceVerified,
  stripe,
  stripeEnabled,
  verifiedPacks,
} from "./config";
import type { TopupPack } from "./config";
import { env } from "cloudflare:workers";
import { assertVerifiedForWrites } from "../verified-writes";

export type CustomerRow = {
  account_id: string;
  stripe_customer_id: string;
  subscription_id: string | null;
  subscription_status: string | null;
  price_id: string | null;
  current_period_end: number | null;
  cancel_at_period_end: number;
  subscription_event_at: number;
};

/** Subscription states that keep the Pro plan. past_due keeps it while Stripe retries the card. */
export const ACTIVE_STATUSES = new Set(["active", "trialing", "past_due"]);

export async function customerFor(accountId: string): Promise<CustomerRow | null> {
  return accountDb(accountId).first<CustomerRow>("SELECT * FROM billing_customers WHERE account_id = ?", accountId);
}