Get Data from an Object in the Browser - javascript

How can I get an object from my browser / get the data stored in the object from my browser?
The user presses submit button after filling out a form with a bad credit card number (a scenario I am testing), which triggers a jQuery function SubmitAPI() (code below).
Google Chrome console displays 400 Bad Request error (because the credit card number is bad) as well as an API Response holding the object with the declined credit card data (response below)
I specifically need to grab "response_type":"D","response_code":"U20","response_desc":"INVALID CREDIT CARD NUMBER" because I want to display this error message to the user. How can I do this in jQuery?
I have tried for hours to figure this out. I use response.response.response_type to get the Response Type when the transaction is successful (approved credit card). However with a bad credit card number, this same attempt results in "undefined". So, instead, I just want to grab the data from my Google Chrome browser that managed to get the Response Code response.
PART 1: jQuery Code (Directly from the API's documentation - except I changed the credit card to be a bad number)
function SubmitAPI() {
var settings = {
"url":
"https://sandbox.forte.net/api/v3/organizations/org_ID/locations/loc_ID/transactions",
"method": "POST",
"headers": {
"X-Forte-Auth-Organization-Id": "org_ID",
"Authorization": "ID",
"Content-Type": "application/json"
},
"data": JSON.stringify({ "action": "sale", "authorization_amount": 102.45, "subtotal_amount": 99.95, "billing_address": { "first_name": "Jennifer", "last_name": "McFly" }, "card": { "card_type": "visa", "name_on_card": "Jennifer McFly", "account_number": "41111sdf11111111", "expire_month": "12", "expire_year": "2017", "card_verification_value": "123" } }),
};
$.ajax(settings).always(function (response) {
console.log(response);
});
}
PART 2: Console Response:
400 (Bad Request)
PART 3: Response Object in Browser:
{"location_id":"loc_241789","action":"sale","authorization_amount":102.45,"entered_by":"59ae172b3bd78bed493ecd5892975764","billing_address":{"first_name":"Jennifer","last_name":"McFly"},"card":{"name_on_card":"Jennifer McFly","last_4_account_number":"1111","masked_account_number":"****1111","expire_month":12,"expire_year":2017,"card_type":"visa"},"response":{"environment":"sandbox","response_type":"D","response_code":"U20","response_desc":"INVALID CREDIT CARD NUMBER"}}

Using error handler for the Ajax call and was able to get the error message with no issues.
var settings = {
"url": "https://sandbox.forte.net/api/v3/organizations/org_381529/locations/loc_241789/transactions",
"method": "POST",
"headers": {
"X-Forte-Auth-Organization-Id": "org_381529",
"Authorization": "Basic NTlhZTE3MmIzYmQ3OGJlZDQ5M2VjZDU4OTI5NzU3NjQ6ZWUwZTZiZDA4ZThlMWNhNWQ3MzUyNGU0ZWU5ZDFjNTg=",
"Content-Type": "application/json"
},
"data": JSON.stringify({
"action": "sale",
"authorization_amount": 102.45,
"subtotal_amount": 99.95,
"billing_address": {
"first_name": "Jennifer",
"last_name": "McFly"
},
"card": {
"card_type": "visa",
"name_on_card": "Jennifer McFly",
"account_number": "41111sdf11111111",
"expire_month": "12",
"expire_year": "2017",
"card_verification_value": "123"
}
}),
};
$.ajax(settings).error(function(xhr) {
console.log("Error", xhr.responseJSON.response.response_desc);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

Related

NodeJS Https.request issue

I am trying to write a test post to the Zip API:
Zip Api
JSON posted, as per Zip Pay's example -
{
"shopper": {
"title": "Mr",
"first_name": "John",
"last_name": "Smith",
"middle_name": "Joe",
"phone": "0400000000",
"email": "test#emailaddress.com",
"birth_date": "2017-10-10",
"gender": "Male",
"statistics": {
"account_created": "2015-09-09T19:58:47.697Z",
"sales_total_number": 2,
"sales_total_amount": 450,
"sales_avg_value": 250,
"sales_max_value": 350,
"refunds_total_amount": 0,
"previous_chargeback": false,
"currency": "AUD"
},
"billing_address": {
"line1": "10 Test st",
"city": "Sydney",
"state": "NSW",
"postal_code": "2000",
"country": "AU"
}
},
"order": {
"reference": "testcheckout1",
"amount": 200,
"currency": "AUD",
"shipping": {
"pickup": false,
"tracking": {
"uri": "http://tracking.com?code=CBX-343",
"number": "CBX-343",
"carrier": "tracking.com"
},
"address": {
"line1": "10 Test st",
"city": "Sydney",
"state": "NSW",
"postal_code": "2000",
"country": "AU"
}
},
"items": [
{
"name": "Awesome shoes",
"amount": 200,
"quantity": 1,
"type": "sku",
"reference": "1"
}
]
},
"config": {
"redirect_uri": "http://www.redirectsuccess.com/zipmoney/approved"
},
"metadata": {
"name1": "value1"
}
}
but I am getting an error message:
{"error":{"code":"request_invalid","message":"There are errors with the request, please see error items for more detail","details":[{"name":"Amount","message":"'Amount' must be greater than '0'."},{"name":"Currency","message":"Currency must be either 'AUD' or 'NZD'"},{"name":"Authority","message":"'Authority' must not be empty."}]}}
Cant figure out what is wrong. These elements exist in the data sent. Have used Axios and the request comes back fine. But Node's HTTPS object doesnt work. Why? :(
TIA
const postData = JSON.stringify(data);
let options = {
"host": 'api.sandbox.zipmoney.com.au',
"path": '/merchant/v1/charges',
"method": 'POST',
"port": 443,
"encoding": "utf8",
"headers": {
'Authorization': 'Bearer test',
'Content-Type': 'application/json',
'Content-Length': postData.length,
'Zip-Version': '2017-03-01'
}
};
const req = https.request(options, (response)=>{
console.log(`statusCode: ${response.statusCode}`)
var str = ''
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
console.log("have end data")
console.log(str);
});
})
req.on('error', error => {
console.log("zip errors...")
console.error(error)
})
req.write(postData)
req.end();
I had some time to take another look at your question, today, but still haven't found a definite solution to your specific issue. While this post may not answer your question, I wanted to post my findings here.
Here is the code that I tried (based on your code) on my side using a different test API:
// ref: https://stackoverflow.com/q/66218603/1167750
// ref: https://attacomsian.com/blog/node-http-post-request
const https = require('https');
let data = {
"title": "test",
"body": "Content",
"userId": 1
}
const postData = JSON.stringify(data);
let options = {
"host": 'jsonplaceholder.typicode.com',
"path": '/posts',
"method": 'POST',
"port": 443,
"encoding": "utf8",
"headers": {
'Content-Type': 'application/json',
'Content-Length': postData.length,
'Zip-Version': '2017-03-01'
}
};
const req = https.request(options, (response)=>{
console.log(`statusCode: ${response.statusCode}`)
var str = ''
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
console.log("have end data")
console.log(str);
});
})
req.on('error', error => {
console.log("zip errors...")
console.error(error)
})
req.write(postData)
req.end();
When I run this with Node, I get the output:
$ node test.js
statusCode: 201
have end data
{
"title": "test",
"body": "Content",
"userId": 1,
"id": 101
}
So I'm able to get a normal response back from this other API while using a lot of your code from your post. This seems to show that your approach with using Node's https module works for another API at least. Maybe this can help you narrow down where the issue is based on this test information.
Additionally, from your example json data, I don't see a place where the Authority field is filled out in your request. The error message you got indicated that it was required and the related documentation seems to require that too. But maybe this was simply removed from your json data before it was posted in your question for security reasons?
Seeing that you do have the amount and currency values set in your json order data, that seems to indicate that the API is not recognizing your json data that is being sent. But hearing that the axios approach works makes this issue still confusing.
Though it might not be necessary, I also checked your json data in a linter and it came back as valid (as you already know). Wanted to double check if there was some issue related to that, though.

How to pull response from a URL and than put said response into a JSON

I need to send a request to https://authserver.mojang.com/authenticate
and get the response
{
"accessToken": "valid accessToken",
"clientToken": "client identifier",
"selectedProfile": {
"id": "profile identifier",
"name": "player name"
},
"requestUser": true
}
But I dont know how to ask the server for the out put.
What I need to input is
{
"agent": { "name": "Minecraft", "version": 1 },
"username": "-email here-",
"password": "-pass here-"
}
That is the data needed to get the token but I can't seem to get the code to ask the server for the token data and than receive it and put it into a JSON.
const postData = async _ => {
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
"agent": { "name": "Minecraft", "version": 1 },
"username": "-email here-",
"password": "-pass here-"
})
})
console.log(response)
}
This should get the response you need judging by https://wiki.vg/Authentication#Payload this link.

Wait for specific response in XHR polling with Cypress

I have a cypress spec with which I want to test a function on my site which polls a third party API until it receives a correct answer and then shows more information for the user to continue with the function.
I start my spec with
cy.server();
cy.route('GET', '**/that-other-api/**').as('otherApi');
I know that this part works. The route is listed in the top of the Cypress test GUI, and my otherApi alias is attached to the XHR requests when they are listed in the command list when running.
When the user (or my test) clicks a button the site will start polling that endpoint. When I receive a status: success in the response, the user (or my test) is provided with a filled dropdown of options and can continue.
How can I get Cypress to wait until I get that specific response from the XHR request (or reaches a cypress timeout) and then continue onwards?
The Network request documentation doesn't explain if this is possible or not. I have tried
cy.wait('#billectaAccounts').should('have.property', 'response.body.status', 'success');
and just to see if stuff works
cy.wait('#billectaAccounts').should('have.property', 'status', 201);
which both throw an error:
InvalidStateError: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's 'responseType' is '' or 'text' (was 'json').
Logging the response with
cy.wait('#billectaAccounts').then(console.log);
logs the response and shows that my status variable is there, but is pending since it's only on the first request.
{
"xhr": {
"method": "GET",
"url": "https://myapi/longToken",
"id": "xhr193"
},
"id": "xhr193",
"url": "https://myapi/longToken",
"method": "GET",
"status": 200,
"statusMessage": "200 (OK)",
"request": {
"headers": {
"Accept": "application/json, text/plain, */*"
},
"body": null
},
"response": {
"headers": {
"cache-control": "max-age=0, private, must-revalidate",
"connection": "close",
"content-type": "application/json; charset=utf-8",
"date": "Tue, 24 Mar 2020 08:32:09 GMT",
"etag": "W/\"f0d6999f3be78c3dc8eab419745ec489\"",
"referrer-policy": "strict-origin-when-cross-origin",
"server": "Cowboy",
"vary": "Origin",
"via": "1.1 vegur",
"x-content-type-options": "nosniff",
"x-download-options": "noopen",
"x-frame-options": "SAMEORIGIN",
"x-permitted-cross-domain-policies": "none",
"x-request-id": "id",
"x-runtime": "0.006788",
"x-xss-protection": "1; mode=block"
},
"body": {
"id": 721,
"public_id": "longTokenId",
"bank": "bank-id",
"ssn": "ssn-number",
"status": "pending",
"created_at": "2020-03-24T09:32:05.362+01:00",
"updated_at": "2020-03-24T09:32:06.028+01:00",
"account_numbers": [],
"token": "pollingToken"
}
},
"duration": 230
}
I would prefer to not stub the response, It's nice to have the end to end test to that API.
Any help appreciated!

firebase "long link is not parsable"

I want to shorten a longLink with firebase and the REST API but I get the following response and I don't know what is wrong:
Response:
{
"error": {
"code": 400,
"message": "Long link is not parsable: https://www.google.de [https://firebase.google.com/docs/dynamic-links/rest#create_a_short_link_from_parameters]",
"status": "INVALID_ARGUMENT"
}
}
And this is how I do it:
The Request: https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=(hereismyapikey)
the Body lookes like this:
{
"longDynamicLink": "https://www.google.de",
"suffix": {
"option": "SHORT"
}
}
I tried first with the real URL I want to shorten. Same error. Than with google and with and without the http(s). I'm out of options and hope somebody sees what I did wrong here.
EDIT: Full Postman request:
"item": [
{
"name": "shortLinks",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\r\n \"longDynamicLink\": \"www.google.de\",\r\n \"suffix\": {\r\n \"option\": \"SHORT\"\r\n }\r\n}"
},
"url": {
"raw": "https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=xxx",
"protocol": "https",
"host": [
"firebasedynamiclinks",
"googleapis",
"com"
],
"path": [
"v1",
"shortLinks"
],
"query": [
{
"key": "key",
"value": "xxx"
}
]
}
},
"response": []
}
]
You are using the simple method for creating dynamic link which is roughly equals to the manual creation of dynamic link : https://firebase.google.com/docs/dynamic-links/create-manually
In the docs if you see the link passed in example carefully you will see the pattern as below:
https://your_subdomain.page.link/?link=your_deep_link&apn=package_name[&amv=minimum_version][&afl=fallback_link]
So you should format the input link according to this or create using the parameters which has very good breakdown of parameters in json:
https://firebase.google.com/docs/dynamic-links/rest#create_a_short_link_from_parameters
Here is the api reference for firebase dynamic link creation from parameters:
https://firebase.google.com/docs/reference/dynamic-links/link-shortener#parameters
I find the JSON parameter method is easier.
var body = {
"dynamicLinkInfo": {
"dynamicLinkDomain": "yourcustom.page.link",
"link": fileUrl
},
"suffix": {
"option": "SHORT"
}
};
Then if you're using Node. The node-fetch package REST call would work like:
var fetchFileUrl = fetch(YOUR_SHORTLINK_URL, {
method: 'POST',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
}).then(function(response){
return response.json();
});

JSONP Object Error

I am trying to make a cross domain request to send/recieve some data. I can't get past the object error. Before I was getting the No Transport Error but adding Query.support.cors = true; solved this issue.
var url = "http://CROSSDOMAINSERVER:PORT/Service1.svc/GetDataUsingDataContract";
$.ajax({
type: 'GET',
url: url,
data: 'tool=1&product=Some%20Product&details=9&bogus=should%20not%20pass%20validation',
datatype: "jsonp",
contentType: "application/json",
success: function (response) {
alert(response.data);
},
error: function (error) {
alert(error.statusText);
}
});
If I type the url out in a browser:
http://CROSSDOMAINSERVER:PORT/Service1.svc/GetDataUsingDataContract?&tool=1&product=Some%20Product&details=9&bogus=should%20not%20pass%20validation
I get the correct response.
{"d":{"__type":"ClientSideData:#ProdResourceToolService","details":"9","product":"Some Product","result":"1","site":"Somewhere, SD","systime":"2\/6\/2013 2:50:20 PM","team":"0000000000","tool":"1","user":"username"}}
When I use ajax it does not submit it to the database or return data, just object error. Does anyone have any suggestions on how to get around this?
I should also specify if I remove http://CROSSDOMAINSERVER:PORT/ from var url when debugging locally I get the correct json response. Why does cross domain not work?
This is your current response:
{
"d": {
"__type": "ClientSideData:#ProdResourceToolService",
"details": "9",
"product": "Some Product",
"result": "1",
"site": "Somewhere, SD",
"systime": "2/6/2013 2:50:20 PM",
"team": "0000000000",
"tool": "1",
"user": "username"
}
}
This is a valid JSON string. However, its not valid JSONP. If possible, make your service wrap the json in a function:
responseFunc({
"d": {
"__type": "ClientSideData:#ProdResourceToolService",
"details": "9",
"product": "Some Product",
"result": "1",
"site": "Somewhere, SD",
"systime": "2/6/2013 2:50:20 PM",
"team": "0000000000",
"tool": "1",
"user": "username"
}
});
And in your $.ajax() call, add a property: jsonpCallback: 'responseFunc'.
Also, I would suggest passing the data as an object:
data: { tool: 1, product: 'Some Product' } //etc...
If you can access the service from the serverside without any issues you could create a httphandler (.ashx for example) and let it generate the JSON for you. Then you wouldn't have to deal with the cross domain issues on the client side.

Categories

Resources