how do i integrate authorize.net into my wix page? - json

I am using authorize.net's sandbox API to test their gateway in my wix (corvid/code) environment. Funny thing is that when i send JSON to the sandbox API i get a valid JSON response approving the (fake) transaction. however when i set it up thru wix i get data errors in my console. I have built on existing files that i have been able to run basic API responses, and more advanced auths with token responses. so the code works, just not with authorize.net. given my level of expertise, i think it might be something im doing wrong. i've done my due diligence, and there are no questions on this topic. here is my code:
///front end, from the corvid page's code
import {buyIt} from 'backend/authorizeNet';
export function button1_click(event) {
buyIt();
}
pretty basic, just calling code from my backend onClick. the filepath is correct. here is the module on the backend:
//// backend/authorizeNet.jsw
import {fetch} from 'wix-fetch';
export function buyIt() {
let data = {
"createTransactionRequest": {
"merchantAuthentication": {
"name": "***************",
"transactionKey": "****************"
},
"refId": "123456",
"transactionRequest": {
"transactionType": "authCaptureTransaction",
"amount": "5",
"payment": {
"creditCard": {
"cardNumber": "5424000000000015",
"expirationDate": "2020-12",
"cardCode": "999"
}
},
"lineItems": {
"lineItem": {
"itemId": "1",
"name": "vase",
"description": "Cannes logo",
"quantity": "18",
"unitPrice": "45.00"
}
},
"tax": {
"amount": "4.26",
"name": "level2 tax name",
"description": "level2 tax"
},
"duty": {
"amount": "8.55",
"name": "duty name",
"description": "duty description"
},
"shipping": {
"amount": "4.26",
"name": "level2 tax name",
"description": "level2 tax"
},
"poNumber": "456654",
"customer": {
"id": "99999456654"
},
"billTo": {
"firstName": "Ellen",
"lastName": "Johnson",
"company": "Souveniropolis",
"address": "14 Main Street",
"city": "Pecan Springs",
"state": "TX",
"zip": "44628",
"country": "USA"
},
"shipTo": {
"firstName": "China",
"lastName": "Bayles",
"company": "Thyme for Tea",
"address": "12 Main Street",
"city": "Pecan Springs",
"state": "TX",
"zip": "44628",
"country": "USA"
},
"customerIP": "192.168.1.1",
"transactionSettings": {
"setting": {
"settingName": "testRequest",
"settingValue": "false"
}
},
"userFields": {
"userField": [
{
"name": "MerchantDefinedFieldName1",
"value": "MerchantDefinedFieldValue1"
},
{
"name": "favorite_color",
"value": "blue"
}
]
}
}
}
}
return fetch("https://test.authorize.net/xml/v1/request.api", {
"method": "post",
"headers": {"Content-Type": "application/json"},
"body": data
})
.then(response => {console.log(response.json())});///if response.text is used, it gives details
}
note at the end of the backend code, calling response.json give me a json error, due to the return code contains HTML saying that i've requested invalid data. if i change it to response.text i get this in my console:
//console response with response.text
{...}
isFulfilled:
true
isRejected:
false
fulfillmentValue:
"<HTML><HEAD>\n<TITLE>Bad Request</TITLE>\n</HEAD><BODY>\n<H1>Bad Request</H1>\nYour browser sent a request that this server could not understand.<P>\nReference #7.1d60fea5.1557756725.387c74\n</BODY>\n</HTML>\n"
how do i get a good response from the API? like ive done with the same code in postman?
thanks in advance

return fetch(url, {
method: "post",
headers: {"Content-Type": "application/json"},
body: JSON.stringify(data)
})
.then(response => console.log(response.text())
)
this got me the result i was looking for
stringify() converted my object to a JSON string. i still cannot get it to read the incoming JSON, might have to use parse...but if i read as text i get the info i want and my API is showing a successful transaction.

Related

Cypress login to REST endpoint is unauthorized, Postman works - upload of JSON file

We have a REST service with an incoming REST endpoint that accepts data. It has no web interface (Swagger or so), only the API. With Postman I can POST a JSON file (response code is 202) to it and then read the uploaded data from another endpoint.
When I want to log in to the same endpoint with Cypress to upload a JSON file from the fixtures folder (with the same body as in the Postman request), then I get response code 401 instead – Unauthorized. I have the feeling that the cypress request is wrong because the logfile of the service does not write a message when I use the cypress POST but it does when I use the Postman POST.
First question: What could I be doing wrong in the cypress request?
Second question: Once the authentication works, how can I POST/upload/push the content of the JSON file to that endpoint? Because I have no webpage to interact with, I cannot use click button functions. The documentation mainly deals with interpreting a JSON response but not with sending it.
My cypress code:
it('logs in to connector through REST API', () => {
cy.request({
method: 'POST',
url: 'localhost:8095/connector/demands/v1/demandData',
failOnStatusCode:false,
form: true,
body: {
Username: 'user',
Password: 'pass',
}
})
})
import my-request from '../fixtures/my-request.json'
it('loads the JSON file', () => {
cy.fixture('my-request.json')
})
The structure of the JSON file to upload is not too simple, here is a shortened version:
{
"#metadata": {
"context": "{{A}}"
},
"pool": "{{B}}",
"action": "NEW",
"Type": "ANNOUNCEMENT",
"ON": "Order123",
"PON": "PO123",
"SNN": "SN123",
"direction": "OUT",
"mode": 3,
"pack": [
{
"out": {
"outKey": "OUT14",
"outQuantity": "3",
"dimension": {
"length": "303",
"width": "33",
"height": "903",
"unit": "mm"
},
"layers": "3",
"weight": "3000",
"weightUnit": "grm",
"in": [
{
"inKey": "IN12",
"inQuantity": "3",
"article": {
"articleKey": "article3",
"quantity": "300",
"PON": "Art_PO300",
"SNN": "Art_SN300"
}
}
]
},
"p1": "pack3",
"p2": "pack4",
"store": true
},
{
"out": {
"outKey": "OUT23",
"outQuantity": "5",
"dimension": {
"length": "505",
"width": "55",
"height": "905",
"unit": "mm"
},
"layers": "5",
"weight": "5000",
"weightUnit": "grm",
"in": [
{
"inKey": "IN19",
"inQuantity": "5",
"article": {
"articleKey": "article5",
"quantity": "500",
"PON": "Art_PO500",
"SNN": "Art_SN500"
}
}
]
},
"p1": "pack5",
"p2": "pack5",
"store": true
}
]
}
Solution found. "form: true" must not be given because this overrides the content-type.
You can pass the contents of the fixture file(which is json) in the request body like this:
describe('Some Test Suite', function() {
// we can use these values to log in
const username = 'jane.lane'
const password = 'password123'
it('logs in to connector through REST API', () => {
cy.fixture('my-request.json').then(myFixture => {
cy.request({
method: 'POST',
url: 'localhost:8095/connector/demands/v1/demandData',
auth: {
username,
password,
},
failOnStatusCode: false,
form: true,
body: myFixture
})
})
})
})
For HTTP auth you have to use. You can check out this cypress recipe.
auth: {
username,
password,
}

How to validate the contents inside the JSON body

In postman i want to to validate '"name": "Twilio"', which is inside data > twilio > viewable > name
here is the JSON response ive got
{
"success": true,
"timestamp": "2019-08-12T12:31:33+00:00",
"response_code": 200,
"data": {
"twilio": {
"name": "Twilio",
"slug": "twilio",
"image": "https://s3-eu-west-1.amazonaws.com/connector-assets/images/twilio.png",
"description": "Twilio is a cloud communications platform as a service. Integrate your Twilio account to send outgoing SMS from Purple.",
"category": "communication",
"connectedCount": 1,
"allowMultipleAdd": false,
"editable": [],
"viewable": {
"cf-5d51503868af3": {
"name": "Twilio"
}
},
"id": "cf-5d515c2527579",
"overrideAllowed": false
},
"salesforce-mc": {
"name": "Salesforce marketing cloud",
"slug": "salesforce-mc",
"image": "https://s3-eu-west-1.amazonaws.com/connector-assets/images/sf-mc.png",
"description": "Salesforce Marketing Cloud is a provider of digital marketing automation and analytics software and services.",
"category": "marketing-automation",
"connectedCount": 0,
"allowMultipleAdd": true,
"editable": [],
"viewable": [],
"id": "cf-5d515c252bc31",
"overrideAllowed": true
}
}
}
The easiest way is to process the response as JSON, and simply check your hierarchy:
In the tests section, you can add a number of tests:
pm.test("Response should be OK", function () {
pm.response.to.be.ok;
});
// You can actually check for explicit response code if a 200 series is not enough.
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
// Optionally test the returned Content-Type is correct.
pm.test("Content-Type is present", function () {
pm.response.to.have.header("Content-Type");
});
pm.test("Response should be okay to process", function () {
pm.response.to.be.ok;
pm.response.to.not.be.error;
});
pm.test("Body contains JSON data result with Twilio as the viewable name", function () {
const JsonData = pm.response.json();
pm.expect(JsonData.data.twilio.viewable.name).to.equal('Twilio');
});
For safety, you can check that each parent element exists first (validate data is in JsonData) to avoid errors should the payload change or not match what you expect.
EDIT: Your JSON structure:
{
"success": true,
"timestamp": "2019-08-12T12:31:33+00:00",
"response_code": 200,
"data": {
"twilio": {
"name": "Twilio",
"slug": "twilio",
"image": "https://s3-eu-west-1.amazonaws.com/connector-assets/images/twilio.png",
"description": "Twilio is a cloud communications platform as a service. Integrate your Twilio account to send outgoing SMS from Purple.",
"category": "communication",
"connectedCount": 1,
"allowMultipleAdd": false,
"editable": [],
"viewable": {
"cf-5d51503868af3": {
"name": "Twilio"
}
},
"id": "cf-5d515c2527579",
"overrideAllowed": false
},
"salesforce-mc": {
"name": "Salesforce marketing cloud",
"slug": "salesforce-mc",
"image": "https://s3-eu-west-1.amazonaws.com/connector-assets/images/sf-mc.png",
"description": "Salesforce Marketing Cloud is a provider of digital marketing automation and analytics software and services.",
"category": "marketing-automation",
"connectedCount": 0,
"allowMultipleAdd": true,
"editable": [],
"viewable": [],
"id": "cf-5d515c252bc31",
"overrideAllowed": true
}
}
}
Based on this, the text you are looking for is present, but under an ID, not directly available as you indicated. There are two checks that could be done:
1. Use the name in the main block
pm.test("Body contains JSON data result with Twilio as the viewable name", function () {
const JsonData = pm.response.json();
pm.expect(JsonData.data.twilio.name).to.equal('Twilio');
});
The other would be to extract the viewable value ('cf-5d51503868af3') and use this value as a key to do the test. Not sure if this is available to you from your user id or another data source. If not, then you need to extract it from the JsonData.data.twilio.viwable object. There are some more useful examples here in this answer.

POSTMAN - Schema validation is passed even for bad response data

tests["Valid schema"] = tv4.validate(jsonData, schema); is passed even if "error" and "responseType" is missing in the schema. How to make sure that response and schema both are matching for JSON schema.
when I hit post request on postman, the following is the Response Body in postman
{
"statusCode": 400,
"error": "Bad Request",
"message": "Email/Phone number not found",
"responseType": "EMAIL_NOT_FOUND",
"arabicMessage": "البريد الإلكتروني / رقم الهاتف غير موجود"
}
Tests in Postman
var jsonData=JSON.parse(responseBody)
var schema ={
"statusCode": {"type":"integer"},
"message": {"type":"string"},
"arabicMessage":{"type":"string"},
"data": {
"accessToken": {"type":"string"},
"userDetails": {
"_id": {"type":"string"},
"deviceType": {"type":"string"},
"countryCode": {"type":"string"},
"OTPCode": {"type":"integer"},
"invitationCode": {"type":"string"},
"availableCredits": {"type":"integer"},
"totalBookings": {"type":"integer"},
"promoCodes": {"type":"array"},
"updatedAt": {"type":"string"},
"createdAt": {"type":"string"},
"language": {"type":"string"},
"IsDeleted": {"type":"boolean"},
"IsVerified": {"type":"boolean"},
"IsBlock": {"type":"boolean"},
"customerAddresses": {"type":"array"},
"address":{"type":"string"},
"phoneVerified": {"type":"boolean"},
"currentLocation": {
"type": "Point",
"coordinates": [
{"type":"integer"},
{"type":"integer"}
]
},
"appVersion": {"type":"integer"},
"profilePicURL": {
"thumbnail": {"type":"string"},
"original": {"type":"string"}
},
"password": {"type":"string"},
"socialId": {"type":"string"},
"phoneNo": {"type":"integer"},
"email": {"type":"string"},
"LastName": {"type":"string"},
"firstName": {"type":"string"},
"__v": {"type":"integer"},
"referralCode": {"type":"string"},
"accessToken": {"type":"string"},
"deviceToken": {"type":"string"}
},
"updateAvailable": {"type":"boolean"},
"stateCallBookingIds": {"type":"array"},
"forceUpdate": {"type":"boolean"}
}
};
tests["Valid schema"] = tv4.validate(jsonData, schema);
//here the test is passing even with invalid jsonData which is the data
console.log("Validation failed: ", tv4.error);
There are lots of open issues on the Postman github account about the tv4 module.
There is a similar question on SO here, could your jsonData be different than your schema?
This is an example from a link on the tv4 github page.
"title": "Person",
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"age": {
"description": "Age in years",
"type": "integer",
"minimum": 0
}
},
"required": ["firstName", "lastName"]
}
You could try adding those fields as required?
Just leaving this here in case it helps anyone else. tv4.validate has two additional boolean parameters: checkRecursive and banUnkownProperties.
Especially the last one can help finding errors in JSON responses when they contain attributes that weren't defined in the schema.
Reference
I prefer to use jsonSchema this way:
var strSchema =
pm.collectionVariables.get("variable_that_contains_the_schema");
pm.test("Validate SCHEMA is OK", () => {
pm.response.to.have.jsonSchema(JSON.parse(strSchema));
});
And if you want to auto-generate the schema, you can use the generate-schema plugin https://www.npmjs.com/package/generate-schema
I use to store the content of this plugin in a collection variable, on the pre-request of my collection, like this:
Then in the test tab of your request, you can call the javascript eval() to load the generate-schema source-code in the postman's test environment:
// eval will evaluate the JavaScript generateSchema code and
// initialize the js on postman environment
eval(pm.collectionVariables.get("generate-schema"));
var strSchema =
pm.collectionVariables.get("variable_that_contains_the_schema");
if (strSchema === undefined){
console.log('>>>> variable for schema not defined!');
return;
}
if(strSchema == '' | strSchema === null) {
// call function generateSchema (external)
var schema = generateSchema.json("variable_that_contains_the_schema", jsonData);
delete schema.$schema; // remove the element '$schema' --> causes error in validator
var strSchema = JSON.stringify(schema);
//save the generated schema
pm.collectionVariables.set("variable_that_contains_the_schema", strSchema);
console.log(" >> schema was generated from the response, validation will proceed on the next request.");
}
else
{
console.log(" >> schema recovered from variable.");
// Schema test ------------------------------------------------
pm.test("Validate SCHEMA is OK", () => {
pm.response.to.have.jsonSchema(JSON.parse(strSchema));
});
}

Liferay API update Data with JSON

I am working on an API for my Portal, to provide users the ability to update there data via API directly from there internal Systems.
Liferay 6.2 bundle Tomcat. (for api call testing I use soapUI)
The get Methods work fine, (I have getAll, and getByID). getByID returns a JSON Object like this:
{
"ID": "ORGANIZATIONID",
"type": "ORGANIZATIONTYPE",
"name": "ORGANIZATIONNAME",
"URI": "ORGANIZATIONNAMEURI"
"date of inclusion": "INCLUTIONDATE",
"last activities": "LASTMODIFIEDDATE",
"address": {
"name of host institution": "NAMEOFHOSTINSTITUTE",
"street1": "STREET1",
"street2" : "STREET2",
"zip": "ZIP",
"city": "CITY",
"country": "COUNTRY",
},
"url": [{"ORGANIZATIONURL"}],
"main contact": {
"first name": "FIRSTNAME",
"last name" : "LASTNAME",
"phone": "PHONE",
"email": "MAINCONTACTEMAIL"
},
"type of host institution" : "TYPEOFHOSTINSTITUTE",
"diseases": [
{
"name": "DISEASENAME1",
"number": "SAMPLECOUNT",
"gene": "GENE",
"orphacode": "ORPHA"
"icd10": "ICD",
"omim": "OMIM";
"synonym": "SYNONYM"
},
{
"name": "DISEASENAME2",
"number": "SAMPLECOUNT",
"gene": "GENE",
"orphacode": "ORPHA"
"icd10": "ICD",
"omim": "OMIM";
"synonym": "SYNONYM"
}
]
}
I would like to have an API for Updating the diseases information for an organization. I have created a URL service where everything is in the url as parameters, but I would like to have it that the in the url only the id parameter is send and the rest of the information in a JSON object. Like:
/api/jsonws/....-portlet...../updateregbb/organization-id/16016/
and the data:
{
"ID": "ORGANIZATIONID",
"diseases": [
{
"name": "DISEASENAME1",
"number": "SAMPLECOUNT",
"gene": "GENE",
"orphacode": "ORPHA"
"icd10": "ICD",
"omim": "OMIM";
"synonym": "SYNONYM"
},
{
"name": "DISEASENAME2",
"number": "SAMPLECOUNT",
"gene": "GENE",
"orphacode": "ORPHA"
"icd10": "ICD",
"omim": "OMIM";
"synonym": "SYNONYM"
}
]
}
But I could not find a solution how I can read the JSON data:
#JSONWebService(value = "updateregbb", method = "POST")
public void updateregbb2(long organizationId, Map jsondata) {
#JSONWebService(value = "updateregbb", method = "POST")
public void updateregbb(long organizationId, JSONObject json) {
How can I get the Data into my function?
Thanks for the help,
Best
Robert

How to Force Jersey to generate Specified JSON Response

So, I have started using Jersey as the implementation of JAX-RS in our application for REST services and I came across a strange issue with it. We have been provided with a standard response as below:
"Outer":
{
"agencyPercentagePayment": "80",
"agencyProviderPaymentAmount": "140.00",
"benCoDtls":
{
"benCode": "String1",
"fullName": "String2",
"id": "String3",
"title": "String4"
},
"levelOfCare": "Full-Time",
"paymentDate": "2014-02-19T15:20",
"titleInfo":
{
"benAmt": "140.0",
"benDesc": "AAAA",
"subTitle": "aaaa",
"title": "String"
},
"units": "10"
}
However, The JSON generated by the Jersey provider generates an arbitary response as below:
"Outer":
{
"agencyProviderPaymentAmount": "140.00",
"benCoDtls":
{
"benCode": "String1",
"fullName": "String2",
"id": "String3",
"title": "String4"
},
"agencyPercentagePayment": "80",
"titleInfo":
{
"benAmt": "140.0",
"benDesc": "AAAA",
"subTitle": "aaaa",
"title": "String"
},
"paymentDate": "2014-02-19T15:20",
"levelOfCare": "Full-Time",
"units": "10"
}
As seen above the response expects agencyPercentagePayment to be first element of Outer levelOfCare as first element after completion of benCoDtls array and paymentDate after levelOfCare, however the response is different as you see.
Any suggestions how to enforce the response generated by the Jersey Jackson Providers? I can share the Java class if required.
Thanks
You should be able to fix this using #XmlType annotation:
#XmlType(propOrder={"agencyPercentagePayment", "agencyProviderPaymentAmount" , ... })
#XmlRootElement
public class Outer {
....
}