Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/components/admin/users-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ function PlanBadge({ plan }: { plan: Plan | null }) {
if (plan && plan !== 'free') {
return (
<span className="inline-flex items-center rounded-full border border-amber-300/30 bg-amber-300/[0.1] px-2.5 py-1 font-mono text-[10px] uppercase text-amber-300">
{plan}
{PAID_PLANS[plan].name}
</span>
)
}
Expand Down Expand Up @@ -227,4 +227,4 @@ function RunsGrant({ workspaceId }: { workspaceId: string }) {
</button>
</div>
)
}
}
11 changes: 6 additions & 5 deletions src/routes/api.billing.webhook.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,15 @@ async function handleEvent(event: BachsEvent): Promise<void> {
productId: event.data?.product_id,
metadataPlan: event.data?.metadata?.plan,
})
// The customer paid, so never leave them on free: an unrecognised product
// falls back to Pro, logged so the product mapping can be fixed.
// If no plan is matched, it indicates an unrecognised product configuration.
// This should be treated as an error to prevent inconsistent state.
if (!matched) {
console.warn(
`[billing] subscription for workspace ${workspaceId} matched no plan; defaulting to pro`,
console.error(
`[billing] subscription for workspace ${workspaceId} matched no known plan for product ID ${event.data?.product_id} and metadata plan ${event.data?.metadata?.plan}; failing webhook processing.`,
)
throw new Error('Unrecognized subscription plan')
}
const plan = matched ?? 'pro'
const plan = matched
await markWorkspacePaid(workspaceId, plan, {
customerId,
subscriptionId: event.data?.subscription_id,
Expand Down
8 changes: 4 additions & 4 deletions src/routes/pricing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ function PricingPage() {
<Feature>One-click fix PRs</Feature>
</ul>
{plan === 'free' && signedIn ? (
<CurrentPlan />
<CurrentPlan currentPlan={plan} />
) : (
<Link
className="button-secondary mt-7 w-full justify-center"
Expand Down Expand Up @@ -201,7 +201,7 @@ function PaidPlanCard({
</ul>

{currentPlan === id ? (
<CurrentPlan paid />
<CurrentPlan currentPlan={currentPlan} paid />
) : currentPlan !== 'free' ? (
<span className="mt-7 inline-flex w-full items-center justify-center rounded-2xl border border-white/[0.08] bg-white/[0.03] px-4 py-3 text-sm text-zinc-500">
You&apos;re on {PAID_PLANS[currentPlan].name}
Expand Down Expand Up @@ -242,11 +242,11 @@ function PaidPlanCard({
)
}

function CurrentPlan({ paid = false }: { paid?: boolean }) {
function CurrentPlan({ paid = false, currentPlan }: { paid?: boolean; currentPlan: Plan }) {
return paid ? (
<span className="mt-7 inline-flex w-full items-center justify-center rounded-2xl border border-emerald-300/25 bg-emerald-300/[0.08] px-4 py-3 text-sm text-emerald-300">
<Check className="mr-2 size-4" />
Your current plan
You&apos;re on {PAID_PLANS[currentPlan as PaidPlan].name}
</span>
) : (
<span className="mt-7 inline-flex w-full items-center justify-center rounded-2xl border border-white/[0.08] bg-white/[0.03] px-4 py-3 text-sm text-zinc-500">
Expand Down
Loading