What to Hook Into to Update a non-s2Member Custom Field on a Billing Modification Form Template?

I am trying to add a non-s2Member custom field (an array, but that’s not the issue since billing modification form submission didn’t kick off the process even when using just a simple string). I can get the field added using a hook into ws_plugin__s2member_during_configure_user_registration on a membership level shortcode template.

From experimentation, I found that a membership upgrade/downgrade (Billing Modification shortcode) uses the same Pro-Form as a new registration. What I can’t figure out is what to hook into to update the profile for an existing user with the custom field when they submit a Billing Modification form.

Thanks in advance.

Have you tried
ws_plugin__s2member_during_configure_user_registration_front_side or
ws_plugin__s2member_during_configure_user_registration_front_side_paid?

Tim,

I’ve tried ws_plugin__s2member_during_configure_user_registration which does not update the custom field when modifying a User, even when simply using a string. I’ll try these 2 and let you know.

Thanks!

Neither of those work either. They don’t return an error, but nothing is being saved when a Billing Modification Form is processed.

I’ve also discovered that I can’t seem to retrieve the data from the array in the database. I’ve tried get_user_field, get_user_option, and get_user_meta. Either nothing is displayed in the dashboard when the product_id field is an array or the word Array is displayed instead of the value of the field. The latter only occurs with get_user_field(). The others simply show nothing.

My code:

<?php
add_action('ws_plugin__s2member_during_configure_user_registration', function ($vars = array())
{
 $user = $vars['user']; // A WP_user object instance.
  $_p   = stripslashes_deep($_POST); // $_POST vars via form submission.
     
  if(!empty($_p['product_id']) && is_string($_p['product_id']))
      $pid = array();
      $pid[] = esc_html($_p['product_id']);
      update_user_option($user->ID, 'product_id', $pid);
});

add_action( 'edit_user_profile', 'sg_add_product_id_to_profile' );

function sg_add_product_id_to_profile ( $user )
{
    ?>
        <h3>Product ID</h3>

        <table class="form-table">
            <tr>
                <th><label for="product_id">Product ID</label></th>
                <td><input type="text" name="product_id" value="<?php echo get_user_field( 'product_id', $user ); ?>" class="regular-text" /></td>
        </tr>

        </table>
    <?php
};

The add_action('ws_plugin__s2member_during_configure_user_registration', function ($vars = array()) works fine when I’m regiatering a new User, but it apparently isn’t called when a User is updated. So my array really does me no good unless I can find the right hook.

As I said the code to display the product_id in the User Profile doesn’t work when I use an array either. There’s nothing I can find in the sample code or s2Member Codex showing anything different being done with get_user_field() to retrieve an array.

For the hook, how about using the WP hook set_user_role instead?

You can try this one:

ws_plugin__s2member_pro_authnet_checkout_post_attr
<?php
add_filter('ws_plugin__s2member_pro_authnet_checkout_post_attr', function ($attr) {
    if (!is_user_logged_in() || empty($_POST['s2member_pro_authnet_checkout'])) {
        return $attr; // Nothing to do here.
    }
    $user_id     = get_current_user_id();
    $post_vars = stripslashes_deep($_POST['s2member_pro_authnet_checkout']);

    if ($user_id && $post_vars) {
        // Your custom code here.
    }
    return $attr;
});

Thanks Jason and Tim!

This doesn’t work at all (either when registering a new member or when upgrading):

add_filter('ws_plugin__s2member_pro_stripe_checkout_post_attr', function ($attr) {
    if (!is_user_logged_in() || empty($_POST['s2member_pro_stripe_checkout'])) {
        return $attr; // Nothing to do here.
    }
    $user_id     = get_current_user_id();
    $post_vars = stripslashes_deep($_POST['s2member_pro_stripe_checkout']);

    if ($user_id && $post_vars) {
      $pid = array();
      $pid[] = esc_html($_p['product_id']);
      update_user_option($user->ID, 'product_id', $pid);
    }
    return $attr;
});

The product_id field is not saved to the WordPress database.

My original code works when registering a new member but not when updating an existing member:

add_action('ws_plugin__s2member_during_configure_user_registration', function ($vars = array())
{
 $user = $vars['user']; // A WP_user object instance.
  $_p   = stripslashes_deep($_POST); // $_POST vars via form submission.
     
  if(!empty($_p['product_id']) && is_string($_p['product_id']))
      $pid = array();
      $pid[] = esc_html($_p['product_id']);
      update_user_option($user->ID, 'product_id', $pid);
});

Thanks.

The code you’re using for the initial checkout/registration looks good to me also. However, that will never work with a billing modification I’m afraid, because the registration hook is never fired in that scenario. So in order to cover the modification scenario you’ll need a separate hook, or one that works in both scenarios.

I noticed a couple of things that I’ll point out in case it helps.

  • The original example that I posted was for Authorize.Net. It should work fine with Stripe also, but just wanted to note that in case you’re actually using Authorize.Net. The Stripe hooks won’t fire for Authorize.Net.

  • You may need to tweak the example that I gave. Based on what you have in the other hook, it looks like this line:

$post_vars = stripslashes_deep($_POST['s2member_pro_stripe_checkout']);

Should probably match what you had in the other:

$post_vars = stripslashes_deep($_POST);

That’s what I’m trying to find: a hook that fires when a billing modification form is submitted. The code you suggested (and, yes, I switched to the stripe version) doesn’t appear to fire at all. I did make the change you suggested and still no-go.

My code works fine at User Registration, but not, of course, when doing a billing modification. Where would I look to see what fires at billing modification? The form is the same in both cases. Or, at least, when I use no custom template for billing modification on my test site, the form called is the same as the one called at user registration.

@JediShark @jaswrks
Hi folks, were you able to get this working?. I have a similar issue, I am using Paypal modification form and want to add some custom fields. Followed https://s2member.com/kb-article/s2member-pro-forms/#-customizing-pro-forms and was able to get the custom fields and the user gets the level upgrade succesfully but whatever is filled in the additional fields won’t get updated into the user profile unless done via [s2member-profile/].

A couple of developers have tried to get it done correctly but the fields info won’t get saved so any suggestion wil be appreciated. Probably if the Stripe or Authorize Net worked I will be able to replicate it.

Thanks,
Eduardo

No, I never got it working. I went in an entirely different direction: switching all the forms to Gravity Forms. There’s some custom code involved in capturing the s2Member fields and right now it isn’t elegant, but it is working. Making that switch was a lot of work because the particular client involved uses many, many different registration forms. If you only had a few, it would not be that bad. It is, of course, another licensing fee, but I use Gravity Forms on almost every website I build so for me that isn’t an issue.

It’s pretty sad because if the additional fields work for a new user (at a desired membership level) should work when upgrading membership. s2member tech Support asked me to run it in a clean installation (by the way I ran into a lot of issues later to restore the widgets configuration, etc.) but even that way the problem persists.

My main concern is that suddenly the communication with Tech Support suddenly stopped (even though I am still a paid user), I have been trying to get a confirmation that they have received any of my last 7 messages in 2 weeks (I understand they may delay on getting the solution but not to confirm communication is received by any of the means I have tried like email to general Tech Support, the messages bubble at their site, directly to @jaswrks or @raamdev email) so I guess I will follow you and give up on this and find another alternative different to s2member pro-form. Once I get it working with another option will let you know so hopefully we can help each other within the forum.

1 Like

@JediShark
Just an update, I was able to solve my issue following the procedure suggested by Tech Support.

The section of the KB Article on customizing Pro-Forms titled Custom Pro-Form Templates that Collect Custom Data is not referring to collecting and saving data for Custom Fields created by s2Member. It’s referring to the more generic user fields that you update via update_user_option().

If you’re updating an s2Member Custom Field, you need to follow the instructions outlined here: https://s2member.com/kb-article/gettingsetting-custom-registrationprofile-fields-configured-w-s2member/

You have to store the data in an array and then update s2member_custom_fields with that array data.

Also used the following article to better understand how to solve it: https://s2member.com/kb-article/how-can-i-modify-the-output-of-certain-types-of-custom-registrationprofile-fields/

To make the story short, I added to the paypal proform template the following (“empresa” should be changed for your own label as well as the database name):

<?php $cf_user_id = get_current_user_id();
		$custom_fields_meta = get_user_meta( $cf_user_id, 'wp1Celes2member_custom_fields', true );
		?>
		<div class="s2member-pro-paypal-form-div s2member-pro-paypal-checkout-form-div">
			<label for="empresa">Empresa: *</label>
			<input class="form-control" type="text" name="empresa" required value="<?php if (isset($custom_fields_meta['empresa'])) { echo $custom_fields_meta['empresa']; } ?>" id="empresa" aria-required="true" />
1 Like