Skip to content

Commit 06fee1b

Browse files
authored
fix(billing): register the Stripe plugin only when the webhook secret is configured (#9363)
Stripe's verifier accepts signatures computed with an empty key, so the Better Auth Stripe plugin now registers only when billing is on and both STRIPE_SECRET_KEY and a non-blank STRIPE_WEBHOOK_SECRET are set, logging an error otherwise. The sim-setup preflight requires the webhook secret alongside the secret key.
1 parent 3fc79a2 commit 06fee1b

2 files changed

Lines changed: 25 additions & 12 deletions

File tree

‎apps/sim/lib/auth/auth.ts‎

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -237,15 +237,28 @@ if (env.NODE_ENV === 'production') {
237237
}
238238
}
239239

240-
const validStripeKey = env.STRIPE_SECRET_KEY
241-
242-
let stripeClient = null
243-
if (validStripeKey) {
244-
stripeClient = new Stripe(env.STRIPE_SECRET_KEY || '', {
245-
apiVersion: '2025-08-27.basil',
246-
})
240+
/**
241+
* Resolves the Stripe billing plugin's client and webhook signing secret, or `null` when the plugin
242+
* must not register. Stripe's verifier accepts a signature computed with an empty key, so a missing
243+
* `STRIPE_WEBHOOK_SECRET` disables the plugin rather than exposing a forgeable webhook receiver.
244+
*/
245+
function resolveStripeBilling() {
246+
if (!isBillingEnabled || !env.STRIPE_SECRET_KEY) return null
247+
const webhookSecret = env.STRIPE_WEBHOOK_SECRET
248+
if (!webhookSecret?.trim()) {
249+
logger.error(
250+
'BILLING_ENABLED and STRIPE_SECRET_KEY are set but STRIPE_WEBHOOK_SECRET is not; the Stripe billing plugin is disabled until it is configured'
251+
)
252+
return null
253+
}
254+
return {
255+
client: new Stripe(env.STRIPE_SECRET_KEY, { apiVersion: '2025-08-27.basil' }),
256+
webhookSecret,
257+
}
247258
}
248259

260+
const stripeBilling = resolveStripeBilling()
261+
249262
/**
250263
* Resolves the org's API instance URL for a freshly linked Salesforce account.
251264
*
@@ -967,7 +980,7 @@ export const auth = betterAuth({
967980
banned: false,
968981
banReason: null,
969982
banExpires: null,
970-
...(isBillingEnabled && stripeClient ? { stripeCustomerId: null } : {}),
983+
...(stripeBilling ? { stripeCustomerId: null } : {}),
971984
...additionalFields,
972985
id,
973986
}),
@@ -1547,11 +1560,11 @@ export const auth = betterAuth({
15471560
* SSO provider behind it.
15481561
*/
15491562
...(isSsoEnabled ? [configuredSsoPlugin] : []),
1550-
...(isBillingEnabled && stripeClient
1563+
...(stripeBilling
15511564
? [
15521565
stripe({
1553-
stripeClient,
1554-
stripeWebhookSecret: env.STRIPE_WEBHOOK_SECRET || '',
1566+
stripeClient: stripeBilling.client,
1567+
stripeWebhookSecret: stripeBilling.webhookSecret,
15551568
createCustomerOnSignUp: true,
15561569
onCustomerCreate: async ({ stripeCustomer, user }) => {
15571570
logger.info('[onCustomerCreate] Stripe customer created', {

‎packages/sim-setup/src/checks.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ function checkCoherence(ctx: CheckContext): Finding[] {
469469
}> = [
470470
{
471471
flag: 'BILLING_ENABLED',
472-
needs: ['STRIPE_SECRET_KEY'],
472+
needs: ['STRIPE_SECRET_KEY', 'STRIPE_WEBHOOK_SECRET'],
473473
label: 'billing',
474474
},
475475
{

0 commit comments

Comments
 (0)