basic auth axios - klarna checkout - javascript

I am implementing Klarna Checkout in my webapp. Backend using aws serverless. Frontend: react.
I am stucked at creating a order. It works fine inside postman but I can't get basic auth working axios.
For testing purposes I am posting orders from my react app. It will be moved to the backend once I get it working.
My axios code looks like this.
axios
.post(
"https://api.playground.klarna.com/checkout/v3/orders",
{
purchase_country: "DE",
purchase_currency: "EUR",
locale: "de-DE",
order_amount: 3,
order_tax_amount: 0,
order_lines: [
{
type: "digital",
reference: "Test",
name: "Test Subscription",
quantity: 1,
quantity_unit: "pcs",
unit_price: 3,
tax_rate: 0,
total_amount: 3,
total_discount_amount: 0,
total_tax_amount: 0
}
],
merchant_urls: {
terms: "https://www.example.com/terms.html",
checkout: "https://www.example.com/checkout.html",
confirmation: "https://www.example.com/confirmation.html",
push: "https://www.example.com/api/push"
}
},
{
auth: {
username: "xxx",
password: "xxx"
},
headers: {
"Content-Type": "application/json"
}
}
)
.then(result => console.dir(result));
I get a 401 error at OPTIONS.
The response I'm getting.
I have tried it with postman, which works fine.

To summarize the comments: Klarna's API cannot be called from browser only from serverside.
I called the same code from my aws lambda and it worked fine.

Related

Patch request to COSMOS DB: 404 not found

Updated: Solved by Sajeetharan's suggestion! Thanks.
I'm trying to implement the api to partially update cosmos db. I got 404 not found when I tested this patch request. I tested query in cosmo's db, it's working as expected. I don't know which part is wrong.
You should invoke the Patch on the container as how you have done fetchAll request.
Here is a sample,
const multipleOperations: PatchOperation[] = [
{
op: "add",
path: "/aka",
value: "MeFamily"
},
{
op: "replace",
path: "/lastName",
value: "Jose"
},
{
op: "remove",
path: "/parents"
},
{
op: "set",
path: "/address/zip",
value: 90211
},
{
op: "incr",
path: "/address/zip",
value: 5
}
];
const { resource: patchSource2 } = await container.item(patchId!).patch(multipleOperations);

Uploading a YouTube Video Using YouTube Data API V3 using Google API Client JavaScript

I visited the Youtube Data v3 API docs to know about how to upload videos using the client library
I got to this page
https://developers.google.com/youtube/v3/docs/videos/insert
but it doesn't seem to explain where to put the video in the request
And Also API explorer just gives the code for request, it doesn't let me execute the code for that page
I also read the resource structure page but didn't find where to put the video
https://developers.google.com/youtube/v3/docs/videos#resource
here's my current code
let req = gapi.client.youtube.videos.insert({
part: 'snippet,status',
snippet: {
title: "Test Video",
description: "Test Description",
categoryId: 28,
defaultLanguage: 'en',
defaultAudioLanguage: 'en'
},
status: {
privacyStatus: "private"
},
});
console.log(req)
try {
req.execute(function (response) {
console.log(response);
});
} catch (e) {
console.error(e);
}
Now, where do I put the video in the request?
do I have to put that as buffer?
I am fetching video from fetch API for uploading via API
and whenever I run the code I get the Error: 400 in the console
code: 400
data: [{…}]
error: {code: 400, data: Array(1), message: 'Request contains an invalid argument.'}
message: "Request contains an invalid argument."
so can you provide a working example of uploading a video using the client library that is fetched from the fetch API
and show to structure the request body when using the client library?
This is the request body I'm using. Code below was taken from this sample script: https://quanticdev.com/articles/automating-my-youtube-uploads-using-nodejs/
In my case I'm uploading an .mp4
auth: auth,
part: 'snippet,status',
requestBody: {
snippet: {
title,
description,
tags,
categoryId: 20,
defaultLanguage: 'en',
defaultAudioLanguage: 'en'
},
status: {
privacyStatus: "public",
selfDeclaredMadeForKids: false
},
},
media: {
body: fs.createReadStream(videoPath),
}

unable to perform CRUD in JSON-SERVER

I am trying to add, update, delete in JSON server with Redux Axios. But I am unable to perform CRUD action. I am always getting an error 404. I am using the following code example. this my db.json
{
"orderdetails": [
{
"OrderID": 111,
"CustomerID": "VINET",
}
]
}
I am using the following code for importing Axios from redux. Please find my server.js
import axios from 'axios';
export default axios.create({
baseURL: "http://localhost:3007/",
headers: {
"Content-type": "application/json"
}
})
I am using the following code example for performing CRUD action in the JSON-Sever. But, I am got a error
import http from "../serverapi";
create(data) {
return http.post("/orderdetails/posts", data);
}
update(id, data) {
return http.put(`/orderdetails/${id}`, data);
}
delete(id) {
return http.delete(`/orderdetails/${id}`);
}
could you please provide the suggestion?
If you are using the json-server npm package, there are a couple of problems with your usage.
First, you db.json is invalid. It should be somewhat like this:
{
"orderdetails": [
{
"OrderID": 111,
"CustomerID": "VINET"
},
{
"OrderID": 12,
"CustomerID": "VINET"
}
]
}
Make sure to check the API url in the browser first.
Second, json-server by default runs on localhost:3000 (Not sure if it can be changed, check the docs here https://www.npmjs.com/package/json-server). Your API is pointing to port 3007 as seen here baseURL: "http://localhost:3007/,
Lastly, you cannot do a request like http://localhost:3000/orderdetails/111. The last part in the api url by default corresponds to the id key in db.json, but since your key is OrderID, your API end point should be modified to http://localhost:3000/orderdetails?OrderID=111. Try this url in your browser, it should return the correct object.
UPDATE
Update operations in json-server require the id key to be present in the db.json file. Hence, update your db.json as follows:
{
"orderdetails": [
{
"id": 1,
"OrderID": 111,
"CustomerID": "VINET"
},
{
"id": 2,
"OrderID": 12,
"CustomerID": "VINET"
}
]
}
Then, you can try running a POST request on the url http://localhost:3000/orderdetails and json body :
{
"OrderID": 12333,
"CustomerID": "VINET"
}
This will create a new object in the db, with incremented id. PUT, DELETE requests can be made using the id param in the url like http://localhost:3000/orderdetails/3.

Axios VS Postman request get different responses

Hello guys I came across a strange issue I got with connection to an API.
While I am using Postman everything goes well but if I make the request with Axios the response is different. So to give you an example I want to get a client with id 616;
Client
await axios
.post("/api/getClient", {
id: 616,
}).then(data => console.log(data))
Backend
// GET CLIENT
app.post('/api/getClient', async (req, res) => {
const d = await axios.get(`${baseURL}/client/account/:client_id`, {
headers: headers,
data: {
id: req.body.id
}
})
res.send(d.data)
res.end()
});
Response from axios look like this
data: {
error: false,
user: {
profile: null,
user_addresses: [],
safe_credits: 0,
rating: 5
}
}
From Postman
{
"error": false,
"user": {
"profile": {
"id": 616,
"phone_number": "07744444444",
"country_code": "44",
"email": "email#example.com",
"first_name": "John",
"last_name": "Doe",
"password": null,
"os": "iOS",
"token": "0c9c09e7dc2f009b4cfdb2e4666ead9e",
"version": "",
"photo": "",
"gender": "male",
"registered_date": "2020-05-08T14:55:05.000Z",
"enabled": 1,
"socketId": "",
"stripe_id": "cus_HF1eUUdada54JKN"
},
"user_addresses": [],
"safe_credits": 0,
"rating": 5
}
}
Instead of using data in your request, you should just be able to append the ID to your API URL:
const d = await axios.get(`${baseURL}/client/account/${req.body.id}`, {
...
});
I had recently a similar issue.
In postman make sure you delete any cookies, as this might affect results.
Postman stores cookies between different requests on the same domain. While axios (or any other backend library) might not.
Under the "Send" button in postman, check the cookies, delete any cookies you find there and re-execute. This might give you the same result you're having in axios.

Simulate PayPal errors in a sandbox account

I'm integrating PayPal payment on a web application I'm developing. I need to create an authorization for a transaction where I lock an amount of money (let's say 20€), then at the end of the transaction I complete the transaction and I take only the money that I need to take (so if the transaction's final cost is 15€, I give back 5€ to the user).
This workflow is currently working on a sandbox account, but now I wanted to test some errors that may occur while starting a new transaction, like for instance when the user doesn't have the sufficient amount of money (20€) that I need to lock in order to start a new transaction.
I found this documentation (https://developer.paypal.com/docs/api/test-values/#invoke-negative-testing) where it is stated To trigger the SENDER_EMAIL_UNCONFIRMED simulation response, set the items[0]/note value to ERRPYO002 in the POST v1/payments/payouts call. with the following code:
curl -X POST https://api.sandbox.paypal.com/v1/payments/payouts \
-H "content-type: application/json" \
-H "Authorization: Bearer Access-Token" \
-d '{
"sender_batch_header": {
"sender_batch_id": "1524086406556",
"email_subject": "This email is related to simulation"
},
"items": [
{
"recipient_type": "EMAIL",
"receiver": "payouts-simulator-receiver#paypal.com",
"note": "ERRPYO002",
"sender_item_id": "15240864065560",
"amount": {
"currency": "USD",
"value": "1.00"
}
}]
}'
So I guess that I need to pass an error code (like ERRPYO002) to a note field in my request body.
I'm using the checkout sdk, and my js code currently looks like this:
const buttonOpts = {
env: 'sandbox',
client: { production: $scope.key, sandbox: $scope.key },
style: {
label: 'paypal',
size: 'medium',
shape: 'rect',
color: 'blue',
tagline: false,
},
validate: actions => {
// stuff
},
payment: (data, actions) => {
return actions.payment.create({
intent: 'authorize',
payer: { payment_method: 'paypal' },
transactions: [
{
amount: {
total: '20.00',
currency: 'EUR',
},
description: 'My description',
},
],
});
},
onAuthorize: data => {
// Sending data.paymentID and data.payerID to my backend to confirm the new transaction
},
onCancel: () => {
// stuff
},
onError: err => {
console.log(err);
// stuff
},
};
Paypal.Button.render(buttonOpts, '#paypal-button');
I guess that I need to pass the code needed to simulate the error to my actions.payment.create object parameter, but I didn't find where exactly since my workflow is different that the one in the docs.
These are the codes that PayPal allows you to use for error testing:
https://developer.paypal.com/docs/payouts/integrate/test-payouts/#test-values
Any help is appreciated.
Thanks a lot.
Ok, I've actually found out how to solve this problem right after I posted this question.
I'll just put my solution here for anyone that may have this problem in the future.
The option object I posted is actually correct as it is now, so after the user confirms that he/she wants to start a new transaction I get the payerID and the paymentID to send to my backend.
On my backend function I changed my code so that it is as follows:
const paypal = require('paypal-rest-sdk');
const paymentId = event.paymentID;
const payerId = { payer_id: event.payerID };
paypal.configure({
mode: process.env.PAYPAL_ENVIRONMENT, //sandbox or live
client_id: '<MY_CLIENT_ID>',
client_secret: '<MY_CLIENT_SECRET>',
});
paypal.payment.execute(
paymentId,
payerId,
// START NEW CODE
{
headers: {
'Content-Type': 'application/json',
'PayPal-Mock-Response': '{"mock_application_codes": "INSUFFICIENT_FUNDS"}',
},
},
// END NEW CODE
(error, payment) => {
console.error(JSON.stringify(error));
console.error(JSON.stringify(payment));
if (error) {
/*
{
"response": {
"name": "INSUFFICIENT_FUNDS",
"message": "Buyer cannot pay - insufficient funds.",
"information_link": "https://developer.paypal.com/docs/api/payments/#errors",
"debug_id": "a1b2c3d4e5f6g",
"details": [
{
"issue": "The buyer must add a valid funding instrument, such as a credit card or bank account, to their PayPal account."
}
],
"httpStatusCode": 400
},
"httpStatusCode": 400
}
*/
return callback('unhandled_error', null);
}
if (payment.state === 'approved' && payment.transactions && payment.transactions[0].related_resources && payment.transactions[0].related_resources[0].authorization) {
return callback(null, payment.transactions[0].related_resources[0].authorization.id);
}
console.log('payment not successful');
return callback('unhandled_error', null);
}
);
In the request headers you just have to put an header called PayPal-Mock-Response that contains the error code you want to test, and that's it.
Hope this'll help somebody!

Categories

Resources