/var/www/hkosl.com/aga/wp-content/plugins/simple-membership/ipn/swpm_handle_subsc_ipn.php


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
<?php

function swpm_handle_subsc_signup_stand_alone($ipn_data$subsc_ref$unique_ref$swpm_id '') {
    global 
$wpdb;
    
$settings SwpmSettings::get_instance();
    
$members_table_name $wpdb->prefix "swpm_members_tbl";
    
$membership_level $subsc_ref;

    if (isset(
$ipn_data['gateway']) && $ipn_data['gateway'] == 'stripe' && isset($ipn_data['subscr_id'])) {
        
$subscr_id $ipn_data['subscr_id'];
    } else {
        
$subscr_id $unique_ref;
    }

    
swpm_debug_log_subsc("swpm_handle_subsc_signup_stand_alone(). Custom value: " $ipn_data['custom'] . ", Unique reference: " $unique_reftrue);
    
$custom_vars parse_str($ipn_data['custom']);

    if (empty(
$swpm_id)) {
        
//Lets try to find an existing user profile for this payment
        
$email $ipn_data['payer_email'];
        
$query_db $wpdb->get_row($wpdb->prepare("SELECT * FROM $members_table_name WHERE email = %s"$email), OBJECT);
        if (!
$query_db) {//try to retrieve the member details based on the unique_ref
            
swpm_debug_log_subsc("Could not find any record using the given email address (" $email "). Attempting to query database using the unique reference: " $unique_reftrue);
            if (!empty(
$unique_ref)) {
                
$query_db $wpdb->get_row($wpdb->prepare("SELECT * FROM $members_table_name WHERE subscr_id = %s"$unique_ref), OBJECT);
                if (
$query_db) {
                    
$swpm_id $query_db->member_id;
                    
swpm_debug_log_subsc("Found a match in the member database using unique reference. Member ID: " $swpm_idtrue);
                } else {
                    
swpm_debug_log_subsc("Did not find a match for an existing member profile for the given reference. This must me a new payment from a new member."true);
                }
            } else {
                
swpm_debug_log_subsc("Unique reference is missing in the notification so we have to assume that this is not a payment for an existing member."true);
            }
        } else {
            
$swpm_id $query_db->member_id;
            
swpm_debug_log_subsc("Found a match in the member database. Member ID: " $swpm_idtrue);
        }
    }

    if (!empty(
$swpm_id)) {
        
//This is payment from an existing member/user. Update the existing member account
        
swpm_debug_log_subsc("Modifying the existing membership profile... Member ID: " $swpm_idtrue);

        
//Upgrade the member account        
        
$account_state 'active'//This is renewal or upgrade of a previously active account. So the status should be set to active      

        
$resultset $wpdb->get_row($wpdb->prepare("SELECT * FROM $members_table_name where member_id=%d"$swpm_id), OBJECT);
        if (!
$resultset) {
            
swpm_debug_log_subsc("ERROR! Could not find a member account record for the given Member ID: " $swpm_idfalse);
            return;
        }
        
$old_membership_level $resultset->membership_level;

        
//If the payment is for the same/existing membership level, then this is a renewal. Refresh the start date as appropriate.
        
$args = array('swpm_id' => $swpm_id'membership_level' => $membership_level'old_membership_level' => $old_membership_level);
        
$subscription_starts SwpmMemberUtils::calculate_access_start_date_for_account_update($args);
        
$subscription_starts apply_filters('swpm_account_update_subscription_starts'$subscription_starts$args);
        
swpm_debug_log_subsc("Setting access starts date value to: " $subscription_startstrue);

        
swpm_debug_log_subsc("Updating the current membership level (" $old_membership_level ") of this member to the newly paid level (" $membership_level ")"true);
        
//Set account status to active, update level to the newly paid level, update access start date, update subsriber ID (if applicable).
        
$updatedb $wpdb->prepare("UPDATE $members_table_name SET account_state=%s, membership_level=%d,subscription_starts=%s,subscr_id=%s WHERE member_id=%d"$account_state$membership_level$subscription_starts$subscr_id$swpm_id);
        
$results $wpdb->query($updatedb);

        
//Trigger level changed/updated action hook
        
do_action('swpm_membership_level_changed', array('member_id' => $swpm_id'from_level' => $old_membership_level'to_level' => $membership_level));
        
        
//Set Email details for the account upgrade notification
        
$email $ipn_data['payer_email'];
        
$subject $settings->get_value('upgrade-complete-mail-subject');
        if (empty(
$subject)) {
            
$subject "Member Account Upgraded";
        }
        
$body $settings->get_value('upgrade-complete-mail-body');
        if (empty(
$body)) {
            
$body "Your account has been upgraded successfully";
        }
        
$from_address $settings->get_value('email-from');

        
$additional_args = array();
        
$email_body SwpmMiscUtils::replace_dynamic_tags($body$swpm_id$additional_args);
        
$headers 'From: ' $from_address "\r\n";
    }
// End of existing user account upgrade/update
    
else {
        
// create new member account
        
$default_account_status $settings->get_value('default-account-status''active');

        
$data = array();
        
$data['user_name'] = '';
        
$data['password'] = '';

        
$data['first_name'] = $ipn_data['first_name'];
        
$data['last_name'] = $ipn_data['last_name'];
        
$data['email'] = $ipn_data['payer_email'];
        
$data['membership_level'] = $membership_level;
        
$data['subscr_id'] = $unique_ref;
        
$data['gender'] = 'not specified';

        
swpm_debug_log_subsc("Creating new member account. Membership level ID: " $membership_leveltrue);

        
$data['address_street'] = $ipn_data['address_street'];
        
$data['address_city'] = $ipn_data['address_city'];
        
$data['address_state'] = $ipn_data['address_state'];
        
$data['address_zipcode'] = isset($ipn_data['address_zip']) ? $ipn_data['address_zip'] : '';
        
$data['country'] = isset($ipn_data['address_country']) ? $ipn_data['address_country'] : '';
        
$data['member_since'] = $data['subscription_starts'] = $data['last_accessed'] = date("Y-m-d");
        
$data['account_state'] = $default_account_status;
        
$reg_code uniqid();
        
$md5_code md5($reg_code);
        
$data['reg_code'] = $md5_code;
        
$data['referrer'] = $data['extra_info'] = $data['txn_id'] = '';
        
$data['subscr_id'] = $subscr_id;
        
$data['last_accessed_from_ip'] = isset($user_ip) ? $user_ip ''//Save the users IP address

        
$data array_filter($data); //Remove any null values.
        
$wpdb->insert($members_table_name$data); //Create the member record
        
$results $wpdb->get_row($wpdb->prepare("SELECT * FROM $members_table_name where subscr_id=%s and reg_code=%s"$subscr_id$md5_code), OBJECT);
        
$id $results->member_id//Alternatively use $wpdb->insert_id;
        
if (empty($id)) {
            
swpm_debug_log_subsc("Error! Failed to insert a new member record. This request will fail."false);
            return;
        }

        
$separator '?';
        
$url $settings->get_value('registration-page-url');
        if (
strpos($url'?') !== false) {
            
$separator '&';
        }

        
$reg_url $url $separator 'member_id=' $id '&code=' $md5_code;
        
swpm_debug_log_subsc("Member signup URL: " $reg_urltrue);

        
$subject $settings->get_value('reg-prompt-complete-mail-subject');
        if (empty(
$subject)) {
            
$subject "Please complete your registration";
        }
        
$body $settings->get_value('reg-prompt-complete-mail-body');
        if (empty(
$body)) {
            
$body "Please use the following link to complete your registration. \n {reg_link}";
        }
        
$from_address $settings->get_value('email-from');
        
$body html_entity_decode($body);

        
$additional_args = array('reg_link' => $reg_url);
        
$email_body SwpmMiscUtils::replace_dynamic_tags($body$id$additional_args);
        
$headers 'From: ' $from_address "\r\n";
    }

    
$subject apply_filters('swpm_email_signup_upgrade_complete_subject'$subject);
    
$email_body apply_filters('swpm_email_signup_upgrade_complete_body'$email_body);
    
wp_mail($email$subject$email_body$headers);
    
swpm_debug_log_subsc("Member signup/upgrade completion email successfully sent to: " $emailtrue);
}

/*
 * All in one function that can handle notification for refund, cancellation, end of term
 */

function swpm_handle_subsc_cancel_stand_alone($ipn_data$refund false) {

    global 
$wpdb;
    
$members_table_name $wpdb->prefix "swpm_members_tbl";

    
$customvariables SwpmTransactions::parse_custom_var($ipn_data['custom']);
    
$swpm_id $customvariables['swpm_id'];

    
swpm_debug_log_subsc("Refund/Cancellation check - lets see if a member account needs to be deactivated."true);
    
//swpm_debug_log_subsc("Parent txn id: " . $ipn_data['parent_txn_id'] . ", Subscr ID: " . $ipn_data['subscr_id'] . ", SWPM ID: " . $swpm_id, true);

    
if (!empty($swpm_id)) {
        
//This IPN has the SWPM ID. Retrieve the member record using member ID.
        
swpm_debug_log_subsc("Member ID is present. Retrieving member account from the database. Member ID: " $swpm_idtrue);
        
$resultset SwpmMemberUtils::get_user_by_id($swpm_id);
    } else if (isset(
$ipn_data['subscr_id']) && !empty($ipn_data['subscr_id'])) {
        
//This IPN has the subscriber ID. Retrieve the member record using subscr_id.
        
$subscr_id $ipn_data['subscr_id'];
        
swpm_debug_log_subsc("Subscriber ID is present. Retrieving member account from the database. Subscr_id: " $subscr_idtrue);
        
$resultset $wpdb->get_row($wpdb->prepare("SELECT * FROM $members_table_name where subscr_id LIKE %s",  '%' $wpdb->esc_like($subscr_id) . '%'), OBJECT);
    } else {
        
//Refund for a one time transaction. Use the parent transaction ID to retrieve the profile.
        
$subscr_id $ipn_data['parent_txn_id'];
        
$resultset $wpdb->get_row($wpdb->prepare("SELECT * FROM $members_table_name where subscr_id LIKE %s"'%' $wpdb->esc_like($subscr_id) . '%'), OBJECT);
    }

    if (
$resultset) {
        
//We have found a member profile for this notification.

        
$member_id $resultset->member_id;

        
//First, check if this is a refund notification. 
        
if ($refund) {
            
//This is a refund (not just a subscription cancellation or end). So deactivate the account regardless and bail.
            
SwpmMemberUtils::update_account_state($member_id'inactive'); //Set the account status to inactive.
            
swpm_debug_log_subsc("Subscription refund notification received! Member account deactivated."true);
            return;
        }

        
//This is a cancellation or end of subscription term (no refund).
        //Lets retrieve the membership level and details
        
$level_id $resultset->membership_level;
        
swpm_debug_log_subsc("Membership level ID of the member is: " $level_idtrue);
        
$level_row SwpmUtils::get_membership_level_row_by_id($level_id);
        
$subs_duration_type $level_row->subscription_duration_type;

        if (
$subs_duration_type == SwpmMembershipLevel::NO_EXPIRY) {
            
//This is a level with "no expiry" or "until cancelled" duration.
            
swpm_debug_log_subsc('This is a level with "no expiry" or "until cancelled" duration'true);

            
//Deactivate this account as the membership level is "no expiry" or "until cancelled".
            
$account_state 'inactive';
            
SwpmMemberUtils::update_account_state($member_id$account_state);
            
swpm_debug_log_subsc("Subscription cancellation or end of term received! Member account deactivated. Member ID: " $member_idtrue);
        } else if (
$subs_duration_type == SwpmMembershipLevel::FIXED_DATE) {
            
//This is a level with a "fixed expiry date" duration.
            
swpm_debug_log_subsc('This is a level with a "fixed expiry date" duration.'true);
            
swpm_debug_log_subsc('Nothing to do here. The account will expire on the fixed set date.'true);
        } else {
            
//This is a level with "duration" type expiry (example: 30 days, 1 year etc). subscription_period has the duration/period.
            
$subs_period $level_row->subscription_period;
            
$subs_period_unit SwpmMembershipLevel::get_level_duration_type_string($level_row->subscription_duration_type);

            
swpm_debug_log_subsc('This is a level with "duration" type expiry. Duration period: ' $subs_period ', Unit: ' $subs_period_unittrue);
            
swpm_debug_log_subsc('Nothing to do here. The account will expire after the duration time is over.'true);

            
//TODO Later as an improvement. If you wanted to segment the members who have unsubscribed, you can set the account status to "unsubscribed" here. 
            //Make sure the cronjob to do expiry check and deactivate the member accounts treat this status as if it is "active".
        
}

        
$ipn_data['member_id'] = $member_id;
        
do_action('swpm_subscription_payment_cancelled'$ipn_data); //Hook for recurring payment received
    
} else {
        
swpm_debug_log_subsc("No associated active member record found for this notification."false);
        return;
    }
}

function 
swpm_update_member_subscription_start_date_if_applicable($ipn_data) {
    global 
$wpdb;
    
$members_table_name $wpdb->prefix "swpm_members_tbl";
    
$email $ipn_data['payer_email'];
    
$subscr_id $ipn_data['subscr_id'];
    
$account_state SwpmSettings::get_instance()->get_value('default-account-status''active');
    
swpm_debug_log_subsc("Updating subscription start date if applicable for this subscription payment. Subscriber ID: " $subscr_id " Email: " $emailtrue);

    
//We can also query using the email address or SWPM ID (if present in custom var).
    
$query_db $wpdb->get_row($wpdb->prepare("SELECT * FROM $members_table_name WHERE subscr_id = %s"$subscr_id), OBJECT);
    if (
$query_db) {
        
$swpm_id $query_db->member_id;
        
$current_primary_level $query_db->membership_level;
        
swpm_debug_log_subsc("Found a record in the member table. The Member ID of the account to check is: " $swpm_id " Membership Level: " $current_primary_leveltrue);

        
$ipn_data['member_id'] = $swpm_id;
        
do_action('swpm_recurring_payment_received'$ipn_data); //Hook for recurring payment received

        
$subscription_starts = (date("Y-m-d"));

        
$updatedb $wpdb->prepare("UPDATE $members_table_name SET account_state=%s,subscription_starts=%s WHERE member_id=%d"$account_state$subscription_starts$swpm_id);
        
$resultset $wpdb->query($updatedb);
        
swpm_debug_log_subsc("Updated the member profile with current date as the subscription start date."true);
    } else {
        
swpm_debug_log_subsc("Did not find an existing record in the members table for subscriber ID: " $subscr_idtrue);
        
swpm_debug_log_subsc("This is a new subscription payment for a new subscription agreement."true);
    }
}

function 
swpm_debug_log_subsc($message$success$end false) {
    
$settings SwpmSettings::get_instance();
    
$debug_enabled $settings->get_value('enable-debug');
    if (empty(
$debug_enabled)) {//Debug is not enabled
        
return;
    }

    
$debug_log_file_name SIMPLE_WP_MEMBERSHIP_PATH 'log.txt';

    
// Timestamp
    
$text '[' date('m/d/Y g:i A') . '] - ' . (($success) ? 'SUCCESS: ' 'FAILURE: ') . $message "\n";
    if (
$end) {
        
$text .= "\n------------------------------------------------------------------\n\n";
    }
    
// Write to log
    
$fp fopen($debug_log_file_name'a');
    
fwrite($fp$text);
    
fclose($fp);  // close file
}