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.

IPN Proxy *return_url variable not processed

Home Forums Community Forum IPN Proxy *return_url variable not processed

This topic contains 10 replies, has 4 voices. Last updated by  Raam Dev 4 years, 8 months ago.

Topic Author Topic
Posted: Saturday Apr 14th, 2012 at 6:53 pm #10825

I’m trying to hack in support for an alternative Payment Gateway called NMI. Things are going well, except that the success url is not working. Here’s my log:

PHP v5.2.17 :: WordPress® v3.3.1 :: s2Member® v120309 :: s2Member® Pro v120309
Memory 50.61 MB :: Real Memory 51.25 MB :: Peak Memory 50.71 MB :: Real Peak Memory 51.25 MB
123.456.789.001/wpLoc/?s2member_paypal_notify=1&s2member_paypal_proxy=nmi&s2member_paypal_proxy_use=pro-emails,subscr-signup-as-subscr-payment&s2member_paypal_proxy_verification=************************************&s2member_paypal_proxy_return_url=%2Fthank-you%2F
User-Agent: WordPress/3.3.1; http://123.456.789.001
array (
‘first_name’ => ‘Mark’,
‘last_name’ => ‘Tester’,
‘username’ => ‘tester’,
‘option_name1’ => ‘Originating Domain’,
‘option_selection1’ => ‘123.456.789.001’,
‘option_name2’ => ‘Customer IP Address’,
‘option_selection2’ => ‘123.456.789.008’,
‘txn_id’ => ‘6111’,
‘subscr_id’ => ‘6111’,
‘custom’ => ‘123.456.789.001’,
‘payer_email’ => ‘mark.tester@gmail.com’,
‘item_number’ => ‘3’,
‘txn_type’ => ‘subscr_signup’,
‘period3’ => ‘1 Y’,
‘mc_amount3’ => ‘205’,
‘mc_gross’ => ‘205’,
‘recurring’ => ‘205’,
‘payment_type’ => ‘instant’,
‘payment_status’ => ‘Completed’,
‘proxy_verified’ => ‘nmi’,
‘s2member_log’ =>
array (
0 => ‘IPN received on: Sat Apr 14, 2012 9:28:08 pm UTC’,
1 => ‘s2Member POST vars verified with a Proxy Key’,
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: “Mark Tester” .’,
6 => ‘Subscr. Return ( `modification=0` ), a Proxy Return URL is ready.’,
7 => ‘Storing `payment` for Subscription via ( `subscr-signup-as-subscr-payment` ).’,
8 => ‘Creating an IPN response for `subscr_payment`. This will go into a Transient Queue; and be processed during registration.’,
9 => ‘Storing IPN signup vars into a Transient Queue. These will be processed on registration.’,
),
‘subscr_gateway’ => ‘nmi’,
‘eotper’ => NULL,
‘ccaps’ => NULL,
‘level’ => ‘3’,
‘ip’ => ‘123.456.789.008’,
‘period1’ => ‘0 D’,
‘mc_amount1’ => ‘0.00’,
‘initial_term’ => ‘0 D’,
‘initial’ => ‘205’,
‘regular’ => ‘205’,
‘regular_term’ => ‘1 Y’,
‘s2member_paypal_proxy’ => ‘nmi’,
‘s2member_paypal_proxy_use’ => ‘pro-emails,subscr-signup-as-subscr-payment’,
‘s2member_paypal_proxy_verification’ => ‘************************************’,
)

It looks like the s2member_paypal_proxy_return_url variable never makes it into the submitted array. What’s more, a payment confirmation is sent to the subscriber but no followup with username and password.

I went through the paypal-notify-in-subscr-or-wa-w-level.inc.php code and found the case where this URL is supposed to be processed. It should result in a log message that reads:

‘Storing IPN signup vars now. These are associated with a User\’s account record; for future reference.’

Instead of the output in index 9 above. I know because a few months back I actually had this working.

I’ve chased the data through every stage of processing many times over and am still at a loss as to why the s2member_paypal_proxy_return_url query var is not making it through. Please help.

List Of Topic Replies

Viewing 10 replies - 1 through 10 (of 10 total)
Author Replies
Author Replies
Posted: Monday Apr 16th, 2012 at 5:55 pm #10935
Raam Dev
Username: Raam
Staff Member

Hi Mark,

As per our support policy, customizations and hacks like these are unsupported (please see s2Member® » Support Policy » Outside Scope). However, I will send the lead developer an email to see if he can offer any insight.

Posted: Tuesday Apr 17th, 2012 at 11:17 am #11006

Raam,

Thanks for getting back. I understand this is outside the scope of your support, however, you do have this line as part of that support policy (which I read before posting the first time):

“Technical support will thus take priority over any assistance with customization or modifications. If you are requesting assistance in this regard, and it only requires us to publish a couple lines of code, we will gladly help you. Or at least point you in the right direction.”

Posted: Thursday Apr 19th, 2012 at 6:55 am #11220

Great job on the integration so far. :)

It’s like Raam said, but I’ll email Jason in case he can tell you where to look off the top of his head. I don’t know how soon he’ll reply, since he’s really busy with the code for the new major release, though.

Posted: Thursday Apr 19th, 2012 at 1:42 pm #11278

Okay, thanks very much Cristián, I’m really in a bind here. Just to reiterate more concisely:

1. I’m trying to signup a new member at the same time the transaction is bring processed (like the standard pro forms do).

2. Even though I get a success response, no redirection is happening.

3. The new user gets a transaction confirmation email but no username and password followup email.

4. I get this message in the log: (‘Storing IPN signup vars into a Transient Queue. These will be processed on registration.’) instead of the desired message: (‘Storing IPN signup vars now. These are associated with a User\’s account record; for future reference.’).

I imagine Jason might know at a glance what’s going on with item 4. as it’s indicative of some processing conditional that’s not being triggered properly (or the way I want it to be). Again, I’d be very grateful of any clues you could give me.

Thank You.

Posted: Thursday Apr 19th, 2012 at 8:52 pm #11297
Staff Member

Hi there. Thanks for the heads up on this thread.

@mark lion
Are you creating the User’s account in WordPress BEFORE posting this data to the IPN processor?
In this case, that would be the ideal approach (please do that).

Posting your IPN data to s2Member AFTER the account is created should resolve the issue you’re having here. The log entry you posted, indicates that you are calling the IPN handler before the User’s account is created within WordPress, so it’s queuing things up in anticipation of on-site registration.

If the account already exists, you’ll get the results you desire.

Also, regarding the Proxy return URL. s2Member’s IPN handler exits script execution and returns the full URL in the output. So it’s not going to show up in the log file entries, but your script can collect this value the same way s2Member itself does. That is, you might do something like this…

$url_with_replacement_codes_filled_in = file_get_contents('123.456.789.001/...s2member_paypal_proxy=nmi&...&s2member_paypal_proxy_return_url=%2Fthank-you%2F');
Posted: Wednesday Apr 25th, 2012 at 5:04 pm #11861

Jason,

Thanks very much for the response. I’ve verified that a new wordpress user is being created before the remote() method is called.

In fact, I’ve modified the authnet.checkout-in.inc.php routines to accomodate the new gateway because the response is very similar to what authnet produces, so my processor is going through the same steps.

I’ve verified that wp_create_user returns a valid user ID but it seems wp_new_user_notification is not successful because the new user never receives an email (and the admin is also not notified).

The remote() method then seems to run fine, but as you can see in my previous post it is not actually setting up all the subscription details for the new user.

After this is done the new user gets the “Congratulations” confirmation email and a new user has in fact been added to the users table, but only as a level 0 free subscriber.

Can you think of why remote() has a problem with the freshly generated user account?

Again, any help is hugely appreciated!

Posted: Thursday Apr 26th, 2012 at 10:19 am #11940
Staff Member

Hi Mark. Thanks for the follow-up.

Couple of things come to mind.

1. Any object caching plugins running on this installation? Or a database cache of any kind?
2. Anything in your own PHP sub-routines that might be making updates to a WP_User object by reference? In other words, is it possible that your script runs something else right after the IPN is sent to s2Member? Something which might actually be operating on what would be a stale WP_User object, once the IPN is processed.

If problems continue, please post a longer code snippet for me, so I can get a bigger picture, and see where you’re at currently with the issue. I’ll be happy to assist further in any way that I can. I’d be particularly interested in seeing the full code snippet that is posting IPN data to s2Member. Perhaps I’ve missed something, that your code will make more apparent to me.

Posted: Tuesday May 1st, 2012 at 4:03 pm #12312

Jason,

Thanks very much for having a look here. I’ve pasted my code that preps and passes user and gateway response data to the remote() method. It ought to look very familiar :)

The wp_new_user_notification() function is now doing its thing properly, so the problem is down to the remote() method not processing the new subscription the way I’d like. The new user is always created as a free subscriber, and nothing is captured in the $s2[“s2member_paypal_proxy_return_url”] element (hence, wp_redirect() is not happening).

You’ll notice a section labeled MANUALLY ADD AUTO_EOT, which is commented out. Your last response made me think this could be interfering somehow, but I get the same result whether it’s in or out.

$GLOBALS["ws_plugin__s2member_pro_paypal_checkout_response"] = array (); /* This holds the global response details. */
$global_response = &$GLOBALS["ws_plugin__s2member_pro_paypal_checkout_response"]; /* This is a shorter reference. */

// QUERY STRING FOR S2 IPN PROCESSOR
$q_url = 's2member_paypal_notify=1';
$q_url .= '&s2member_paypal_proxy=nmi';
$q_url .= '&s2member_paypal_proxy_verification=' . urlencode ( c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen () );
$q_url .= '&s2member_paypal_proxy_use=pro-emails,subscr-signup-as-subscr-payment';
$q_url .= '&s2member_paypal_proxy_return_url=' . rawurlencode ( self::$successURI );

// IPN DATA
$s2[ 'first_name' ]						= $userData[ 'firstname' ];
$s2[ 'last_name' ]						= $userData[ 'lastname' ];
$s2[ 'username' ]						= $userData[ 'username' ];
$s2[ 'option_name1' ]					= 'Originating Domain';
$s2[ 'option_selection1' ]				= $_SERVER[ 'HTTP_HOST' ];
$s2[ 'option_name2' ]					= 'Customer IP Address';
$s2[ 'option_selection2' ]				= $_SERVER[ 'REMOTE_ADDR' ];	
$s2[ 'txn_id' ]							= $nmiResponse[ 'transactionid' ];
$s2[ 'subscr_id' ]						= $nmiResponse[ 'transactionid' ];
$s2[ 'custom' ]							= self::$custom;			
$s2[ 'payer_email' ]					= $userData[ 'email' ];
$s2[ 'item_name' ]						= 'Subscription';
$s2[ 'item_number' ]					= $userData[ 'level' ];
$s2[ 'txn_type' ]						= self::$txn_type;
$s2[ 'period3' ]						= self::$period3;
$s2[ 'mc_amount3' ]						= $userData[ 'amount' ];
$s2[ 'mc_gross' ]						= $userData[ 'amount' ];
$s2[ 'recurring' ]						= self::$recurring;
$s2[ 'payment_type' ]					= self::$payment_type;
$s2[ 'payment_status' ]					= self::$payment_status;

if (!($create_user = array ())) /* Build post fields for registration configuration, and then the creation array. */
{
	$_POST["ws_plugin__s2member_custom_reg_field_user_pass1"] = $userData["password1"]; /* Fake this for registration configuration. */
	$_POST["ws_plugin__s2member_custom_reg_field_first_name"] = $s2["first_name"]; /* Fake this for registration configuration. */
	$_POST["ws_plugin__s2member_custom_reg_field_last_name"] = $s2["last_name"]; /* Fake this for registration configuration. */
	$_POST["ws_plugin__s2member_custom_reg_field_opt_in"] = $userData["custom_fields"]["opt_in"]; /* Fake this too. */
	/**/
	if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"])
		foreach (json_decode ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"], true) as $field)
		{
			$field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field["id"]));
			$field_id_class = preg_replace ("/_/", "-", $field_var);
			/**/
			if (isset ($s2["custom_fields"][$field_var]))
			$_POST["ws_plugin__s2member_custom_reg_field_" . $field_var] = $s2["custom_fields"][$field_var];
		}
	/**/
	$_COOKIE["s2member_subscr_gateway"] = c_ws_plugin__s2member_utils_encryption::encrypt ("nmi"); /* Fake this for registration configuration. */
	$_COOKIE["s2member_subscr_id"] = c_ws_plugin__s2member_utils_encryption::encrypt ( $nmiResponse[ 'transactionid' ] ); /* Fake this for registration configuration. */
	$_COOKIE["s2member_custom"] = c_ws_plugin__s2member_utils_encryption::encrypt ($s2["custom"]); /* Fake this for registration configuration. */
	$_COOKIE["s2member_item_number"] = c_ws_plugin__s2member_utils_encryption::encrypt ( $s2[ 'item_number' ] ); /* Fake this too. */
	/**/
	$create_user["user_login"] = $s2["username"]; /* Copy this into a separate array for `wp_create_user()`. */
	$create_user["user_pass"] = wp_generate_password (); /* Which may fire `c_ws_plugin__s2member_registrations::generate_password()`. */
	$create_user["user_email"] = $s2["payer_email"]; /* Copy this into a separate array for `wp_create_user()`. */
}

if ( ( ( $new__user_id = wp_create_user ($create_user["user_login"], $create_user["user_pass"], $create_user["user_email"] ) ) ) && !is_wp_error ( $new__user_id ) )
{
			
	update_user_option ($new__user_id, "default_password_nag", true, true); /* Password nag. */
	wp_new_user_notification ($new__user_id, $create_user["user_pass"]);
	/**/
	$s2["s2member_paypal_proxy_return_url"] = trim (c_ws_plugin__s2member_utils_urls::remote (site_url ("/?" . $q_url), $s2, array ("timeout" => 20)));

	// MANUALLY ADD AUTO_EOT
	// this gateway will not be sending IPN notifications 
	// ---------------------------------------------------
	// update_user_option ($new__user_id, "s2member_auto_eot_time", strtotime( '+1 year' ) );

	/**/
	$global_response = array ("response" => _x ($s2["s2member_paypal_proxy_return_url"] . ' ' . $new__user_id . ' ' . '<strong>Thank you.</strong> Your account has been approved.<br />&mdash; You\'ll receive an email momentarily.', "s2member-front", "s2member"));
	/**/
	
	if (substr ($s2["s2member_paypal_proxy_return_url"], 0, 2) === substr (self::$successURI, 0, 2) && ($custom_success_url = str_ireplace (array ("%%s_response%%", /* Deprecated in v111106 ». */ "%%response%%"), array (urlencode (c_ws_plugin__s2member_utils_encryption::encrypt ($global_response["response"])), urlencode ($global_response["response"])), $s2["s2member_paypal_proxy_return_url"])) && ($custom_success_url = trim (preg_replace ("/%%(.+?)%%/i", "", $custom_success_url))))
		wp_redirect ( c_ws_plugin__s2member_utils_urls::add_s2member_sig ( $custom_success_url, "s2p-v" ) ) . exit ();
	
}

Thanks again!

Posted: Wednesday May 2nd, 2012 at 9:59 pm #12409

Call this one resolved, tho I came up with an entirely different solution. I decided to make another attempt at leveraging as much of the s2 codebase as possible and wound up finding just a few derivations in the NMI gateway’s API that could mostly be adjusted for with a filter. So just to sum up, I’m using authnet pro forms and then filtering some of the API values before wordpress cURLs it.

In case anyone’s interested, I’m using this filter hook:
add_filter( ‘http_request_args’, ‘my_filter_function’, 10, 2 );

found in the WP_Http->request() method. This also passes the api url as the second parameter so I use it to make sure I’m altering the right requests.

Speaking of the api url, this is the only thing I had to manually edit as it’s hardcoded in to the authnet-utilities.inc.php file. Jason, ever thought of dropping some filter hooks in your c_ws_plugin__s2member_utils_urls::remote() method? Being able to hook into the $url value would be pretty handy, unless I’m overlooking another way.

And thanks for giving this some of your attention!

Posted: Saturday May 5th, 2012 at 1:36 pm #12677
Raam Dev
Username: Raam
Staff Member

Mark, thank you for the suggestion.

I spoke to the lead developer, Jason, and here’s what he said:

Thanks. The next release will include this new Hook.

eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
do_action("ws_plugin__s2member_before_wp_remote_request", get_defined_vars());
unset($__refs, $__v); /* Unset defined __refs, __v. */
/**/
$response = /* Process remote request via ``wp_remote_request()``. */ wp_remote_request($url, $args);
Viewing 10 replies - 1 through 10 (of 10 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.