I am trying to integrate my ASP.Net MVC C# website with the new PayPal V2 API. My website has its own Order Numbers (my website’s Order Numbers are not the same as the Order ID PayPal generates in its V2 API). So with the older PayPal EWP (which is being deprecated), by the time the customer reached the payment page to click on the PayPal "Buy Now" button, my website had already created the Order Number. Using PayPal EWP, all my backend ASP.Net MVC C# methods knew which Order Number it was dealing with, when it requested an encrypted PayPal "Buy Now" button. Thus, I never had to expose the Order Number in the HTML of the payment page.
Fast forward to the new PayPal V2 API. Whereas with PayPal EWP, the first interaction with PayPal was from my backend ASP.Net MVC C# methods, in the new PayPal V2 API, the first interaction with PayPal is when the customer finally clicks on the yellow PayPal button on the webpage: https://developer.paypal.com/demo/checkout/#/pattern/server. The Javascript return fetch('/demo/checkout/api/paypal/order/create/', {
is called, which then calls my backend ASP.Net C# method.
In order for my backend ASP.Net C# method to know which Order Number it is dealing with, I have to change that Javascript fetch call to something like: return fetch('/demo/checkout/api/paypal/order/create?ordernumber=1234', {',
where ?ordernumber=1234 needs to be appended as a query string parameter. The problem is, I am exposing my Order Number in the HTML, and because I am doing this, I don’t even know if this is subject to hacking.
With the older PayPal EWP, because my Order Number was never exposed in HTML on the front end, I didn’t have to worry about any possible hacking of Javascript/HTML, etc. With this new PayPal V2 API, unless I append the query string parameter, such as ?ordernumber=1234 above, my backend ASP.Net C# method called by return fetch('/demo/checkout/api/paypal/order/create/', {
has no idea which Order Number it is dealing with.
The only other way, that I can think of, for my backend ASP.Net C# method to know which Order Number it is dealing with (without exposing this in HTML) is storing it in the Session. I don’t even think TempData is a good idea because according to the documentation I read, once TempData is read the first time, the value is deleted, which means if somehow that fetch call is called twice, it will fail the second time because the value has already been deleted. But with Session, I am worried about what if the customer clicks on the browser’s back button and orders another product (which will have a different Order Number) and the possible bugs that may crop up (ie. if the customer clicks on the back button on the browser, it may not trigger the Session to be updated if the page is already cached).
Is there a way where my backend ASP.Net C# method can get the Order Number, without appending the Order Number as a query string to the fetch call, and without using the Session?
2
Answers
So I considered adding it to the header as per @jdweng's advice but I ran into problems trying to add it to the header (it was constantly null). Also, seeing other Stackoverflow questions/answers where different browsers treat the adding of headers differently, was concerning to me because bugs may crop up.
With the Session, I am also concerned about bugs and stability, especially if the user clicks back and the page is cached by the browser, which means the Session won't be updated.
Taking into consideration stability, avoiding bugs, and exposing my Order Number in HTML, I figured the best solution was just encrypting the Order Number in HTML. The order number is still exposed in the HTML (although it's encrypted) an it's still subject to hacking, but it makes it a little more harder for a hacker to mess with the Order Number.
Thanks to @jdweng and @Preston PHX for their answers!
The most common approach is for clicking the PayPal button to trigger a fetch to the backend ‘create-order’ route that posts a body (not a get/url string) with a
cart
object that includes an array of item id/skus and quantities. The backend then uses that information to lookup and calculate the necessary amounts and creates a PayPal order ID with aninvoice_id
that is unique to your system (never used for a previously captured payment). This invoice_id value can be your own system’s "Order Number", effectively.If you need to create an order number earlier in the process and send send it back and forth between the client and server before creating the PayPal order, well there are use cases that need to do this for whatever reason. It’s not common, but if your is one of them just make sure you ensure any values submitted by the client are reasonable/valid. You can use web server session variables or whatever else is needed, it’s a rather straightforward web application design consideration that will depend on your needs and aims.