Need help extracting all transaction details from Paypal API in C# - c#

I am trying to retrieve all my Paypal transactions via an API call in C#. I have read through the documentation and fiddled with things here and there, but I am relatively new to APIs in C# an d all. I am not exactly sure where to place the ClientID and Secret. I have tried to go through the OAuth2 documentation, but it isn't making a ton of sense.
I am hoping someone can guide me in the right direction, thanks!

Curl and postman examples are here: https://developer.paypal.com/docs/api/overview/#get-credentials
Such HTTPS requests can be adapted to any environment, including C#. Make sure you put the clientid:secret in an auth parameter provided by your HTTP library so that it will do the basic auth for you, or set the header yourself and give a username:password value that is base64 encoded as required for HTTP basic authentication.
Once you are getting an access token back, use it for a Transaction Reports API calls -- if that is what you truly want to integrate, although I would not recommend using an API for this.
Instead, the best solution is to use the paypal.com Activity -> "All Reports" to do an Activity Download in CSV format, and import that into your system.
After that, to be notified of new transactions in real time, it's best to do so at the moment you capture/execute a transaction on your server. This would involve creating two routes, one for 'Create Order' and one for 'Capture Order', documented here. These routes should return JSON data, but the second route can check for success and record a successful transaction in your database (and any other business logic you need) before forwarding on its return JSON.
After creating those two routes that return JSON, pair them with the following approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server

Related

How to get the URL of the current page in C#?

In the new .NET 7.0 framework, things have changed considerably...
This has been asked a gazillion times before and if the .NET Core framework would not break all kinds of backwards compatibility then I would have an easy answer. Too bad a lot of answers are related to .NET 4.9 and older and they just don't work.
So in my minimal Web API I want to do some simple request logging by sending the complete URL as a string to a database. (With some additional information.) So I have the HttpContext class (NOT the HttpContext class) with the Request property of type HttpRequest and it just does not have any method to get the original URL that was requested. Only the various parts which I have to concatenate and hope it resembles the original uri...
So, a useful method like Request.Url is now totally gone and the DisplayUrl helper() isn't providing me everything. It leaves out the QueryString. I need that QueryString also.
And yes, I can concatenate this again to get the value that it originally received and made hidden. It just feels wrong, though. Plus, this method makes the uri suitable to be returned in a header. Again, I want to store it in a database for logging purposes exactly as it originally was!
So now I have to ask something that has been asked a gazillion times before, simply because the latest .NET update breaks things again.
The application I'm working on is a multi-tenant application running on multiple domain names including wildcard subdomains and is used to analyze the amount of traffic I get for new domains that I've registered. The whole API will just generate 404-errorcodes back to the user, but I want the whole URL to get registered to determine if the domain isn't getting any funny requests. (Like hackers trying to access https://owa.example.com/wp-booking.php or https://forum.example.com/default.aspx?g=rsstopic&pg=0&ft=0 or whatever.) I also log the body of the request, the request method, the IP address of the user and the headers that are passed and it cal be used by me to extend a blacklist of users who seem to have malicious intent.
The domains where I use it are often fresh out of quarantine and are just in a wait-state until development starts. (Or until someone takes it over.) Responding with a 404-error should tell users (and hackers) that the site does not exist any more. Most users will be aware that the site is gone so they stop visiting, but various automated (and hacking) tools might still be running so the information tells me what the user is trying to do.
Anyways, I need the full URL with the query string, domain name, protocol and everything else that the client has passed to my server. But .NET 7 is preventing me from access to the original URL which is dumb. And the whole project is basically a single app.Run() statement which always returns a 404 error after logging the request. And yes, slow is fine for this API.
Sigh... Request.Url.AbsoluteUri was such a useful function, but it's gone, making all answers going back 14 years or so obsolete as Request has no Url...
UriHelper.GetDisplayUrl(source) should do the trick:
app.MapGet("test_uri", (HttpContext context) => context.Request.GetDisplayUrl());
Returns http://localhost:5207/test_uri?query=1&test=2 for this url.
So in my minimal Web API I want to do some simple request logging by sending the complete URL as a string to a database.
Minimal APIs support request logging - docs, example. Potentially you can combine it with some logging library which allows writing to database.

REST session workflow for creating users

I am working on a C# WebApi/MVC project that has a rather large workflow process for creating a user and placing in their required information.
There is about 10 major steps involved, in which it could technically take a user hours to fill out.
The first step takes standard basic information such as username, password, email, name, address etc.
What I would like to do is after this first step is successful, send a rest call that will create the basic user in the user table, and then prepare a session for the further steps in which when any field is filled out in the next steps, it will automatically send an ajax call and update the field in the database.
While this all sounds easy and simple in theory with the use of sessions, which I could do in MVC, I want to do this in WebApi with REST in which REST is supposed to be STATELESS.
Has anyone come across similar issues, and if so what do they recommend as an approach? The options I can currently think of are:
-Ditch the REST for standard MVC for this process and leave WebAPI for only Reads instead of Writes as the only Write process is the inital creation of users/accounts.
-Using Authentication tokens? But can this handle this process successfully?
-Once the user is created, take the username/password for every REST call as the auth to the WebAPI? Store the User/Password in MVC session and directly call the API from MVC, mobile applications would just store the username/password in the application and call the WebAPI (I think this is the most appropriate)
Can anyone tell me if any of those options are the best practice, or does anyone have a better best practice/process for these things? I would prefer to write things once to cover Web and Mobile as much as possible rather than having to duplicate processes.
Thanks in advance!!!
I would consider to modify regular WebAPI OWIN register flow.
Collect basic user info and post to Web API via Ajax. If succeeded -
send OWIN token back to the caller in HTTP header.
Proceed to extra
steps for user info updates (via HTTP PUT for example) and put the
token in authenticate header. Mark WebAPI update procedure with
Authorize attribute.
This blog post could help to setup WebAPI to issue and accept bearer tokens.

create an OAuth client in c# for automation testing

I am trying to test againt a service that implements the OAuth 2.0 authentication protocol and I want to run the automation without using any browser elements. Is that possible and if so how?
What i am currently doing is opening a browser and then sending user/key combination and then on redirect, I get the access token from the URL which I then use in subsequent REST calls. but this method takes a bit of time and may not be completely reliable for running lots of tests.
Is there any way that I can programatically handle the initial handshake, i.e, send the user/key, get the permission request page and then accept it through c# as well and finally get the access token without any browser in the middle?
Check out DotNetOpenAuth - http://www.dotnetopenauth.net/
You should be able to write automated test cases quite simply
You could try service account authentication for your test system. This approach replaces user interaction with cryptographically signed JSON Web Tokens (JWTs).
Google's implementation docs have some details.

How to prevent editing of hidden field with PayPal's Website Payment Standard?

I'm using PayPal's Website Payment Standard in my ASP.NET website.
What I do is when the user clicks on the "Pay Now" button, I do the following in the codebhind:
DB status changes
Generation of the PayPal form, hidden fields for the items
Call ScriptManager.RegisterClientScriptBlock() to call the javascript function that submits the PayPal form to PayPal.
I'm worried that the user can press stop on the web browser and then edit the values in the hidden forms and then submit the form. Is there a way to prevent this? Or a better alternative?
Thank you so much in advance!
I haven't done PP Standard. I've used Gateway and Pro/Express Checkout but its been quite a while - still, your question can be handled in a more "generic" way...
Unfortunately your plan will not do anything to protect you - just like any other HTML Form on the web, HTTP requests and responses can be inspected and tampered with using readily available tools.
The common way to prevent tampering is to do server-side validation of submitted values coming from any client/browser (the rule of thumb is "trust no one"). In your scenario, you are doing things on the server side, but that's still prior to the actual submission target of the data - which is PayPal. The step that actually sends the data to the "target" is still the browser/client - and there lies the issue so to speak. The data to be validated is meant for a system other than yours (so you can't validate for PayPal).
Unless there is an added layer of security, e.g. signature or encryption, it will always be vulnerable to tampering (viewing is a foregone matter, it can be viewed).
I don't believe (but I could be wrong) PP Standard has a server-to-server option for POSTing data. This would effectively "hide" the data altogether from the client/browser - nothing to see, nothing to tamper with. Data transfer is in the background - client/browser knows nothing of it.
However, their PayPal Payments Standard and Button Manager API seems to be the right/secure way of doing this.
In essence you will be creating what they call "encrypted buttons" on the fly. This way the data will look like gibberish to anyone inspecting it - it will only make sense to PayPal because they can decrypt the data accordingly. That's how the data is secured/protected from tampering (not viewing - but again, what can be seen is gibberish)...
Hth...
Update:
Also, you should consider PayPal IPN for storing data. You are making the assumption above (I think) that everyone who clicks the button will actually go through with the payment (or can pay successfully). With IPN, you will "listen" for data coming from PayPal only after successful payment (which is where you should store order related data and/or inventory updates, etc.) ....
Even though I'm working with PHP, using the NVP API you can get links to redirect using a token which can only be used by paypal. All the links will look like https://www.sandbox.paypal.com/webscr?cmd=_express-checkout&token=TOKEN, where TOKEN is a token retrieved previously by calling the PayPal API.
I've only developed it for ExpressCheckout. You can check the API here:
https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/howto_api_reference

Google ClientLogin Authorization and Google Music

I am playing around with Google Music. I'm trying to see if I can write an app that will stream my music files uploaded to Google Music. So far, I've managed to authenticate myself using ClientLogin and access the music.google.com page. However, whenever I try to access http://music.google.com/music/services/loadalltracks, the page that contains all of my tracks in JSON format, I get a 401: Unauthorized error. However, if I pass the cookies containing SID and HSID, it works and I can access the page.
Does anyone know why It doesn't work with ClientLogin, outside of Google not supporting it with Music? Have you had similiar experience with other Google Services? In the event I can't get ClientLogin to work, is there anyway to work around it, using the SID? I don't know how the HSID is generated.
Since there is no official api for Google Music, you need full SSO credentials to use those endpoints. The easiest way to do this is to emulate a browser (with eg mechanize).
The way my unofficial Google Music api accomplishes this is a bit cleaner, but more work: use clientlogin to authenticate to the Music Manager service, then upgrade those credentials using tokenauth. This isn't really a public feature, but it's described by a third party here, and by a Google design doc here. The specific endpoints you need are in my code here (in clientlogin.py and tokenauth.py).
You'll want to send u=0 and xt=[value of xt cookie] in the querystring as well. The first argument specifies which account you're using (if you're signed into multiple), and the second is a xsrf token.
Well, as far as I can tell the reason sending the SID and HSID cookies makes the request work is because you're simulating the way a normal user is accessing the service.
You can't go the regular application way because that's not supported in google music (as far as my internet research showed, there's no API for google music).
Oh, and one thing: google discourages people from using ClientLogin and instead tells people to use OAuth ("ClientLogin [is] Google's proprietary authorization API ... you should avoid using [this] service." found at http://code.google.com/apis/gdata/docs/auth/overview.html) so in the future you might want to use that. Maybe it'll even work in this case (It sends a different token from ClientLogin - OAuth token instead of an Auth token) though I doubt that.
Anyway, I hope this cleared things up.

Categories