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