Stripe not allowing updating of connected account due to permissions? - node.js

I'm attempting to create a new external bank account on a stripe connected account like so:
await stripe.accounts.createExternalAccount(existingAccount.id, {
default_for_currency: true,
external_account: {
routing_number: bsb,
account_number: accountNumber,
account_holder_name: accountName,
country: 'AU',
currency: 'AUD',
object: 'bank_account',
account_holder_type: 'individual'
}
})
Where existingAccount.id is the id of the connected account.
This creates the error:
This application does not have the required permissions for this endpoint on account 'acct_[Account ID].
The connected account is an express account, when first created I give it a bank account and want the connected account user to be able to change/update it from within the app.
I'm not sure why this is creating permission issues and can't find any setings around permissions, the key I used to create the account is the same one I'm using to add a new external account to the created account.

You're receiving that error because you cannot create an external account for Express accounts. For context, Express accounts are expected to manage their own bank accounts from their Stripe Express Dashboard.

Related

This application does not have the required permissions for this endpoint on account

I am using stripe implementation with Node JS by following this API. I am able to create connect and account but I can't add external bank account for the connected stripe account. I am using Test account credentials. Connected account acct_1KCRy1PszwCMk9PS is enabled. I can't add external account to the connected account from stripe console also. The error says,
This application does not have the required permissions for this
endpoint on account 'acct_1KCRy1PszwCMk9PS'.
Code:
let accountNumber = '000999999991' //https://stripe.com/docs/connect/testing
let name = 'testanme'
let object = "bank_account"
let country = "US"
let currency = "USD"
let stripeAccountNumber = 'acct_1KCRy1PszwCMk9PS'
await stripe.accounts.createExternalAccount(
stripeAccountNumber,
{
external_account: {
object:object,
country:country,
currency: currency,
account_holder_name:name,
account_number:accountNumber
},
}
).then(
function(result) {
console.log(result)
},
function(err){
console.log(err.message)
}
);
Could you please help me to find out what is the problem? Thanking you.
This account is likely Standard account, where the external accounts used for payouts are managed by Stripe and are not controlled by your platform.
If you want to have full control over an account experience, you might want to consider Customer accounts, where this is reversed and you are responsible for collecting external account details.
Either you use Standard API secret key or else you can create Restricted keys with below permissions
helper url https://dashboard.stripe.com/test/apikeys

Angular/node.js Stripe Checkout Integration (1 account to facilitate payments from third party payer to third party receiver)

Man, I have been at this for some days and can't find a good solution to this. I want to use my account (via public key and private key) to facilitate payments from one account to another (nothing will be going into my account). On the front-end I have:
checkout(amount) {
const strikeCheckout = (<any>window).StripeCheckout.configure({
key: environment.PRODUCTION==='true'?stripeLiveClientId:stripeTestClientId,
locale: 'auto',
token: (stripeToken: any) => {
if(stripeToken){
console.log(stripeToken)
this.createCharge(stripeToken,amount)
}
}
});
strikeCheckout.open({
name: 'Camel Stripe',
description: 'Stripe Checkout',
amount: amount
});
}
Just a small snipet, but essentially this just captures the credit card and email and ensures it is a valid credit card and then makes a stripe token. I then pass this token to the node backend and do:
stripe.paymentIntents.create({
amount: priceInPence,
currency: 'usd',
source: stripeTokenId,
capture: false, // note that capture: false
}).then(charge => {
return res.json({ success: true, message: 'Success', result: charge })
}).catch(error => {
res.status(400).json({ success: false, status: 400, message: error });
});
//})
};
No matter how I structure it, it always end's up getting the payment to my account, the account with the public/private key. Does anyone know a way I can use this token since it has the necessary information, and send the money to another account?
You can't accept payments and move the funds into a completely different Stripe account unless you're using Connect.
To piggy back on Paul's comment, after much research on Stripe Connect I wanted to share my findings. Please note this is specific to my use case and is using angular/express.
Connect offers multi-party payments, meaning you can receive funds from 1 user, then route them into another users account. You will need a stripe connect account. After that you connect an account, aka create account. They offer 3 account types all these account types need to be
Custom: basically is if you don't want the account you're routing to to see anything stripe related, meaning it is white labeled and the user has no dashboard or view of what is going on in the background.
Standard(the one I chose): this account will have a full stripe dashboard, it has all the functionality that an account would have that you make on your own. You will get a unique account id relevant to your specific connect account environment, on their end, they will have multiple account ids depending on how many other connects they are connected to, or if it is an already existing account. You will need to use this api to get the link to have them verify information before they are integrated into your connect environment account link api
Express: they will have a slimmed down version of a dashboard, it is similar to standard with less functionality
At this point you're ready to start routing payments. I did angular on the front-end, here is an example basically this simply creates a stripeToken, which is a verification that the card data is valid. You need to pass this to a backend to make use of it, this will not create any charges.
On the backend, I used express, you use the charge api You pass the stripeToken as the source attribute. One important step is to add the stripe account id you see in your connected accounts dashboard. It should look similar to:
stripe.charges.create({
amount: priceInPence,
currency: 'usd',
source: stripeTokenId,
capture: false, // note that capture: false
},{
stripeAccount:'{{acctId}}'
})
This should be sufficient to get your payments routing to the necessary account while leveraging a simple UI checkout.
One thing to note about the charges API, this is an older API and has less functionality. For my use case (US CA only with only card payments) it is sufficient. If you have a more complicated use case, or maybe your app is for heavy prod use to many users you should look into payment intents.

stripe express connected accounts agreement type error

just wondering if you have ever had problems with express accounts and the agreement type in order to transfer to cross borders individuals. when I create an account for a user through my stripe dashboard, it creates the right agreement type which is "Recipient" but when a user creates the account by himself through the mobile app of the platform, the account will be created with the wrong agreement type which is the "full".
this is the error shown: Funds can't be sent to accounts located in CA when the account is under the full service agreement. To learn more, see https://stripe.com/docs/connect/service-agreement-types.
so, I tried by updating the code adding:
const account = await stripe.accounts.update(
'{{CONNECTED_STRIPE_ACCOUNT_ID}}',
{
tos_acceptance: {
service_agreement: 'recipient',
},
}
);
but I would not work and when the user does the onboarding process from the mobile app, still appears with the wrong agreement type which is "full"

Google classroom API - creating a course with Active status and using service account errors out

I am using googleapis to create a classroom course with a service account.
Everything works well if I don't specify the status and the course is created with status: PROVISIONED.
However, if I try to update the status to ACTIVE or create a course with status ACTIVE I get an error:
GaxiosError: #CourseStateDenied This user cannot create or transition courses into the requested state.
Here's some relevant code:
// authenticate with service account
const auth = new google.auth.GoogleAuth({
keyFile: path.join(__dirname, 'service_account_creds.json'),
scopes: [
'https://www.googleapis.com/auth/classroom.courses',
'https://www.googleapis.com/auth/classroom.rosters',
'https://www.googleapis.com/auth/classroom.profile.emails',
'https://www.googleapis.com/auth/classroom.profile.photos'
],
});
const authClient = await auth.getClient();
google.options({auth: authClient});
// create a course with status: ACTIVE
const res = await classroom.courses.create({
requestBody: {
name: 'Test Course',
description: 'this is my course description',
ownerId: 'me',
courseState: 'ACTIVE'
}
});
console.log(res.data);
I think the problem is related to your account
See the documentation for creating courses:
Courses are created with the courseState set to PROVISIONED by default; however, this can be overridden to ACTIVE. If the course is created in the PROVISIONED state, the teacher identified in the ownerId must accept the class in the Classroom UI or the course must be updated through the API to change the courseState to ACTIVE and make it available to their students.
And then:
Note: Consumer accounts (*#gmail.com) cannot create courses in ACTIVE state. Requests to do so will return 403: PERMISSION_DENIED.
In other words, consumer accounts are not allowed to create courses with the status ACTIVE.
ziganotschka got it almost on the spot. The missing details is that you are using a service account without impersonation, so the course is being created with the service account as the owner.
If you are doing it for a school/university, you need to grant the service account domain-wide access to create courses for the users. Then:
If the school/uni wants to allow teachers to create their own classes, you can set the credentials subject the user that will be the main teacher.
Regardless of whether the teachers are allowed to create new classes, you can set the credentials subject to an Admin email, allowing you to create courses for other users.

Stripe Connect create accounts from server

I'm trying to create a stripe connect account using my firebase functions backend when the user signs up but keep getting this error Express accounts may only be created via the OAuth flow I know the error seems self-explanatory that I need to use the standard OAuth registration method but in the Documentation it states that custom types can be created by the API and presenting the OAuth for every user who just wants to send funds and not receive is just annoying am I doing something wrong for the API not to create it? Or is there a workaround to not have to show the OAuth for users who just want to send funds?
exports.createStripeCustomer = functions.auth.user().onCreate(async (user) => {
const customer = await stripe.customers.create({email: user.email});
const account = await stripe.accounts.create({type: 'custom', business_type: 'individual', individual: {email: user.email}, requested_capabilities: ['card_payments', 'transfers'], email: user.email});
return admin.firestore().collection('stripe_customers').doc(user.uid).set({account_id: account.id, customer_id: customer.id});
});
Express Accounts and Custom Accounts are distinct types of accounts when using Connect. You can create Custom Accounts using the API, but Express Accounts must be created via OAuth.
The main difference is that Express Accounts have access to the Stripe Dashboard and can be updated in some ways by the end user, while Custom Accounts are entirely managed by the platform.
The issue seems to be being caused by me not specifying the Country in the stripe.accounts.create function. Once I did it created the account.

Resources