Stripe Product Integration
I have set up all the stripe variables into .env.server but I still dont know how OpenSaaS pulls the products so the user can purchase a subscription.
What is the process for a user to purchase a Stripe product and then getting it assigned to them?
15 Replies
Hi @alphadog2584. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
The process for a user to purchase a Stripe product (such as a subscription) in OpenSaaS (built with Wasp) generally works as follows:
1. Stripe Product Setup: You create products and prices in your Stripe dashboard. The relevant price IDs (e.g.,
SUBSCRIPTION_PRICE_ID
, PRO_SUBSCRIPTION_PRICE_ID
, or CREDITS_PRICE_ID
) are then added to your .env.server
file so the backend knows which Stripe products to use.
2. Initiating Checkout: When a user wants to purchase a subscription, the app triggers a backend action (typically in actions.ts
) that creates a Stripe Checkout Session. The code uses the price ID from the environment variables to specify which product the user is buying. For example:
This session is then used to redirect the user to Stripe's hosted checkout page, where they complete the payment. The price
field determines which Stripe product is being purchased, and you can have multiple price IDs for different subscription tiers or products by referencing different environment variables in your code. If you want to support multiple products, you need to adjust the backend logic to select the correct price ID based on the user's choice see example discussion.
3. Webhook Handling: After payment, Stripe sends webhook events (like checkout.session.completed
or customer.subscription.updated
) to your server. The webhook handler (often in stripe.ts
) listens for these events and updates the user's record in your database. For example, when a subscription is purchased, the webhook updates the user's subscriptionStatus
and possibly other fields like hasPaid
or subscriptionTier
see discussion.
4. Assigning the Product to the User: The webhook handler uses the Stripe customer ID to find the corresponding user in your database and updates their status. For example, it might set user.subscriptionStatus = 'active'
when a payment succeeds. If you are selling credits instead of subscriptions, you can increment the user's credits in the webhook handler when the relevant product is purchased see code example.
5. Client-Side Access: The frontend checks the user's subscription status (e.g., subscriptionStatus === 'active'
) to determine access to premium features. This status is updated after the webhook processes the Stripe event and updates the database.
Key Points:
- The Stripe product is not "pulled" dynamically; instead, the app uses the price IDs you configure in your environment variables.
- The backend logic determines which product to use based on user actions and the configured price IDs.
- Webhooks are essential for updating the user's status after payment.
If you want to support multiple products or subscription tiers, you need to extend the backend logic to handle different price IDs and update the user accordingly. If you have issues with products not updating or only one price being used, ensure your backend code is referencing the correct price ID for each product and that your webhook handler is set up to process the relevant events see troubleshooting discussion.
If you need to see specific code examples, you can check the OpenSaaS repository, especially the webhook handler and actions related to Stripe integration see code reference.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
Sorry @alphadog2584, 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?Hey @alphadog2584 did the bot answer your question? It did a pretty good job of summarizing how it works. All the code is in the
src/payment/stripe
directory and the integration guide is in the docs.
Let me know if you have more Questions.OpenSaaS.sh
Payments Integration
Open SaaS is a free, open-source, full-stack SaaS starter kit for React + NodeJS.
It did though I was hoping OpenSaaS would pull the products from Stripe.
Wohooo @alphadog2584, you just became a Waspeteer level 1!
What do you mean?
It references the product by its
priceId
. You have to put the info about your product on your pricing page and the product info on stripe will be displayed on the checkout page.
There might be a way to get this product info that you added to your stripe dashboard via their API. have you checked the stripe docs?I havent got that far down the line, I am still building the SaaS functionality
I wish there was a script that would easily remove the demo functions. I have been struggling with it for the last hour.
I remove too much, then roll back then hit walls: like what is MessageButton for?
https://docs.stripe.com/api/products/object
will give you the products, description, images, etc from the stripe dashboard
The Product object | Stripe API Reference
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
Thank you, I will look into it
That's an placeholder for the admin dashboard that's not hooked up yet.
At least, something in the doco to say what to remove
but its there for you to use in the Admin Dashboard if you want. Apart from some things that aren't hooked up in the Admin Dash, everything else is functonal
Maybe I should have stated, I am using OpenSaaS. I have commented out and now have an error:
[plugin:vite:import-analysis] Failed to resolve import "../../../../src/messages/MessagesPage" from "src/router.tsx". Does the file exist?
https://docs.opensaas.sh/start/guided-tour/#:~:text=Remove%20any%20features%20you%20might%20not%20use%20or%20need%3A
you can remove any feature you want by removing the feature directory in
app/src
, for example remove app/src/file-upload
dir and then remove the file upload definitions from the wasp config file entity File, route FileUploadRoute, action createFile, query getAllFilesByUser, getDownloadFileSignedURL
you need to remove the MessagesPage definition from the wasp config file, main.wasp
.I believe there a few other things to change, I will make a list and then pass it along so you can put it in the doco
thatd be great thanks