Netlify Identity for paid subscriptions

I want to limit certain functionality on my website to paying users.

Now I’m using a payment provider (Mollie) similar to Stripe.

My idea was to use the webhook fired by this service to call a Netlify function and give the paying user a role (something like “pro” or “subscriber”).

But I’m not sure how I can connect the payment result to a user in Identity. I can pass metadata to the payment, like the user ID, or maybe even an auth token?

Is this possible, or even recommended? I’m not sure about the security implications. Any experience with this?

Thanks!

It’s possible. You might have to change up your signup flow though. You can create a Netlify function called identity-signup.js and it will run automatically every time a user signs up via Netlify Identity. So, the ideal flow would be that a user enters their payment information via Mollie (or however your current payment flow is) and then you store that data wherever you need to. Then, after there has been a successful payment, take them to a user creation flow via Netlify Identity. Once they’ve signed up, it will run the identity-signup.js function and you can set a role for that user by returning a response in the function like so:

    const responseBody = {
        app_metadata: {
            authorization: { roles: ["admin", "editor", "whatever_role_you_want"] }
        },
    };

    return {
        statusCode: 200,
        body: JSON.stringify(responseBody),
    };

In the end, you will have a user that has made a successful payment and has the role set in Netlify Identity. Next, you’ll just set your access control configs in your _redirects or netlify.toml file like so: /admin/* 200! Role=admin,editor

1 Like

@parkeragee Thanks for the reply!

That sounds like an interesting approach, however for me there are 2 issues with it:

  1. I also want to have a free tier for users.
  2. I’d like to do it without having any external backend/storage (outside of Netlify and Mollie).

Where 2 I realize is a severe constraint.

If it’s not possible to edit the role of a user outside of an event-triggered function I think I’ll have to go look into an external database!

Hi,

That’s a good idea @parkeragee. @RobertBroersma, as an extension of Parker’s suggestion, you can have users signup for free and add custom data to the app_metadata via netlify functions later when they successfully make a purchase. You can update a user’s metadata in functions by doing something like this:

    import fetch from "node-fetch";

    exports.handler = async (event, context) => {
    const { identity, user } = context.clientContext;
    // you need to pass in the user ID, which you can do by passing in the users jwt
    // or by just adding it as a parameter to your request.
    // Another way is to make a request to search for the user by e-mail but that's slower
    // const userID = 
    const usersUrl = `${identity.url}/admin/users/${userID}`;
    const adminAuthHeader = "Bearer " + identity.token;

    const attributes = {
    app_metadata: {
    roles: ['test', 'user', 'member'],
    my_user_info: "this is user info that the user can't change from the UI",
    },
};

    try {
        return fetch(usersUrl, {
        method: "PUT",
        headers: { Authorization: adminAuthHeader },
        body: JSON.stringify(attributes)
        })
        .then(response => {
            return response.json();
        })
        .then(data => {
            console.log("Updated the user");
            console.log(JSON.stringify({ data }));
            return { statusCode: 204 };
        })
        .catch(e => {...};
        });
    } catch (e) {
        return e;
    }
    };

Note that I haven’t actually tested that function, but it should do what you want it to do.

1 Like

Thanks @futuregerald, that seems like exactly what I need! I’ll give it a spin.