PayPal 401 Client Authentication Failed in Sandbox environment with node js sdk - node.js

I've followed this guide https://developer.paypal.com/docs/checkout/reference/server-integration/setup-sdk/ and this example https://github.com/paypal/Checkout-Nodejs-SDK/
Here is my code:
import paypalCheckout from '#paypal/checkout-server-sdk';
const environment = new paypalCheckout.core.SandboxEnvironment(
'ACTUAL_CLIENT_ID_FROM_PAYPAL_DASHBOARD',
'ACTUAL_CLIENT_SECRET_FROM_PAYPAL_DASHBOARD'
);
const client = new paypalCheckout.core.PayPalHttpClient(environment);
const request = new paypalCheckout.orders.OrdersCreateRequest();
request.requestBody({
intent: 'CAPTURE',
purchase_units: [
{
amount: {
currency_code: 'USD',
value: `100.00`
}
}
],
});
client.execute(request)
.then((response) => {
console.log(`${JSON.stringify(response)}`);
console.log(`${JSON.stringify(response?.result)}`);
})
.catch((executeError) => {
console.log(`${JSON.stringify(executeError)}`);
});
I get:
{
error: HttpError: {"error":"invalid_client","error_description":"Client Authentication failed"}
at IncomingMessage.<anonymous> (.../node_modules/#paypal/paypalhttp/lib/paypalhttp/http_client.js:136:22)
at IncomingMessage.emit (events.js:388:22)
at endReadableNT (internal/streams/readable.js:1336:12)
at processTicksAndRejections (internal/process/task_queues.js:82:21) {
statusCode: 401,
headers: {
'content-type': 'application/json',
'content-length': '77',
connection: 'close',
date: 'Tue, 29 Jun 2021 01:22:38 GMT',
'cache-control': 'max-age=0, no-cache, no-store, must-revalidate',
'paypal-debug-id': 'c2b.......c7a',
'x-paypal-token-service': 'IAAS',
'strict-transport-security': 'max-age=31536000; includeSubDomains'
},
_originalError: {
text: '{"error":"invalid_client","error_description":"Client Authentication failed"}',
statusCode: 401,
headers: [Object]
}
},
message: '{"error":"invalid_client","error_description":"Client Authentication failed"}'
}
I've searched Google and Stack Overflow but I only find similar issues about switching from sandbox to live.
My code isn't working in sandbox environment.

Related

When i am removing my account from stripe in node it gives some err

I get the error:
You cannot delete the default external account for your default currency. Please make another external account the default using the default_for_currency param, and then delete this one.
err1 StripeInvalidRequestError: You cannot delete the default external account for your default currency. Please make another external account the default using the default_for_currency param, and then delete this one.
at Function.generate (/var/www/html/SageRider/node_modules/stripe/lib/Error.js:38:16)
at IncomingMessage. (/var/www/html/SageRider/node_modules/stripe/lib/StripeResource.js:175:33)
at Object.onceWrapper (events.js:299:28)
at IncomingMessage.emit (events.js:215:7)
at endReadableNT (_stream_readable.js:1199:12)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
type: 'StripeInvalidRequestError',
raw: {
message: 'You cannot delete the default external account for your default currency. Please make another external account the default using the default_for_currency param, and then delete this one.',
type: 'invalid_request_error',
headers: {
server: 'nginx',
date: 'Thu, 25 Jun 2020 19:28:55 GMT',
'content-type': 'application/json',
'content-length': '264',
connection: 'keep-alive',
'access-control-allow-credentials': 'true',
'access-control-allow-methods': 'GET, POST, HEAD, OPTIONS, DELETE',
'access-control-allow-origin': '*',
'access-control-expose-headers': 'Request-Id, Stripe-Manage-Version, X-Stripe-External-Auth-Required, X-Stripe-Privileged-Session-Required',
'access-control-max-age': '300',
'cache-control': 'no-cache, no-store',
'request-id': 'req_bXINneBUbmPyo2',
'stripe-account': 'acct_1GwmPSFNjTTd70ro',
'stripe-version': '2019-12-03',
'strict-transport-security': 'max-age=31556926; includeSubDomains; preload'
},
statusCode: 400,
requestId: 'req_bXINneBUbmPyo2'
},
rawType: 'invalid_request_error',
code: undefined,
param: undefined,
detail: undefined,
headers: {
server: 'nginx',
date: 'Thu, 25 Jun 2020 19:28:55 GMT',
'content-type': 'application/json',
The code I use is:
stripe.accounts.deleteExternalAccount(
cryptr.decrypt(data[0].accountId),
cryptr.decrypt(data[0].bankAccountId),
function(err, confirmation) {
if(err) {
console.log("err1",err)
callback(err, false)
}else {
console.log("confirmation",confirmation)
callback(false, true)
}
Today, you can not remove the last external account saved on a Custom account in the API. Stripe requires that an account always has a valid bank account for the currency once you've added this.
My guess is that this is the error you are getting right now though you didn't share the exact message. In that case, you need to change your code to stop removing the last external account or replace it by a new external account instead.

Problems connecting Service Account to Admob API with Google-Auth-Library

I've been trying to connect to Admob API from an AWS Lambda to extract some values from reports automatically from time to time. I've successfully got google-auth-library-nodejs to a layer and I am trying to use it to connect to Admob API.
I've made sure to give my Service account an Owner role and I've added the necessary GOOGLE_APPLICATION_CREDENTIALS path to the environement variables.
This is the code that I've added to my Lambda:
const {GoogleAuth} = require('google-auth-library');
exports.handler = (event, context, callback) => {
async function main() {
const auth = new GoogleAuth({
scopes: ['https://www.googleapis.com/auth/admob.report'],
});
const client = await auth.getClient();
//console.log("client", JSON.stringify(client));
const url = `https://admob.googleapis.com/v1/accounts`;
const res = await client.request({ url });
console.log("res: ", JSON.stringify(res.data));
}
main().catch(console.error);
};
When I run the code, I get the following error:
ERROR GaxiosError: Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
at Gaxios._request (/opt/nodejs/node_modules/gaxios/build/src/gaxios.js:85:23)
at processTicksAndRejections (internal/process/task_queues.js:94:5)
at async JWT.requestAsync (/opt/nodejs/node_modules/google-auth-library/build/src/auth/oauth2client.js:350:18)
at async main (/var/task/index.js:97:19) {
response: {
config: {
url: 'https://admob.googleapis.com/v1/accounts',
headers: [Object],
params: [Object: null prototype] {},
paramsSerializer: [Function: paramsSerializer],
validateStatus: [Function: validateStatus],
responseType: 'json',
method: 'GET'
},
data: { error: [Object] },
headers: {
'alt-svc': 'quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000',
'cache-control': 'private',
connection: 'close',
'content-encoding': 'gzip',
'content-type': 'application/json; charset=UTF-8',
date: 'Wed, 26 Feb 2020 18:41:51 GMT',
server: 'ESF',
'transfer-encoding': 'chunked',
vary: 'Origin, X-Origin, Referer',
'x-content-type-options': 'nosniff',
'x-frame-options': 'SAMEORIGIN',
'x-xss-protection': '0'
},
status: 401,
statusText: 'Unauthorized',
request: { responseURL: 'https://admob.googleapis.com/v1/accounts' }
},
config: {
url: 'https://admob.googleapis.com/v1/accounts',
headers: {
Authorization: 'Bearer [Removed]',
'User-Agent': 'google-api-nodejs-client/5.10.1',
'x-goog-api-client': 'gl-node/12.14.1 auth/5.10.1',
Accept: 'application/json'
},
params: [Object: null prototype] {},
paramsSerializer: [Function: paramsSerializer],
validateStatus: [Function: validateStatus],
responseType: 'json',
method: 'GET'
},
code: 401,
errors: [
{
message: 'Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.',
domain: 'global',
reason: 'unauthorized'
}
]
}
I've been trying to find my mistake by searching on google, stack overflow, reading tutorials about connecting to Admob API as well as reading the library's code. I would really appreciate if someone could point me towards a solution.
The problem is you are trying to use a service account where OAuth User Credentials are required. You will need to implement the OAuth 2 Flow where the user enters their Google username and password.
AdMob: Authorization for the request
Refer to the following Google example on how to create a node.js OAuth 2 client.
https://github.com/googleapis/google-auth-library-nodejs#oauth2

I have followed the api documentation for Watson Tone analyser to no avail - can't connect the two endpoints

I have a Watson Tone cloud service up and running and I am trying to link it to my index.js file. However it doesn't seem to want to connect.
Code below:
const ToneAnalyzerV3 = require('watson-developer-cloud/tone-analyzer/v3');
const toneAnalyzer = new ToneAnalyzerV3({
version: '2017-09-21',
iam_apikey: 'omoNirDx1MUQwCdlHTQ-5Fxklx2_c0dUVAyMFIItFLty',
url: 'http://watson-row-analyser.eu-gb.cf.appdomain.cloud/#'
});
const text =
'Team, I know that times are tough! Product ' +
'sales have been disappointing for the past three ' +
'quarters. We have a competitive product, but we ' +
'need to do a better job of selling it!';
const toneParams = {
tone_input: { text: text },
content_type: 'application/json'
};
toneAnalyzer
.tone(toneParams)
.then((toneAnalysis) => {
console.log(JSON.stringify(toneAnalysis, null, 2));
})
.catch((err) => {
console.log('error:', err);
});
Current error code:
Marcs-MacBook-Pro:npm-global marcwatts$ node index1.js
error: { Not Found: Not Found
at formatError (/Users/marcwatts/Desktop/mxw817/DBTestApp/npm-global/node_modules/watson-developer-cloud/node_modules/ibm-cloud-sdk-core/lib/requestwrapper.js:111:17)
at /Users/marcwatts/Desktop/mxw817/DBTestApp/npm-global/node_modules/watson-developer-cloud/node_modules/ibm-cloud-sdk-core/lib/requestwrapper.js:259:19
at process._tickCallback (internal/process/next_tick.js:68:7)
name: 'Not Found',
code: 404,
message: 'Not Found',
body:
'"<!DOCTYPE html>\\n<html lang=\\"en\\">\\n<head>\\n<meta charset=\\"utf-8\\">\\n<title>Error</title>\\n</head>\\n<body>\\n<pre>Cannot POST /</pre>\\n</body>\\n</html>\\n"',
headers:
{ 'x-backside-transport': 'FAIL FAIL',
connection: 'close',
'transfer-encoding': 'chunked',
'content-security-policy': 'default-src \'none\'',
'content-type': 'text/html; charset=utf-8',
date: 'Sat, 06 Jul 2019 15:32:34 GMT',
'x-content-type-options': 'nosniff',
'x-powered-by': 'Express',
'x-global-transaction-id': 'ba9308f85d20bf12a70673ff' } }
Link to api for Watson:
https://cloud.ibm.com/apidocs/tone-analyzer?code=node
Code 404 means Not Found. A requested item or parameter does not exist. What am I missing?

the problem of unauthorized in IBM watson assistant Nodejs

I tried the API v1 and v2 of IBM Watson assistant to creat a new conversion.
But it gived me always the samr error code 401 Unauthorized: Access is denied due to invalid credentials.
i don't know what happened, thanks in advance for your answers.
{ Unauthorized: Access is denied due to invalid credentials.
at RequestWrapper.formatError (E:\Documents\Techniques\Desktop\front_back_end\version-watson\node_modules\ibm-watson\node_modules\ibm-cloud-sdk-core\lib\requestwrapper.js:218:21)
at E:\Documents\Techniques\Desktop\front_back_end\version-watson\node_modules\ibm-watson\node_modules\ibm-cloud-sdk-core\lib\requestwrapper.js:206:29
at process._tickCallback (internal/process/next_tick.js:68:7)
name: 'Unauthorized',
code: 401,
message: 'Access is denied due to invalid credentials.',
body: '{"code":401,"error":"Unauthorized"}',
headers:
{ 'x-backside-transport': 'FAIL FAIL',
'content-type': 'application/json',
'x-dp-transit-id': 'gateway01-1474836587',
'x-global-transaction-id': '7ecac92c5d14b5ae57e8386b',
'strict-transport-security': 'max-age=31536000;',
'x-dp-watson-tran-id': 'gateway01-1474836587',
'content-length': '37',
'x-edgeconnect-midmile-rtt': '82',
'x-edgeconnect-origin-mex-latency': '110',
date: 'Thu, 27 Jun 2019 12:25:18 GMT',
connection: 'close' } }
const AssistantV1 = require('ibm-watson/assistant/v1');
const service = new AssistantV1({
version: '2019-02-28',
iam_apikey: '{apikey}',
url: '{url}'
});
service.message({
workspace_id: '{workspace_id}',
input: {'text': 'Hello'}
})
.then(res => {
console.log(JSON.stringify(res, null, 2));
})
.catch(err => {
console.log(err)
});
I am not sur that for Version2 the session-id is correct or not. But the API v1 doesn't need the session_id, it gives the same error code too.

How to correctly create a stripe source from a stripe token

I am attempting to create a stripe source server-side from a stripe token received client-side. When using console.log(), the token is the correct one retrieved from the client-side, but the error message I am receiving refers to a token that I did not even pass into the Stripe source promise.
Client side js
stripe.createToken(card).then(function(result) {
if (result.error) {
// Inform the user if there was an error.
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
document.getElementById('token').setAttribute('value',result.token.id);
document.getElementById('type').setAttribute('value',result.token.type);
myForm.submit();
}
});
and on my server I have the following...
router.post("/purchase",middleware.isLoggedIn, function(req,res){
let tokenId = req.body.token;
let type = req.body.type;
console.log(tokenId);
stripe.sources.create({
token: tokenId,
type: req.body.type
}).then((source) => {
console.log(source);
}).catch((e) =>{
console.log(tokenId);
console.log(e);
});
});
});
I get the following result from the conole.log(tokenId) statement
tok_1CdT3H2eZvKYlo2CNGY0W0JJ
but my error message from console.log(e) refers to a token beginning with 'card' that was not passed into the promise, which is the source of my confusion.
{ Error: Invalid token id: card_1CdT3H2eZvKYlo2Cv1PzIBCv
at Error._Error (/home/ec2-user/environment/node_modules/stripe/lib/Error.js:12:17)
at Error.Constructor (/home/ec2-user/environment/node_modules/stripe/lib/utils.js:124:13)
at Error.Constructor (/home/ec2-user/environment/node_modules/stripe/lib/utils.js:124:13)
at Function.StripeError.generate (/home/ec2-user/environment/node_modules/stripe/lib/Error.js:57:12)
at IncomingMessage.<anonymous> (/home/ec2-user/environment/node_modules/stripe/lib/StripeResource.js:170:39)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickDomainCallback (internal/process/next_tick.js:128:9)
type: 'StripeInvalidRequestError',
stack: 'Error: Invalid token id: card_1CdT3H2eZvKYlo2Cv1PzIBCv\n at Error._Error (/home/ec2-user/environment/node_modules/stripe/lib/Error.js:12:17)\n at Error.Constructor (/home/ec2-user/environment/node_modules/stripe/lib/utils.js:124:13)\n at Error.Constructor (/home/ec2-user/environment/node_modules/stripe/lib/utils.js:124:13)\n at Function.StripeError.generate (/home/ec2-user/environment/node_modules/stripe/lib/Error.js:57:12)\n at IncomingMessage.<anonymous> (/home/ec2-user/environment/node_modules/stripe/lib/StripeResource.js:170:39)\n at emitNone (events.js:91:20)\n t IncomingMessage.emit (events.js:185:7)\n at endReadableNT (_stream_readable.js:974:12)\n at _combinedTickCallback (internal/process/next_tick.js:80:11)\n at process._tickDomainCallback (internal/process/next_tick.js:128:9)',
rawType: 'invalid_request_error',
code: 'invalid_token_id',
param: undefined,
message: 'Invalid token id: card_1CdT3H2eZvKYlo2Cv1PzIBCv',
detail: undefined,
raw:
{ code: 'invalid_token_id',
message: 'Invalid token id: card_1CdT3H2eZvKYlo2Cv1PzIBCv',
type: 'invalid_request_error',
headers:
{ server: 'nginx',
date: 'Sat, 16 Jun 2018 01:18:04 GMT',
'content-type': 'application/json',
'content-length': '155',
connection: 'close',
'access-control-allow-credentials': 'true',
'access-control-allow-methods': 'GET, POST, HEAD, OPTIONS, DELETE',
'access-control-allow-origin': '*',
'access-control-expose-headers': 'Request-Id, Stripe-Manage-Version, X-Stripe-External-Auth-Required, X-Stripe-Privileged-Session-Required',
'access-control-max-age': '300',
'cache-control': 'no-cache, no-store',
'request-id': 'req_EfxhCBwQpauiVP',
'stripe-version': '2017-08-15' },
statusCode: 400,
requestId: 'req_EfxhCBwQpauiVP' },
headers:
{ server: 'nginx',
date: 'Sat, 16 Jun 2018 01:18:04 GMT',
'content-type': 'application/json',
'content-length': '155',
connection: 'close',
'access-control-allow-credentials': 'true',
'access-control-allow-methods': 'GET, POST, HEAD, OPTIONS, DELETE',
'access-control-allow-origin': '*',
'access-control-expose-headers': 'Request-Id, Stripe-Manage-Version, X-Stripe-External-Auth-Required, X-Stripe-Privileged-Session-Required',
'access-control-max-age': '300',
'cache-control': 'no-cache, no-store',
'request-id': 'req_EfxhCBwQpauiVP',
'stripe-version': '2017-08-15' },
requestId: 'req_EfxhCBwQpauiVP',
statusCode: 400 }
Technically you can but it's likely a lot easier to just create a Source client-side directly instead of creating a token. Elements can create a Source, so does Checkout withe source callback.
If you really want to do this server-side, just pass the token in the token parameter when you create the Card Source.

Resources