Help Please Custom Fields Not Saving API payment notification

Hello, I’m trying to update a custom user profile field called user_credit using the API payment notification.
All i’m doing is incrementing this field by 1 every time a new payment is made and then save.

When a payment notification comes thru it fires off my php code and changes the field value but does not save it.
I don’t see the User field updated at all on WP User dashboard
When I check The user thru WP Users Dashboard and Click edit user i see the field was Incremented correctly but was not completely saved. If i click on “Update User” button then the changes are saved correctly.

I’m not sure why my code is not saving the changes to that field. Its incrementing the field fine but does not commit the changes and is not saved. Any help would be greatly appreciated.
Thank you…

here is code i’m using in the MU directory for the API notification.
filename is: s2_payment_notification.php
http://example.com/?s2_payment_notification=yes&user_id=%%user_id%%

<?php add_action('init', 's2_payment_notification'); function s2_payment_notification() { if(!empty($_GET['s2_payment_notification']) && $_GET['s2_payment_notification'] === 'yes') // ↑ In my URL, I have `?s2_payment_notification=yes`, that's what I'm looking for here. { if(!empty($_GET['user_id'])) // In my URL, I have `&user_id=%%user_id%%, that's what I'm looking for here. // http://example.com/?s2_payment_notification=yes&user_id=%%user_id%% { // Here I might perform any number of tasks related to this user. $user_id = (integer)$_GET['user_id']; // Add user credit when purchase complete from payment gateway // Assign amount of credit to add to account $add_credit = 1; $custom_fields = get_user_option('s2member_custom_fields', $user_id); // Grab any existing credit from The Unique Custom Field ID configured with s2Member. $credit_sum = $custom_fields['user_credit']; $total = $credit_sum + $add_credit; // Set total credit to field $custom_fields['user_credit'] = $total; update_user_option($user_id, 's2member_custom_fields', $custom_fields); } exit; // We can exit here. There's no reason to continue loading WordPress in this case. } }

This is because s2M saves the custom fields after your function, thus replaces the original values. Fire your function not by “init” hook, but by a wp_cron job with 5 sec delay. At “init” you must set that delay.

Something like this? I’m not sure how to apply to my code above.??

function do_this_in_five_seconds() {

// do something

}
add_action( ‘my_save_event’,‘do_this_in_five_seconds’ );

// put this line inside a function,
// presumably in response to something the user does
// otherwise it will schedule a new event on every page visit

wp_schedule_single_event( time() + 5, ‘my_save_event’ );

// time() + 3600 = one hour from now.

The first part is OK. You also must set “wp_schedule_single_event” in another function, that must run at “init” hook, at payment notification (like you did before).

So sequence is: (1) payment notification arrives -> (2) fires “init” hook -> (3) “wp_schedule_single_event” is set to 5 sec -> (4) next click on the site 5 sec later -> (5) WP cron runs your function to save need values. Thus you must set need values at step (3), otherwise at (5) you will not have need info. Or, can save it at (3) somehow (in DB, ironically…) and read it at (5). That is because (3) and (5) are not in same thread.

Do you think there might be a more elegant way of handling updating a custom field with payment notification without using cron job? wp_schedule_single_event i believe can only be run once every 10 minutes…

“Note that scheduling an event to occur before 10 minutes after an existing event of the same name will be ignored, unless you pass unique values for $args to each”

This seems to be something that should be more simple. In any case i’m willing to pay someone for the working .php file that can simply update custom field when payment notification arrives.

I’m in a pretty similar situation with what nextedge’s code is trying to achieve and I’m trying to figure out why the Payment Notification occasionally won’t update my custom field value.

It seems that this is the exact purpose of the s2member’s Notification API and a fairly common scenario for affiliate or other purposes.

This is because s2M saves the custom fields after your function

Does that mean i couldn’t update my custom field in the “init” hook? Is there any workaround other than using wp cron, another hook after “init”?

Also i put some wp_mail right after where the updating is supposed to happen for logging purpose, and no email was sent after 2 payments for this particular user only (that i know of), the first 2 payments emails got sent just fine. So why doesn’t the Notification init hook work for this user?

In any case, this kb https://s2member.com/kb-article/building-an-api-notification-handler-webhook/ has to be updated to include “pulling custom fields value is possible, but not updating them”

Hello In my case I was updating a custom field every time a payment notification was triggered.
cron job was NOT the solution… “init” hook is fine. The real issue was trying to save an integer value in my custom field. S2member was not saving integer values correctly. My solution was using strval($variable) to convert whatever integer (number) variable to string first and then save. E.g. update_user_option($user_id, ‘s2member_custom_fields’, $custom_fields);

hope that helps…

Hi nextedge, i also did notice the issue with integer values not showing on the dashboard, and like you i solved it by casting them into string.
But i just noticed another puzzling problem a user faced when he gets billed at the end of each month, the first 2 months were fine: custom field values got updated nicely, debug emailer that i placed after the update_user also got sent. However custom field values didn’t get updated this past 2 months, debug email did not get sent either.
I checked the fields for any abnormalities and compared with other normal users’ to no avail.
Thank you anyways for your reply, really appreciate it.

Note: i used update_user_meta instead of update_user_option, but that shouldn’t be a problem.