Skip to content

Commit 3940956

Browse files
committed
fix(billing): register the Stripe plugin only when the webhook secret is configured
The Better Auth Stripe plugin was passed `STRIPE_WEBHOOK_SECRET || ''`. Stripe's verifier accepts signatures computed with an empty key, so the plugin's own falsy-secret check was the only thing keeping the receiver from accepting forged events. Billing now registers only when the webhook secret is set, logging an error otherwise, and the setup preflight requires it alongside STRIPE_SECRET_KEY.
1 parent d4dfd17 commit 3940956

2 files changed

Lines changed: 24 additions & 12 deletions

File tree

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

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -237,15 +237,27 @@ 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+
if (!env.STRIPE_WEBHOOK_SECRET) {
248+
logger.error(
249+
'BILLING_ENABLED and STRIPE_SECRET_KEY are set but STRIPE_WEBHOOK_SECRET is not; the Stripe billing plugin is disabled until it is configured'
250+
)
251+
return null
252+
}
253+
return {
254+
client: new Stripe(env.STRIPE_SECRET_KEY, { apiVersion: '2025-08-27.basil' }),
255+
webhookSecret: env.STRIPE_WEBHOOK_SECRET,
256+
}
247257
}
248258

259+
const stripeBilling = resolveStripeBilling()
260+
249261
/**
250262
* Resolves the org's API instance URL for a freshly linked Salesforce account.
251263
*
@@ -967,7 +979,7 @@ export const auth = betterAuth({
967979
banned: false,
968980
banReason: null,
969981
banExpires: null,
970-
...(isBillingEnabled && stripeClient ? { stripeCustomerId: null } : {}),
982+
...(stripeBilling ? { stripeCustomerId: null } : {}),
971983
...additionalFields,
972984
id,
973985
}),
@@ -1547,11 +1559,11 @@ export const auth = betterAuth({
15471559
* SSO provider behind it.
15481560
*/
15491561
...(isSsoEnabled ? [configuredSsoPlugin] : []),
1550-
...(isBillingEnabled && stripeClient
1562+
...(stripeBilling
15511563
? [
15521564
stripe({
1553-
stripeClient,
1554-
stripeWebhookSecret: env.STRIPE_WEBHOOK_SECRET || '',
1565+
stripeClient: stripeBilling.client,
1566+
stripeWebhookSecret: stripeBilling.webhookSecret,
15551567
createCustomerOnSignUp: true,
15561568
onCustomerCreate: async ({ stripeCustomer, user }) => {
15571569
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)