@@ -27,66 +27,7 @@ import {
2727} from '@/lib/ban-conditions'
2828import { ORG_BILLING_ENABLED } from '@/lib/billing-config'
2929import { logger } from '@/util/logger'
30-
31- /**
32- * Checks whether a Stripe customer ID belongs to an organization.
33- *
34- * Uses `org.stripe_customer_id` which is set at org creation time, making it
35- * reliable regardless of webhook ordering (unlike `stripe_subscription_id`
36- * which may not be populated yet when early invoice events arrive).
37- */
38- async function isOrgCustomer ( stripeCustomerId : string ) : Promise < boolean > {
39- try {
40- const orgs = await db
41- . select ( { id : schema . org . id } )
42- . from ( schema . org )
43- . where ( eq ( schema . org . stripe_customer_id , stripeCustomerId ) )
44- . limit ( 1 )
45- return orgs . length > 0
46- } catch ( error ) {
47- logger . error (
48- { stripeCustomerId, error } ,
49- 'Failed to check if customer is an org - defaulting to false' ,
50- )
51- return false
52- }
53- }
54-
55- /**
56- * BILLING_DISABLED: Checks if a Stripe event is related to organization billing.
57- * Used to reject org billing events while keeping personal billing working.
58- */
59- async function isOrgBillingEvent ( event : Stripe . Event ) : Promise < boolean > {
60- const eventData = event . data . object as unknown as Record < string , unknown >
61- const metadata = ( eventData . metadata || { } ) as Record < string , string >
62-
63- // Check metadata for organization markers
64- if ( metadata . organization_id || metadata . organizationId ) {
65- return true
66- }
67- if ( metadata . grantType === 'organization_purchase' ) {
68- return true
69- }
70-
71- // For invoice events, check if customer belongs to an org
72- // (metadata.organizationId is already checked above in the generic metadata check)
73- if ( event . type . startsWith ( 'invoice.' ) ) {
74- const customerId = eventData . customer
75- if ( customerId && typeof customerId === 'string' ) {
76- return await isOrgCustomer ( customerId )
77- }
78- }
79-
80- // For subscription events, check if customer is an org
81- if ( event . type . startsWith ( 'customer.subscription.' ) ) {
82- const customerId = eventData . customer
83- if ( customerId && typeof customerId === 'string' ) {
84- return await isOrgCustomer ( customerId )
85- }
86- }
87-
88- return false
89- }
30+ import { isOrgBillingEvent , isOrgCustomer } from './_helpers'
9031
9132async function handleCheckoutSessionCompleted (
9233 session : Stripe . Checkout . Session ,
@@ -699,6 +640,3 @@ const webhookHandler = async (req: NextRequest): Promise<NextResponse> => {
699640}
700641
701642export { webhookHandler as POST }
702-
703- // Exported for testing
704- export { isOrgBillingEvent , isOrgCustomer }
0 commit comments