latest stable versions: v150827 (changelog)

Old Forums (READ-ONLY): The community now lives at WP Sharks™. If you have an s2Member® Pro question, please use our new Support System.

Error 4020 on Paypal PDT

Home Forums Community Forum Error 4020 on Paypal PDT

This topic contains 19 replies, has 3 voices. Last updated by  Jason (Lead Developer) 4 years, 5 months ago.

Topic Author Topic
Posted: Thursday Jul 5th, 2012 at 6:40 am #18369
Tim Parkin
Username: timparkin

I’m working on a new wordpress website and am using an existing paypal account with express checkout. I’ve set up the S2Member with auto return and PDT and IPN’s seem to be working fine (I can see the results in the paypal-ipn.log showing correct responses). However, the return page shows the dissapointing grey screen informing me “Unable to verify $_POST vars”.

I’ve tried to dig into this a bit and have run the server php page which reports everything is OK. I have also exported the parameters sent to paypal so I can check the paypal return code.

The params are ..

{'tx': '59L86352N7049751A', 'cmd': '_notify-synch', 'at': 'EM--snipped--Yod-V04'}

I’ve used a small python script to send the ssl request to paypal and paypal is returning a 4020 code suggesting that the PDT identity token is incorrect (as far as I can understand reading around about 4020) but I’ve checked the value in the ‘at’ param key and it matches my PDT token.

The only thing I can think is that when I started using S2Member, I also applied for a payments pro account and am wondering if there is something in ‘limbo’ in paypal whilst this account is being approved?

My test users are signing up OK as they end up being redirected back to the home page after getting the ‘unable to verify’ message and, I presume, are just registering and the IPN sync is happening.

Tim

p.s. Python script used to check the connection is ..

import urllib
params = { 'tx': '59L86352N7049751A', 'cmd': '_notify-synch', 'at': 'EM--snipped--Yod-V04'}
params = urllib.urlencode(params)
f = urllib.urlopen("https://www.paypal.com/cgi-bin/webscr", params)
print f.read()

List Of Topic Replies

Viewing 19 replies - 1 through 19 (of 19 total)
Author Replies
Author Replies
Posted: Friday Jul 6th, 2012 at 7:07 am #18455

Hi Tim.

What does your IPN log say about the transactions? Could you quote the entry for one of the transactions with the problem? (x’ing out any private info, e.g. emails)

Could you try this in your site and see if everything’s okay there? http://www.s2member.com/r/server-check-tool/

Thanks!

Posted: Friday Jul 6th, 2012 at 7:43 am #18464
Tim Parkin
Username: timparkin

What does your IPN log say about the transactions? Could you quote the entry for one of the transactions with the problem? (x’ing out any private info, e.g. emails)

PHP v5.3.2-1ubuntu4.15 :: WordPress® v3.4.1 :: s2Member® v120622 :: s2Member® Pro v120622
Memory 32.71 MB :: Real Memory 33.00 MB :: Peak Memory 32.74 MB :: Real Peak Memory 33.00 MB
mydomain.com/?s2member_paypal_notify=1
User-Agent: 
array (
  'txn_type' => 'subscr_signup',
  'subscr_id' => 'I-xxxx',
  'last_name' => 'Elsen',
  'option_selection1' => 'mydomain.com',
  'option_selection2' => '82.132.xxx.xxx',
  'residence_country' => 'GB',
  'mc_currency' => 'GBP',
  'item_name' => 'Bi-weeky recurring subscription.',
  'business' => 'paypalemail@paypaldomain.com',
  'recurring' => '90.00',
  'verify_sign' => 'A17O5CpnB8Msm1oZA40qsYHojqAVAsfh6TryG1Wt4OXWJbUi5aiMxxxx',
  'payer_status' => 'unverified',
  'payer_email' => 'customer@gmail.com',
  'first_name' => 'Jerry',
  'receiver_email' => 'paypalemail@paypaldomain.com',
  'payer_id' => 'W9TSBC44Gxxxx',
  'option_name1' => 'Originating Domain',
  'invoice' => '4ff55e1d9ab4e~82.132.xxx.xxx',
  'option_name2' => 'Customer IP Address',
  'reattempt' => '1',
  'item_number' => '1',
  'subscr_date' => '02:29:18 Jul 05, 2012 PDT',
  'custom' => 'mydomain.com',
  'charset' => 'windows-1252',
  'notify_version' => '3.4',
  'period3' => '2 W',
  'mc_amount3' => '90.00',
  'ipn_track_id' => '4b36a084exxxx',
  's2member_log' => 
  array (
    0 => 'IPN received on: Thu Jul 5, 2012 9:29:38 am UTC',
    1 => 's2Member POST vars verified through a POST back to PayPal®.',
    2 => 's2Member originating domain ( `$_SERVER["HTTP_HOST"]` ) validated.',
    3 => 's2Member `txn_type` identified as ( `web_accept|subscr_signup` ).',
    4 => 's2Member `txn_type` identified as ( `web_accept|subscr_signup` ) w/o update vars.',
    5 => 'Signup Confirmation Email sent to: "Jerry Reed" <customer@gmail.com>.',
    6 => 'Storing IPN signup vars into a Transient Queue. These will be processed on registration.',
  ),
  'subscr_gateway' => 'paypal',
  'eotper' => NULL,
  'ccaps' => NULL,
  'level' => '1',
  'ip' => '82.132.xxx.xxx',
  'period1' => '0 D',
  'mc_amount1' => '0.00',
  'initial_term' => '0 D',
  'initial' => '90.00',
  'regular' => '90.00',
  'regular_term' => '2 W',
)

the paypal-rtn looks like this

PHP v5.3.2-1ubuntu4.15 :: WordPress® v3.4.1 :: s2Member® v120622 :: s2Member® Pro v120622
Memory 28.91 MB :: Real Memory 29.25 MB :: Peak Memory 29.01 MB :: Real Peak Memory 29.25 MB
mydomain.com/?s2member_paypal_return=1&s2member_paypal_return_tra=fnIyOlMwWjVNS01kekVUeE9pN2pydTYzVVhKeTJkcTJndUZ2OjQ2MzY4ZmNlNDg5OGNiNTQ3ZjE4ZTkwZDBlMjU2Z
jNkfCzjX64cgzLQgxchJBCeSDXjQiGGJE3qgZoKp7fZ6W6RLPDORGAQJfhxSHeLfeg_u4KWc_ZT1vFmH_g9QfDk1VnwtiJiI-tmtmAS_T_5Nekh1ETsK-7LMJWexH5iB9jfHCiCYOVACtpisxD67KYRf1A1bNnkTtdRt
83mDvj9cbjjq47J2BeGPKmW16ve5idjxF7R7uKajqC4z5lhFJugGt2y7nAPnM_8rqWNv1D_8fvny6_0y76hqTlbCP626fm6MqUUAqhQsiD3jRQPsXt5h5lsQGOnYNdgXh8seAtOmFVFpbrbO6XOUCZX6sO5b7n4T8woC
Q4hDkLDClfWONJ-ZN9l4Sm71Qs1WYvWADMvHqHHO1V3RSsVEjMuVKcRKz2WmA&tx=0JU85470SY786432Y&st=Completed&amt=3.00&cc=GBP&cm=mydomain.com&item_number=&sig=uEnlhdPojC
pZ5KwP9KEXMH57lv%2foRXjs67znlZ7YB6zGr6JJ8GJ6Vccamds0S8K6PGOfDc%2bAiR7gahX6cJHIRzhHOY0S2ho%2fxW6lvt1I08HFqWdDgJDr4Q07nCSgZf9LTW2wFrjzZB%2f6qlbGrZieyNLiWQYqjTtFKvsfO6
nxxxxx%3d
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:13.0) Gecko/20100101 Firefox/13.0.1
array (
  's2member_log' => 
  array (
    0 => 'Unable to verify $_POST vars. This is most likely related to an invalid configuration of s2Member, or a problem with server compatibility.',
    1 => 'If you\'re absolutely SURE that your configuration is valid, you may want to run some tests on your server, just to be sure $_POST variables are populated
, and that your server is able to connect/communicate with your Payment Gateway over an HTTPS connection.',
    2 => 's2Member uses the `WP_Http` class for remote connections; which will try to use `cURL` first, and then fall back on the `FOPEN` method when `cURL` is not 
available. On a Windows® server, you may have to disable your `cURL` extension; and instead, set `allow_url_fopen = yes` in your php.ini file. The `cURL` extension 
(usually) does NOT support SSL connections on a Windows® server.',
    3 => 'Please see this thread: `http://www.s2member.com/forums/topic/ideal-server-configuration-for-s2member/` for details regarding the ideal server configurati
on for s2Member.',
    4 => 'array (
  \'s2member_paypal_return\' => \'1\',
  \'s2member_paypal_return_tra\' => \'fnIyOlMwWjVNS01kekVUeE9pN2pydTYzVVhKeTJkcTJndUZ2OjQ2MzY4ZmNlNDg5OGNiNTQ3ZjE4ZTkwZDBlMjU2ZjNkfCzjX64cgzLQgxchJBCeSDXjQiGGJE3qgZ
oKp7fZ6W6RLPDORGAQJfhxSHeLfeg_u4KWc_ZT1vFmH_g9QfDk1VnwtiJiI-tmtmAS_T_5Nekh1ETsK-7LMJWexH5iB9jfHCiCYOVACtpisxD67KYRf1A1bNnkTtdRt83mDvj9cbjjq47J2BeGPKmW16ve5idjxF7R7u
KajqC4z5lhFJugGt2y7nAPnM_8rqWNv1D_8fvny6_0y76hqTlbCP626fm6MqUUAqhQsiD3jRQPsXt5h5lsQGOnYNdgXh8seAtOmFVFpbrbO6XOUCZX6sO5b7n4T8woCQ4hDkLDClfWONJ-ZN9l4Sm71Qs1WYvWADMvHq
HHO1V3RSsVEjMuVKcRKz2xxx\',
  \'tx\' => \'0JU85470SY786xxxx\',
  \'st\' => \'Completed\',
  \'amt\' => \'90.00\',
  \'cc\' => \'GBP\',
  \'cm\' => \'mydomain.com\',
  \'item_number\' => \'\',
  \'sig\' => \'uEnlhdPojCpZ5KwP9KEXMH57lv/oRXjs67znlZ7YB6zGr6JJ8GJ6Vccamds0S8K6PGOfDc+AiR7gahX6cJHIRzhHOY0S2ho/xW6lvt1I08HFqWdDgJDr4Q07nCSgZf9LTW2wFrjzZB/6qlbGrZiey
NLiWQYqjTtFKvsfO6nxxxx=\',
)',
    5 => 'Redirecting Customer to the Home Page, due to an error that occurred.',
  ),
  's2member_paypal_return_tra' => 'fnIyOlMwWjVNS01kekVUeE9pN2pydTYzVVhKeTJkcTJndUZ2OjQ2MzY4ZmNlNDg5OGNiNTQ3ZjE4ZTkwZDBlMjU2ZjNkfCzjX64cgzLQgxchJBCeSDXjQiGGJE3qgZoKp
7fZ6W6RLPDORGAQJfhxSHeLfeg_u4KWc_ZT1vFmH_g9QfDk1VnwtiJiI-tmtmAS_T_5Nekh1ETsK-7LMJWexH5iB9jfHCiCYOVACtpisxD67KYRf1A1bNnkTtdRt83mDvj9cbjjq47J2BeGPKmW16ve5idjxF7R7uKaj
qC4z5lhFJugGt2y7nAPnM_8rqWNv1D_8fvny6_0y76hqTlbCP626fm6MqUUAqhQsiD3jRQPsXt5h5lsQGOnYNdgXh8seAtOmFVFpbrbO6XOUCZX6sO5b7n4T8woCQ4hDkLDClfWONJ-ZN9l4Sm71Qs1WYvWADMvHqHHO
1V3RSsVEjMuVKcRKz2xxxx',
)

The server check tools runs with all green lights..

Posted: Saturday Jul 7th, 2012 at 3:39 am #18520

Thanks.

Are both for the same transaction? I ask because I noticed the RTN log entry with the error is missing the item number, but the IPN log has it and the entry looks okay. The item number should not be missing.

Are you using the s2Member shortcodes? Could you quote the shortcode you’re using?

Could you send me the link to the page where you’re using the shortcode, please? s2Member® » Private Contact Form

Thanks!

Posted: Sunday Jul 8th, 2012 at 6:48 am #18601
Tim Parkin
Username: timparkin

Since these posts I have also been debugging some older IPNs… It seems that paypal stores the IPN with the transaction and so some IPNs have been failing (although paypal has stored them as a 200 return code).

I’ve since added an apache redirect to get them into the right place but now I have been getting “unable to verify server host” because the old subscription transactions used a different value for the ‘custom’ field (e.g. 14_3_GBP_464_858ba4765e53c712ef672a9570474b1d_D_subscriber_86.31.173.xx_0).

How do I make s2member accept these IPNs? I don’t fancy hacking the ‘paypal-return-in.inc.php‘ code but I think I may have to end up hacking

if (!empty ($paypal["custom"]) && preg_match ("/^" . preg_quote (preg_replace ("/\:([0-9]+)$/", "", $_SERVER["HTTP_HOST"]), "/") . "/i", $paypal["custom"]))

to force a successful match? Any other ideas?

p.s. I did hack this line just to check if there were any other issues. Then the server stated it was going to ignore this IPN. I’m presuming this is because the item_number and possibly other fields didn’t match. Does this mean I have to rewrite the packet completely to match a new subscriber profile? If so could you tell me which fields would need fixing?

  • This reply was modified 4 years, 6 months ago by  Tim Parkin.
Posted: Sunday Jul 8th, 2012 at 7:30 am #18609

I see. Check out this thread and Jason’s tips there, you may find it helpful: http://www.s2member.com/forums/topic/help-with-paypal-central-ipn-php-and-ipn/

By the way, the central IPN script they’re talking about is in your Account page, in the Extras zip file. http://www.s2member.com/account/

I hope that helps. :)

Posted: Sunday Jul 8th, 2012 at 8:28 am #18611
Tim Parkin
Username: timparkin

Yes I’ve gone through this already. What about the question in the ps i.e. item_number not matching current system expectations?

Posted: Sunday Jul 8th, 2012 at 4:31 pm #18622

p.s. I did hack this line just to check if there were any other issues. Then the server stated it was going to ignore this IPN. I’m presuming this is because the item_number and possibly other fields didn’t match. Does this mean I have to rewrite the packet completely to match a new subscriber profile? If so could you tell me which fields would need fixing?

I don’t know how to answer this one. I don’t know what your change the code was, or what exactly should happen in the code there for s2Member to work. I’m emailing Jason and will have to wait for his input.

Posted: Sunday Jul 8th, 2012 at 4:46 pm #18623
Tim Parkin
Username: timparkin

Hi Cristián,

My fix was just to skip the paypal[‘custom’] check so it forced a domain (server host) match. However, once this happened the IPN packets were being ignored – I think this is because some of the variables didn’t atch what was expected.

I’m thinking that item_numer, item_name and txn_type probably need to be hacked but I’d love to have some feedback before I go ahead and do that.

Tim

Posted: Wednesday Jul 11th, 2012 at 11:07 am #18928
Tim Parkin
Username: timparkin

Jason?

I’m still getting an error when people subscribe (post vars problem) and the error when IPN updates come through (non matching item numbers). As time goes by the amount of manual fixes I’m going to have to make is going up (and not being able to export the whole database for analysis isn’t helping – any ideas on that as well?)

  • This reply was modified 4 years, 6 months ago by  Tim Parkin.
Posted: Wednesday Jul 11th, 2012 at 6:15 pm #18962
Tim Parkin
Username: timparkin

please?

Posted: Thursday Jul 12th, 2012 at 7:49 am #19027

My fix was just to skip the paypal[‘custom’] check so it forced a domain (server host) match.

What did you change the condition to, something like just [hilite code]if (true)[/hilite]? I don’t see how that affects the item_number, but I haven’t tried it…

What about the question in the ps i.e. item_number not matching current system expectations?

Are these new purchases you’re testing or old subscriptions? What is the [hilite mono]item_number[/hilite] in the transactions that fail?

Yes I’ve gone through this already.

So you tried the central IPN script already? http://www.s2member.com/forums/topic/error-4020-on-paypal-pdt/#post-18609

and not being able to export the whole database for analysis isn’t helping – any ideas on that as well?

No idea about that. Do you have phpMyAdmin? It has an export tool.

Posted: Thursday Jul 12th, 2012 at 8:40 am #19033
Tim Parkin
Username: timparkin

the S2member stores the domain at the front of the custom field. For older IPN’s from Your Members, the custom field does not contain the domain at the start and hence the server host check fails.

Here is an array of txn_type, item_number, custom fields – firstly a current s2member one

'txn_type' => 'subscr_cancel',
'item_number' => '3',
'custom' => 'www.newdomain.co.uk',

and now an older one

'txn_type' => 'subscr_payment',
'item_number' => '314',
'custom' => '14_3_GBP_2049_858ba4765e53c712ef672a9570474b1d_D_subscriber_78.143.213.237_0',

or

'txn_type' => 'subscr_payment',
'item_number' => 'buy_subscription_7_2678',
'custom' => '14_3_GBP_1808_858ba4765e53c712ef672a9570474b1d_D_subscriber_90.218.6.193_0',
 

The central IPN script would require that I change the url on each transaction which I am unable to do. Instead I have rewritten the requests to point at the s2member url and forced a match on server host.

I am occasionally getting error messages now that read

0 => 'IPN received on: Thu Jul 12, 2012 10:42:32 am UTC',
1 => 's2Member POST vars verified through a POST back to PayPal®.',
2 => 's2Member originating domain ( `$_SERVER["HTTP_HOST"]` ) validated.',
3 => 'Ignoring this IPN request. The `txn_type/status` does NOT require any action on the part of s2Member.',

alhtough some IPNs with the same txn_type and status are going through.

My concern now is the 4020 codes coming back from paypal when a new subscription is going through. The error suggests POST vars could not be verified but the IPN system is happy verifiying post vars with the same PDT.

I’m putting in some more logging and testing again but if you have any experience of new subs going to the ‘grey’ page with the ‘post vars could not be verified’ I would really appreciate some ideas..

Posted: Thursday Jul 12th, 2012 at 6:13 pm #19084

if you have any experience of new subs going to the ‘grey’ page with the ‘post vars could not be verified’ I would really appreciate some ideas..

I know that happens when there’s a problem with allow_url_fopen or cURL, but those seem to be fine in your installation or the server check tool would have warned you about them.

I researched the error some more and found mentioned in one place that it may be caused by bad PDT Identity Token. Could you check that you have entered the PDT Identity Token correctly? [hilite path]Dashboard -› s2Member® -› PayPal® Options -› PayPal® PDT Integration[/hilite]

For older IPN’s from Your Members, the custom field does not contain the domain at the start and hence the server host check fails.

Ah okay, I didn’t know you had transactions from a previous plugin there.

The central IPN script would require that I change the url on each transaction which I am unable to do. Instead I have rewritten the requests to point at the s2member url and forced a match on server host.

I see. Well, in the central IPN script you can add the domain name to the custom value. Then s2Member would work as usual. This would be better than hacking s2Member in all the places where it’d check the custom value.

Take a look at the thread I pointed you to earlier, these posts in particular:
http://www.s2member.com/forums/topic/help-with-paypal-central-ipn-php-and-ipn/#post-16326
http://www.s2member.com/forums/topic/help-with-paypal-central-ipn-php-and-ipn/#post-16698


I hope that helps. :)

Posted: Thursday Jul 12th, 2012 at 6:21 pm #19085
Tim Parkin
Username: timparkin

Did I mention that I can’t change the ipn url for older transactions and hence can’t use the central ipn.

PDT is fine as the post vars are being verified properly for the normal IPN transactions.

I suppose I could add a url handler that redirected to the central IPN script.

Have you got any idea whether this looks like a correct packet for the PDT callback

post vars :-
array (
  'tx' => '58563307UC021584B',
  'cmd' => '_notify-synch',
  'at' => 'EM3E9cLMxGWoOQNSfjO5qszsXnU85W1OvFAKOqG7hxxxxxxxxxxd-V04',
)
args :-
array (
  'timeout' => 20,
)
url :-
'https://www.paypal.com/cgi-bin/webscr'

This is the ‘remote’ call that ends up with a 4020 return value. The PDT is fine and the tx is fine… can’t work out why it would fail?

Posted: Thursday Jul 12th, 2012 at 6:43 pm #19088

This is the ‘remote’ call that ends up with a 4020 return value. The PDT is fine and the tx is fine… can’t work out why it would fail?

If your PDT token is correct, then I’m not sure why the 4020. Maybe it’s a mod_security problem? I’m not familiar with it, but would be worth checking it to make sure it’s not part of this trouble you’re having. Knowledge Base » Mod Security, Random 503/403 Errors

Did I mention that I can’t change the ipn url for older transactions and hence can’t use the central ipn.

The way I understnad it, you’d put the central IPN script in the URLs that the PayPal subscriptions point to for IPN, then the script would forward it to s2Member in a way that they’ll work with s2Member.

Posted: Thursday Jul 12th, 2012 at 6:48 pm #19089
Tim Parkin
Username: timparkin

No mod_security on the server (I manage a dedicated).

I’ll take another look at the IPN and use a redirect for it.

Could you ask if that args packet looks right for a new subscription post vars call?

Posted: Friday Jul 13th, 2012 at 5:34 am #19138

I’ll ask, will let you know when I get a reply.

Are you using live transactions when you test? It’s better to do live 1 cent transactions than using the PayPal Sandbox, which many times has its own bugs, which are pointless to resolve if they won’t be present in the actual service.

I don’t know if another plugin may be causing a conflict. Some weird problems were found to come from this, so it may be worth testing for it. Deactivate other plugins one by one and test after each to see if the problem is gone, please.

If you’re okay with it, could you send the login info to your WP and FTP to take a look? s2Member® » Private Contact Form

Posted: Friday Jul 13th, 2012 at 6:17 am #19147
Tim Parkin
Username: timparkin

I’ve sent the details already but if you want ftp access you’ll need to send me a public key. For security sake, you can login in to my wordpress and paste the public key into a draft page.

All transactions are live..

I have the system working for new transactions now but I have to force people to register an account first and then go through subscription. I thought it was possible to pay for a subscription and then create an account but this is where the 4020 problem is happening.

Tim

Posted: Saturday Jul 14th, 2012 at 3:33 am #19205
Staff Member

Thanks for the heads up on this request for support.

Yes, this looks very strange indeed. A 4020 error would certainly indicate an issue with your PDT Identity Token from PayPal. However, it could also be caused by corrupted HTTP communication, or with PayPal account settings. Here are some things I would take a look at.

1. Is Auto-Return enabled in your PayPal account Profile? PDT and Auto-Return work hand-in-hand. While having Auto-Return off should not produce this type of error, I think it’s worth taking a look at anyway, just to rule out the possibility of a strange PayPal behavior in this regard. Please make sure Auto-Return is “on” in your PayPal account, and that “PDT” is enabled as well.

2. If problems persist, I’d take a look at the HTTP communication that’s occurring, even closer.

Please create this directory and file:
/wp-content/mu-plugins/http-api-debug.php
( these are MUST USE plugins, see: http://codex.wordpress.org/Must_Use_Plugins )

<?php
add_action('http_api_debug', 'http_api_debug', 1000, 5);
function http_api_debug($response = NULL, $state = NULL, $class = NULL, $args = NULL, $url = NULL)
	{
		$log = array('state' => $state, 'transport_class' => $class, 'args' => $args, 'url' => $url, 'response' => $response);
		file_put_contents(WP_CONTENT_DIR.'/debug.log', print_r($log, TRUE)."\n\n", FILE_APPEND);
	}

Then run your tests again. Check the /wp-content/debug.log file for further details about HTTP communication.

Viewing 19 replies - 1 through 19 (of 19 total)

This topic is closed to new replies. Topics with no replies for 2 weeks are closed automatically.

Old Forums (READ-ONLY): The community now lives at WP Sharks™. If you have an s2Member® Pro question, please use our new Support System.

Contacting s2Member: Please use our Support Center for bug reports, pre-sale questions & technical assistance.