← back to Lawyer Directory Builder

src/scripts/setup_stripe_lawyer_pro_price.ts

76 lines

/**
 * One-shot setup: create (or reuse) the Stripe Product + recurring Price
 * for the Counsel & Bar Lawyer Pro $29/mo subscription tier and print the
 * price ID. Caller saves it via the secrets-manager CLI as
 * STRIPE_PRICE_LAWYER_PRO_MONTHLY.
 *
 * Idempotent: if a "Counsel & Bar — Lawyer Pro" product already exists with
 * an active monthly USD price at $29, we reuse it. Otherwise we create both.
 *
 *   npx tsx src/scripts/setup_stripe_lawyer_pro_price.ts
 */
import 'dotenv/config';
import Stripe from 'stripe';

const PRODUCT_NAME = 'Counsel & Bar — Lawyer Pro';
const UNIT_AMOUNT = 2900;        // $29.00 USD
const CURRENCY = 'usd';
const INTERVAL: 'month' | 'year' = 'month';

const SK = process.env.STRIPE_SECRET_KEY;
if (!SK || !SK.startsWith('sk_')) {
  console.error('STRIPE_SECRET_KEY missing or invalid in .env');
  process.exit(2);
}
const stripe = new Stripe(SK);

function fmtCents(c: number): string { return `$${(c / 100).toFixed(2)}`; }

(async () => {
  // 1. Find or create the Product
  let product: Stripe.Product | null = null;
  for await (const p of stripe.products.list({ active: true, limit: 100 })) {
    if (p.name === PRODUCT_NAME) { product = p; break; }
  }
  if (!product) {
    console.log(`creating product "${PRODUCT_NAME}"…`);
    product = await stripe.products.create({
      name: PRODUCT_NAME,
      description: 'Lawyer-tier subscription on Counsel & Bar (lawyers.agentabrams.com). Includes profile claim, review responses, client DMs, lead alerts.',
      metadata: { sku: 'lawyer-pro-monthly', site: 'lawyers.agentabrams.com' },
    });
  } else {
    console.log(`found existing product ${product.id} (${product.name})`);
  }

  // 2. Find an existing matching active Price, else create one
  const prices = await stripe.prices.list({ product: product.id, active: true, limit: 100 });
  let price: Stripe.Price | null = null;
  for (const pr of prices.data) {
    if (pr.unit_amount === UNIT_AMOUNT && pr.currency === CURRENCY && pr.recurring?.interval === INTERVAL) {
      price = pr; break;
    }
  }
  if (!price) {
    console.log(`creating recurring price ${fmtCents(UNIT_AMOUNT)} ${CURRENCY.toUpperCase()} / ${INTERVAL}…`);
    price = await stripe.prices.create({
      product: product.id,
      unit_amount: UNIT_AMOUNT,
      currency: CURRENCY,
      recurring: { interval: INTERVAL },
      lookup_key: 'lawyer_pro_monthly',
      metadata: { tier: 'lawyer', sku: 'lawyer-pro-monthly' },
    });
  } else {
    console.log(`found existing price ${price.id} (${fmtCents(price.unit_amount!)} ${price.currency.toUpperCase()} / ${price.recurring?.interval})`);
  }

  console.log('\n=== Stripe Lawyer Pro price ready ===');
  console.log('product id:    ', product.id);
  console.log('price id:      ', price.id);
  console.log('amount:        ', fmtCents(price.unit_amount!), price.currency.toUpperCase(), '/', price.recurring?.interval);
  console.log('lookup key:    ', price.lookup_key || '(none)');
  console.log('\nNext step (run from your shell):');
  console.log(`  node ~/Projects/secrets-manager/cli.js add STRIPE_PRICE_LAWYER_PRO_MONTHLY '${price.id}'\n`);
})().catch(e => { console.error('setup failed:', e); process.exit(1); });