#nirav-rathod_api

1 messages ¡ Page 1 of 1 (latest)

junior rainBOT
#

👋 Welcome to your new thread!

⏲️ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.

⏱️ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.

🔗 This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1299238388146376774

📝 Have more to share? Add more details, code, screenshots, videos, etc. below.

Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.

sick zephyr
#

hello! Are you creating Express connected accounts?

surreal glacier
#

No standard

sick zephyr
surreal glacier
#

redirectToStripeForLogin: async (req, res, next) => {
try {
const loginLink =
"https://connect.stripe.com/oauth/authorize?response_type=code&client_id=ca_QwVFBW1IGvJSuGYfBxzk6CJMqfE7JrZS&scope=read_write";

  if (!loginLink) {
    return next(
      createError.InternalServerError("Error generating login link")
    );
  }
  // res.redirect(loginLink);
  res.status(200).send({
    success: true,
    message: {
      english: "Redirecting to Stripe login link",
     
    },
    data: loginLink,
  });
} catch (error) {
  next(error);
}

},

I am creating login link form Oauth Url

sick zephyr
#

okay, you'll want to make sure you use the correct terms since they all refer to entirely different flows and APIs

surreal glacier
#

If my user is coming agaoin then he will not again call the creae connected acoount api he only wants to login from that account.

sick zephyr
#

To provide some context, OAuth was the inital flow for connecting an existing and creating new Standard accounts to a platform. At that point in time, we allowed a Standard account to connect to many different platforms and any platform that was connected to that account could read and write all objects on the account (assuming if they requested for read_write access). This often led to issues, for example :

  • platforms may not want to allow other platforms to update objects created by them. However, there's no way to restrict this. Reporting payments (that are created by your app) on connected accounts (i.e. Direct Charges) is also more complicated since you would have to identify if the payment object was originally created by your app.
  • sometimes due to an integration issue on a platform's end, the connected account ends up getting rate limited and other platforms are also rate limited and are unable to make requests on that specific connected account

Subsequently, in 2021, Stripe introduced platform controls to address these concerns / issues : https://docs.stripe.com/connect/platform-controls-for-stripe-dashboard-accounts. To summarize, connected accounts that are controlled by your platform, cannot connect to another platform with read_write access. With only a single platform controlling the connected account, we are hence also able to introduce other features mentioned in the that link.

To ensure that a Standard connected account is controlled only by your platform account, it's best to follow the Connect Onboarding flow whereby you :

  1. Create an Account via the API
  2. Create an Account Link for the user to be onboarded

If you use OAuth, new accounts that are created via your OAuth link will be controlled by your plaform. However, existing accounts connected via OAuth will not be controlled by your platform. This can lead to different behaviour amongst the connected accounts and complicate your integration.

Manage more features on behalf of your connected accounts that use the Stripe Dashboard with platform controls.

surreal glacier
#

createConnectedAccount: async () => {
try {
const account = await stripe.accounts.create({
type: "standard",
});
if (!account) {
throw createError(500, "Error creating account");
}
const returnUrl = ${process.env.BACKEND_HOST}stripe/oauth-callback?accountId=${account.id};
const accountLink = await stripe.accountLinks.create({
account: account?.id,
refresh_url: "https://example.com/reauth",
return_url: returnUrl,
type: "account_onboarding",
});
if (!accountLink) {
throw createError(500, "Error creating account link");
}
const shopkeeper = await ShopkeeperModel.create({
stripeAccountId: account?.id,
stripeLoginLink: accountLink?.url,
});
if (!shopkeeper) {
throw createError(500, "Error creating shopkeeper");
}
return shopkeeper;
} catch (err) {
throw err;
}
},

this is my code for creating connected account this way I am creating the stripe standard connected account. so when I am logged in from this account. I have one button of create new business. cAN i HIDE THAT BUTTON?

sick zephyr
#

what do you mean by you have one button of create new business? where do you see that button? Can you share a screenshot?

surreal glacier
#

I have that button when I am creating login link and by redirecting to that login link.
I am talking anot this "create new account"

sick zephyr
#

no, you can't hide that button. Also you shouldn't be using both Account Links and OAuth to onboard / connect accounts. You should only use OAuth if you want to be able to connect existing accounts, OAuth itself will also allow creating a new account.

surreal glacier
sick zephyr
#

have you gone through the OAuth doc which I shared? https://docs.stripe.com/connect/oauth-reference - the doc mentions that to "Complete the connection and get the account ID", you need to do the below using your secret key in your server

const response = await stripe.oauth.token({
  grant_type: 'authorization_code',
  code: 'ac_123456789',
});

var connected_account_id = response.stripe_user_id;

Since you have the connected account id from ^, you can store that connected account id in your db

This reference lists available public methods for our OAuth endpoints for Connect.

surreal glacier
#

Where I will receive that account id

#

Sorry I got it.

#

handleStripeOAuthCallback: async (req, res, next) => {
try {
const { code } = req.query; // Retrieve the authorization code from the query parameters

  // Exchange authorization code for access token
  const response = await axios.post(
    "https://connect.stripe.com/oauth/token",
    new URLSearchParams({
      grant_type: "authorization_code",
      code,
      client_id: process.env.STRIPE_CLIENT_ID,
      client_secret: process.env.STRIPE_SECRET_KEY,
    }),
    {
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
      },
    }
  );

  const { access_token, stripe_user_id } = response.data;


  if (access_token) {
    try {
      // Retrieve details for the connected account
      const accountResponse = await axios.get(
        `https://api.stripe.com/v1/accounts/${stripe_user_id}`,
        {
          headers: {
            Authorization: `Bearer ${access_token}`,
          },
        }
      );
    

      const { id: accountId, email } = accountResponse.data;

      const shopkeeper = await ShopkeeperModel.findOne({
        stripeAccountId: accountId,
      });

      res.status(200).send({
        success: true,
        message: "Login successful",
        data: {
          loggedIn: true,
          access_token,
          accountId,
          email,
          shopkeeperId: shopkeeper?._id,
        },
      });
    } 
    }
  }
} catch (error) {
  next(error);
}

},

in this I want the shopkeeperId which is coming from my db so Now how I will manage this

sick zephyr
#

I don't understand the question, the shopkeeper id is something that you generate yourself right? Why are you having trouble getting / managing the shopkeeperId?

surreal glacier
#

I am using mongoDB so when am creating connected account I am creating one document in db In that I am getting my _id that is my shopkeeoerId.

sick zephyr
#

You should either use Account Links or OAuth, not both.

If you want to allow existing accounts to connect to you, then you should only use OAuth. OAuth also allows creating a new connected account. You do not create a new Account via the API with OAuth. When you get the account id back using OAuth, then you create your shopkeeper id and link it to the Account id.

surreal glacier
#

Then can you explain how can I create connected account from oauth url and how can i login from that account?

sick zephyr
#

the image you shared before which should be from the OAuth flow already shows a "Create a new account" button

#

what do you mean by how can i login from that account? - what's the specific problem you're facing?

surreal glacier
#

But when I am creating connected account by clicking create a new account, How can i store that in db

sick zephyr
#

you still get the account id back in stripe_user_id - what's the problem you're facing with storing this account id in the DB?

surreal glacier
#

handleStripeOAuthCallback: async (req, res, next) => {
try {
const { code } = req.query; // Retrieve the authorization code from the query parameters

  const response = await axios.post(
    "https://connect.stripe.com/oauth/token",
    new URLSearchParams({
      grant_type: "authorization_code",
      code,
      client_id: process.env.STRIPE_CLIENT_ID,
      client_secret: process.env.STRIPE_SECRET_KEY,
    }),
    {
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
      },
    }
  );

  const { access_token, stripe_user_id } = response.data;

  if (access_token) {
    try {
      const accountResponse = await axios.get(
        `https://api.stripe.com/v1/accounts/${stripe_user_id}`,
        {
          headers: {
            Authorization: `Bearer ${access_token}`,
          },
        }
      );

      const { id: accountId, email } = accountResponse.data;

      const shopkeeper = await ShopkeeperModel.findOne({
        stripeAccountId: accountId,
      });

      res.status(200).send({
        success: true,
        message: "Login successful",
        data: {
          loggedIn: true,
          access_token,
          accountId,
          email,
          shopkeeperId: shopkeeper?._id,
        },
      });
    } catch (err) {
    
      return res.status(500).send({
        success: false,
        message: "Error retrieving account details",
        error: err.response ? err.response.data : err.message,
      });
    }
  } 
} catch (error) {
  next(error);
}

},

here I am log in in response I am getting shopkeeper id. How can I create in db at ther same time when I am fetching it.

sick zephyr
#

Why would you create and fetch at the same time? If the Shopkeeper id doesn't exist at that point in time, then you should only be creating it.

surreal glacier
#

But in the above code response I want that shopkeeperid I have tio send it to frontend developer

sick zephyr
#

so after you create it, then you have the shopkeeper id to return in the response? I'm honestly not seeing the problem here.

surreal glacier
#

Can You please provide reference for this creating account if I have button for creating account then which api i have to call?

sick zephyr
#

If you are using OAuth, the user goes to the Stripe hosted page via the OAuth link you generate, which has the "Create a new account" button.

You don't need to create a new Stripe Account via the API. The new Stripe account is created automatically via the Stripe hosted page if the user clicks on the "Create a new account" button.

When the user finishes the form(s), and you complete the connection, you will get an account id back in stripe_user_id.

#

I suggest you try out using the "Create a new account" to see how it works

surreal glacier
#

So now no need to call this function right?
createConnectedAccount: async () => {
try {
const account = await stripe.accounts.create({
type: "standard",

  });
  if (!account) {
    throw createError(500, "Error creating account");
  }
  const returnUrl = `${process.env.BACKEND_HOST}stripe/oauth-callback?accountId=${account.id}`;
  const accountLink = await stripe.accountLinks.create({
    account: account?.id,
    refresh_url: "https://example.com/reauth",
    // return_url: "https://example.com/return",
    return_url: returnUrl,
    type: "account_onboarding",
  });
  if (!accountLink) {
    throw createError(500, "Error creating account link");
  }
  const shopkeeper = await ShopkeeperModel.create({
    // firstName,
    // lastName,
    // email,
    stripeAccountId: account?.id,
    stripeLoginLink: accountLink?.url,
  });
  if (!shopkeeper) {
    throw createError(500, "Error creating shopkeeper");
  }
  return shopkeeper;
} catch (err) {
  throw err;
}

},

sick zephyr
#

that's correct, you don't need that entire section of code you just pasted. However, please always test it out to make sure things work as expected

surreal glacier
#

Okay. Can you please just share me docs or code format which will help me in storing that data in my db

sick zephyr
#

I'm not sure what you mean, you don't use Stripe's API to write to your db, that's not something we can help with

surreal glacier
#

No. Please help me with stripe api which I have to call.

sick zephyr
#

call to do what specifically?

#

all you said was to help (you) in storing that data in (your) db - which as I've mentioned, you wouldn't use Stripe API to write to your db