{"record":{"id":"6f1f864004e73051","repo":"calcom/cal.diy","slug":"failed-generating-a-stripe-checkout-session-url","errorCode":null,"errorMessage":"Failed generating a Stripe checkout session URL.","messagePattern":"Failed generating a Stripe checkout session URL\\.","errorType":"http","errorClass":"InternalServerErrorException","httpStatus":500,"severity":"critical","filePath":"apps/api/v2/src/modules/stripe/stripe.service.ts","lineNumber":208,"sourceCode":"          quantity: 1,\n        },\n      ],\n      customer_update: {\n        address: \"auto\",\n      },\n      // Disabled when testing locally as usually developer doesn't setup Tax in Stripe Test mode\n      automatic_tax: {\n        enabled: this.environment === \"production\",\n      },\n      metadata: {\n        pendingPaymentTeamId,\n        ownerId,\n        dubCustomerId: ownerId, // pass the userId during checkout creation for sales conversion tracking: https://d.to/conversions/stripe\n      },\n    });\n\n    if (!session.url) {\n      throw new InternalServerErrorException({\n        message: \"Failed generating a Stripe checkout session URL.\",\n      });\n    }\n\n    return session;\n  }\n\n  async getStripeCustomerIdFromUserId(userId: number) {\n    const user = await this.usersRepository.findById(userId);\n\n    if (!user?.email) return null;\n    const customerId = await this.getStripeCustomerId(user);\n    if (!customerId) {\n      return this.createStripeCustomerId(user);\n    }\n\n    return customerId;\n  }","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/stripe/stripe.service.ts#L190-L226","documentation":"Thrown by StripeService.generateTeamCheckoutSession after stripe.checkout.sessions.create returns a session whose url is null/empty. Because a checkout session without a URL is unusable, the service throws 500 InternalServerError. This is a server-side failure, not a client input error - the cause is in the Stripe configuration or the session parameters.","triggerScenarios":"Creating a team checkout session where Stripe returns a session object but no url - typically because teamMonthlyPriceId is invalid/missing, the price is archived, the Stripe account cannot create sessions, or a region/currency restriction applies.","commonSituations":"The STRIPE_TEAM_MONTHLY_PRICE_ID (teamMonthlyPriceId) config points to a deleted/archived Stripe price. The Stripe account is restricted from creating Checkout sessions. A Stripe-side incident. The webhook/checkout feature is disabled on the account.","solutions":["Verify teamMonthlyPriceId is set to an active, non-archived Stripe price in the current environment.","Confirm in the Stripe dashboard that Checkout sessions can be created on the connected account.","Retry after fixing config; if it persists, capture the full Stripe session response in logs to see why url is null."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Validate the configured team price exists in Stripe before checkout.\nasync function teamPriceIsLive(stripe, priceId: string) {\n  const price = await stripe.prices.retrieve(priceId);\n  return price.active;\n}","typeGuard":"function hasCheckoutUrl(session: { url?: string | null }): session is { url: string } {\n  return typeof session.url === 'string' && session.url.length > 0;\n}","tryCatchPattern":"try {\n  const session = await stripeService.generateTeamCheckoutSession(teamId, ownerId);\n  return session;\n} catch (e) {\n  if (e.status === 500 && /checkout session URL/.test(e.message ?? '')) {\n    // alert ops: teamMonthlyPriceId likely invalid/archived; verify config\n    throw new OperationalError('Stripe checkout config issue');\n  }\n  throw e;\n}","preventionTips":["Verify teamMonthlyPriceId points to an active, non-archived Stripe price in each environment.","Add a startup check that retrieves the price from Stripe and fails fast if it is missing/inactive.","Alert on this 500 specifically - it indicates a config defect, not a user error."],"tags":["stripe","checkout","teams","api-v2","config","internal-error"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}