Subscription Based Web App Template

@Antti_Neonto @juha_neonto - once I get that account thing finally worked out and the stripe payment gateway into a plugin, I will have the third thing I am working on in React Studio done which is a template for “subscription based web apps”. Essentially a landing page and an authenticated dashboard with monetization capabilities.

I have identified a number of things that I use over and over and they also happen to be the things that hold me back a bit from getting my app to the place I want it to be. I will post it here for download once I am finished and you are welcome to make it available it you think that would be valuable.

This one will be for Firebase but I can also think about one that includes the new Xano backend. I suppose I would also be willing to create a video of how to configure it similar to how you did with the chat app. Those videos were what really helped me learn the ropes in addition to the community / medium posts.

@Antti_Neonto - maybe you can see why I am wanting that data slot value between login and the rest of the downstream screens so bad. It’s one of two really critical points in the template. The other is the gateway to capture payment (Stripe). Now Stripe takes some pretty high fees but their ease of use makes up for that until you have enough momentum to get something more custom built by an engineer who does web development full time (something custom of course). Ideally you would want to replace it down the road (I think stripe is like 30% of something crazy like that).

Essentially it will be a template with the following components built out:

  • Landing Page (login and sign up buttons & spot for logo top left)
  • Firebase auth (communicating with user_account table that also brings back some context such as “isSubscribed”)
  • Responsive footer (for all screen sizes)
  • Create Account Page
  • Update Account Page
  • Subscribe to Service Page (with button to trigger a stripe payment gateway)
  • Post login drawer menu with logout button
  • Dashboard landing page (empty)
  • Support landing page (empty)
  • 404 Error Page
  • Logout
  • All needed events being logged into Firebase for analytics purposes

I’m following this thread and sounds very interesting! I did something similar, including integrating Firestore Stripe extension and some custom scripting. In the Catalyzer case, there’s was a lot of logic to consider. Wondering how can we collaborate. Best, Marcos
Check it out here. https://catalyzer.app

1 Like

Hey really nice app! Awesome work. It would be great to collaborate.

The main app I am working on is this one - https://digitaliqstudio.com/ - trying to get it to a v3. I have a full redesign already done but working through some engineering challenges before it will work right and I can release it.

I don’t want to have to keep adding in the Stripe code after I export code to react so getting a Stripe plugin done is one of my top priorities. It’s a really simple code block but I am just now starting to get comfortable with these plugins so will take me a bit to get it done. I really want to learn this part of React Studio though so it will be good to do AND document here so there is some help for the community.

The second part is being able to query data and perform logic between screens. I think I almost have this solved with @juha_neonto over on the other thread.

I will throw this template up on my github tonight and you can check it out. I am definitely in for you helping push it to a better place if you want to help develop it with me.

1 Like

I am also paying attention to this new plugin asI would love to be able to add a way to manage subscription. I have a Firestore database with a users collection and I am excited to see this plugin released.

Does this stripe allow PayPal payments?

Anyone can download the current version here for now - but it is NOT fully done yet. It does not have a stripe integration or the login feature completed yet. Please let me know if anyone has trouble downloading this.

As for how you can currently use stripe, here is what I am doing. Note - this is for a “one time payment” and not a subscription payment. Still working on that one.

  1. Go create your stripe account and get it activated (this can be a pain FYI)
  2. Make sure you have a “success” and "“cancel” url ready in your app
  3. Grab your live key and the price id from the item you setup in your strip account
  4. Update the below code with your details
  5. Place a button in anywhere in your app and just hook it to the screen you want it to go if it is successful.
  6. Export your app to react code
  7. Add stripe SDK to index.html file
  8. Dig into code and find the spot where your button is triggered (the file should be the component name from within React studio that the button is sitting within followed by .js)
  9. Past your updated code below as the code that runs when that button is hit.

Now when you hit that button, it will launch a stripe payment gateway will then route you to the next place based upon if it was success or not.

If it was successful, you will see the payment come through in your stripe account (minus the fees) which is then deposited into your bank account.

var stripe = window.Stripe(“pk_live_xxxxxxxxxxxxxxxx”);
   stripe.redirectToCheckout({
       mode: 'payment',
       lineItems: [{ price: "price_1xxxxxxxxxxxxxxxxxxx", quantity: 1 }],
       successUrl: "https://example.com/success",
       cancelUrl: "https://example.com/cancel",
   }); 

Thank you Jim. I have finished the Stripe integration which you don’t have to add any code after RS export. Is right there in the check-out button. To do so, you need install the extension and the blaze plan as well. Later I’ll try to share how to do so. There’s some important improvements I need to do for Catalyzer. The data visualization dashboard, which I’m using Chartjs could be much better. Also I’m looking for some easy html tiny editor simple for the text-area input. Something that could turn easy for users write large texts, which is the case when posting online challenges.

Best, Marcos

@Marcos_Alencar that’s awesome! Please post. I will try it out for sure.

I finally got the post login issue worked out with the firebase plugin. I will post a new version later with it updated.

Hi Jim, sorry being late. I being busy trying to fix some cross-browser inconsistency issues occurred during a 20 people test.

Consider reading how Firestore extension works. This extension runs the Subscription Payments with Stripe. You will need to configure your extension through the Firebase console.

React Studio:
1.


2.
When you set up your products, Stripe extension will create the produtc, and price collection. After that you are good to go.
When the user subscribes, Stripe extension will write the subscription, price and collection for that user and updating the status.

Script for checkout.
first I have the button states. [START FREE]
var PRICE_ID = this.props.document_key
if (PRICE_ID === ‘price_FreePlan’){return 0}
else if (PRICE_ID === ‘price_key1’){return 1}
else if (PRICE_ID === ‘rice_key2’){return 2}
else if (PRICE_ID === ‘rice_key3’){return 3}
else if (PRICE_ID === ‘rice_key4’){return 4}
else if (PRICE_ID === ‘’ || PRICE_ID === undefined || PRICE_ID === null){return 5}
else {return 6}
console.log(‘PRICE_ID’, PRICE_ID)

//

Then for each button modifying your price key.
Each time the user clicks on a button, it creates the checkout_sessions collection. From there, Stripe gets the data to proceed.

//
var customerEmail = this.props.appActions.dataSlots[‘ds_SlotUserEmail’]
const PUBLISHABLE_KEY = ‘pk_live_yourkey’;
var DOMAIN = window.location.origin;
var customerID = this.props.appActions.dataSlots[‘ds_SlotUserID’]
var userName = this.props.appActions.dataSlots[‘ds_SlotUserName’]
var SUBSCRIPTION_BASIC_PRICE_ID = “price_yourkey”;
var currentUser = customerID
const stripe = Stripe(PUBLISHABLE_KEY);
const customer = this.props.appActions.dataSlots[‘ds_SlotstripeId’]

const db = firebase.firestore();

           var redirectToCheckout = async function (priceId) {
            
             const docRef = await db
             .collection('users')
             .doc(currentUser)
             .collection('checkout_sessions')
             .add({
                     price: priceId,
               		 tax_rates: ['txr_yourtaxerate'],
                     success_url: window.location.origin + "/success",
                     cancel_url: window.location.origin + "/chooseplan",
                     metadata: {
                         plan: priceId,
                         },
               mode: 'subscription',
               trial_from_plan: true,
                 });
                 // Wait for the CheckoutSession to get attached by the extension
             docRef.onSnapshot((snap) => {
             const { error, sessionId } = snap.data();
             if (error) {
                 // Show an error to your customer and 
                 // inspect your Cloud Function logs in the Firebase console.
                 console.log(`An error occured: ${error.message}`);
             }
             if (sessionId) {
                 // We have a session, let's redirect to Checkout
                 // Init Stripe
                 const stripe = window.Stripe('pk_live_yourkey');
                 stripe.redirectToCheckout({ sessionId });
             }
             });
         }
redirectToCheckout(SUBSCRIPTION_BASIC_PRICE_ID)

//

What else?.. oh yeap.

How the user manage, cancel or update.
In my case I have a “price_FreePlan” prebuilt plan with the same collections, and sub-collections of Stripe structure, but not integrated with any Stripe plan.

let UserRole = this.props.appActions.dataSlots[‘ds_SlotUserRole’]
let RoleAccount = this.props.appActions.dataSlots[‘ds_SlotuserRoleAccount’]

if(RoleAccount === ‘price_FreePlan’){
return 1
} else {
return 0
}

0
//
const db = firebase.firestore();

const stripe = require(‘stripe’)('sk_liveYOURKEY);
const customer = this.props.appActions.dataSlots[‘ds_SlotstripeId’]

var createPortalLink = async function () {
const functionRef = firebase
.app()
.functions(‘us-central1’)
.httpsCallable(‘ext-firestore-stripe-subscriptions-createPortalLink’);
const { data } = await functionRef({ returnUrl: window.location.origin + “/profile”});
window.location.assign(data.url);
}

createPortalLink()
//

1
a simple link tho chooseplan screen

//

That’s it.

Have fun :slight_smile:

1 Like

Excellent! Thank you very much. I will dig in and integrate it into the template. I still need to post an updated version with the new post login stuff. I will soon.

1 Like

Thank you so much! I really believe it goes beyond my skill but I will try to make it when I feel with enough courage.

1 Like

I’ve got the extension configured in Firebase and my products setup in Stripe. I’m working on client side work now but it is a bit complicated. These are some other resources I have found that were helpful - https://github.com/stripe-samples/firebase-subscription-payments

@Marcos_Alencar when does the stripe role get saved in your user account table? Is it right after “successful” subscribe event?

How fast does all this take place by the way? The sync for you that is.

Also - how do you handle new users that sign up? The Stripe role field would not show up in the user account until after they have subscribed it looks like.

Hi Jim. Yes, right after the subscription event, stripe will write the collection very fast.
Regarding your last question, I need to figure out how to show this.

Ok I have gotten a little further. When you login to google it will sync a couple items from stripe right away. They still don’t put in a value for the subscription status. I’m wondering if you go ahead and create a default value in there after first login or something like that. That’s pretty nice they go ahead and create a customer record for you like that. Need to do some testing on how fast it gets done so I can make a decision off of it. Still interested in how you handle the subscription status.

1 Like

You don’t have the subscription status value yet. It will be written after the user signs a subscription plan. as a sub-collection inside the user collection.
In my case, after signing in with Google or Facebook, the user will find the button [Choose plan/ Create], depending on if it has a plan. Here’s where it all starts, I mean, in the Catalyzer’s case, creating a new workspace or choosing a plan if you don’t’ have one.
Here we will check, using a two-states button for the value active or trialing. If not go to 0.

var status = this.props.appActions.dataSlots[‘ds_Slotsubscriptions’];
if (status === ‘active’ || status === ‘trialing’){
return 1
} else {
return 0
}

1 Like

Ok this makes sense and is helpful. Let me dig in and then will send an update. Thanks!

@Marcos_Alencar how are you importing the Stripe module into React Studio? When I put anything with “Stripe()” in my code it says it doesn’t recognize it and throws an error.

Yes, sure. First install stripe. npm install --save stripe

import Stripe from ‘stripe’;

merry christmas :slight_smile:

1 Like

Ok I should have known that. Thanks for the reminder haha.

By the way - I’m not sure if you are using an older version of Stripe but the Firebase docs call for a bit of a different approach it seems.

I can now get the stripe checkout gateway window to launch but it fails right after. Any thoughts?

I first installed this:
npm install @stripe/stripe-js