What is the callback URL after calling repeat.vsp when using Form Integration? - opayo

I'm trying to do repeat payments with Form Integration in Sagepay (now Opayo).
From an earlier problem posted on here, I get that the securitykey is needed but is not returned in the Form call, so an additional call needs to be made to the getTransactionDetails command.
I have the securitykey and can now make a call to https://test.sagepay.com/gateway/service/repeat.vsp to initiate the repeat payment. However, the documentation does not say where the response to that call goes. I assume therefore, that it would go to the NotificationURL that is set up with a payment when using the Server or Direct integrations. Since I'm using Form, this is not set.
The question is, is there any way of capturing the response to the https://test.sagepay.com/gateway/service/repeat.vsp call if the initial payment was created using Form integration?
I suppose the second question is, has anybody successfully made repeat payments work with Sagepay Form integration?

Not sure if this helps you and we didn't do repeat payments; but we are looking at releasing deferred payments and I think it is a similar approach.
How do you make the call to 'https://test.sagepay.com/gateway/service/repeat.vsp'?
Could you use a 'HttpWebRequest' to make the call then capture the direct response in 'HttpWebResponse'?
EG:
private static void DeferredSharedApiCall(Dictionary<string, string> data, string type, string url)
{
string postData = string.Join("&", data.Select(x => $"{x.Key}={HttpUtility.UrlEncode(x.Value)}"));
HttpWebRequest request = WebRequest.CreateHttp(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
using (TextWriter tw = new StreamWriter(request.GetRequestStream()))
{
tw.Write(postData);
}
HttpWebResponse response = null;
try
{
response = request.GetResponse() as HttpWebResponse;
}
catch (WebException ex)
{
//log.Error($"{type} Error, data: {postData}", ex);
}
catch (Exception ex)
{
//log.Error($"{type} Error, data: {postData}", ex);
}
if (response != null)
{
using (TextReader tr = new StreamReader(response.GetResponseStream()))
{
string result = tr.ReadToEnd();
//log.Info($"{type} Response: {Environment.NewLine}{result}");
}
}
}

Related

Do I need a second HttpClient to make an API call to refresh JWT token inside custom DelegatingHandler?

For each API call in my App, I want to check whether the user has an expired JWT, and if so, I want to get a new one using a refresh token, and then proceed with the original request to API. This is supposed to all work in the background without the APP user experiencing any interruptions or need to login again.
I create my HttpClient like this:
static DelegatingHandler handler = new AuthenticationHandler();
static HttpClient httpClient = new HttpClient(handler)
{
BaseAddress = new Uri("https://10.0.2.2:5001/api/v1")
};
AuthenticationHandler is a custom DelegatingHandler which has an override SendAsync method. Inside that method I check if request has status Unauthorised:
if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
And if it does, I need to send another request to my API with the currently owned JWT and Refresh tokens to generate new pair of tokens... Since this is an API call in the middle of another API call (as it all happens inside the custom DelegatingHandler which is a parameter for constructing my main HttpClient) - does refreshing the token needs to happen using a second HttpClient that I need to create literally to make the refresh token call?
I can't see how can I use the same HttpClient for this, how is this usually being done?
EDIT:
I can't see how I could use the same HttpClient for refreshToken call from inside AuthenticationHandler, as the handler is used to construct the HttpClient. Feels like a circular reference. I just have no idea how others do it in their code... I currently implemented it by using that second HttpClient which I only use for that one refreshToken call, and it works, but I have a feeling that there is a cleaner way to achieve this?
Btw, my (not refactored yet) SendAsync method inside AuthenticationHandler looks like this currently:
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
try
{
HttpResponseMessage response = new HttpResponseMessage();
request = CheckForAuthToken(request);
response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
for (int i = 1; i == _maxRefreshAttempts; i++)
{
// Here I make a call to the API to refresh and return a new JWT, The authApiService uses a different HttpClient
RefreshTokenRequestModel refreshTokenRequestModel = new RefreshTokenRequestModel
{
Token = await SecureStorage.GetAsync("jwtToken"),
RefreshToken = await SecureStorage.GetAsync("refreshToken")
};
var apiResponse = await authApiService.RefreshToken(refreshTokenRequestModel);
if (apiResponse.IsSuccessStatusCode)
{
await SecureStorage.SetAsync("jwtToken", apiResponse.Content.Token);
await SecureStorage.SetAsync("refreshToken", apiResponse.Content.RefreshToken);
request = CheckForAuthToken(request);
response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
}
}
}
return response;
}
catch (Exception e)
{
throw e;
}
}

Paypal:IPN Listener not receiving IPN messages

I have a website with online transaction using paypal as payment option. Checkout and the shopping cart calculations on paypal side are working, but i'm not receiving any IPN messages from paypal sandbox. after writing the log I found out that parameter formdata is null. Even checked with the IPN history and it shows the status of IPN message as retrying... IPN notification url has also been set.
Below is the listener code.
[Route("IPN")]
public IHttpActionResult IPN(FormDataCollection formData)
{
var formVals = new Dictionary<string, string>();
formVals.Add("cmd", "_notify-validate");
string response = GetPayPalResponse(formVals, formData);
if (response.ToUpper().Trim() == "VERIFIED")
{
//entry into database
}
else
{
return InternalServerError();
}
return InternalServerError();
}
string GetPayPalResponse(Dictionary<string, string> formVals, FormDataCollection formData)
{
string paypalUrl = GetPayPalURL();
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(paypalUrl);
// Set values for the request back
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
Encoding encoding = Encoding.UTF8;
StringBuilder sb = new StringBuilder();
foreach (var entry in formData.ToList())
{
sb.AppendFormat("{0}={1}&", entry.Key, encoding.GetString(encoding.GetBytes(entry.Value)));
}
string strRequest = sb.ToString();
strRequest += "cmd=_notify-validate";
req.ContentLength = strRequest.Length;
//Send the request to PayPal and get the response
StreamWriter streamOut = new StreamWriter(req.GetRequestStream());
streamOut.Write(strRequest);
streamOut.Close();
StreamReader streamIn = new StreamReader(req.GetResponse().GetResponseStream());
string strResponse = streamIn.ReadToEnd();
streamIn.Close();
return strResponse;
}
This was working before, but no idea what had stopped it.
Being new to paypal payment gateway, any help would be highly appreciated.
There is a certain problem with paypal since yesterday. I hope it is a remporary issue and it will be fixed asap. I have problems with sandbox myself, but it has happened before as well.
I am also having problems with Sandbox mode... can anyone else confirm this? I am using .NET SDK and adaptive payments...
EDIT: all working again today ;)

Windows Phone sends more than one web requests in order in a call

Reccently, I am working on a project in Windows Phone. and In this project, to validate a user, I need to check at 3 web API, the logic is like below:
Step 1: access web api 1 to get the token
Step 2: access web api 2 to get the username/password by the token retrieved in Step 1
Step 3: access web API 3 to validate the user name/password in step 2
you can see we need to access those 3 API in order. as well know, window phone now access the network asynchronously, which causes a big challenge on make those API access in order, and which make the soure code hard to maintainace.
I also consider the synchronous source code like below, but I found there are some problems to access the network,many exeption will be thrown. For example, when an exception is thrown, I try to use asynchronous web request to access the same URL, it is OK. I am strugglig in it now. And I have to introduce thread to call it to avoid to block the UI thread.
internal static class HttpWebRequestExtensions
{
public const int DefaultRequestTimeout = 60000;
public static bool IsHttpExceptionFound = false;
public static WebResponse GetResponse(this WebRequest request, int nTimeOut = DefaultRequestTimeout)
{
var dataReady = new AutoResetEvent(false);
HttpWebResponse response = null;
var callback = new AsyncCallback(delegate(IAsyncResult asynchronousResult)
{
try
{
response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
dataReady.Set();
}
catch(Exception e)
{
IsHttpExceptionFound = true;
}
});
request.BeginGetResponse(callback, request);
if (dataReady.WaitOne(nTimeOut))
{
return response;
}
return null;
}
public static WebResponse PostRequest(this HttpWebRequest request, String postData, int nTimeOut = DefaultRequestTimeout)
{
var dataReady = new AutoResetEvent(false);
HttpWebResponse response = null;
var callback = new AsyncCallback(delegate(IAsyncResult asynchronousResult)
{
Stream postStream = request.EndGetRequestStream(asynchronousResult); //End the operation.
byte[] byteArray = Encoding.UTF8.GetBytes(postData); //Convert the string into a byte array.
postStream.Write(byteArray, 0, postData.Length); //Write to the request stream.
postStream.Close();
dataReady.Set();
});
request.BeginGetRequestStream(callback, request);
if (dataReady.WaitOne(nTimeOut))
{
response = (HttpWebResponse)request.GetResponse(nTimeOut);
if (IsHttpExceptionFound)
{
throw new HttpResponseException("Failed to get http response");
}
return response;
}
return null;
}
}
Any suggestion on using asynchronous web request to solve my case?
There's an example here of using asynchronous web services in a chained manner to call the Microsoft Translator service on WP7
Maybe it will give you some pointers?
http://blogs.msdn.com/b/translation/p/wp7translate.aspx

WebService ASP.NET MVC 3 Send and Receive

I've been racking my brain for a couple of days now on how to approach a new requirement.
I have two websites. The first one lets the user fill out an application. The second website is an internal website use to manage the users applications. I need to develop a "web service" that sends the application data from website 1 to website 2 and return a response to website 2 of success or failure. I have never done a web service before and I'm a bit confused on where to start. I've been reading various examples online but they all seem to be just a starting point for building a webservice... no specific examples.
So for posting the data website 1, what would my controller method look like? Do I use Json to post the data to website 2? What would and example of that look like? Is there some form of redirect in the method that points to website 2?
So for posting the response back to website 2 what would that controller method look like? I assume I would use Json again to send the response back to website 1? Is there some form of redirect in the method that points back to website 1?
I would use JSON and POST the application to the web service.
First I am assuming the application data is contained in some type of object. Use JSON.Net to serialize the object into JSON. It will look something like the following code.
var application = new Application();
string serializedApplication = JsonConvert.Serialize(application);
Second is to POST the code your endpoint(webservice, mvc action). To this you'll need to make a HTTPRequest to the endpoint. The following code is what I use to make to POST the code.
public bool Post(string url, string body)
{
//Make the post
ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
var bytes = Encoding.Default.GetBytes(body);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
Stream stream = null;
try
{
request.KeepAlive = false;
request.ContentLength = bytes.Length;
request.ContentType = "application/x-www-form-urlencoded";
request.Timeout = -1;
request.Method = "POST";
stream = request.GetRequestStream();
stream.Write(bytes, 0, bytes.Length);
}
finally
{
if (stream != null)
{
stream.Flush();
stream.Close();
}
}
bool success = GetResponse(request);
return success;
}
public bool GetResponse(HttpWebRequest request)
{
bool success;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.Created)
{
throw new HttpException((int)response.StatusCode, response.StatusDescription);
}
var end = string.Empty;
using (StreamReader reader = new StreamReader(responseStream))
{
end = reader.ReadToEnd();
reader.Close();
success = JsonConvert.DeserializeObject<bool>(end);
}
response.Close();
}
}
return success;
}
So now you have can POST JSON to an endpoint and receive a response the next step is to create the endpoint. The following code will get you started on an endpoint in mvc that will receive an application and process it.
[HttpPost]
public ActionResult SubmitApplication()
{
//Retrieve the POSTed payload
string body;
using (StreamReader reader = new StreamReader(Request.InputStream))
{
body = reader.ReadToEnd();
reader.Close();
}
var application = JsonConvert.Deserialize<Application>(body);
//Save the application
bool success = SaveApplication(application);
//Send the server a response of success or failure.
return Json(success);
}
The above code is a good start. Please note, I have not tested this code.
You have obviously more than one client for the data & operations. so a service is what you are looking for.
ASP.NET MVC is a good candidate for developing RESTful services. If you (and your Manager) are ready to use beta version, Then Checkout ASP.NET-Web API.
If you want to stay with a stable product, Go for MVC3. you may need to write some custom code to return the data in XML as well as JSON to server different kind of clients. There are some tutorials out there.
So create a Service (ASP.NET MVC / WCF Service) .You may then create 2 client apps, one for the external clients and another for the Internal users. Both of this apps can call methods in the Service to Create/ Read the user accounts / or whatever operation you want to do.
To make the apps more interactive and lively , you may conside including a wonderful thing called SiganalR, which helps you to get some real time data without continuosly polling the data base/ middle tier very in every n seconds !

Accessing a website using C#

I'm trying to make an App for windows phone 7. This app will basiclly retrive information from a website that we use at work as our working schedule then rearrange the retrived info into a metro style UI. To be honest i don't know where to start ie. how to retrive the info. Should i use webclient class? httpwebrequest class? or something else?
All idea are appriciated
Here is a:-
Update:-
Okay either im totally stupid or there is something wrong with the code i'm writing, that i can't figure it out. I was using the same code that you wrote BUT i still get an error that a definition for Proxy is not in the System.Net.WebRequest :( This is my code (the working version):-
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
if (!App.ViewModel.IsDataLoaded)
{
App.ViewModel.LoadData();
}
string url = "https://medinet.se/*****/schema/ibsef";
WebRequest request = WebRequest.Create(url);
request.BeginGetResponse(new AsyncCallback(ReadWebRequestCallBack), request);
}
private void ReadWebRequestCallBack(IAsyncResult callbackResult)
{
try
{
WebRequest myRequest = (WebRequest)callbackResult.AsyncState;
WebResponse myResponse = (WebResponse)myRequest.EndGetResponse(callbackResult);
using (StreamReader httpwebStreamReader = new StreamReader(myResponse.GetResponseStream()))
{
string results = httpwebStreamReader.ReadToEnd();
Dispatcher.BeginInvoke(() => parsertextBlock.Text = results);
}
myResponse.Close();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
Dispatcher.BeginInvoke(() => parsertextBlock.Text = ex.ToString());
}
}
But if i add request.Proxy=null!! i get an error, that there is no definition for Proxy in (System.Net.WebRequest). And to be honest i start getting mad of this.
Yours
/Omar
The process is called ScreenScrape and i recommend you to use Html Agility Pack http://htmlagilitypack.codeplex.com/ . Make a web service that retrieves the information from your website and rearranges to appropriate format. Use your web service by a phone and display your data.
Use WebRequest ( http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx) and WebResponse ( http://msdn.microsoft.com/en-us/library/system.net.webresponse(v=vs.100).aspx) .
TIP: Set the WebRequest.Proxy property ( http://msdn.microsoft.com/en-us/library/system.net.webrequest.proxy.aspx) to null, as i find it will be much faster.
UPDATE: More info on WebRequest Proxy property
Set Proxy = null on the WebRequest object to avoid an initial delay (that way the request won't start auto detecting proxies, which i find it's faster).
WebRequest req = WebRequest.Create("yourURL");
req.Proxy = null;
It's in the System.Net namespace so put an using statement using System.Net; or
System.Net.WebRequest req = WebRequest.Create("yourURL");
req.Proxy = null;
Regards.

Resources