I am trying to develop payment module with angularjs and asp.net web api.
I am using an payment api (iyzico).
With that api I create shopping token request and this request return an js script response and a shopping token.
I load this js file and payment form is generated by returning js file.
After generating payment form, I entered my credit card infos and send these infos to payment api then payment api return response but I could not get this response from page (This response come when page is loading).
Http Get method for generating shopping token in payment.js
function loadDetails() {
$http.get( '/API/api/profile/GetPaymentToken').then(function (results) {
$scope.paymentData = jQuery.parseJSON(results.data);
$scope.code_snippet = $sce.trustAsHtml($scope.paymentData.code_snippet);
var paymentScriptUrl = "https://www.iyzico.com/frontend/form/v1/widget.js?mode=test&token=" + $scope.paymentData.transaction_token;
$.ajax({
url: paymentScriptUrl,
dataType: "script",
cache: true,
success: function (data, textStatus, jqXHR) {
var f = new Function(data);
f();
iyzi_jQuery(this).iyziPayment({
host: 'https://iyziconnect.com/pay-with-transaction-token/',
mode: 'test',
assetsURL: 'https://www.iyzico.com/frontend/form/v1/',
installment: '0',
language: 'tr'
});
},
error: function (jqXHR, status, err) {
console.log("");
}
});
},
function (response) { // optional
_helper.error.handleError(toaster, response.data, response.status);
})
}
Token Generator in Web.Api, it is called in payment.js
[Authorize]
[HttpGet]
[Route("GetPaymentToken")]
public async Task<IHttpActionResult> GetPaymentToken()
{
System.Diagnostics.Debugger.Break();
WebRequest request = WebRequest.Create("https://api.iyzico.com/v2/create");
request.Method = "POST";
var rand = new Random();
var external_id = rand.Next(0, 100000000);
string postData = "api_id=my_id"
+ "&secret=my_secret"
+ "&external_id=" + external_id.ToString()
+ "&mode=test"
+ "&type=CC.DB"
+ "&return_url=http://localhost:2020/payment2" //returning url
+ "&amount=10020"
+ "¤cy=TRY"
+ "&descriptor=PAYMENT_DESCRIPTION"
+ "&customer_contact_ip=CUSTOMER_IP"
+ "&customer_language=tr"
+ "&installment=false";
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
System.IO.Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse response = request.GetResponse();
dataStream = response.GetResponseStream();
System.IO.StreamReader reader = new System.IO.StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
reader.Close();
dataStream.Close();
response.Close();
return Ok(responseFromServer);
After getting shopping token I enter my credit card infos and send form to external payment api and external api return information to my return url (http://localhost:2020/payment2) about my payment is successful or failed .
I can see returning responce from external api at chrome developer tools > network actions but I can not get that form data from mycontroller js file. returning response is at below
Remote Address:[::1]:2020
Request URL:http://localhost:2020/payment2
Request Method:POST
Status Code:200 OK
Response Headers
view source
Cache-Control:private
Content-Length:11337
Content-Type:text/html
Date:Fri, 03 Apr 2015 08:45:22 GMT
Server:Microsoft-IIS/8.5
X-Powered-By:ASP.NET
Request Headers
view source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6,tr;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Content-Length:532
Content-Type:application/x-www-form-urlencoded
Cookie:countrySCJS=TR; ootdcuSCJS=34602; ootdchSCJS=10742; ctxjs1420m06d05=7b2273756363657373223a302c226c6f675f616374697665223a317d; ASPSESSIONIDQCDBDRBQ=BKGJHHKCKDDLJCBBPMPJJHFH; ASPSESSIONIDQAADBTBR=AMPJDALCPFGILMAOKEDMMGBP; ASPSESSIONIDSCAADQAR=GKKFJCCDLILKPNHAEHBHHLHJ
Host:localhost:2020
Origin:null
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36
Form Data
view source
view URL encoded
**json:{"response":{"state":"failed","date_time":"15-04-03 08:43:24","error_code":"800.100.154","error_message":"transaction marked as invalid","error_message_tr":""},"transaction":{"transaction_id":"MTQyODA1MDU4NAnrin0vdEV06f4hWARX","external_id":"23583443","reference_id":"____________20150403084323.653059Kq","state":"rejected","connector_type":"Isbank","installment_count":0}}**
How can I get that json named array?
You have to sacrifice your your single page application for callback.
Get callback to your REST address
Process the POST parameters
Generate (return text/html) a simple SUCCESS of FAIL page. Let this page contain the result and link to appropriate page (main page url or payment page url)
Link should open your single page angularjs and your controller should display
appropriate page according to URL.
Related
I've created an asp.net core project and in the project I have an angularjs application and also a web api project. The angularjs application loads when I login via postman I get the response I expect in json. But when I try the same in angularjs I get the response in html.
I've tried quite a few settings but unable to get this working.
Tried setting the $http services header, and $httpProvider header but unable to get this working in angular js.
I set the content-type in postman to application/json and it works so not think its because the content-type is wrong in angular js.
Startup.cs file:
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvcCore()
.AddJsonFormatters();
// Add framework services.
services.AddMvc().AddJsonOptions(
options =>
options.SerializerSettings.ContractResolver = new
CamelCasePropertyNamesContractResolver()
);
The controller in web api is:
[Route("test3")]
[HttpPost]
public JsonResult Test3([FromBody]LoginUserRequest model)
{
LoginUserResponse response = new LoginUserResponse();
response.validLogin = false;
response.Message = "failed" + model.Email;
return Json(response);
}
Angular js service:
vm.getLogin = getLogin;
function getLogin(request) {
return $http.post('/webapi/account/test3',request,{
headers: { 'Content-Type': 'application/json; charset=utf-8'}
})
.then(getLoginComplete)
.catch(getLoginFailed);
}
function getLoginComplete(data, status, headers, config) {
return data.data;
}
function getLoginFailed(e) {
var newMessage = 'XHR Failed for login';
if (e.data && e.data.description) {
newMessage = newMessage + '\n' + e.data.description;
}
e.data.description = newMessage;
return {"error":true, "message":"Unable to login please try again later"};
}
Chrome network via developer tools:
Request URL:http://localhost:5000/webapi/account/test3
Request Method:POST
Status Code:200 OK
Remote Address:[::1]:5000
Referrer Policy:no-referrer-when-downgrade
Response Headers
view source
Content-Type:text/html; charset=utf-8
Date:Tue, 11 Jul 2017 19:58:46 GMT
Server:Kestrel
Transfer-Encoding:chunked
Request Headers
view source
Accept:application/json, text/plain, /
Accept-Encoding:gzip, deflate, br
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Connection:keep-alive
Content-Length:61
Content-Type:application/json; charset=UTF-8
Host:localhost:5000
Origin:http://localhost:5000
Referer:http://localhost:5000/login
All, I just created a new Angular package using 1.6.1 but now the data doesn't seem to pass to my WebAPI. However, when I post bits via SoapUI or something like that, everything is fine.
The Javascript looks like this:
function testapi()
{
var serviceRoot='http://server/testangular16/api/Values';
var deferred=$q.defer();
var req = {
method: 'POST',
url: serviceRoot,
data: 'PassInTheText'
};
$http(req).then(goodResponse,badResponse);
return deferred.promise;
};
function goodResponse(response)
{
console.log("Good response");
console.log(response);
}
function badResponse(response)
{
console.log("Bad response");
console.log(response);
}
and the webapi is a very simple C# controller:
// POST api/values
public HttpResponseMessage Post([FromBody]string value)
{
HttpResponseMessage rp = new HttpResponseMessage(HttpStatusCode.OK);
rp.Content = new StringContent(value);
return rp;
}
I am making it into the controller, I can set a break point and hit the parts where I can look at the value. It's always null.
Looking at the network trace, the angular part does do a preflight and I can see the 200 response back.
Request URL:http://server/testangular16/api/Values
Request Method:OPTIONS
Status Code:200 OK
Remote Address:10.7.14.209:80
**Response Headers view source**
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:content-type
Access-Control-Allow-Origin:http://localhost:8000
Cache-Control:no-cache
Content-Length:0
Date:Fri, 03 Feb 2017 18:09:04 GMT
Expires:-1
Pragma:no-cache
Server:"Management Corporation"
X-AspNet-Version:4.0.30319
**Request Headers view source**
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:mjvzrx3
Origin:http://localhost:8000
Referer:http://localhost:8000/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
So, it looks like I'm passing CORS, but when I get to trying to pass the data in as the content of the post, it doesn't make it.
Any ideas what I'm missing?
Thanks,
Nick
Web API expects an object in the message body, you cant pass in a primitive type unless you use application/x-www-form-urlencoded as the content-type and prefix the value with an equals = sign.
So you can fix it by one of these methods
Adjust the c# parameter and turning it into a type that has a string property and then send in a json object with a matching parameter name.
Change the request to url-encoding content type and add a = to the variable value.
Send it as a part of the URL instead of the message body, you can still use the POST method.
Change to form-urlencoded
function testapi()
{
var serviceRoot='http://server/testangular16/api/Values';
var deferred=$q.defer();
var req = {
method: 'POST',
url: serviceRoot,
data: '=PassInTheText', // added =
contentType: 'application/x-www-form-urlencoded' // specify content type
};
$http(req).then(goodResponse,badResponse);
return deferred.promise;
};
It seems if I do this, it works as expected.... Thoughts?
// POST api/values
public HttpResponseMessage Post(HttpRequestMessage request)
{
var data = request.Content.ReadAsStringAsync().Result;
Console.WriteLine("Data: {0}", data);
HttpResponseMessage rp = new HttpResponseMessage(HttpStatusCode.OK);
rp.Content = new StringContent("Data back from WebAPI" + data);
return rp;
}
I'm facing a problem, I tried to connect to Auth0 API to enable a strong identification on my WebApp.
For context :
Front-End : I'm using an angularJS front, and there I implemented the Lock Library to manage the Auth0 popup by following this webapp-specific tutorial.
Back-End : NodeJS & Express server, in order to verify the user's authentification, I use the npm lib "request" to call the Auth0 API.
If i understand well, a click on the auth0 widget sends a request to the specified endpoint URL, and it's received by the back-end:
app.get('/auth0CallbackURL', function (req, res) {
console.log(req.query.code);
var auth0code = req.query.code;
var client_secret = PROCESS.ENV.SERCRETID;
var domain = PROCESS.ENV.DOMAIN;
var client_id = PROCESS.ENV.CLIENTID;
var redirectUrl = PROCESS.ENV.REDIRECTURL;
var request = require('request'); // request-promise
var requestParams = {
url: 'https://mycompanydomain.auth0.com/oauth/token?client_id='+client_id+'&redirect_uri='+redirectUrl+'&client_secret='+client_secret+'&code='+auth0code+'&grant_type=authorization_code',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
And then I call request() to get back the access_token and verify the authentification.
request(requestParams, function(err, data) {
if (err) {
console.log('Err:', err);
} else {
console.log('response body: ', data.body)
}
But the only result I get is :
{
"error": "access_denied"
"error_description": "Unauthorized"
}
At the begining i thougt it was my Auth0 configuration that's didn't allow my authentification, but it seems that there are OK.
Thanks in advance for your replies.
As per the page you linked, you need to pass the following information:
client_id=YOUR_CLIENT_ID
&redirect_uri=https://YOUR_APP/callback
&client_secret=YOUR_CLIENT_SECRET
&code=AUTHORIZATION_CODE
&grant_type=authorization_code
in the request body and with a content type of application/x-www-form-urlencoded.
You're setting the content type correctly, but then are passing the data in the URL query component and instead you need to pass it the POST request body.
Using request package you should do the following:
var requestParams = {
url: 'https://mycompanydomain.auth0.com/oauth/token',
method: 'POST',
body: 'client_id=' + client_id +
'&redirect_uri=' + redirectUrl +
'&client_secret=' + client_secret +
'&code=' + auth0code +
'&grant_type=authorization_code',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
I have an AngularJS application that sends a POST request to a REST service (onClick method of a button). The POST request contains a JSON object with various settings. The REST service uses those settings to create a MS Word/Excel file.
At the moment the REST service sends the contents of the file back as a byte stream (in response to the previously mentioned POST request). When the file arrives I want a save-file-dialog to show up, where I can save the file. The backend is a Spring Boot app using Spring-MVC.
Can this be done in AngularJS?
If you can't use something like location.href to get your data to the server instead of post it, then check it out others using html 5:
more info AngularJS $http-post - convert binary to excel file and download
$http({
url: 'your/webservice',
method: 'POST',
responseType: 'arraybuffer',
data: json, //this is your json data string
headers: {
'Content-type': 'application/json',
'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
}
}).success(function(data){
var blob = new Blob([data], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
saveAs(blob, 'File_Name_With_Some_Unique_Id_Time' + '.xlsx');
}).error(function(){
//Some error log
});
This is the Controller function I ended up using:
#RequestMapping(value = "/downloadDocx", method = RequestMethod.POST)
#ResponseStatus(value = HttpStatus.CREATED)
public void downloadDocx(#RequestBody DocxInputBean docxInput,
HttpServletResponse response) throws Exception {
File docxFile = outputManager.createDocxProfile(docxInput);
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
InputStream is = new FileInputStream(docxFile);
org.apache.commons.io.IOUtils.copy(is, response.getOutputStream());
response.flushBuffer();
is.close();
}
I am using Revel + angular for my application. The index page is the login interface, and once you are successful, you should be directed to the dashboard.html page. The problem is once I have made a POST request, I get a GET request with my 'response body', however, I am still in the login page. I am using angular to make a post request to my restful server. However, whenever I make a POST request I get status 302 on my POST request but my GET request fetches the response for the page.
My Angular Controller
appMainLogin.controller('MainLoginForm',function($scope, $http){
$scope.user_email = null;
$scope.user_pass = null;
$scope.user_remember = true;
$scope.userLogin = function () {
var val = {
"user_email": $scope.user_email,
"user_pass": $scope.user_pass,
"user_remember": $scope.user_remember,
};
var stringify = JSON.stringify(val);
$http({
url: '/login',
method: 'POST',
data: stringify || '',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
}
}).success($scope.getEmailData).error($scope.httpError);
alert("error");
};
});
My routes
POST /login App.Login
GET /dash Dash.Index
I get this: 302 on the POST request
I get this: 200 OK on the GET request
On the 'response body' of the GET request (firefox debugger) I see my I intended html page but I still remain in the index page.
Why is my app not redirecting to the dashboard.html(index.html->dashboard.html) after the user enters their login credential (based on my code above)?