Arguments in fetchCustomerPortalUrl

I'm implementing subscriptions in my wasp app and need to implement the ability to manage the users subscription via stripe Looking at the open saas code, I can see the follow function being called to get the url:
fetchCustomerPortalUrl: async (args: FetchCustomerPortalUrlArgs) =>
requireNodeEnvVar('STRIPE_CUSTOMER_PORTAL_URL')
fetchCustomerPortalUrl: async (args: FetchCustomerPortalUrlArgs) =>
requireNodeEnvVar('STRIPE_CUSTOMER_PORTAL_URL')
Which is called by this operation function
export const getCustomerPortalUrl: GetCustomerPortalUrl<void, string | null> = async (_args, context) => {
if (!context.user) {
throw new HttpError(401);
}
return paymentProcessor.fetchCustomerPortalUrl({
userId: context.user.id,
prismaUserDelegate: context.entities.User,
});
};
export const getCustomerPortalUrl: GetCustomerPortalUrl<void, string | null> = async (_args, context) => {
if (!context.user) {
throw new HttpError(401);
}
return paymentProcessor.fetchCustomerPortalUrl({
userId: context.user.id,
prismaUserDelegate: context.entities.User,
});
};
My question is - why is it called with these context arguments if they aren't used - can't I just attached the customer portal url to a variable?
12 Replies
kapa.ai
kapa.ai4mo ago
Hi @CamBlackwood. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Looking at your code example, I can see why you're confused about the arguments being passed to fetchCustomerPortalUrl. The function you're showing appears to be from the OpenSaaS template, where fetchCustomerPortalUrl is being called with specific arguments (userId and prismaUserDelegate) even though the implementation you've shown simply returns an environment variable without using those arguments. This is likely a design pattern that allows for flexibility in implementation. While the simple implementation you've shown doesn't use the arguments, they're provided so that: 1. You could modify the implementation to use them if needed (for example, to fetch user-specific data from the database) 2. It maintains a consistent interface with other payment processor functions that might need these arguments In Wasp, operations (queries and actions) receive a context object that's automatically injected by Wasp. This context contains useful information like the current user and entity access. When implementing operations, you need to pass relevant parts of this context to any helper functions that might need them, even if the current implementation doesn't use them. As documented in the Wasp docs:
context (type depends on the Query) - An additional context object passed into the Query by Wasp. This object contains user session information, as well as information about entities. Data Model Operations: Queries
So to answer your question - yes, you could simplify this if you're certain you'll never need the user information or database access in your implementation. You could just return the URL directly from your operation function:
export const getCustomerPortalUrl: GetCustomerPortalUrl<void, string | null> = async (_args, context) => {
if (!context.user) {
throw new HttpError(401);
}
return requireNodeEnvVar('STRIPE_CUSTOMER_PORTAL_URL');
};
export const getCustomerPortalUrl: GetCustomerPortalUrl<void, string | null> = async (_args, context) => {
if (!context.user) {
throw new HttpError(401);
}
return requireNodeEnvVar('STRIPE_CUSTOMER_PORTAL_URL');
};
However, the pattern used in the OpenSaaS template provides more flexibility for future changes and maintains consistency with other payment processor functions that might need those arguments. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @CamBlackwood, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
CamBlackwood
CamBlackwoodOP4mo ago
@kapa.ai ok thanks - so the way it works is that the customer gets a generic link to stripe, and then logs in with their credentials from there via a one time link - so I'm ok to just attach it to a variable, or even just have it in an anchor link in the code, as it isn't really a sensitive url in this case?
kapa.ai
kapa.ai4mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the information in the knowledge sources, I need to clarify something important about Stripe customer portal links and environment variables. The Stripe customer portal link is typically stored as an environment variable (like STRIPE_CUSTOMER_PORTAL_LINK or STRIPE_CUSTOMER_PORTAL_URL). This appears to be a standard practice in Wasp applications that use Stripe, as seen in the OpenSaaS template. While the URL itself might not contain sensitive information, there are good reasons to store it as an environment variable rather than hardcoding it: 1. Environment variables allow you to have different values for different environments (development vs. production) 2. It follows the best practice of keeping configuration separate from code 3. It makes it easier to update the URL without changing code From the Discord conversations, we can see that missing this environment variable can cause build errors:
[Db] ⛔️ STRIPE_CUSTOMER_PORTAL_LINK is not defined
[Db] ⛔️ STRIPE_CUSTOMER_PORTAL_LINK is not defined
For server-side environment variables in Wasp, you would define them in your .env file during development, and then in production, you would set them according to your deployment platform. For example, on Fly.io, you would use:
flyctl secrets set STRIPE_CUSTOMER_PORTAL_URL=your_url_here
flyctl secrets set STRIPE_CUSTOMER_PORTAL_URL=your_url_here
So while the URL itself might not be highly sensitive, following the pattern of using environment variables is still recommended for maintainability and flexibility. Is there a specific reason you're considering hardcoding this URL instead of using the environment variable approach? ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @CamBlackwood, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
CamBlackwood
CamBlackwoodOP4mo ago
@kapa.ai very true, thank you as always my virtual friend
kapa.ai
kapa.ai4mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- You're welcome! I'm glad I could help clarify the best practices for handling environment variables in your Wasp application. Using environment variables for configuration like the Stripe customer portal URL will definitely make your application more maintainable and flexible in the long run. If you have any other questions about Wasp, environment variables, or implementing Stripe integration in your application, feel free to ask anytime! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @CamBlackwood, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
WWWillems
WWWillems4mo ago
There’s a simple & better (imo) way to do this @CamBlackwood, using a link that auto logs in the user to their Stripe customer portal.
MEE6
MEE64mo ago
Wohooo @WWWillems, you just became a Waspeteer level 6!
WWWillems
WWWillems4mo ago
Not at computer rn, will send you the snippet later, its only a few lines of code Biggest benefit is user doesnt need to know/remember which email they used to pay for the subscription (can be diff than email they used to sign up to your product)
Filip
Filip4mo ago
Hey @CamBlackwood, from what I understood, I think Kappa gave the correct answer to the question. @WWWillems Thanks for jumping in! Please do send the snippet. If it's an obvious improvement over the current OpenSaas code, we could add it there
WWWillems
WWWillems4mo ago
It's literally just making a Wasp query that fetches the (logged in) billing portal session url from Stripe:
import { stripe } from "./../stripeClient.js";

const session = await stripe.billingPortal.sessions.create({
customer: STRIPE_CUSTOMER_ID_HERE,
return_url: "https://your.app.com",
});
import { stripe } from "./../stripeClient.js";

const session = await stripe.billingPortal.sessions.create({
customer: STRIPE_CUSTOMER_ID_HERE,
return_url: "https://your.app.com",
});
Filip
Filip4mo ago
Yeah, this is great. Thanks! @CamBlackwood Check it out and see if it works for you 🙂
CamBlackwood
CamBlackwoodOP4mo ago
will do! Thanks for sharing @WWWillems 🙂

Did you find this page helpful?