I set up a sandbox account and I'm simulating payments with sandbox and logging $_POST array posted by paypal sandbox (simulating).
This is the form that I'm sending to paypal (not simulating)
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
// charset, name, email, etc.
// ...
<input type='hidden' name='on0' value='Custom field 1 NAME'>
<input type='hidden' name='os0' value='Custom field 1 VALUE'>
</form>
As you can see I have 1 custom field named on0.
How am I supposed to retrieve that value? I can't create custom fields on paypal's sandbox page.
These should be variables that get returned back to you. Can you provide the full PayPal button code that you are using. Also, what is the method that you are using to return data back to your site?
Related
I'm setting up Payment Data Transfer (PDT) in PayPal.
After a purchase PayPal redirects the user to my return page and I have the tx parameter from the URL.
I also have my unique PDT token from the PayPal profile settings page.
The documentation says the next step (step 3 in the diagram) is:
Your return URL web page contains an HTML POST form that retrieves the transaction ID and sends the transaction ID and your unique PDT token to PayPal.
That's fine.
But what is the PayPal URL that I POST this data to, to retrieve the transaction details? And what form / parameter names do I use?
I've read multiple pages on the PayPal documentation site but can't find any reference to this PDT URL!?
When you enable PDT via your PayPal dashboard, PayPal sends you a confirmation email. In this email is a link to, what appears to be, hidden documentation!
https://developer.paypal.com/docs/classic/paypal-payments-standard/integration-guide/paymentdatatransfer/
Post a FORM to PayPal that includes the transaction ID and your identity token, a string value that identifies your account to PayPal. The form looks like this:
<form method=post action="https://www.paypal.com/cgi-bin/webscr">
<input type="hidden" name="cmd" value="_notify-synch">
<input type="hidden" name="tx" value="TransactionID">
<input type="hidden" name="at" value="YourIdentityToken">
<input type="submit" value="PDT">
</form>
In PayPal's reply to your post, the first line is SUCCESS or FAIL. A successful response looks like this, with the HTTP header omitted:
SUCCESS
first_name=Jane+Doe
last_name=Smith
payment_status=Completed
payer_email=janedoesmith%40hotmail.com
payment_gross=3.99
mc_currency=USD
custom=For+the+purchase+of+the+rare+book+Green+Eggs+%26+Ham
...
I initially discarded this email without reading it, which is why I missed the secret documentation!
I also found this stackexchange question which references a much older PayPal documentation page which says the same thing:
https://www.paypal.com/us/cgi-bin/webscr?cmd=p/xcl/rec/pdt-techview-outside
But again, the documentation page is not browsable, so you must happen to know the exact URL to find it!
As suggested on stackoverflow, I make sure to log in to https://developer.paypal.com, to set cookies for sandbox development before attempting my SetExpressCheckout flows.
I get a successful response from my SetExpressCheckout call, with a reply such as:
TOKEN=EC%2d2D3179619P0352202&TIMESTAMP=2014%2d08%2d08T01%3a58%3a29Z&CORRELATIONID=ca8756c977f0&ACK=Success&VERSION=116&BUILD=12301660
My problem comes when trying to redirect to PayPal with the _express-checkout command:
I extract the TOKEN value, and pass that in an HTTP form, with GET and POST variations shown below. I'm using Perl, but the forms are just plain HTML, and the forms below are taken directly from viewing the page source that is generated by my Perl CGI script.
form using GET:
<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="GET">
<input type="hidden" name="cmd" value="_express-checkout">
<input type="hidden" name="token" value="EC%2d1BH04005UH441943R">
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynow_SM.gif" border="0" alt="PayPal - The safer, easier way to pay online!">
</form>
form URL: https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC%252d1BH04005UH441943R&x=61&y=11
lands on: https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_flow&SESSION=S4XbHMPLePuv_A93vhHvqIo4GEYOpsQCYkn6iiIE6AeRfMEkXHzSPWYeH3G&dispatch=50a222a57771920b6a3d7b606239e4d529b525e0b7e69bf0224adecfb0124e9b61f737ba21b08198a0586321b47f5ae7b54ee269d9200b8b
( PayPal page with "This transaction is invalid. Please return to the recipient's website to complete your transaction using their regular checkout flow." )
form using POST:
<form action=https://www.sandbox.paypal.com/cgi-bin/webscr METHOD='POST'>
<input type=hidden name='cmd' value='_express-checkout'>
<input type=hidden name='token' value=EC%2d9MK58577ER8913409>
<input type=image src=https://www.paypalobjects.com/en_US/i/btn/btn_buynow_SM.gif border=0 alt='PayPal - The safer, easier way to pay online!'>
</form>
form URL: https://www.sandbox.paypal.com/cgi-bin/webscr
lands on: https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_flow&SESSION=MQjOoKQ1FNeHGrVOsukD0Ln8K8LvfvfrejsDm9XZq3JeLThBanMZ2vC1Wtm&dispatch=50a222a57771920b6a3d7b606239e4d529b525e0b7e69bf0224adecfb0124e9b61f737ba21b08198a0586321b47f5ae7b54ee269d9200b8b
( PayPal page with "This transaction is invalid. Please return to the recipient's website to complete your transaction using their regular checkout flow." )
Curiously, if I manually enter the URL that would have been the 'action=' URL of my form using method=GET, it all works:
Manual cut-n-paste of form URL: https://www.sandbox.paypal.com/cgi-bin/webscr&cmd=_express-checkout&token=EC%2d00D71751FM635411H (with or w/o appending &x=nn&y=nn)
lands on: https://www.sandbox.paypal.com/cgi-bin/webscr&cmd=_express-checkout&token=EC%2d00D71751FM635411H
( Sandbox test store, showing order summary and buyer PayPal account login prompts, as expected )
It seems to me there is some issue with PayPal's session caching, since my form URLs get transformed to ones with parms "_cmd=flow&SESSION={long session ID}, but I clear (Safari) browser cookies before logging in to developer.paypal.com.
I get similar behavior on a different computer, using Firefox and IE browsers.
PayPal won't accept your token because you send it back as percent-encoded twice.
The SetExpressCheckout response is a string that contains a series of parameter names and values. This string is percent-encoded, meaning that you need to decode it to extract the actual values.
Most importantly, you are interested in the TOKEN=EC%2d2D3179619P0352202 part, where the %2d represents the character -.
When you re-inject the string directly to a form input as shown in your question, the %2d represents nothing but the sequence of characters % 2 d. Moreover, when sent to PayPal as a GET request, the sequence will be percent-encoded itself, with the percent sign encoded to %25, resulting in the sequence % 2 5 2 d that you observed. So the token gets lost in translation.
What you need to input is the decoded version of the token:
<input type="hidden" name="token" value="EC-1BH04005UH441943R">
In Perl, the decoding can be achieved using, for example, CPAN's URI::Escape module.
I am trying to get my Paypal subscription to redirect to a custom page after a successful checkout.
Before submitting to Paypal I overload the submit handler, run my own function (to store details) and return a unique id. I want to attach that id to my return URL. (as a GET or POST var so to speak)
I have turned auto redirect "on" in my Paypal sandbox sellers preferences, but it only seems to re-direct to the URL that I HAVE to put in there.
using the <input type="hidden" name="return" value="someurl" /> does no seem to work.
I want it this way so that I can capture the user information when entered with a "non-paid" flag, then via the IPN I can update that record with a "PAID" flag, and I want to use the unique ID to tie it all together so to speak.
Your hidden field name needs to comply with the accepted variable name required by PayPal. Does ReturnUrl (not case-sensitive) not work?
<input type=hidden name="RETURNURL" value="https://www.YourReturnURL.com">
Note: I have only investigated and implemented express checkout so this may not apply to your implemenation: https://cms.paypal.com/en/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ECGettingStarted
When my users are logged in with their username and userid saved in the session variable they can donate using paypal. With the simple buy now button that you can simply generate at paypal.
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="XXX">
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>
When they payment is successful they are sent to my confirm_payment.php with all the _POST data. I can use the mail they paid with and compare this with my user database to find the correct user, but I can't be sure that they use the same email for paypal and my site.
I need to pass the $_SESSION['username'] to paypal so I can use this information to give my users donator status automatically. Can I add something like:
<input type="hidden" name="custom" value="custom variable">
to my button code? Here is more info on the variables avaliable paypal info
I found the documentation confusing but after a lot of web browsing I discovered that the custom variables do not allow you to create your own hidden fields but there are 3 variables that may be useful:
"custom" Optional Pass-through variable for your own tracking purposes, which buyers do not see.
Default – No variable is passed back to you. 256 characters
"item_number" See description. Pass-through variable for you to track product or service purchased or the contribution made. The value you specify is passed back to you upon payment completion. This variable is required if you want PayPal to track inventory or track profit and loss for the item the button sells.
"invoice" Optional Pass-through variable you can use to identify your invoice number for this purchase.
Default – No variable is passed back to you. 127characters.
So if you save your data prior to allowing the buy now button to fire (I do this by having a summary screen which shows the choices made and saves them to a database) you can then put a value (e.g. primary key of the saved data) as the custom value.
Note that the data will be posted to the instant payment notification page that you designate.
From
https://www.x.com/developers/paypal/documentation-tools/paypal-payments-standard/integration-guide/Appx_websitestandard_htmlvariables#id08A6HF00TZS
yes you can add like this, this is the correct way, and when paypal pings you back on IPNHandler then you'll get the value of this custom hidden field in querystring with the same name.
Ive been using express checkout API to convert people's accounts on my site to premium accounts after paying. The only problem with it is that it doesn't send the user back to the site until they click the button to return, and it updates their permission when that happens. About 40% of the users don't seem to do that.... so their accounts never get credited after payment.
Although paypal does an instant post-back upon the successful payment, I was never able to make it actually update the user's account right away, since I cant get it to send back some sort of informational that would identify the user that just completed the payment. I could only do that when you are sent back to the site, which sends the transaction ID, that I logged with a post-back. It searches for it, and grants permission if it was found int he DB.
Is there a way to submit some sort of a variable to paypal, that it will then post back to me? Something like &user_id=123, which would make it very handly to update the user's permission.
Iten_number hidden variable don't work in my application. But i found that custom hidden field works fine. Just add this field to the form, generated by paypal: <input type="hidden" name="custom" value="YOUR VALUE FROM DB"/>. After, you can read this value to identify, for example, what product have been purchased. (Java code): String custom = request.getParameter("custom");
Yes, if you send item_number, the IPN notification will include that when it posts back to you. I record a unique ID in the database when the user starts the payment process, and include that when sending them to PayPal. When the IPN comes in, that unique ID matches up with the record in the database, giving me all the info I need.
Edit Re your comment:
I expect there's a code example somewhere on the site linked above, but basically in my case I'm using a form that I POST to https://www.paypal.com/cgi-bin/webscr. Within that form are various hidden fields documented in the IPN stuff (cmd for what command to perform, business to specify your business ID, item_name for a nice description in the PayPal UI, item_number for the item number I mentioned above, etc., etc.). When IPN posts back to your IPN address, it includes various fields (such as payment_status — kind of important! &mdash and the item_number you fed in when posting to them).
Just to add to this old question...
There are option parameters that are commonly used for custom data sending through paypal.
These option tags are on0, on1, or on2 for the custom field names and os0, os1, and os2 for the custom field values.
I would send on0 with a value of "UserID" and os0 the actual ID.
These values will be represented in the IPN as follows:
os0 is represented as option_selection1
os1 is represented as option_selection2
os2 is represented as option_selection3
on0 is represented as option_name1
on1 is represented as option_name2
on2 is represented as option_name3
Here's the info on PayPal's HTML parameters
According to HTML Variables for PayPal Payments Standard you can send all the "Pass-through" variables:
item_number Pass-through variable for you to track product or service
purchased or the contribution made. The value you specify is passed
back to you upon payment completion. This variable is required if you
want PayPal to track inventory or track profit and loss for the item
the button sells.
custom Pass-through variable for your own tracking purposes, which buyers do not see. Default – No variable is passed back to you.
and
invoice Pass-through variable you can use to identify your invoice number for this purchase. Default – No variable is passed back to
you.
All these pass-through variables are sent back by the IPN in the payment response info.
You just have to render your HTML template server-side and write the fields back in the HTML code like
<input type="hidden" name="item_number" value="{{ productID }}">
<input type="hidden" name="invoice_id" value="{{ invoiceID }}">
<input type="hidden" name="custom" value="{{ jsonInfo }}">
Technically the field "custom" can be a JSON encoded string if you want to handle more data like
myItemObject = {
"customerEmail" : "john#doe.com
"customerID: "AAFF324"
}
jsonInfo = json.dumps( myItemObject )
return render_template(tmpl_name, jsonInfo=jsonInfo, productID=productID, invoiceID=invoiceID)
I finally get this answer, I want to share with all of you look:
on your HTML form put this code (this is Paypal sandbox):
form action="https://www.sandbox.paypal.com/cgi-bin/webscr?custom=YOUR_VAR" method="post"
On your PHP after the Paypal redirect to your page success: use the cm GET variable:
$example = $_GET["cm"];
I hope this URL solves your issue. As it solved mine as well. Add a custom variable to your form and then retrieve it on your success payment page.
Example :
<input type='hidden' name='custom' value='<?php echo $email; ?>'/>
and then retrieve it as :
$_POST['custom']
<input type="hidden" name="on0" value="Ajay Gadhavana">
<input type="hidden" name="on1" value="my_phone_number">
<input type="hidden" name="on2" value="my_third_extra_field">
Response from paypal would be
[option_name1] => Ajay Gadhavana
[option_name1] => my_phone_number
[option_name1] => my_third_extra_field
What worked for me in 2021 is passing "custom_id" (inside the "purchase_units" array) to PayPal in my client app and checking "custom" on my backend.
Yes, it looks like PayPal renames the parameter for some reason.