How to allow MemberStack users to upgrade from free to paid plans when the initial upgrade flow fails? Answered

Post author
Lakshman Mody

My site needs to support free and paid users. There is an edge state in which a user can sign up, but if they don't subscribe to the paid plan during the sign up process, they can't ever update to a paid plan. I THINK the solution is to create a free plan as well, add it by default on sign up, and then add a button with "data-ms-action="customer-portal" to allow free users to upgrade to the pro plan. Does that sound right?

Comments

9 comments

  • Comment author
    Josh Lopez

    Hey Lakshman Mody Check these data attributes out https://docs.memberstack.com/hc/en-us/articles/7252466484635-All-Webflow-Package-Data-Attributes#subheading7
    You are able to use data-ms-content="no-plans" to show a div that would have a button to upgrade to a paid plan.

    0
  • Comment author
    Jon Chan

    Would anyone be able to help me out with allowing a user to change their plan from a free one to a paid one?

    For example, a user is logged in and has the option to click a button to change and purchase to a paid plan.

    I have a button with the custom attribute data-ms-price:update="my_Price_id"

    When I click on it, nothing happens.
    If anyone has any suggestions I would greatly appreciate it!

    0
  • Comment author
    A J

    Hey Jon Chan, have you tried out data-ms-price:add attribute with your price ID instead? If yes, can you share what happens when user clicks on that button?

    0
  • Comment author
    Duncan from Memberstack

    Hey Jon 👋 If a logged-in member clicks on a button with data-ms-price:update="my_Price_id" then it will launch the checkout.

    If a logged out user clicks on the same button, then nothing will happen. I recommend adding a link to your sign up page, so that new members can click the button to select the plan, create an account, and then the checkout will automatically appear.

    0
  • Comment author
    Jon Chan

    Nothing happens when I click on the button. Essentially the way I have it setup right now is that. When a user selects the 'Regular Member' they have to be approved to in order to purchase that membership. When a user signs up for a 'Regular Member' I assign them to a free plan called 'Pending Regular'. Through a Xano and a couple other things. When the member is approved by an admin, the member can log into their account and they will be able to change/purchase from 'Pending Regular' to 'Regular Member' by clicking the purchase button (refer to images attached)

    link to the page - https://asga-beta.webflow.io/login

    <a id="purchase" href="#" class="w-button" data-ms-price:update="prc_level-1-member-y0a90fta" style="display: block;">Button Text</a>
    0
  • Comment author
    Duncan from Memberstack

    That's super strange! https://www.loom.com/share/1219100a2362484da87cda66d89941a2

    0
  • Comment author
    Jon Chan

    Duncan Hamra Hmm unfortunately having the button present on page load does not resolve the issue. Could it be because the user does not have a StripeID? This is my code currently:

    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@xano/js-sdk@latest/dist/xano.min.js"></script>
    <script type="text/javascript">
    var xano = new XanoClient({
    'apiGroupBaseUrl': 'https://x8ki-letl-twmt.n7.xano.io/api:39fUdv_Q'
    });

    function getMemberId() {
    return
    window.$memberstackDom.getCurrentMember().then(({ data: member }) => {
    return member ? member.id : null;
    });
    }

    async function checkApplication() {
    try {
    const memberId = await getMemberId();

    if (!memberId) {
    console.error('Member is not logged in or there is no member ID.');
    return;
    }

    // Make API call with member ID as a parameter const response = await
    xano.get(`/application_check?MS_id=${memberId}`);

    // Access mem_check through response.body const data = response.body;

    if (data.mem_check) {
    const { member_plans_id, member_status } = data.mem_check;
    const planId = data.plan_id.plan_id;

    // Log the member_plans_id to the console console.log('Member Plan ID:', member_plans_id);

    // Handle application status based on the member_status from the API response
    switch (member_status) {
    case 1:
    // Redirect to pending page
    window.location.href = '/member/pending';
    break;
    case 2:
    // Application Under Review
    document.getElementById('title').innerText = 'Application Under Review'; document.getElementById('text').innerText = 'Your application is pending review'; document.getElementById('text').style.display = 'block';

    //document.getElementById('purchase').style.display = 'none'; break;
    case 3:
    // Purchase Membership document.getElementById('title').innerText = 'Purchase Membership'; document.getElementById('text').style.display = 'block';

    // Set the data-ms-price:update attribute for the purchase button based on planId without affecting other attributes
    const purchaseButton =
    document.getElementById('purchase');
    purchaseButton.setAttribute('data-ms-price:update', planId);
    break;
    case 4:
    // Redirect to Dashboard
    window.location.href = '/member/dashboard';
    break;
    default:
    console.error('Unexpected member_status:', member_status);
    }
    } else {
    console.error('mem_check object is not available in the API response.');
    }
    } catch (error) {
    console.error('Error fetching application check:', error);
    }
    }

    window.onload = function() {
    // Check application status on page load checkApplication();
    };

    </script>
    0
  • Comment author
    A J

    Hey Jon Chan, +1 to what Duncan said, now although the button does appear on load, checking your code I believe the actual price attribute is added dynamically after memberstack loads and hence maybe it is missing to locate this button. Since you have set the attribute in a static way for the logout button, MS updates the functionality on page load correctly.

    One workaround could be that while you are assigning the attribute dynamically, you could make use of functions like purchasePlansWithCheckout if the user who lands on this page is not gonna have any paid plans until that point and is freshly purchasing a paid plan. You could have the code listen to the 'purchase membership' button click and launch the checkout experience via that function. Here's the documentation for that function and an example guide where this was used to solve a different use-case.

    0
  • Comment author
    Jon Chan

    Thanks Duncan Hamra and A J for looking into this issue for me. It's a bit crude, but I now have the button dynamically change the href according to the api response and redirects users to a page with the button with the attribute already set to the priceID. Having the button with the static attribute allows me to click on the button then proceed to checkout. Thanks again!

    0

Please sign in to leave a comment.