I am using the paypal-rest-sdk to practice using the paypal checkout. I've set up a small test and whenever I click submit in my form I get a "localhost refused to connect" error in Chrome. I've turned off my proxy and cleared my history and cache. I've also double checked my client and secret keys from Paypal. I'm not sure what I am doing wrong. Here's my code:
app.js:
const express = require('express');
const ejs = require('ejs');
const paypal = require('paypal-rest-sdk');
paypal.configure({
'mode': 'sandbox', //sandbox or live
'client_id': 'xxxxxxxx',
'client_secret': 'xxxxxxx'
});
const app = express();
app.set('view engine', 'ejs');
app.get('/', (req, res) => res.render('index'));
// create the json obj for the transaction with the order details
app.post('/pay', (req, res) => {
const create_payment_json = {
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
"redirect_urls": {
"return_url": "http://localhost:3000/success",
"cancel_url": "http://localhost:3000/cancel"
},
"transactions": [{
"item_list": {
"items": [{
"name": "Red Sox Hat",
"sku": "001",
"price": "25.00",
"currency": "USD",
"quantity": 1
}]
},
"amount": {
"currency": "USD",
"total": "1.00"
},
"description": "This is the payment description."
}]
};
// pass in the object we've created and now create the actual payment
paypal.payment.create(create_payment_json, function (error, payment) {
if (error) {
console.log(error);
throw error;
} else {
console.log("Create Payment Response");
console.log(payment);
res.send('test');
}
});
});
app.listen(3000, () => console.log('Server Started'));
here is what the terminal outputs from the error:
response:
{ name: 'VALIDATION_ERROR',
details: [ [Object] ],
message: 'Invalid request - see details',
information_link: 'https://developer.paypal.com/docs/api/payments/#errors',
debug_id: 'fb61fe9c14b46',
httpStatusCode: 400 },
httpStatusCode: 400 }
I expect the message of 'test' to appear on the screen when the pay route is rendered so that I know the connection works, but so far all I've gotten is "ERR_CONNECTION_REFUSED" from Chrome. Please let me know what I am doing wrong. Thanks in advance.
Your payment JSON is missing required information.
Please see an valid payment JSON below:
{
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
"redirect_urls": {
"return_url": "http://www.example.com/return_url",
"cancel_url": "http://www.example.com.br/cancel"
},
"transactions": [
{
"amount": {
"currency": "USD",
"total": "200.00",
"details": {
"shipping": "10.00",
"subtotal": "190.00"
}
},
"item_list": {
"items": [
{
"name": "Foto 1",
"currency": "USD",
"sku": "123",
"quantity": "1",
"price": "190.00"
}
]
},
"description": "Payment description"
}
]
}
Related
So I am using the hendt/ebay-api library but having no success with the getOrders call.
Here's the auth scopes I'm using when setting the ORIGINAL User access token...:
eBay.auth.oAuth2.setScope([
'https://api.ebay.com/oauth/api_scope',
'https://api.ebay.com/oauth/api_scope/sell.marketing.readonly',
'https://api.ebay.com/oauth/api_scope/sell.marketing',
'https://api.ebay.com/oauth/api_scope/sell.inventory.readonly',
'https://api.ebay.com/oauth/api_scope/sell.inventory',
'https://api.ebay.com/oauth/api_scope/sell.account',
'https://api.ebay.com/oauth/api_scope/sell.account.readonly',
'https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly',
'https://api.ebay.com/oauth/api_scope/sell.fulfillment',
'https://api.ebay.com/oauth/api_scope/sell.analytics.readonly',
'https://api.ebay.com/oauth/api_scope/sell.finances',
'https://api.ebay.com/oauth/api_scope/sell.payment.dispute',
'https://api.ebay.com/oauth/api_scope/commerce.identity.readonly',
]);
Here's my code (ExpressJS backend controller method...):
exports.getOrders = async (req, res) => {
let _id = req.params.userId; // user's _id
let token = await refreshEbayToken(_id, eBay)
console.log(`token...`, token) // not an array! It's an object!
// set OAuth2 eBay credentials
eBay.auth.oAuth2.setCredentials(token.access_token);
try {
let result = await eBay.sell.fulfillment.getOrders({
filter: 'orderfulfillmentstatus:{NOT_STARTED|IN_PROGRESS}',
limit: 5
})
console.log(`Got a result...`, result)
res.json(result)
} catch (e) {
console.log(`Got an error in getOrders...`, e)
res.status(400).json( { error: e } )
}
}
Here's the error I get:
{
"meta": {
"errors": [
{
"errorId": 1100,
"domain": "ACCESS",
"category": "REQUEST",
"message": "Access denied",
"longMessage": "Insufficient permissions to fulfill the request."
}
]
},
"name": "EBayAccessDenied"
}
Even freshly minted User access tokens through those scopes get this error.
According to the ebay docs on getOrders, these are the required auth scopes for this call:
https://api.ebay.com/oauth/api_scope/sell.fulfillment
https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly
Upon further investigation, I found I am certainly using those scopes in the response (below is a snippet of the scopes grabbed from the larger ebay error)...
...%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.fulfillment.readonly%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.fulfillment%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.analytics.readonly%20https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.finances%20...
As shown above, I am clearly using the sell.fulfillment and sell.fulfillment.readonly scopes so I do not understand what is the issue.
What do you think could be the issue?
So I am using the library but having no success with the getOrders call.
Here's the auth scopes I'm using when setting the ORIGINAL User access token
https://gist.github.com/mudassaralichouhan/d952b464b2907c7f833c87c05152eb76
I finally got it working.
Here is an example of what I receive now:
{
"sales": [
{
"orderId": "xxxxxxxxx",
"legacyOrderId": "xxxxxxxxx-xxxxxxxxx",
"creationDate": "2022-03-09T23:10:36.000Z",
"lastModifiedDate": "2022-03-18T15:51:04.000Z",
"orderFulfillmentStatus": "FULFILLED",
"orderPaymentStatus": "PAID",
"sellerId": "xxxx",
"buyer": {
"username": "xxxxx",
"taxAddress": {
"stateOrProvince": "xx",
"postalCode": "xxxxxxxx",
"countryCode": "xx"
}
},
"pricingSummary": {
"priceSubtotal": {
"value": "xxxxx",
"currency": "USD"
},
"deliveryCost": {
"value": "0.0",
"currency": "USD"
},
"total": {
"value": "xxxxx",
"currency": "USD"
}
},
"cancelStatus": {
"cancelState": "NONE_REQUESTED",
"cancelRequests": []
},
"paymentSummary": {
"totalDueSeller": {
"value": "xxxxx",
"currency": "USD"
},
"refunds": [],
"payments": [
{
"paymentMethod": "EBAY",
"paymentReferenceId": "xxxxxx",
"paymentDate": "2022-03-09T23:15:33.109Z",
"amount": {
"value": "xxxxxxxx",
"currency": "USD"
},
"paymentStatus": "PAID"
}
]
},
"fulfillmentStartInstructions": [
{
"fulfillmentInstructionsType": "SHIP_TO",
"minEstimatedDeliveryDate": "2022-03-14T07:00:00.000Z",
"maxEstimatedDeliveryDate": "2022-03-19T07:00:00.000Z",
"ebaySupportedFulfillment": false,
"shippingStep": {
"shipTo": {
"fullName": "xxxxxxxxxx",
"contactAddress": {
"addressLine1": "xxxxxxxxxxx",
"city": "xxxxxxxxxx",
"stateOrProvince": "xx",
"postalCode": "xxxxxxxxx",
"countryCode": "US"
},
"primaryPhone": {
"phoneNumber": "xxxxxxxxxxxxx"
},
"email": "xxxxxxxxxxxx#members.ebay.com"
},
"shippingServiceCode": "ShippingMethodStandard"
}
}
],
"fulfillmentHrefs": [
"https://api.ebay.com/sell/fulfillment/v1/order/xxxxxxxxxxx/shipping_fulfillment/xxxxxxxxxx"
],
"lineItems": [
{
"lineItemId": "xxxxxxxxxx",
"legacyItemId": "xxxxxxxxxx",
"legacyVariationId": "xxxxxxxxxx",
"sku": "xxxxxxxxxx",
"title": "xxxxxxxxxx",
"lineItemCost": {
"value": "xxxxxxxxxx",
"currency": "USD"
},
"quantity": 1,
"soldFormat": "FIXED_PRICE",
"listingMarketplaceId": "EBAY_US",
"purchaseMarketplaceId": "EBAY_US",
"lineItemFulfillmentStatus": "FULFILLED",
"total": {
"value": "xxxxxxxxxx",
"currency": "USD"
},
"deliveryCost": {
"shippingCost": {
"value": "0.0",
"currency": "USD"
}
},
"appliedPromotions": [],
"taxes": [],
"ebayCollectAndRemitTaxes": [
{
"taxType": "STATE_SALES_TAX",
"amount": {
"value": "xxxxxxxxxx",
"currency": "USD"
},
"collectionMethod": "NET"
}
],
"properties": {
"buyerProtection": true
},
"lineItemFulfillmentInstructions": {
"minEstimatedDeliveryDate": "2022-03-14T07:00:00.000Z",
"maxEstimatedDeliveryDate": "2022-03-19T07:00:00.000Z",
"shipByDate": "2022-03-14T06:59:59.000Z",
"guaranteedDelivery": false
},
"itemLocation": {
"location": "xxxxxxxxxx",
"countryCode": "US",
"postalCode": "xxxxxxxxxx"
}
}
],
"ebayCollectAndRemitTax": true,
"salesRecordReference": "xxxxxxxxxx",
"totalFeeBasisAmount": {
"value": "xxxxxxxxxx",
"currency": "USD"
},
"totalMarketplaceFee": {
"value": "xxxxxxxxxx",
"currency": "USD"
}
}
]
}
Here are my scopes:
eBay.auth.oAuth2.setScope([
'https://api.ebay.com/oauth/api_scope',
'https://api.ebay.com/oauth/api_scope/sell.marketing.readonly',
'https://api.ebay.com/oauth/api_scope/sell.marketing',
'https://api.ebay.com/oauth/api_scope/sell.inventory.readonly',
'https://api.ebay.com/oauth/api_scope/sell.inventory',
'https://api.ebay.com/oauth/api_scope/sell.account',
'https://api.ebay.com/oauth/api_scope/sell.account.readonly',
'https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly',
'https://api.ebay.com/oauth/api_scope/sell.fulfillment',
'https://api.ebay.com/oauth/api_scope/sell.analytics.readonly',
'https://api.ebay.com/oauth/api_scope/sell.finances',
'https://api.ebay.com/oauth/api_scope/sell.payment.dispute',
'https://api.ebay.com/oauth/api_scope/commerce.identity.readonly',
]);
Here is the code getting it right ( express.js )...
exports.getOrders = async (req, res) => { // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetOrders.html
let _id = req.params.userId; // user's _id
let a = {}
a._id = _id
a.userDoc = await User.findById( { _id: a._id } )
eBay.auth.oAuth2.setCredentials( a.userDoc.token[ 0 ] ) // set OAuth2 eBay credentials
try
{
a.result = await eBay.trading.getOrders({
filter: 'orderfulfillmentstatus:{NOT_STARTED|IN_PROGRESS}',
limit: 5
})
console.log(`Got a result...`, a.result)
} catch ( e ) {
}
}
I send in the mongodb user _id as request params and use that to pull out their user token, which is passed into eBay.auth.oAuth2.setCredentials( a.userDoc.token[ 0 ] ) and allows the call to actually be made... eBay.trading.getOrders
I hope this helps someone out there. I remember being unable to make this call for months.
I am trying to create a DialogFlow chatbot setting up my fullfilment with rich message but the payload that carry it never show up.
Here is the inline code I'm using:
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion, Payload} = require('dialogflow-fulfillment');
var answers = [];
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
function fallback(agent) {
agent.add(`I didn't understand FULLFILMENT`);
agent.add(`I'm sorry, can you try again? FULLFILMENT`);
}
function answer1Handler(agent){
agent.add(`Intent answer1 called`);
const answer = agent.parameters.number;
answers.push(answer);
const payload = {
"text": "Trucmuche"/*,
"attachments": []*/
};
agent.add(new Payload(agent.SLACK, payload));
/*agent.add(
new Payload(agent.SLACK, payload, {rawPayload: true, sendAsMessage: true})
);*/
}
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('Default Fallback Intent', fallback);
intentMap.set('answer1', answer1Handler);
agent.handleRequest(intentMap);
});
This is called when reaching "answer1" intent. It works well when my answer1Handler is only:
function answer1Handler(agent){
agent.add(`Intent answer1 called`);
}
I don't know what I missed I tried both to follow the official documentation on rich message as well as this response but none helped me create my rich responses.
However, when I add a the custom payload you can see above, it doesn't answer anymore and I get an error message in raw api response. Indeed, it wither gives an error:
{
"responseId": "49e306dc-c2a9-4667-ac67-60eb3692ce98-e15c53b8",
"queryResult": {
"queryText": "1",
"parameters": {
"number": 1
},
"allRequiredParamsPresent": true,
"outputContexts": [
{
"name": "projects/pollingagent-jnscpa/agent/sessions/b6a5e9be-dd3e-7b54-3c4f-d942de297036/contexts/await_answer2",
"lifespanCount": 5,
"parameters": {
"number.original": "1",
"number": 1
}
},
{
"name": "projects/pollingagent-jnscpa/agent/sessions/b6a5e9be-dd3e-7b54-3c4f-d942de297036/contexts/await_answer1",
"lifespanCount": 4,
"parameters": {
"number.original": "1",
"number": 1
}
}
],
"intent": {
"name": "projects/pollingagent-jnscpa/agent/intents/bea1536a-dede-4faf-ab44-2ba4f80e9c0f",
"displayName": "answer1"
},
"intentDetectionConfidence": 1,
"diagnosticInfo": {
"webhook_latency_ms": 4993
},
"languageCode": "en"
},
"webhookStatus": {
"code": 4,
"message": "Webhook call failed. Error: DEADLINE_EXCEEDED."
},
"alternativeQueryResults": [
{
"queryText": "1",
"outputContexts": [
{
"name": "projects/pollingagent-jnscpa/agent/sessions/b6a5e9be-dd3e-7b54-3c4f-d942de297036/contexts/await_answer1",
"lifespanCount": 4,
"parameters": {
"number.original": "1",
"number": 1
}
},
{
"name": "projects/pollingagent-jnscpa/agent/sessions/b6a5e9be-dd3e-7b54-3c4f-d942de297036/contexts/await_answer2",
"lifespanCount": 3,
"parameters": {
"number.original": "1",
"number": 1
}
}
],
"languageCode": "en"
}
]
}
Or only gives back the first message as you can see in the raw API response:
{
"responseId": "b6bc8807-eca9-45e5-b25e-30e1b4142da7-e15c53b8",
"queryResult": {
"queryText": "1",
"parameters": {
"number": 1
},
"allRequiredParamsPresent": true,
"fulfillmentMessages": [
{
"text": {
"text": [
"Intent answer1 called"
]
}
}
],
"outputContexts": [
{
"name": "projects/pollingagent-jnscpa/agent/sessions/b6a5e9be-dd3e-7b54-3c4f-d942de297036/contexts/await_answer2",
"lifespanCount": 5,
"parameters": {
"number.original": "1",
"number": 1
}
},
{
"name": "projects/pollingagent-jnscpa/agent/sessions/b6a5e9be-dd3e-7b54-3c4f-d942de297036/contexts/await_answer1",
"lifespanCount": 4,
"parameters": {
"number.original": "1",
"number": 1
}
}
],
"intent": {
"name": "projects/pollingagent-jnscpa/agent/intents/bea1536a-dede-4faf-ab44-2ba4f80e9c0f",
"displayName": "answer1"
},
"intentDetectionConfidence": 1,
"diagnosticInfo": {
"webhook_latency_ms": 217
},
"languageCode": "en"
},
"webhookStatus": {
"message": "Webhook execution successful"
},
"alternativeQueryResults": [
{
"queryText": "1",
"outputContexts": [
{
"name": "projects/pollingagent-jnscpa/agent/sessions/b6a5e9be-dd3e-7b54-3c4f-d942de297036/contexts/await_answer1",
"lifespanCount": 4
}
],
"languageCode": "en"
}
]
}
Consequently how can I send rich message within dialogflow fullfilment?
I'm new to Node.js and was deploying Paypal rest SDK, I'm stuck at this point, I want to pass a parameter from 'success' api that called by the paypal API, to the original API called by angular
//paypal
paypal.configure({
'mode': 'sandbox', //sandbox or live
'client_id': '',
'client_secret': ''
});
app.post('/pay-online', (req, res) => {
console.log('request came')
console.log(req.body.fare.toString())
var create_payment_json = {
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
"redirect_urls": {
"return_url": "localhost:3000/success",
"cancel_url": "localhost:3000/cancel"
},
"transactions": [{
"item_list": {
"items": [{
"name": "item",
"sku": "item",
"price": req.body.fare,
"currency": "USD",
"quantity": 1
}]
},
"amount": {
"currency": "USD",
"total": req.body.fare
},
"description": "This is the payment description."
}]
};
paypal.payment.create(create_payment_json, function (error, payment) {
if (error) {
throw error;
} else {
console.log("Create Payment Response");
console.log(payment);
res.send(payment.links);
}
});
});
var getSuccess = app.get('/success', (req, res) => {
var paymentId = req.query.paymentId;
var payerId = { payer_id: req.query.PayerID };
paypal.payment.execute(paymentId, payerId, function (error, payment) {
console.log(payment.state)
if (error) {
console.error(JSON.stringify(error));
} else {
if (payment.state == 'approved') {
console.log('payment completed successfully');
} else {
console.log('payment not successful');
}
}
});
});
My question that I need to pass (payment.state) to the page that called 'pay-online' API, how can I pass the parameter back to the page?
You can return a JSON object to the page which calls the 'pay-online' API as follows if you can get the state from "paypal.payment.create" method.
app.post('/pay-online', (req, res) => {
console.log('request came')
console.log(req.body.fare.toString())
var create_payment_json = {
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
"redirect_urls": {
"return_url": "localhost:3000/success",
"cancel_url": "localhost:3000/cancel"
},
"transactions": [{
"item_list": {
"items": [{
"name": "item",
"sku": "item",
"price": req.body.fare,
"currency": "USD",
"quantity": 1
}]
},
"amount": {
"currency": "USD",
"total": req.body.fare
},
"description": "This is the payment description."
}]
};
paypal.payment.create(create_payment_json, function (error, payment) {
if (error) {
throw error;
} else {
console.log("Create Payment Response");
console.log(payment);
res.send({
payment:payment.links,
state:payment.state . <----JSON Property
});
}
});
});
If you need to call the "paypal.payment.execute" method to get the payment state then you have to call "paypal.payment.execute" method inside the '/pay-online' method's success block.
I am trying to get specific data filtered on an API call. The objects are not iterable and I have tried a million different ways to get the specific data I need.
So...I need to filter out tip_money and return only that data instead of the full response.
Here is the call
router.get('/', auth, (req, res) => {
try {
apiInstance.listPayments(opts).then(function (payments) {
res.send(payments)
})
} catch (error) {
console.error(error)
}
});
and here is the response (partially):
{
"payments": [
{
"id": "rt6Q8LL3XrCLGltl3bBhazMF",
"created_at": "2019-11-12T23:34:03.012Z",
"updated_at": "2019-11-12T23:53:45.481Z",
"amount_money": {
"amount": 13080,
"currency": "USD"
},
"total_money": {
"amount": 14047,
"currency": "USD"
},
"processing_fee": [
{
"effective_at": "2019-11-13T01:53:44.000Z",
"type": "INITIAL",
"amount_money": {
"amount": 375,
"currency": "USD"
}
}
],
"status": "COMPLETED",
"source_type": "CARD",
"card_details": {
"status": "CAPTURED",
"card": {
"card_brand": "VISA",
"last_4": "",
"exp_month": ,
"exp_year": ,
"cardholder_name": "",
"fingerprint": "",
"bin": ""
},
"entry_method": "EMV",
"cvv_status": "CVV_NOT_CHECKED",
"avs_status": "AVS_NOT_CHECKED",
"auth_result_code": "009208",
"application_identifier": "A0000000031010",
"application_name": "CITI VISA",
"application_cryptogram": "6b7992ab9fba75fe",
"verification_method": "SIGNATURE",
"verification_results": "UNKNOWN",
"statement_description": ""
},
"location_id": "",
"order_id": "",
"employee_id": "DrU-af4--DVfMCkl2z73"
},
any help in the right direction would be appreciated!
See if something like this works for you
router.get('/tips', auth, (req, res) => {
try {
apiInstance.listPayments(opts).then(function (payments) {
const tips = payments.map(payment => payment.tip_money).filter(tip => tip != undefined);
res.send(tips);
})
} catch (error) {
console.error(error)
}
});
Remove the .filter at the end if you also want the endpoint to return the undefined tips since it doesn't seem like all the payments have tips on them.
I'm trying to return some data from an api, however when I hit the server I receive a bad request message. I think the issue lies with my JSON Stringify, have I used this function correctly to concatenate my request body?
Output:
{ request:
{ passengers: { kind: 'qpxexpress#passengerCounts', adultCount: 1 },
slice: [ [Object] ],
saleCountry: 'GB',
ticketingCountry: 'GB',
solutions: 10 } }
Upload successful! Server responded with: {
"error": {
"errors": [
{
"domain": "global",
"reason": "badRequest",
"message": "Invalid inputs: received empty request."
}
],
"code": 400,
"message": "Invalid inputs: received empty request."
}
}
Code:
var express = require('express')
var router = express.Router()
var request = require('request')
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' })
})
let flightRequest = {
"request": {
"passengers": {
"kind": "qpxexpress#passengerCounts",
"adultCount": 1
},
"slice": [{
"kind": "qpxexpress#sliceInput",
"origin": "LHR",
"destination": "OSL",
"date": "2016-12-03",
"permittedDepartureTime": {
"kind": "qpxexpress#timeOfDayRange",
"earliestTime": "06:00",
"latestTime": "11:00"
}}],
"saleCountry": "GB",
"ticketingCountry": "GB",
"solutions": 10
}
}
console.log(JSON.stringify("hello" + flightRequest))
JSON.stringify(flightRequest)
console.log(flightRequest)
request.post({url:'https://www.googleapis.com/qpxExpress/v1/trips/search?key=XXXXXXXXXXXXXXXXXXXXXXXX', flightRequest: flightRequest}, function optionalCallback(err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
});
module.exports = router
I think you need to post the request as follows
request({
url: 'https://www.googleapis.com/qpxExpress/v1/trips/search?key=XXXXXXXXXXXXXXXXXXXXXXXX',
method: "POST",
json: JSON.stringify(flightRequest)
}, function optionalCallback(err, httpResponse, body) { ...
or it could be
request.post({
url: 'https://www.googleapis.com/qpxExpress/v1/trips/search?key=XXXXXXXXXXXXXXXXXXXXXXXX',
json: JSON.stringify(flightRequest)
}, ...
have I used this function correctly to concatenate my request body?
This Code
let flightRequest =
{
"request": {
"passengers": {
"kind": "qpxexpress#passengerCounts",
"adultCount": 1
},
"slice": [
{
"kind": "qpxexpress#sliceInput",
"origin": "LHR",
"destination": "OSL",
"date": "2016-12-03",
"permittedDepartureTime": {
"kind": "qpxexpress#timeOfDayRange",
"earliestTime": "06:00",
"latestTime": "11:00"
}
}
],
"saleCountry": "GB",
"ticketingCountry": "GB",
"solutions": 10
}
}
let flightAppend = {"appended text":"hello"}
var obj = Object.assign(flightAppend, flightRequest)
console.log(JSON.stringify(obj))
Produces This Output
{
"appended text": "hello",
"request": {
"passengers": {
"kind": "qpxexpress#passengerCounts",
"adultCount": 1
},
"slice": [
{
"kind": "qpxexpress#sliceInput",
"origin": "LHR",
"destination": "OSL",
"date": "2016-12-03",
"permittedDepartureTime": {
"kind": "qpxexpress#timeOfDayRange",
"earliestTime": "06:00",
"latestTime": "11:00"
}
}
],
"saleCountry": "GB",
"ticketingCountry": "GB",
"solutions": 10
}
}
I don't know if that's what you're looking for, or which side of the API you're on, but the output is valid JSON
As opposed to the original code which produces "hello[object Object]"