Assume the following code:
const stripe = window.Stripe('pk_xxx', { stripeAccount: 'acct_xxx' });
const elements = stripe.elements();
const card = elements.create('card');
stripe.createToken(card);
It succeeds in 3 of the 4 possible setups (test environment making LIVE stripe calls, test environment making TEST stripe calls, live environment making LIVE stripe calls) but not when in a live environment making TEST stripe calls.
It fails with a 403 error and the following response:
{
"error": {
"code": "secret_key_required",
"doc_url": "https://stripe.com/docs/error-codes/secret-key-required",
"message": "This API call cannot be made with a publishable API key. Please use a secret API key. You can find a list of your API keys at https://dashboard.stripe.com/account/apikeys.",
"type": "invalid_request_error"
}
}
How can a JS call require the secret key? Everyone would see it.
Here is the HTTP request:
card[number]: 4242424242424242
card[cvc]: 242
card[exp_month]: 04
card[exp_year]: 24
card[address_zip]: 42424
guid: 282d554c-4271-4730-9df4-ad142b19a812
muid: 722e4d63-4df0-40db-8d60-100f841d1718
sid: d5f44fce-9835-497b-a4dd-766894b4c23a
payment_user_agent: stripe.js/3b5fc4c8; stripe-js-v3/3b5fc4c8
referrer: https://app.myowndomain.com/
key: pk_test_xxx (also tried the pk_live_xxx - no difference)
_stripe_account: acct_xxx
Token creation would never require a Secret API key. This would be a real security issue and that's why Stripe has a pair of keys: the Secret key for your server-side code and the Publishable key for your client-side code.
The code you shared would always work with a publishable key and creating a token would never fail with that error. The Publishable key is also what is documented: https://stripe.com/docs/stripe.js
It is tricky to say what is causing this in your example but it has to be something unrelated to that line of code. Something else in the code would be triggered after the token creation and that other part must be misconfigured and have your Publishable key server-side. I would recommend following up with Stripe's support team on this as they can investigate your account directly: https://support.stripe.com/email
The problem was with the requested scope using Stripe Connect. It was set to "read_only", while I needed "read_write".
Stripe support acknowledged the fact that the current error message is not intuitive at all, and have passed the information to the engineering team so it is less confusing for developers.
Related
I have implemented an app that uses Stripe Oauth implementation, after following the instructions in the building extensions
Authentication is done perfectly. I'm able to retrieve access token and other details.
{
"access_token":"sk_test_51KHr6dAuxxxx",
"refresh_token":"rt_KxmgQFvxxxx",
"expires_in":1642171943,
"livemode":false,
"stripe_publishable_key":"pk_test_51KHr6dxxx",
"stripe_user_id":"acct_1KHrxxxx"
}
Now the problem comes when trying to get resources from Stripe. If an API call is made to https://api.stripe.com/v1/customers, an empty data is returned.
{
"object": "list",
"data": [],
"has_more": false,
"url": "/v1/customers"
}
At the same time, if customer "key (secret test mode API key.)" is used, that endpoint return 4 customers (all of them).
So clearly, the access token received after OAuth is missing something.
Also tried adding the Stripe-Account key and customer account id in the headers, and received the following error.
{
"error": {
"code": "platform_account_required",
"doc_url": "https://stripe.com/docs/error-codes/platform-account-required",
"message": "Only Stripe Connect platforms can work with other accounts. If you specified a client_id parameter, make sure it's correct. If you need to setup a Stripe Connect platform, you can do so at https://dashboard.stripe.com/account/applications/settings.",
"type": "invalid_request_error"
}
}
I suspect something might be wrong with the app itself, but not sure :D
EDIT
Adding a few tried items using composer require stripe/stripe-php
\Stripe\Stripe::setApiKey("sk_test_51KHxxx");
return \Stripe\Customer::all()
$stripe = new \Stripe\StripeClient('sk_test_51Kxxx');
return $stripe->customers->all(['limit' => 30]);
This error typically occurs when you try to make a request from an account that is not a platform account i.e. it has no Connected accounts.
Looking at your code snippets, I'm guessing that you're making the request with the connected account's secret key since the first few characters are the same.
When making Connect requests, you should be using the API key that belongs to the platform account and then provide the optional stripe_account parameter [0].
\Stripe\Stripe::setApiKey("PLATFORM_SECRET_KEY");
$customers = \Stripe\Customer::all([],["stripe_account" => "CONNECTED_ACCOUNT_ID"]);
[0] https://stripe.com/docs/connect/authentication
Whenever i create a Bank account token using plaid/stripe integration and proceed to use this to create a Stripe bank account for my customer it keeps on returning the No Such token error.
Now i have gone through other questions posted here that suggest to check if the environments match i.e if my stripe keys are test keys and if my Plaid is in Sandbox mode.
They are both in test modes but it still fails.
PLAID_ENV = sandbox
const client = new plaid.Client({
clientID: PLAID_CLIENT_ID,
secret: PLAID_DEV_SECRET,
env: plaid.environments[PLAID_ENV],
options: {
version: '2020-09-14', // '2020-09-14' | '2019-05-29' | '2018-05-22' | '2017-03-08'
}
});```
My stripe is using the Stripe Test keys. I confirmed the accounts are linked.
Any help figuring out why it still returns this error would be appreciated
"No such..." errors are usually caused by either a mismatch in API keys (e.g. using a mixture of your test plus live keys) or by trying to access objects that exist on a different account (e.g. trying to perform an operation from your platform account on an object that was created on a connected account).
I want to create a new customer in Stripe upon form submit and add that customer's credit card to their account. As of now, I'm using the following code upon submit in my React App. The create customer call is then made separately from my server:
async submit(ev) {
let {token} = await this.props.stripe.createToken({name: "Name"});
let response = await fetch("https://api.stripe.com/v1/customers", {
method: "POST",
headers: {"Content-Type": "text/plain"},
body: token.id
});
When sending that data, I get a 401 error on the let response = ... line. I know that a 401 is an auth error, but my test API keys are definitely correct and don't have limits on how they can access my stripe account. Can anyone advise?
The issue here is that you are trying to create a Customer object client-side in raw Javascript. This API request requires your Secret API key. This means you can never do this client-side, otherwise anyone could find your API key and use it to make refunds or transfer for example.
Instead, you need to send the token to your own server. There, you will be able to create a Customer or a Charge using one of Stripe's official libraries instead of making the raw HTTP request yourself.
In my case, it's throwing the error due to a missing of stripe public key
var stripe = Stripe('{{ env("STRIPE_KEY") }}');
then I pass the public key as above, and it worked like a charm.
After developing in the sandbox, we got our api key approved and promoted to a live account.
Since then we've been getting the following response -
response: {
"errorCode": "ACCOUNT_LACKS_PERMISSIONS",
"message": "This Account lacks sufficient permissions."
}
http code: 401
exeucted at: 2017-05-17 15:03:59
Based on my research and according to ACCOUNT_LACKS_PERMISSIONS error when creating envelope
A setting needs to be switched on the backend at Docusign. The user mentions -
"They changed a setting called In Session to Enabled in API section near limiter that only the account manager or tier 2 support can change. All is well."
The account ID is 30953035
API username bcbffa28-a316-473e-b2b7-48d964d909a7
The API request is below. This was working just fine under a Demo account. I've even upgraded to the Intermediate API in the hopes that it will resolve my issues but no dice.
Support says that I need to post here...
This is caused by a bad account baseUrl that's being used in the request. When your integration performs authentication for a given user, if you are using Legacy auth (X-DocuSign-Authentication header) then you need to point to the following /login_information endpoint for the live system:
https://www.docusign.net/restapi/v2/login_information
When you get the response you then need to parse the baseUrl value that was returned and use that sub-domain for subsequent API requests. (Note that there are multiple sub-domains in the live system such as NA1, NA2, EU, etc)
The baseUrl that's returned will look something like:
https://na2.docusign.net/restapi/v2/accounts/12345/envelopes
Make sure you configure your code to read this sub-domain and use in subsequent requests, otherwise you if you simply use www for instance you will not be hitting the correct account endpoint and you'll receive the "Account lacks permissions" error you're receiving.
Ergin's answer seems to work; however, he does not state which part of the baseUrl to keep after parsing. In his example the baseUrl = "https://na2.docusign.net/restapi/v2/accounts/12345/envelopes" In all subsequent calls after authApi.Login(); use "https://na2.docusign.net/restapi" as the URL and that should eliminate the error message.
In my Meteor web application I have managed to successfully implement some functions that allow me to take an authorization code granted from Paypal's authorizeUrl function via the RESTful Paypal Node SDK in the Sandbox in order to assign a refresh token to an existing user. However, now that we need to deploy it to a Live environment, we are running into problems because the Paypal API is complaining with the following error:
Error: Response Status: 400
This means the request was bad, due perhaps to a 'bad syntax.' However, I am using the correct live API credentials and the authorization URL endpoint is the correct one at https://www.paypal.com/signin/authorize
Unfortunately this bug doesn't occur when I am reverting back to my sandbox mode configuration.
As a follow up, trying to pass an invalid authorization code to my sandbox configuration endpoint provides me the appropriate error message 400 with Invalid authorization code whereas the live environment gives me no such help...
The latest paypal-debug-id I have on hand is 83d570f17357e
EDIT:
It turns out Paypal thinks client id or secret is null even though I have clearly provided the configuration with client_id, client_secret, openid_client_id and openid_client_secret. This confuses me even more
EDIT 2:
Using the same Live API credentials I can successfully set up a basic payment flow using the Rest SDK, but I cannot use open ID connect with the same client ID and secret. Maybe that has something to do with it?
After some extensive testing and wrestling with the API it was discovered that there was actually a configuration conflict going on when binding the Meteor.wrapAsync API call to an instance of paypal created from the node SDK.
Assuming my Meteor.wrapAsync call is this:
var wrapGetUserInfo = Meteor.wrapAsync(openIdCxn.userinfo.get.bind(openIdCxn.userinfo), function (err, userinfo) {
if (err) {
console.log(err);
throw new Meteor.Error(500, "Internal Server Error", err);
}
});
Then instead of doing
var userInfo = wrapGetUserInfo(returnObject.access_token, paypal);
I will do
var userInfo = wrapGetUserInfo(returnObject.access_token);
And then it no longer complains