I'm using PayPal Payments Advanced with TEMPLATE=TEMPLATEC. I already figured out how to create an IFRAME and receive confirm/cancel/silent_post responses from PayPal. But I've found no way to validate parameters my confirm/cancel/silent_post pages receive. Is there a way to ensure that these parameters are from PayPal and not just sent by arbitrary user?
About the best option you have is to run an inquiry transaction (TRXTYPE=I) against the secure token and secure token ID you received from PayPal before displaying the iframe. If a transaction was run, that call will give you the transaction ID (PNREF) from the transaction. (And depending on your situation, the PNREF may be all you need.) If that matches the PNREF sent back to you by the buyer, then there's a good chance that the rest of the data is genuine.
For example:
Request:
USER=****&VENDOR=****&PARTNER=****&PWD=****&TRXTYPE=I&SECURETOKEN=7tGDq6ILZeEmATCwTXrSRkwjz&SECURETOKENID=76ac5819ee01475daf15b2af038da977&VERBOSITY=HIGH
Response:
RESULT=0&PNREF=E79P4ABEC9DE&TRANSSTATE=8&ORIGRESULT=0&ORIGPNREF=E19P4BFB14B2&RESPMSG=Approved&AUTHCODE=111111&AVSADDR=Y&AVSZIP=Y&CVV2MATCH=Y&ORIGPPREF=1XR06058R58346646&CORRELATIONID=bdd79cb3c7fb6&PROCAVS=X&PROCCVV2=M&SETTLE_DATE=2013-04-23 07:22:06&TRANSTIME=2013-04-23 07:22:06&LASTNAME=NotProvided&AMT=24.99&ACCT=3698&EXPDATE=1214&CARDTYPE=0&IAVS=N
ORIGRESULT is the result of the original transaction (0 is a success; anything else is a failure.)
ORIGPNREF is the PNREF from the original transaction.
You can also put a long, unique "token" parameter in your silent post URL. Something like
"http:// www.my-web-site.com/confirm-payment?token=2348349u21034ms39n899"
and match it up with the same token a server side script is expecting. Since the silent post URL is stored in your PayPal manager account, the token is confidential, and even the URL as a whole is confidential. Plus the transaction info is also passed to this silent post URL allowing you to match up info with your transaction you saved in your database at checkout. This is a good secure method to confirm payment was correctly made. The silent post will work for both "pay with paypal" and "direct credit card payment" methods on the payments advanced iframe (a.k.a. hosted checkout page). Additionally, you can also throw in one more check, to see if PayPal is the $_SERVER['HTTP_REFERER']; (which of course can't be trusted purely on its own).
Related
I'm trying to implement the new PayPal Orders API, here is what I did:
Create a developer account, add an app name and then I have Client Id and Secret.
Use OrderCreateRequest to create an Order
Get approvel_url from the resposne->result->links
Redirect to this approvel_url and finish the payment
Paypal will redirect back to my website.
But I never got any thing from the PayPal testing account,Please, what did I miss?
Edit:
On No.4, when redirects to the PayPal page, somehow it only shows 'Continue' button on the page, not the 'make payment' button.
You are missing:
Display an order review page to the payer.
Capture the order with an API call, which (if successful) will return the transaction ID in the purchase_units[0].payments.captures[0] object.
On success, display a thank you/confirmation page.
Without the final capture API call, there is no PayPal transaction.
You are also still using an old integration method based on redirects, which is for old websites. Current PayPal Checkout integrations use no redirects. At all.
Instead of redirecting, make two routes on your server, one for 'Create Order' and one for 'Capture Order', documented here. These routes should return only JSON data (no HTML or text). When a capture response is successful, store its resulting payment details in your database (particularly purchase_units[0].payments.captures[0].id, the PayPal transaction ID) and perform any necessary business logic (such as sending confirmation emails or reserving product) right before sending your return JSON.
Pair those two routes with the following approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server
2 questions for you regarding Paypal Hosted Checkout solution and the goal of the "Identity Token" or "Token ID".
1-
I've come accross several online Paypal docs (such as for Payflow integration) that talk about providing the "Identity Token" (or "Token ID", I think they're the same do they?), but I was wondering what's the goal of passing over this token ID, is it for my own security, or Paypal's one, or something else? Does anybody know exactly what's the purpose of that token ID, what Paypal is doing with it, and/or what the vendor shall be doing with it?
Asking this because when doing the form post to redirect the user to the Paypal hosted checkout, we have to first call the paypal gateway server to obtain the "secure token" and this API call is already secured through another method right, I need to pass my account credentials. So why posting only the "secure token" is not enough and we also need to post that "token ID"? Paypal should already have associated the secure token with my account information through the first API call no?
2-
Also, at the end of the flow, once Paypal returns the customer to my vendor website, does Paypal include any of those tokens (token ID or secure token) as part of their request (perhaps by adding url parameters to my given vendor return url)? If so, does Paypal recommands any sort of validation to be made on the vendor side, such as validating that the tokens match the ones that I, the vendor, stored in the user session prior to redirecting the customer through a form post to the Paypal hosted checkout? Basically, how can I ensure that the session was not hijacked between the time I redirect the customer to Paypal hosted checkout and the time Paypal returns the customer back to my site?
Reference: https://developer.paypal.com/docs/classic/payflow/integration-guide/#hosted-checkout-pages
Thanks a lot
As the previous user states, the Token id is used basically to identify an specific transaction process during it's workflow.
About your second question, in case of Express Checkout, the workflow does not ends when PayPal returns the user to your site. This step you are describing is probably when you send the user to PayPal to AUTHORIZE a payment that you will issue later. The last step is the DoExpressCheckoutPayment, in which you just inform paypal to make the transaction, for this you just pass to PayPal the token, so PayPal knows what you are "talking" about.
Is it good practice to validate the token, I would say yes. Somebody might be listening at your connection and injecting some invalid token. In any case, if you send an invalid token you will get an error message from paypal.
the following image illustrates very good the whole process:
As I understand it (and if reading this correctly), the Secure Token is for processing transactions on your own site instead of passing the user and order to paypal for processing. The Secure Token identifies that specific transaction and ensures the continuity of the order is not broken. You require a Token ID in order to obtain a Secure Token.
Using the PayPal permissions API can you receive notifications from payments made after a customer clicks on a payment button, proceeds to PayPal, and then pays?
I notice they have IPN, but will this work with the permissions API?
Thanks!
You can include NotifyURL in your API requests to set a URL for IPN to POST data to. It's not something that technically "works with the permissions API" but any transaction that is made would indeed trigger the IPN.
If you're building an app for 3rd parties to use, though, and you're passing NotifyURL in your API requests, that will override any IPN configuration each individual merchant using your tool might have setup on their own. This can cause frustration for such users because then their own IPN solution doesn't get hit when they take payments through your app.
If you're going to do that I recommend setting up a way for your users to enter their own IPN URL in your app settings, and then if they have a value, forward the POSTed data to their URL when PayPal sends it to yours. That way both IPN scripts will get hit and process the data accordingly.
I've setup a PayPal site which uses IPN and I was having trouble getting PayPal to send the GET variables to the return URL that I had specified. It was sending the user's browser to the return URL, but nothing was being passed via GET or POST.
I changed one setting in the PayPal business account: "Payment Data Transfer (optional)" to On which generated an "Identity Token" on the PayPal website.
I also got an automated email from PayPal saying:
---------- Forwarded message ----------
From: service#paypal.com <service#paypal.com>
Subject: Payment Data Transfer (PDT) Has Been Enabled
This email is to inform you that you have successfully enabled Payment Data Transfer.
PDT's primary function is to display payment transaction details to buyers when they are redirected back to your site upon payment completion. However, there are cases, such as with pending transactions, where you won't receive notification of all transactions. For this reason, PayPal strongly recommends that you also enable Instant Payment Notification (IPN).
To learn more about enabling and setting up IPN:
https://www.paypal.com/us/cgi-bin/?cmd=p/xcl/rec/ipn-intro-outside
To learn more about Payment Data Transfer, including setup instructions and a complete list of variables:
https://www.paypal.com/us/cgi-bin/?cmd=p/xcl/rec/pdt-intro-outside
Sincerely,
PayPal
Clicking on the second link and clicking on "Technical Overview" (https://www.paypal.com/us/cgi-bin/webscr?cmd=p/xcl/rec/pdt-techview-outside) shows:
Your POST should be sent to
https://www.paypal.com/cgi-bin/webscr.
You must post the transaction token
using the variable "tx" and the value
of the transaction token previously
received (e.g.
"tx=transaction_token"), and the
special identity token using the
variable at and the value of your PDT
identity token (e.g.
"at=identity_token"). You will also
need to append a variable named "cmd"
with the value "_notify-synch", for
example "cmd=_notify-synch", to the
POST string.
However, I am NOT passing the Identity Token at all, yet everything is working fine!
(a) Is this a problem?
(b) Why is it working if the documentation implies that it shouldn't?
(c) Is this a consequence of specifying an outdated API version (58.0)? What is the value I should be using?
In my opinion the identity token should be a required param since it is the only way Paypal can verify that the request you're making is valid. Otherwise, other people can simply guess a transaction id (even though it is not intended for their accounts) and get details for that transaction from Paypal.
I'm guessing this is a bug you're experiencing. Are you testing in the Paypal sandbox or in a live environment?
Realizing that the OP probably no longer needs an answer after 9 years, but others still might:
The POST of the transaction ID and identity token is purely for the purpose of verifying that the original transaction notification (relayed via the GET method to the merchant's Return URL) actually came from PayPal.
It is as if to say to PayPal, "My website just got this supposed confirmation that a customer paid. Here is the transaction ID and my seller ID again. Is this a legitimate match?"
In fact, at https://developer.paypal.com/docs/api-basics/notifications/payment-data-transfer/, when talking about setting up for testing, it only talks about getting your script ready to receive, parse and display the GET data. It doesn't mention the POSTing back to PayPal (though that is mentioned elsewhere). So, yes, the PDT function should work without doing the POST back to PayPal afterward and waiting for that response of SUCCESS or FAIL, but...
Anyone who knew what they were doing could go to a seller's URL and append a query string with the right combination of variables to fake the same kind of GET request that the PayPal PDT system would initially send, whether or not the transaction ID were a real one.
I'm implementing a simple Buy Now button and I'm using IPN (not PDT) to verify the transaction.
A thing that bugs me is that I don't understand how come only after I set the notify_url field to the button I also get the transaction variables to the success URL, as GET params. It would seem normal to be the other way around.
Since the user could or could not choose to "return to the merchant's website" there's not way I should rely on that data. It does however seem to be identical to the one sent to the notify URL.
Some clarification would help. Thanks!
I know what you mean, after the user has finished paying and chooses to return to the sellers website (button in paypal page) they are redirected to your thankyou page.
I don't think it used to do this back in 2009 but now paypal will issue the redirect with all sorts of parameters in the url query string.
I'm just ignoring this information and relying on the backend IPN post which is verifiable by paypal
In my previous experience with IPN, I defined the location of the notify URL in the control panel. Once the payment is processed, PayPal sends a POST notification to this URL independent of any user behavior.
In any case, even if you define the notify_url parameter in the button, I believe PayPal will still send the payment notification seperate from the user behavior - they spawn a new process to send the data. As to why they are using a GET rather than a POST, that is odd behavior. However, in your IPN script you should still have logic that verifies the call with PayPal before you continue processing.